diff options
Diffstat (limited to 'writerfilter/source/dmapper')
81 files changed, 0 insertions, 36912 deletions
diff --git a/writerfilter/source/dmapper/BorderHandler.cxx b/writerfilter/source/dmapper/BorderHandler.cxx deleted file mode 100644 index 0045805d6e85..000000000000 --- a/writerfilter/source/dmapper/BorderHandler.cxx +++ /dev/null @@ -1,213 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "BorderHandler.hxx" -#include "TDefTableHandler.hxx" -#include "PropertyMap.hxx" -#include "ConversionHelper.hxx" -#include <com/sun/star/table/BorderLine2.hpp> -#include <o3tl/enumarray.hxx> -#include <o3tl/enumrange.hxx> -#include <ooxml/resourceids.hxx> -#include <filter/msfilter/util.hxx> -#include <comphelper/sequence.hxx> -#include <tools/color.hxx> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; - - -BorderHandler::BorderHandler( bool bOOXML ) : -LoggedProperties("BorderHandler"), -m_nLineWidth(15), // Word default, in twips -m_nLineType(0), -m_nLineColor(0), -m_nLineDistance(0), -m_bShadow(false), -m_bOOXML( bOOXML ) -{ - m_aFilledLines.fill(false); - m_aBorderLines.fill(table::BorderLine2()); -} - -BorderHandler::~BorderHandler() -{ -} - -void BorderHandler::lcl_attribute(Id rName, Value & rVal) -{ - sal_Int32 nIntValue = rVal.getInt(); - switch( rName ) - { - case NS_ooxml::LN_CT_Border_sz: - // width of a single line in 1/8 pt, max of 32 pt -> twip * 5 / 2. - m_nLineWidth = nIntValue * 5 / 2; - appendGrabBag("sz", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Border_val: - m_nLineType = nIntValue; - appendGrabBag("val", TDefTableHandler::getBorderTypeString(nIntValue)); - break; - case NS_ooxml::LN_CT_Border_color: - m_nLineColor = nIntValue; - appendGrabBag("color", OUString::fromUtf8(msfilter::util::ConvertColor(Color(ColorTransparency, nIntValue)))); - break; - case NS_ooxml::LN_CT_Border_space: // border distance in points - m_nLineDistance = ConversionHelper::convertTwipToMM100( nIntValue * 20 ); - appendGrabBag("space", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Border_shadow: - m_bShadow = nIntValue; - break; - case NS_ooxml::LN_CT_Border_frame: - case NS_ooxml::LN_CT_Border_themeTint: - appendGrabBag("themeTint", OUString::number(nIntValue, 16)); - break; - case NS_ooxml::LN_CT_Border_themeColor: - appendGrabBag("themeColor", TDefTableHandler::getThemeColorTypeString(nIntValue)); - break; - default: - OSL_FAIL( "unknown attribute"); - } -} - -void BorderHandler::lcl_sprm(Sprm & rSprm) -{ - BorderPosition pos; - const bool rtl = false; // TODO detect - OUString aBorderPos; - switch( rSprm.getId()) - { - case NS_ooxml::LN_CT_TblBorders_top: - pos = BorderPosition::Top; - aBorderPos = "top"; - break; - case NS_ooxml::LN_CT_TblBorders_start: - pos = rtl ? BorderPosition::Right : BorderPosition::Left; - aBorderPos = "start"; - break; - case NS_ooxml::LN_CT_TblBorders_left: - pos = BorderPosition::Left; - aBorderPos = "left"; - break; - case NS_ooxml::LN_CT_TblBorders_bottom: - pos = BorderPosition::Bottom; - aBorderPos = "bottom"; - break; - case NS_ooxml::LN_CT_TblBorders_end: - pos = rtl ? BorderPosition::Left : BorderPosition::Right; - aBorderPos = "end"; - break; - case NS_ooxml::LN_CT_TblBorders_right: - pos = BorderPosition::Right; - aBorderPos = "right"; - break; - case NS_ooxml::LN_CT_TblBorders_insideH: - pos = BorderPosition::Horizontal; - aBorderPos = "insideH"; - break; - case NS_ooxml::LN_CT_TblBorders_insideV: - pos = BorderPosition::Vertical; - aBorderPos = "insideV"; - break; - default: - return; - } - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties) - { - std::vector<beans::PropertyValue> aSavedGrabBag; - if (!m_aInteropGrabBagName.isEmpty()) - { - aSavedGrabBag = m_aInteropGrabBag; - m_aInteropGrabBag.clear(); - } - pProperties->resolve(*this); - if (!m_aInteropGrabBagName.isEmpty()) - { - aSavedGrabBag.push_back(getInteropGrabBag(aBorderPos)); - m_aInteropGrabBag = aSavedGrabBag; - } - } - ConversionHelper::MakeBorderLine( m_nLineWidth, m_nLineType, m_nLineColor, - m_aBorderLines[ pos ], m_bOOXML ); - m_aFilledLines[ pos ] = true; -} - -PropertyMapPtr BorderHandler::getProperties() -{ - static const o3tl::enumarray<BorderPosition, PropertyIds> aPropNames = - { - 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 ) - { - for( auto nProp: o3tl::enumrange<BorderPosition>()) - { - if ( m_aFilledLines[nProp] ) { - pPropertyMap->Insert( aPropNames[nProp], uno::makeAny( m_aBorderLines[nProp] ) ); - } - } - } - return pPropertyMap; -} - -table::BorderLine2 BorderHandler::getBorderLine() -{ - table::BorderLine2 aBorderLine; - ConversionHelper::MakeBorderLine( m_nLineWidth, m_nLineType, m_nLineColor, aBorderLine, m_bOOXML ); - return aBorderLine; -} - - -void BorderHandler::enableInteropGrabBag(const OUString& aName) -{ - m_aInteropGrabBagName = aName; -} - -beans::PropertyValue BorderHandler::getInteropGrabBag(const OUString& aName) -{ - beans::PropertyValue aRet; - if (aName.isEmpty()) - aRet.Name = m_aInteropGrabBagName; - else - aRet.Name = aName; - - aRet.Value <<= comphelper::containerToSequence(m_aInteropGrabBag); - return aRet; -} - -void BorderHandler::appendGrabBag(const OUString& aKey, const OUString& aValue) -{ - beans::PropertyValue aProperty; - aProperty.Name = aKey; - aProperty.Value <<= aValue; - m_aInteropGrabBag.push_back(aProperty); -} - -} //namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/BorderHandler.hxx b/writerfilter/source/dmapper/BorderHandler.hxx deleted file mode 100644 index 1261416760b3..000000000000 --- a/writerfilter/source/dmapper/BorderHandler.hxx +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_BORDERHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_BORDERHANDLER_HXX - -#include <vector> -#include "LoggedResources.hxx" -#include "PropertyMap.hxx" -#include <com/sun/star/table/BorderLine2.hpp> -#include <com/sun/star/beans/PropertyValue.hpp> -#include <o3tl/enumarray.hxx> - -namespace writerfilter::dmapper -{ -class PropertyMap; -class BorderHandler : public LoggedProperties -{ -private: - //todo: order is a guess - enum class BorderPosition - { - Top, - Left, - Bottom, - Right, - Horizontal, - Vertical, - LAST = Vertical - }; - - //values of the current border - sal_Int32 m_nLineWidth; - sal_Int32 m_nLineType; - sal_Int32 m_nLineColor; - sal_Int32 m_nLineDistance; - bool m_bShadow; - bool m_bOOXML; - - o3tl::enumarray<BorderPosition, bool> m_aFilledLines; - o3tl::enumarray<BorderPosition, css::table::BorderLine2> m_aBorderLines; - OUString m_aInteropGrabBagName; - std::vector<css::beans::PropertyValue> m_aInteropGrabBag; - void appendGrabBag(const OUString& aKey, const OUString& aValue); - - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - -public: - explicit BorderHandler( bool bOOXML ); - virtual ~BorderHandler() override; - - PropertyMapPtr getProperties(); - css::table::BorderLine2 getBorderLine(); - sal_Int32 getLineDistance() const { return m_nLineDistance;} - sal_Int32 getLineType() const { return m_nLineType;} - bool getShadow() const { return m_bShadow;} - void enableInteropGrabBag(const OUString& aName); - css::beans::PropertyValue getInteropGrabBag(const OUString& aName = OUString()); -}; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/CellColorHandler.cxx b/writerfilter/source/dmapper/CellColorHandler.cxx deleted file mode 100644 index 193477a31fc2..000000000000 --- a/writerfilter/source/dmapper/CellColorHandler.cxx +++ /dev/null @@ -1,331 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "CellColorHandler.hxx" -#include "PropertyMap.hxx" -#include "TDefTableHandler.hxx" -#include <ooxml/resourceids.hxx> -#include <com/sun/star/drawing/FillStyle.hpp> -#include <com/sun/star/drawing/ShadingPattern.hpp> -#include <filter/msfilter/util.hxx> -#include <comphelper/sequence.hxx> -#include <tools/color.hxx> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; - -CellColorHandler::CellColorHandler() : -LoggedProperties("CellColorHandler"), -m_nShadingPattern( drawing::ShadingPattern::CLEAR ), -m_nColor( 0xffffffff ), -m_nFillColor( 0xffffffff ), -m_bAutoFillColor( true ), -m_bFillSpecified( false ), - m_OutputFormat( Form ) -{ -} - -CellColorHandler::~CellColorHandler() -{ -} - -// ST_Shd strings are converted to integers by the tokenizer, store strings in -// the InteropGrabBag -static uno::Any lcl_ConvertShd(sal_Int32 nIntValue) -{ - OUString aRet; - // This should be in sync with the ST_Shd list in ooxml's model.xml. - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_Shd_clear: aRet = "clear"; break; - case NS_ooxml::LN_Value_ST_Shd_solid: aRet = "solid"; break; - case NS_ooxml::LN_Value_ST_Shd_pct5: aRet = "pct5"; break; - case NS_ooxml::LN_Value_ST_Shd_pct10: aRet = "pct10"; break; - case NS_ooxml::LN_Value_ST_Shd_pct20: aRet = "pct20"; break; - case NS_ooxml::LN_Value_ST_Shd_pct25: aRet = "pct25"; break; - case NS_ooxml::LN_Value_ST_Shd_pct30: aRet = "pct30"; break; - case NS_ooxml::LN_Value_ST_Shd_pct40: aRet = "pct40"; break; - case NS_ooxml::LN_Value_ST_Shd_pct50: aRet = "pct50"; break; - case NS_ooxml::LN_Value_ST_Shd_pct60: aRet = "pct60"; break; - case NS_ooxml::LN_Value_ST_Shd_pct70: aRet = "pct70"; break; - case NS_ooxml::LN_Value_ST_Shd_pct75: aRet = "pct75"; break; - case NS_ooxml::LN_Value_ST_Shd_pct80: aRet = "pct80"; break; - case NS_ooxml::LN_Value_ST_Shd_pct90: aRet = "pct90"; break; - case NS_ooxml::LN_Value_ST_Shd_horzStripe: aRet = "horzStripe"; break; - case NS_ooxml::LN_Value_ST_Shd_vertStripe: aRet = "vertStripe"; break; - case NS_ooxml::LN_Value_ST_Shd_reverseDiagStripe: aRet = "reverseDiagStripe"; break; - case NS_ooxml::LN_Value_ST_Shd_diagStripe: aRet = "diagStripe"; break; - case NS_ooxml::LN_Value_ST_Shd_horzCross: aRet = "horzCross"; break; - case NS_ooxml::LN_Value_ST_Shd_diagCross: aRet = "diagCross"; break; - case NS_ooxml::LN_Value_ST_Shd_thinHorzStripe: aRet = "thinHorzStripe"; break; - case NS_ooxml::LN_Value_ST_Shd_thinVertStripe: aRet = "thinVertStripe"; break; - case NS_ooxml::LN_Value_ST_Shd_thinReverseDiagStripe: aRet = "thinReverseDiagStripe"; break; - case NS_ooxml::LN_Value_ST_Shd_thinDiagStripe: aRet = "thinDiagStripe"; break; - case NS_ooxml::LN_Value_ST_Shd_thinHorzCross: aRet = "thinHorzCross"; break; - case NS_ooxml::LN_Value_ST_Shd_thinDiagCross: aRet = "thinDiagCross"; break; - case NS_ooxml::LN_Value_ST_Shd_pct12: aRet = "pct12"; break; - case NS_ooxml::LN_Value_ST_Shd_pct15: aRet = "pct15"; break; - case NS_ooxml::LN_Value_ST_Shd_pct35: aRet = "pct35"; break; - case NS_ooxml::LN_Value_ST_Shd_pct37: aRet = "pct37"; break; - case NS_ooxml::LN_Value_ST_Shd_pct45: aRet = "pct45"; break; - case NS_ooxml::LN_Value_ST_Shd_pct55: aRet = "pct55"; break; - case NS_ooxml::LN_Value_ST_Shd_pct62: aRet = "pct62"; break; - case NS_ooxml::LN_Value_ST_Shd_pct65: aRet = "pct65"; break; - case NS_ooxml::LN_Value_ST_Shd_pct85: aRet = "pct85"; break; - case NS_ooxml::LN_Value_ST_Shd_pct87: aRet = "pct87"; break; - case NS_ooxml::LN_Value_ST_Shd_pct95: aRet = "pct95"; break; - case NS_ooxml::LN_Value_ST_Shd_nil: aRet = "nil"; break; - } - return uno::makeAny(aRet); -} - -void CellColorHandler::lcl_attribute(Id rName, Value & rVal) -{ - sal_Int32 nIntValue = rVal.getInt(); - switch( rName ) - { - case NS_ooxml::LN_CT_Shd_val: - { - createGrabBag("val", lcl_ConvertShd(nIntValue)); - m_nShadingPattern = nIntValue; - } - break; - case NS_ooxml::LN_CT_Shd_fill: - createGrabBag("fill", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(Color(ColorTransparency, nIntValue))))); - if( nIntValue == sal_Int32(COL_AUTO) ) - nIntValue = 0xffffff; //fill color auto means white - else - m_bAutoFillColor = false; - - m_nFillColor = nIntValue; - m_bFillSpecified = true; - break; - case NS_ooxml::LN_CT_Shd_color: - createGrabBag("color", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(Color(ColorTransparency, nIntValue))))); - if( nIntValue == sal_Int32(COL_AUTO) ) - nIntValue = 0; //shading color auto means black - //color of the shading - m_nColor = nIntValue; - break; - case NS_ooxml::LN_CT_Shd_themeFill: - createGrabBag("themeFill", uno::makeAny(TDefTableHandler::getThemeColorTypeString(nIntValue))); - break; - case NS_ooxml::LN_CT_Shd_themeFillShade: - createGrabBag("themeFillShade", uno::makeAny(OUString::number(nIntValue, 16))); - break; - case NS_ooxml::LN_CT_Shd_themeFillTint: - createGrabBag("themeFillTint", uno::makeAny(OUString::number(nIntValue, 16))); - break; - case NS_ooxml::LN_CT_Shd_themeColor: - createGrabBag("themeColor", uno::makeAny(TDefTableHandler::getThemeColorTypeString(nIntValue))); - break; - case NS_ooxml::LN_CT_Shd_themeShade: - createGrabBag("themeShade", uno::makeAny(OUString::number(nIntValue, 16))); - break; - case NS_ooxml::LN_CT_Shd_themeTint: - createGrabBag("themeTint", uno::makeAny(OUString::number(nIntValue, 16))); - break; - default: - OSL_FAIL( "unknown attribute"); - } -} - -void CellColorHandler::lcl_sprm(Sprm &) {} - -TablePropertyMapPtr CellColorHandler::getProperties() -{ - TablePropertyMapPtr pPropertyMap(new TablePropertyMap); - - // Code from binary word filter (the values are out of 1000) - sal_Int32 nWW8BrushStyle = 0; - switch (m_nShadingPattern) - { - // Clear-Brush - case NS_ooxml::LN_Value_ST_Shd_clear: nWW8BrushStyle = 0; break; - // Solid-Brush - case NS_ooxml::LN_Value_ST_Shd_solid: nWW8BrushStyle = 1000; break; - // Percent values - case NS_ooxml::LN_Value_ST_Shd_pct5: nWW8BrushStyle = 50; break; - case NS_ooxml::LN_Value_ST_Shd_pct10: nWW8BrushStyle = 100; break; - case NS_ooxml::LN_Value_ST_Shd_pct20: nWW8BrushStyle = 200; break; - case NS_ooxml::LN_Value_ST_Shd_pct25: nWW8BrushStyle = 250; break; - case NS_ooxml::LN_Value_ST_Shd_pct30: nWW8BrushStyle = 300; break; - case NS_ooxml::LN_Value_ST_Shd_pct40: nWW8BrushStyle = 400; break; - case NS_ooxml::LN_Value_ST_Shd_pct50: nWW8BrushStyle = 500; break; - case NS_ooxml::LN_Value_ST_Shd_pct60: nWW8BrushStyle = 600; break; - case NS_ooxml::LN_Value_ST_Shd_pct70: nWW8BrushStyle = 700; break; - case NS_ooxml::LN_Value_ST_Shd_pct75: nWW8BrushStyle = 750; break; - case NS_ooxml::LN_Value_ST_Shd_pct80: nWW8BrushStyle = 800; break; - case NS_ooxml::LN_Value_ST_Shd_pct90: nWW8BrushStyle = 900; break; - // Special cases - case NS_ooxml::LN_Value_ST_Shd_horzStripe: nWW8BrushStyle = 333; break; // Dark Horizontal - case NS_ooxml::LN_Value_ST_Shd_vertStripe: nWW8BrushStyle = 333; break; // Dark Vertical - case NS_ooxml::LN_Value_ST_Shd_reverseDiagStripe: nWW8BrushStyle = 333; break; // Dark Forward Diagonal - case NS_ooxml::LN_Value_ST_Shd_diagStripe: nWW8BrushStyle = 333; break; // Dark Backward Diagonal - case NS_ooxml::LN_Value_ST_Shd_horzCross: nWW8BrushStyle = 333; break; // Dark Cross - case NS_ooxml::LN_Value_ST_Shd_diagCross: nWW8BrushStyle = 333; break; // Dark Diagonal Cross - case NS_ooxml::LN_Value_ST_Shd_thinHorzStripe: nWW8BrushStyle = 333; break; // Horizontal - case NS_ooxml::LN_Value_ST_Shd_thinVertStripe: nWW8BrushStyle = 333; break; // Vertical - case NS_ooxml::LN_Value_ST_Shd_thinReverseDiagStripe: nWW8BrushStyle = 333; break; // Forward Diagonal - case NS_ooxml::LN_Value_ST_Shd_thinDiagStripe: nWW8BrushStyle = 333; break; // Backward Diagonal - case NS_ooxml::LN_Value_ST_Shd_thinHorzCross: nWW8BrushStyle = 333; break; // Cross - case NS_ooxml::LN_Value_ST_Shd_thinDiagCross: nWW8BrushStyle = 333; break; // 25 Diagonal Cross - // Different shading types - case NS_ooxml::LN_Value_ST_Shd_pct12: nWW8BrushStyle = 125; break; - case NS_ooxml::LN_Value_ST_Shd_pct15: nWW8BrushStyle = 150; break; - case NS_ooxml::LN_Value_ST_Shd_pct35: nWW8BrushStyle = 350; break; - case NS_ooxml::LN_Value_ST_Shd_pct37: nWW8BrushStyle = 375; break; - case NS_ooxml::LN_Value_ST_Shd_pct45: nWW8BrushStyle = 450; break; - case NS_ooxml::LN_Value_ST_Shd_pct55: nWW8BrushStyle = 550; break; - case NS_ooxml::LN_Value_ST_Shd_pct62: nWW8BrushStyle = 625; break; - case NS_ooxml::LN_Value_ST_Shd_pct65: nWW8BrushStyle = 650; break; - case NS_ooxml::LN_Value_ST_Shd_pct85: nWW8BrushStyle = 850; break; - case NS_ooxml::LN_Value_ST_Shd_pct87: nWW8BrushStyle = 875; break; - case NS_ooxml::LN_Value_ST_Shd_pct95: nWW8BrushStyle = 950; break; - } - - sal_Int32 nApplyColor = 0; - if( !nWW8BrushStyle ) - { - // Clear-Brush - if ( m_bFillSpecified && m_bAutoFillColor ) - nApplyColor = sal_Int32(COL_AUTO); - else - 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; - } - - // Check if it is a 'Character' - if (m_OutputFormat == Character) - { - sal_Int32 nShadingPattern = drawing::ShadingPattern::CLEAR; - switch (m_nShadingPattern) - { - case NS_ooxml::LN_Value_ST_Shd_clear: nShadingPattern = drawing::ShadingPattern::CLEAR; break; - case NS_ooxml::LN_Value_ST_Shd_solid: nShadingPattern = drawing::ShadingPattern::SOLID; break; - case NS_ooxml::LN_Value_ST_Shd_pct5: nShadingPattern = drawing::ShadingPattern::PCT5; break; - case NS_ooxml::LN_Value_ST_Shd_pct10: nShadingPattern = drawing::ShadingPattern::PCT10; break; - case NS_ooxml::LN_Value_ST_Shd_pct20: nShadingPattern = drawing::ShadingPattern::PCT20; break; - case NS_ooxml::LN_Value_ST_Shd_pct25: nShadingPattern = drawing::ShadingPattern::PCT25; break; - case NS_ooxml::LN_Value_ST_Shd_pct30: nShadingPattern = drawing::ShadingPattern::PCT30; break; - case NS_ooxml::LN_Value_ST_Shd_pct40: nShadingPattern = drawing::ShadingPattern::PCT40; break; - case NS_ooxml::LN_Value_ST_Shd_pct50: nShadingPattern = drawing::ShadingPattern::PCT50; break; - case NS_ooxml::LN_Value_ST_Shd_pct60: nShadingPattern = drawing::ShadingPattern::PCT60; break; - case NS_ooxml::LN_Value_ST_Shd_pct70: nShadingPattern = drawing::ShadingPattern::PCT70; break; - case NS_ooxml::LN_Value_ST_Shd_pct75: nShadingPattern = drawing::ShadingPattern::PCT75; break; - case NS_ooxml::LN_Value_ST_Shd_pct80: nShadingPattern = drawing::ShadingPattern::PCT80; break; - case NS_ooxml::LN_Value_ST_Shd_pct90: nShadingPattern = drawing::ShadingPattern::PCT90; break; - case NS_ooxml::LN_Value_ST_Shd_horzStripe: nShadingPattern = drawing::ShadingPattern::HORZ_STRIPE; break; - case NS_ooxml::LN_Value_ST_Shd_vertStripe: nShadingPattern = drawing::ShadingPattern::VERT_STRIPE; break; - case NS_ooxml::LN_Value_ST_Shd_reverseDiagStripe: nShadingPattern = drawing::ShadingPattern::REVERSE_DIAG_STRIPE; break; - case NS_ooxml::LN_Value_ST_Shd_diagStripe: nShadingPattern = drawing::ShadingPattern::DIAG_STRIPE; break; - case NS_ooxml::LN_Value_ST_Shd_horzCross: nShadingPattern = drawing::ShadingPattern::HORZ_CROSS; break; - case NS_ooxml::LN_Value_ST_Shd_diagCross: nShadingPattern = drawing::ShadingPattern::DIAG_CROSS; break; - case NS_ooxml::LN_Value_ST_Shd_thinHorzStripe: nShadingPattern = drawing::ShadingPattern::THIN_HORZ_STRIPE; break; - case NS_ooxml::LN_Value_ST_Shd_thinVertStripe: nShadingPattern = drawing::ShadingPattern::THIN_VERT_STRIPE; break; - case NS_ooxml::LN_Value_ST_Shd_thinReverseDiagStripe: nShadingPattern = drawing::ShadingPattern::THIN_REVERSE_DIAG_STRIPE; break; - case NS_ooxml::LN_Value_ST_Shd_thinDiagStripe: nShadingPattern = drawing::ShadingPattern::THIN_DIAG_STRIPE; break; - case NS_ooxml::LN_Value_ST_Shd_thinHorzCross: nShadingPattern = drawing::ShadingPattern::THIN_HORZ_CROSS; break; - case NS_ooxml::LN_Value_ST_Shd_thinDiagCross: nShadingPattern = drawing::ShadingPattern::THIN_DIAG_CROSS; break; - case NS_ooxml::LN_Value_ST_Shd_pct12: nShadingPattern = drawing::ShadingPattern::PCT12; break; - case NS_ooxml::LN_Value_ST_Shd_pct15: nShadingPattern = drawing::ShadingPattern::PCT15; break; - case NS_ooxml::LN_Value_ST_Shd_pct35: nShadingPattern = drawing::ShadingPattern::PCT35; break; - case NS_ooxml::LN_Value_ST_Shd_pct37: nShadingPattern = drawing::ShadingPattern::PCT37; break; - case NS_ooxml::LN_Value_ST_Shd_pct45: nShadingPattern = drawing::ShadingPattern::PCT45; break; - case NS_ooxml::LN_Value_ST_Shd_pct55: nShadingPattern = drawing::ShadingPattern::PCT55; break; - case NS_ooxml::LN_Value_ST_Shd_pct62: nShadingPattern = drawing::ShadingPattern::PCT62; break; - case NS_ooxml::LN_Value_ST_Shd_pct65: nShadingPattern = drawing::ShadingPattern::PCT65; break; - case NS_ooxml::LN_Value_ST_Shd_pct85: nShadingPattern = drawing::ShadingPattern::PCT85; break; - case NS_ooxml::LN_Value_ST_Shd_pct87: nShadingPattern = drawing::ShadingPattern::PCT87; break; - case NS_ooxml::LN_Value_ST_Shd_pct95: nShadingPattern = drawing::ShadingPattern::PCT95; break; - } - - // Write the shading pattern property - pPropertyMap->Insert(PROP_CHAR_SHADING_VALUE, uno::makeAny( nShadingPattern )); - } - - if (m_OutputFormat == Paragraph && m_nShadingPattern != NS_ooxml::LN_Value_ST_Shd_nil) - { - if (nWW8BrushStyle || !m_bAutoFillColor) - pPropertyMap->Insert(PROP_FILL_STYLE, uno::makeAny(drawing::FillStyle_SOLID)); - else if (m_bFillSpecified) // m_bAutoFillColor == true - pPropertyMap->Insert(PROP_FILL_STYLE, uno::makeAny(drawing::FillStyle_NONE)); - - pPropertyMap->Insert(PROP_FILL_COLOR, uno::makeAny(nApplyColor)); - } - else if ( nWW8BrushStyle || !m_bAutoFillColor || m_bFillSpecified ) - pPropertyMap->Insert( m_OutputFormat == Form ? PROP_BACK_COLOR - : PROP_CHAR_BACK_COLOR, uno::makeAny( nApplyColor )); - - createGrabBag("originalColor", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(Color(ColorTransparency, nApplyColor))))); - - return pPropertyMap; -} - -void CellColorHandler::createGrabBag(const OUString& aName, const uno::Any& rAny) -{ - if (m_aInteropGrabBagName.isEmpty()) - return; - - beans::PropertyValue aValue; - aValue.Name = aName; - aValue.Value = rAny; - m_aInteropGrabBag.push_back(aValue); -} - -void CellColorHandler::enableInteropGrabBag(const OUString& aName) -{ - m_aInteropGrabBagName = aName; -} - -beans::PropertyValue CellColorHandler::getInteropGrabBag() -{ - beans::PropertyValue aRet; - aRet.Name = m_aInteropGrabBagName; - aRet.Value <<= comphelper::containerToSequence(m_aInteropGrabBag); - return aRet; -} - -void CellColorHandler::disableInteropGrabBag() -{ - m_aInteropGrabBagName.clear(); - m_aInteropGrabBag.clear(); -} - -bool CellColorHandler::isInteropGrabBagEnabled() const -{ - return !(m_aInteropGrabBagName.isEmpty()); -} - -} //namespace writerfilter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/CellColorHandler.hxx b/writerfilter/source/dmapper/CellColorHandler.hxx deleted file mode 100644 index a011cd9fd794..000000000000 --- a/writerfilter/source/dmapper/CellColorHandler.hxx +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#pragma once - -#include "LoggedResources.hxx" -#include "PropertyMap.hxx" -#include <vector> - -#include <com/sun/star/beans/PropertyValue.hpp> - -namespace writerfilter::dmapper -{ -class TablePropertyMap; -class CellColorHandler : public LoggedProperties -{ -public: - enum OutputFormat { Form, Paragraph, Character }; // for what part of the document -private: - sal_Int32 m_nShadingPattern; - sal_Int32 m_nColor; - sal_Int32 m_nFillColor; - bool m_bAutoFillColor; - bool m_bFillSpecified; - OutputFormat m_OutputFormat; - - OUString m_aInteropGrabBagName; - std::vector<css::beans::PropertyValue> m_aInteropGrabBag; - - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - - void createGrabBag(const OUString& aName, const css::uno::Any& rValue); - -public: - CellColorHandler( ); - virtual ~CellColorHandler() override; - - TablePropertyMapPtr getProperties(); - - void setOutputFormat( OutputFormat format ) { m_OutputFormat = format; } - - void enableInteropGrabBag(const OUString& aName); - css::beans::PropertyValue getInteropGrabBag(); - void disableInteropGrabBag(); - bool isInteropGrabBagEnabled() const; -}; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/CellMarginHandler.cxx b/writerfilter/source/dmapper/CellMarginHandler.cxx deleted file mode 100644 index 8b7b5fa77c23..000000000000 --- a/writerfilter/source/dmapper/CellMarginHandler.cxx +++ /dev/null @@ -1,177 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "CellMarginHandler.hxx" -#include "ConversionHelper.hxx" -#include <ooxml/resourceids.hxx> -#include <comphelper/propertysequence.hxx> -#include <comphelper/sequence.hxx> -#include <sal/log.hxx> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; -using namespace ::writerfilter; - -CellMarginHandler::CellMarginHandler() : -LoggedProperties("CellMarginHandler"), -m_nValue( 0 ), -m_nWidth( 0 ), -m_nType( 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(); - switch( rName ) - { - case NS_ooxml::LN_CT_TblWidth_w: - m_nWidth = nIntValue; - m_nValue = ConversionHelper::convertTwipToMM100Unsigned( nIntValue ); - break; - case NS_ooxml::LN_CT_TblWidth_type: - SAL_WARN_IF(NS_ooxml::LN_Value_ST_TblWidth_dxa != sal::static_int_cast<Id>(nIntValue), "writerfilter", "CellMarginHandler: cell margins work for absolute values only"); - m_nType = nIntValue; - break; - default: - SAL_WARN("writerfilter", "CellMarginHandler::lcl_attribute: unknown attribute"); - } -} - -void CellMarginHandler::createGrabBag(const OUString& aName) -{ - if (m_aInteropGrabBagName.isEmpty()) - return; - - beans::PropertyValue aRet; - aRet.Name = aName; - - OUString sType; - switch (m_nType) - { - case NS_ooxml::LN_Value_ST_TblWidth_nil: sType = "nil"; break; - case NS_ooxml::LN_Value_ST_TblWidth_pct: sType = "pct"; break; - case NS_ooxml::LN_Value_ST_TblWidth_dxa: sType = "dxa"; break; - case NS_ooxml::LN_Value_ST_TblWidth_auto: sType = "auto"; break; - } - uno::Sequence<beans::PropertyValue> aSeq( comphelper::InitPropertySequence({ - { "w", uno::Any(m_nWidth) }, - { "type", uno::Any(sType) } - })); - - aRet.Value <<= aSeq; - m_aInteropGrabBag.push_back(aRet); -} - -void CellMarginHandler::lcl_sprm(Sprm & rSprm) -{ - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties) - { - pProperties->resolve( *this ); - const bool rtl = false; // TODO - switch( rSprm.getId() ) - { - case NS_ooxml::LN_CT_TblCellMar_top: - case NS_ooxml::LN_CT_TcMar_top: - m_nTopMargin = m_nValue; - m_bTopMarginValid = true; - createGrabBag("top"); - break; - case NS_ooxml::LN_CT_TblCellMar_start: - case NS_ooxml::LN_CT_TcMar_start: - if( rtl ) - { - m_nRightMargin = m_nValue; - m_bRightMarginValid = true; - } - else - { - m_nLeftMargin = m_nValue; - m_bLeftMarginValid = true; - } - createGrabBag("start"); - break; - case NS_ooxml::LN_CT_TblCellMar_left: - case NS_ooxml::LN_CT_TcMar_left: - m_nLeftMargin = m_nValue; - m_bLeftMarginValid = true; - createGrabBag("left"); - break; - case NS_ooxml::LN_CT_TblCellMar_bottom: - case NS_ooxml::LN_CT_TcMar_bottom: - m_nBottomMargin = m_nValue; - m_bBottomMarginValid = true; - createGrabBag("bottom"); - break; - case NS_ooxml::LN_CT_TblCellMar_end: - case NS_ooxml::LN_CT_TcMar_end: - if( rtl ) - { - m_nLeftMargin = m_nValue; - m_bLeftMarginValid = true; - } - else - { - m_nRightMargin = m_nValue; - m_bRightMarginValid = true; - } - createGrabBag("end"); - break; - case NS_ooxml::LN_CT_TblCellMar_right: - case NS_ooxml::LN_CT_TcMar_right: - m_nRightMargin = m_nValue; - m_bRightMarginValid = true; - createGrabBag("right"); - break; - default: - SAL_WARN("writerfilter", "CellMarginHandler::lcl_sprm: unknown sprm"); - } - } - m_nValue = 0; -} - -void CellMarginHandler::enableInteropGrabBag(const OUString& aName) -{ - m_aInteropGrabBagName = aName; -} - -beans::PropertyValue CellMarginHandler::getInteropGrabBag() -{ - beans::PropertyValue aRet; - aRet.Name = m_aInteropGrabBagName; - aRet.Value <<= comphelper::containerToSequence(m_aInteropGrabBag); - return aRet; -} - -} //namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/CellMarginHandler.hxx b/writerfilter/source/dmapper/CellMarginHandler.hxx deleted file mode 100644 index 8dcbf2dc5245..000000000000 --- a/writerfilter/source/dmapper/CellMarginHandler.hxx +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#pragma once - -#include "LoggedResources.hxx" -#include <vector> -#include <com/sun/star/beans/PropertyValue.hpp> - -namespace writerfilter::dmapper -{ -class TablePropertyMap; -class CellMarginHandler : public LoggedProperties -{ -private: - sal_Int32 m_nValue; ///< Converted value. - sal_Int32 m_nWidth; ///< Original value. - sal_Int32 m_nType; ///< Unit of the value (dxa, etc). - - OUString m_aInteropGrabBagName; - std::vector<css::beans::PropertyValue> m_aInteropGrabBag; - - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - - void createGrabBag(const OUString& aName); - -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() override; - - void enableInteropGrabBag(const OUString& aName); - css::beans::PropertyValue getInteropGrabBag(); - -}; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ConversionHelper.cxx b/writerfilter/source/dmapper/ConversionHelper.cxx deleted file mode 100644 index 809e85c90372..000000000000 --- a/writerfilter/source/dmapper/ConversionHelper.cxx +++ /dev/null @@ -1,670 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "ConversionHelper.hxx" -#include <com/sun/star/table/BorderLine2.hpp> -#include <com/sun/star/lang/Locale.hpp> -#include <com/sun/star/text/HoriOrientation.hpp> -#include <com/sun/star/style/NumberingType.hpp> -#include <editeng/borderline.hxx> -#include <ooxml/resourceids.hxx> -#include <rtl/ustrbuf.hxx> -#include <tools/color.hxx> -#include <tools/mapunit.hxx> -#include <tools/UnitConversion.hxx> - -using namespace com::sun::star; - -namespace writerfilter::dmapper::ConversionHelper{ - -/// Convert OOXML border style to WW8 that editeng can handle. -static sal_Int32 lcl_convertBorderStyleFromToken(sal_Int32 nOOXMLType) -{ - switch (nOOXMLType) - { - case NS_ooxml::LN_Value_ST_Border_nil: return 255; - case NS_ooxml::LN_Value_ST_Border_none: return 0; - case NS_ooxml::LN_Value_ST_Border_single: return 1; - case NS_ooxml::LN_Value_ST_Border_thick: return 2; - case NS_ooxml::LN_Value_ST_Border_double: return 3; - case NS_ooxml::LN_Value_ST_Border_dotted: return 6; - case NS_ooxml::LN_Value_ST_Border_dashed: return 7; - case NS_ooxml::LN_Value_ST_Border_dotDash: return 8; - case NS_ooxml::LN_Value_ST_Border_dotDotDash: return 9; - case NS_ooxml::LN_Value_ST_Border_triple: return 10; - case NS_ooxml::LN_Value_ST_Border_thinThickSmallGap: return 11; - case NS_ooxml::LN_Value_ST_Border_thickThinSmallGap: return 12; - case NS_ooxml::LN_Value_ST_Border_thinThickThinSmallGap: return 13; - case NS_ooxml::LN_Value_ST_Border_thinThickMediumGap: return 14; - case NS_ooxml::LN_Value_ST_Border_thickThinMediumGap: return 15; - case NS_ooxml::LN_Value_ST_Border_thinThickThinMediumGap: return 16; - case NS_ooxml::LN_Value_ST_Border_thinThickLargeGap: return 17; - case NS_ooxml::LN_Value_ST_Border_thickThinLargeGap: return 18; - case NS_ooxml::LN_Value_ST_Border_thinThickThinLargeGap: return 19; - case NS_ooxml::LN_Value_ST_Border_wave: return 20; - case NS_ooxml::LN_Value_ST_Border_doubleWave: return 21; - case NS_ooxml::LN_Value_ST_Border_dashSmallGap: return 22; - case NS_ooxml::LN_Value_ST_Border_dashDotStroked: return 23; - case NS_ooxml::LN_Value_ST_Border_threeDEmboss: return 24; - case NS_ooxml::LN_Value_ST_Border_threeDEngrave: return 25; - case NS_ooxml::LN_Value_ST_Border_outset: return 26; - case NS_ooxml::LN_Value_ST_Border_inset: return 27; - case NS_ooxml::LN_Value_ST_Border_apples: return 64; - case NS_ooxml::LN_Value_ST_Border_archedScallops: return 65; - case NS_ooxml::LN_Value_ST_Border_babyPacifier: return 66; - case NS_ooxml::LN_Value_ST_Border_babyRattle: return 67; - case NS_ooxml::LN_Value_ST_Border_balloons3Colors: return 68; - case NS_ooxml::LN_Value_ST_Border_balloonsHotAir: return 69; - case NS_ooxml::LN_Value_ST_Border_basicBlackDashes: return 70; - case NS_ooxml::LN_Value_ST_Border_basicBlackDots: return 71; - case NS_ooxml::LN_Value_ST_Border_basicBlackSquares: return 72; - case NS_ooxml::LN_Value_ST_Border_basicThinLines: return 73; - case NS_ooxml::LN_Value_ST_Border_basicWhiteDashes: return 74; - case NS_ooxml::LN_Value_ST_Border_basicWhiteDots: return 75; - case NS_ooxml::LN_Value_ST_Border_basicWhiteSquares: return 76; - case NS_ooxml::LN_Value_ST_Border_basicWideInline: return 77; - case NS_ooxml::LN_Value_ST_Border_basicWideMidline: return 78; - case NS_ooxml::LN_Value_ST_Border_basicWideOutline: return 79; - case NS_ooxml::LN_Value_ST_Border_bats: return 80; - case NS_ooxml::LN_Value_ST_Border_birds: return 81; - case NS_ooxml::LN_Value_ST_Border_birdsFlight: return 82; - case NS_ooxml::LN_Value_ST_Border_cabins: return 83; - case NS_ooxml::LN_Value_ST_Border_cakeSlice: return 84; - case NS_ooxml::LN_Value_ST_Border_candyCorn: return 85; - case NS_ooxml::LN_Value_ST_Border_celticKnotwork: return 86; - case NS_ooxml::LN_Value_ST_Border_certificateBanner: return 87; - case NS_ooxml::LN_Value_ST_Border_chainLink: return 88; - case NS_ooxml::LN_Value_ST_Border_champagneBottle: return 89; - case NS_ooxml::LN_Value_ST_Border_checkedBarBlack: return 90; - case NS_ooxml::LN_Value_ST_Border_checkedBarColor: return 91; - case NS_ooxml::LN_Value_ST_Border_checkered: return 92; - case NS_ooxml::LN_Value_ST_Border_christmasTree: return 93; - case NS_ooxml::LN_Value_ST_Border_circlesLines: return 94; - case NS_ooxml::LN_Value_ST_Border_circlesRectangles: return 95; - case NS_ooxml::LN_Value_ST_Border_classicalWave: return 96; - case NS_ooxml::LN_Value_ST_Border_clocks: return 97; - case NS_ooxml::LN_Value_ST_Border_compass: return 98; - case NS_ooxml::LN_Value_ST_Border_confetti: return 99; - case NS_ooxml::LN_Value_ST_Border_confettiGrays: return 100; - case NS_ooxml::LN_Value_ST_Border_confettiOutline: return 101; - case NS_ooxml::LN_Value_ST_Border_confettiStreamers: return 102; - case NS_ooxml::LN_Value_ST_Border_confettiWhite: return 103; - case NS_ooxml::LN_Value_ST_Border_cornerTriangles: return 104; - case NS_ooxml::LN_Value_ST_Border_couponCutoutDashes: return 105; - case NS_ooxml::LN_Value_ST_Border_couponCutoutDots: return 106; - case NS_ooxml::LN_Value_ST_Border_crazyMaze: return 107; - case NS_ooxml::LN_Value_ST_Border_creaturesButterfly: return 108; - case NS_ooxml::LN_Value_ST_Border_creaturesFish: return 109; - case NS_ooxml::LN_Value_ST_Border_creaturesInsects: return 110; - case NS_ooxml::LN_Value_ST_Border_creaturesLadyBug: return 111; - case NS_ooxml::LN_Value_ST_Border_crossStitch: return 112; - case NS_ooxml::LN_Value_ST_Border_cup: return 113; - case NS_ooxml::LN_Value_ST_Border_decoArch: return 114; - case NS_ooxml::LN_Value_ST_Border_decoArchColor: return 115; - case NS_ooxml::LN_Value_ST_Border_decoBlocks: return 116; - case NS_ooxml::LN_Value_ST_Border_diamondsGray: return 117; - case NS_ooxml::LN_Value_ST_Border_doubleD: return 118; - case NS_ooxml::LN_Value_ST_Border_doubleDiamonds: return 119; - case NS_ooxml::LN_Value_ST_Border_earth1: return 120; - case NS_ooxml::LN_Value_ST_Border_earth2: return 121; - case NS_ooxml::LN_Value_ST_Border_eclipsingSquares1: return 122; - case NS_ooxml::LN_Value_ST_Border_eclipsingSquares2: return 123; - case NS_ooxml::LN_Value_ST_Border_eggsBlack: return 124; - case NS_ooxml::LN_Value_ST_Border_fans: return 125; - case NS_ooxml::LN_Value_ST_Border_film: return 126; - case NS_ooxml::LN_Value_ST_Border_firecrackers: return 127; - case NS_ooxml::LN_Value_ST_Border_flowersBlockPrint: return 128; - case NS_ooxml::LN_Value_ST_Border_flowersDaisies: return 129; - case NS_ooxml::LN_Value_ST_Border_flowersModern1: return 130; - case NS_ooxml::LN_Value_ST_Border_flowersModern2: return 131; - case NS_ooxml::LN_Value_ST_Border_flowersPansy: return 132; - case NS_ooxml::LN_Value_ST_Border_flowersRedRose: return 133; - case NS_ooxml::LN_Value_ST_Border_flowersRoses: return 134; - case NS_ooxml::LN_Value_ST_Border_flowersTeacup: return 135; - case NS_ooxml::LN_Value_ST_Border_flowersTiny: return 136; - case NS_ooxml::LN_Value_ST_Border_gems: return 137; - case NS_ooxml::LN_Value_ST_Border_gingerbreadMan: return 138; - case NS_ooxml::LN_Value_ST_Border_gradient: return 139; - case NS_ooxml::LN_Value_ST_Border_handmade1: return 140; - case NS_ooxml::LN_Value_ST_Border_handmade2: return 141; - case NS_ooxml::LN_Value_ST_Border_heartBalloon: return 142; - case NS_ooxml::LN_Value_ST_Border_heartGray: return 143; - case NS_ooxml::LN_Value_ST_Border_hearts: return 144; - case NS_ooxml::LN_Value_ST_Border_heebieJeebies: return 145; - case NS_ooxml::LN_Value_ST_Border_holly: return 146; - case NS_ooxml::LN_Value_ST_Border_houseFunky: return 147; - case NS_ooxml::LN_Value_ST_Border_hypnotic: return 148; - case NS_ooxml::LN_Value_ST_Border_iceCreamCones: return 149; - case NS_ooxml::LN_Value_ST_Border_lightBulb: return 150; - case NS_ooxml::LN_Value_ST_Border_lightning1: return 151; - case NS_ooxml::LN_Value_ST_Border_lightning2: return 152; - case NS_ooxml::LN_Value_ST_Border_mapPins: return 153; - case NS_ooxml::LN_Value_ST_Border_mapleLeaf: return 154; - case NS_ooxml::LN_Value_ST_Border_mapleMuffins: return 155; - case NS_ooxml::LN_Value_ST_Border_marquee: return 156; - case NS_ooxml::LN_Value_ST_Border_marqueeToothed: return 157; - case NS_ooxml::LN_Value_ST_Border_moons: return 158; - case NS_ooxml::LN_Value_ST_Border_mosaic: return 159; - case NS_ooxml::LN_Value_ST_Border_musicNotes: return 160; - case NS_ooxml::LN_Value_ST_Border_northwest: return 161; - case NS_ooxml::LN_Value_ST_Border_ovals: return 162; - case NS_ooxml::LN_Value_ST_Border_packages: return 163; - case NS_ooxml::LN_Value_ST_Border_palmsBlack: return 164; - case NS_ooxml::LN_Value_ST_Border_palmsColor: return 165; - case NS_ooxml::LN_Value_ST_Border_paperClips: return 166; - case NS_ooxml::LN_Value_ST_Border_papyrus: return 167; - case NS_ooxml::LN_Value_ST_Border_partyFavor: return 168; - case NS_ooxml::LN_Value_ST_Border_partyGlass: return 169; - case NS_ooxml::LN_Value_ST_Border_pencils: return 170; - case NS_ooxml::LN_Value_ST_Border_people: return 171; - case NS_ooxml::LN_Value_ST_Border_peopleWaving: return 172; - case NS_ooxml::LN_Value_ST_Border_peopleHats: return 173; - case NS_ooxml::LN_Value_ST_Border_poinsettias: return 174; - case NS_ooxml::LN_Value_ST_Border_postageStamp: return 175; - case NS_ooxml::LN_Value_ST_Border_pumpkin1: return 176; - case NS_ooxml::LN_Value_ST_Border_pushPinNote2: return 177; - case NS_ooxml::LN_Value_ST_Border_pushPinNote1: return 178; - case NS_ooxml::LN_Value_ST_Border_pyramids: return 179; - case NS_ooxml::LN_Value_ST_Border_pyramidsAbove: return 180; - case NS_ooxml::LN_Value_ST_Border_quadrants: return 181; - case NS_ooxml::LN_Value_ST_Border_rings: return 182; - case NS_ooxml::LN_Value_ST_Border_safari: return 183; - case NS_ooxml::LN_Value_ST_Border_sawtooth: return 184; - case NS_ooxml::LN_Value_ST_Border_sawtoothGray: return 185; - case NS_ooxml::LN_Value_ST_Border_scaredCat: return 186; - case NS_ooxml::LN_Value_ST_Border_seattle: return 187; - case NS_ooxml::LN_Value_ST_Border_shadowedSquares: return 188; - case NS_ooxml::LN_Value_ST_Border_sharksTeeth: return 189; - case NS_ooxml::LN_Value_ST_Border_shorebirdTracks: return 190; - case NS_ooxml::LN_Value_ST_Border_skyrocket: return 191; - case NS_ooxml::LN_Value_ST_Border_snowflakeFancy: return 192; - case NS_ooxml::LN_Value_ST_Border_snowflakes: return 193; - case NS_ooxml::LN_Value_ST_Border_sombrero: return 194; - case NS_ooxml::LN_Value_ST_Border_southwest: return 195; - case NS_ooxml::LN_Value_ST_Border_stars: return 196; - case NS_ooxml::LN_Value_ST_Border_starsTop: return 197; - case NS_ooxml::LN_Value_ST_Border_stars3d: return 198; - case NS_ooxml::LN_Value_ST_Border_starsBlack: return 199; - case NS_ooxml::LN_Value_ST_Border_starsShadowed: return 200; - case NS_ooxml::LN_Value_ST_Border_sun: return 201; - case NS_ooxml::LN_Value_ST_Border_swirligig: return 202; - case NS_ooxml::LN_Value_ST_Border_tornPaper: return 203; - case NS_ooxml::LN_Value_ST_Border_tornPaperBlack: return 204; - case NS_ooxml::LN_Value_ST_Border_trees: return 205; - case NS_ooxml::LN_Value_ST_Border_triangleParty: return 206; - case NS_ooxml::LN_Value_ST_Border_triangles: return 207; - case NS_ooxml::LN_Value_ST_Border_tribal1: return 208; - case NS_ooxml::LN_Value_ST_Border_tribal2: return 209; - case NS_ooxml::LN_Value_ST_Border_tribal3: return 210; - case NS_ooxml::LN_Value_ST_Border_tribal4: return 211; - case NS_ooxml::LN_Value_ST_Border_tribal5: return 212; - case NS_ooxml::LN_Value_ST_Border_tribal6: return 213; - case NS_ooxml::LN_Value_ST_Border_twistedLines1: return 214; - case NS_ooxml::LN_Value_ST_Border_twistedLines2: return 215; - case NS_ooxml::LN_Value_ST_Border_vine: return 216; - case NS_ooxml::LN_Value_ST_Border_waveline: return 217; - case NS_ooxml::LN_Value_ST_Border_weavingAngles: return 218; - case NS_ooxml::LN_Value_ST_Border_weavingBraid: return 219; - case NS_ooxml::LN_Value_ST_Border_weavingRibbon: return 220; - case NS_ooxml::LN_Value_ST_Border_weavingStrips: return 221; - case NS_ooxml::LN_Value_ST_Border_whiteFlowers: return 222; - case NS_ooxml::LN_Value_ST_Border_woodwork: return 223; - case NS_ooxml::LN_Value_ST_Border_xIllusions: return 224; - case NS_ooxml::LN_Value_ST_Border_zanyTriangles: return 225; - case NS_ooxml::LN_Value_ST_Border_zigZag: return 226; - case NS_ooxml::LN_Value_ST_Border_zigZagStitch: return 227; - default: break; - } - return 0; -} - -void MakeBorderLine( sal_Int32 nLineThickness, sal_Int32 nLineToken, - sal_Int32 nLineColor, - table::BorderLine2& rToFill, bool bIsOOXML ) -{ - static const Color aBorderDefColor[] = - { - // The first item means automatic color (COL_AUTO), but we - // do not use it anyway (see the next statement) .-) - // See also GetLineIndex in sw/source/filter/ww8/ww8par6.cxx - 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 - }; - if(!bIsOOXML && sal::static_int_cast<sal_uInt32>(nLineColor) < SAL_N_ELEMENTS(aBorderDefColor)) - nLineColor = sal_Int32(aBorderDefColor[nLineColor]); - //no auto color for borders - if (nLineColor == sal_Int32(COL_AUTO)) - nLineColor = sal_Int32(COL_BLACK); - - sal_Int32 nLineType = lcl_convertBorderStyleFromToken(nLineToken); - - // 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 deficit up in additional white space or - // object size - SvxBorderLineStyle const nLineStyle( - ::editeng::ConvertBorderStyleFromWord(nLineType)); - rToFill.LineStyle = static_cast<sal_Int16>(nLineStyle); - double const fConverted( (SvxBorderLineStyle::NONE == nLineStyle) ? 0.0 : - ::editeng::ConvertBorderWidthFromWord(nLineStyle, nLineThickness, - nLineType)); - rToFill.LineWidth = convertTwipToMM100(fConverted); - rToFill.Color = nLineColor; -} - -namespace { -void lcl_SwapQuotesInField(OUString &rFmt) -{ - //Swap unescaped " and ' with ' and " - sal_Int32 nLen = rFmt.getLength(); - OUStringBuffer aBuffer( rFmt ); - const sal_Unicode* pFmt = rFmt.getStr(); - for (sal_Int32 nI = 0; nI < nLen; ++nI) - { - if ((pFmt[nI] == '\"') && (!nI || pFmt[nI-1] != '\\')) - aBuffer[nI] = '\''; - else if ((pFmt[nI] == '\'') && (!nI || pFmt[nI-1] != '\\')) - aBuffer[nI] = '\"'; - } - rFmt = aBuffer.makeStringAndClear(); -} -bool lcl_IsNotAM(OUString const & rFmt, sal_Int32 nPos) -{ - return ( - (nPos == rFmt.getLength() - 1) || - ( - (rFmt[nPos+1] != 'M') && - (rFmt[nPos+1] != 'm') - ) - ); -} -} - -OUString ConvertMSFormatStringToSO( - const OUString& rFormat, lang::Locale& rLocale, bool bHijri) -{ - 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(); - OUStringBuffer aNewFormat( sFormat ); - while (nI < nLen) - { - if (aNewFormat[nI] == '\\') - nI++; - else if (aNewFormat[nI] == '\"') - { - ++nI; - //While not at the end and not at an unescaped end quote - while ((nI < nLen) && ((aNewFormat[nI] != '\"') && (aNewFormat[nI-1] != '\\'))) - ++nI; - } - else //normal unquoted section - { - sal_Unicode nChar = aNewFormat[nI]; - if (nChar == 'O') - { - aNewFormat[nI] = 'M'; - bForceNatNum = true; - } - else if (nChar == 'o') - { - aNewFormat[nI] = 'm'; - bForceNatNum = true; - } - else if ((nChar == 'A') && lcl_IsNotAM(sFormat, nI)) - { - aNewFormat[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[nI+1] == 'E')) - { - //todo: this cannot be the right way to replace a part of the string! - aNewFormat[nI] = 'Y'; - aNewFormat[nI + 1] = 'Y'; - aNewFormat.insert(nI + 2, "YY"); - nLen+=2; - nI+=3; - } - bForceJapanese = true; - } - else if (nChar == 'e') - { - if ((nI != nLen-1) && (aNewFormat[nI+1] == 'e')) - { - //todo: this cannot be the right way to replace a part of the string! - aNewFormat[nI] = 'y'; - aNewFormat[nI + 1] = 'y'; - aNewFormat.insert(nI + 2, "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[nI] = '\\'; - aNewFormat.insert(nI + 1, "/"); - nI++; - nLen++; - } - } - ++nI; - } - - if (bForceNatNum) - bForceJapanese = true; - - if (bForceJapanese) - { - rLocale.Language = "ja"; - rLocale.Country = "JP"; - } - - if (bForceNatNum) - { - aNewFormat.insert( 0, "[NatNum1][$-411]"); - } - - if (bHijri) - { - aNewFormat.insert( 0, "[~hijri]"); - } - return aNewFormat.makeStringAndClear(); - -} - -sal_Int32 convertTwipToMM100(sal_Int32 _t) -{ - // It appears that MSO handles large twip values specially, probably legacy 16bit handling, - // anything that's bigger than 32767 appears to be simply ignored. - if( _t >= 0x8000 ) - return 0; - return ::convertTwipToMm100( _t ); -} - -double convertTwipToMM100Double(sal_Int32 _t) -{ - // It appears that MSO handles large twip values specially, probably legacy 16bit handling, - // anything that's bigger than 32767 appears to be simply ignored. - if( _t >= 0x8000 ) - return 0.0; - return _t * 254.0 / 144.0; -} - -sal_uInt32 convertTwipToMM100Unsigned(sal_Int32 _t) -{ - if( _t < 0 ) - return 0; - return convertTwipToMM100( _t ); -} - -text::RubyAdjust convertRubyAlign( sal_Int32 nIntValue ) -{ - text::RubyAdjust rubyAdjust = text::RubyAdjust_LEFT; - switch( nIntValue ) - { - case NS_ooxml::LN_Value_ST_RubyAlign_center: - case NS_ooxml::LN_Value_ST_RubyAlign_rightVertical: - rubyAdjust = text::RubyAdjust_CENTER; - break; - case NS_ooxml::LN_Value_ST_RubyAlign_distributeLetter: - rubyAdjust = text::RubyAdjust_BLOCK; - break; - case NS_ooxml::LN_Value_ST_RubyAlign_distributeSpace: - rubyAdjust = text::RubyAdjust_INDENT_BLOCK; - break; - case NS_ooxml::LN_Value_ST_RubyAlign_left: - rubyAdjust = text::RubyAdjust_LEFT; - break; - case NS_ooxml::LN_Value_ST_RubyAlign_right: - rubyAdjust = text::RubyAdjust_RIGHT; - break; - } - return rubyAdjust; -} - -sal_Int16 convertTableJustification( sal_Int32 nIntValue ) -{ - sal_Int16 nOrient = text::HoriOrientation::LEFT_AND_WIDTH; - switch( nIntValue ) - { - case NS_ooxml::LN_Value_ST_Jc_center: - nOrient = text::HoriOrientation::CENTER; - break; - case NS_ooxml::LN_Value_ST_Jc_right: - case NS_ooxml::LN_Value_ST_Jc_end: - nOrient = text::HoriOrientation::RIGHT; - break; - case NS_ooxml::LN_Value_ST_Jc_left: - case NS_ooxml::LN_Value_ST_Jc_start: - //no break - default:; - - } - return nOrient; -} - -sal_Int16 ConvertNumberingType(sal_Int32 nFmt) -{ - sal_Int16 nRet; - switch(nFmt) - { - case NS_ooxml::LN_Value_ST_NumberFormat_decimal: - nRet = style::NumberingType::ARABIC; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_upperRoman: - nRet = style::NumberingType::ROMAN_UPPER; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman: - nRet = style::NumberingType::ROMAN_LOWER; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_ordinal: - nRet = style::NumberingType::TEXT_NUMBER; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_bullet: - nRet = style::NumberingType::CHAR_SPECIAL; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_none: - nRet = style::NumberingType::NUMBER_NONE; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_upperLetter: - nRet = style::NumberingType::CHARS_UPPER_LETTER_N; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter: - nRet = style::NumberingType::CHARS_LOWER_LETTER_N; - 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_decimalEnclosedCircle: - 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_koreanLegal: - 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_taiwaneseCountingThousand: - case NS_ooxml::LN_Value_ST_NumberFormat_ideographDigital: - case NS_ooxml::LN_Value_ST_NumberFormat_chineseCountingThousand: - nRet = style::NumberingType::NUMBER_LOWER_ZH; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_chineseLegalSimplified: - nRet = style::NumberingType::NUMBER_UPPER_ZH; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_hebrew1: - //91726 - nRet = style::NumberingType::NUMBER_HEBREW; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth: - case NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth2: - nRet = style::NumberingType::FULLWIDTH_ARABIC; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_cardinalText: - nRet = style::NumberingType::TEXT_CARDINAL; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_ordinalText: - nRet = style::NumberingType::TEXT_ORDINAL; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_chicago: - nRet = style::NumberingType::SYMBOL_CHICAGO; - break; - case NS_ooxml::LN_Value_ST_NumberFormat_decimalZero: - nRet = style::NumberingType::ARABIC_ZERO; - 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_hex = 91685; - 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_decimalEnclosedFullstop = 91703; - NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedParen = 91704; - NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiacTraditional = 91709; - 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_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; -} - -sal_Int16 ConvertCustomNumberFormat(std::u16string_view rFormat) -{ - sal_Int16 nRet = -1; - - if (rFormat == u"001, 002, 003, ...") - { - nRet = style::NumberingType::ARABIC_ZERO3; - } - else if (rFormat == u"0001, 0002, 0003, ...") - { - nRet = style::NumberingType::ARABIC_ZERO4; - } - else if (rFormat == u"00001, 00002, 00003, ...") - { - nRet = style::NumberingType::ARABIC_ZERO5; - } - - return nRet; -} - -util::DateTime ConvertDateStringToDateTime( const 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_Int32 nIndex = 0; - OUString sDate = rDateTime.getToken( 0, 'T', nIndex ); - // HACK: this is broken according to the spec, but MSOffice always treats the time as local, - // and writes it as Z (=UTC+0) - 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() ); - if (nIndex != -1) - 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() ); - if (nIndex != -1) - aDateTime.Seconds = sal_uInt16( sTime.copy( nIndex ).toInt32() ); - - return aDateTime; -} - - -} //namespace writerfilter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ConversionHelper.hxx b/writerfilter/source/dmapper/ConversionHelper.hxx deleted file mode 100644 index ad0cd615fbec..000000000000 --- a/writerfilter/source/dmapper/ConversionHelper.hxx +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#pragma once - -#include <sal/types.h> -#include <rtl/ustring.hxx> -#include <com/sun/star/util/DateTime.hpp> -#include <com/sun/star/table/BorderLine2.hpp> -#include <com/sun/star/text/RubyAdjust.hpp> - -namespace com::sun::star{ - namespace lang{ - struct Locale; - } - namespace table{ - struct BorderLine2; - } -} - -namespace writerfilter::dmapper::ConversionHelper{ - - // create a border line and return the distance value - void MakeBorderLine(sal_Int32 nLineThickness, - sal_Int32 nLineType, - sal_Int32 nLineColor, - css::table::BorderLine2& rToFill, - bool bIsOOXML); - //convert the number format string form MS format to SO format - OUString ConvertMSFormatStringToSO(const OUString& rFormat, css::lang::Locale& rLocale, bool bHijri); - // export just for test - SAL_DLLPUBLIC_EXPORT sal_Int32 convertTwipToMM100(sal_Int32 _t); - SAL_DLLPUBLIC_EXPORT double convertTwipToMM100Double(sal_Int32 _t); - SAL_DLLPUBLIC_EXPORT sal_uInt32 convertTwipToMM100Unsigned(sal_Int32 _t); - sal_Int16 convertTableJustification( sal_Int32 nIntValue ); - css::text::RubyAdjust convertRubyAlign( sal_Int32 nIntValue ); - sal_Int16 ConvertNumberingType(sal_Int32 nFmt); - sal_Int16 ConvertCustomNumberFormat(std::u16string_view rFormat); - - css::util::DateTime ConvertDateStringToDateTime(const OUString& rDateTime); -} // namespace writerfilter::dmapper::ConversionHelper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx deleted file mode 100644 index 964abf0e58fd..000000000000 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ /dev/null @@ -1,4112 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "BorderHandler.hxx" -#include "PageBordersHandler.hxx" - -#include "util.hxx" -#include "SdtHelper.hxx" -#include "TagLogger.hxx" -#include "TDefTableHandler.hxx" -#include "DomainMapper_Impl.hxx" -#include "ConversionHelper.hxx" -#include "ModelEventListener.hxx" -#include "MeasureHandler.hxx" -#include <i18nlangtag/languagetag.hxx> -#include <i18nutil/paper.hxx> -#include <ooxml/resourceids.hxx> -#include <oox/token/tokens.hxx> -#include <oox/drawingml/drawingmltypes.hxx> -#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> -#include <com/sun/star/document/XOOXMLDocumentPropertiesImporter.hpp> -#include <com/sun/star/drawing/TextVerticalAdjust.hpp> -#include <com/sun/star/table/BorderLineStyle.hpp> -#include <com/sun/star/table/ShadowFormat.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/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/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/text/FootnoteNumbering.hpp> -#include <com/sun/star/text/TextGridMode.hpp> -#include <com/sun/star/text/XDocumentIndexesSupplier.hpp> -#include <com/sun/star/text/XTextFieldsSupplier.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/text/XTextColumns.hpp> -#include <com/sun/star/text/RubyPosition.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/text/FontEmphasis.hpp> -#include <com/sun/star/awt/CharSet.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <comphelper/types.hxx> -#include <comphelper/storagehelper.hxx> -#include <comphelper/sequence.hxx> -#include <editeng/escapementitem.hxx> -#include <filter/msfilter/util.hxx> -#include <sfx2/DocumentMetadataAccess.hxx> -#include <unotools/mediadescriptor.hxx> - -#include "TextEffectsHandler.hxx" -#include "CellColorHandler.hxx" -#include "SectionColumnHandler.hxx" -#include "GraphicHelpers.hxx" -#include <dmapper/GraphicZOrderHelper.hxx> -#include <tools/diagnose_ex.h> -#include <sal/log.hxx> -#include <tools/UnitConversion.hxx> - -using namespace ::com::sun::star; -using namespace oox; - -namespace writerfilter::dmapper{ - -struct -{ - sal_Int32 h; - bool orient; - sal_Int32 w; -} CT_PageSz; - - -DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xContext, - uno::Reference<io::XInputStream> const& xInputStream, - uno::Reference<lang::XComponent> const& xModel, - bool bRepairStorage, - SourceDocumentType eDocumentType, - utl::MediaDescriptor const & rMediaDesc) : - LoggedProperties("DomainMapper"), - LoggedTable("DomainMapper"), - LoggedStream("DomainMapper"), - m_pImpl(new DomainMapper_Impl(*this, xContext, xModel, eDocumentType, rMediaDesc)), - mbIsSplitPara(false) - ,mbHasControls(false) -{ - // #i24363# tab stops relative to indent - m_pImpl->SetDocumentSettingsProperty( - getPropertyName( PROP_TABS_RELATIVE_TO_INDENT ), - uno::makeAny( false ) ); - m_pImpl->SetDocumentSettingsProperty( - getPropertyName( PROP_SURROUND_TEXT_WRAP_SMALL ), - uno::makeAny( true ) ); - m_pImpl->SetDocumentSettingsProperty( - getPropertyName( PROP_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING ), - uno::makeAny( true ) ); - - // Don't load the default style definitions to avoid weird mix - m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::makeAny(true)); - m_pImpl->SetDocumentSettingsProperty("MsWordCompTrailingBlanks", uno::makeAny(true)); - m_pImpl->SetDocumentSettingsProperty("HeaderSpacingBelowLastPara", - uno::makeAny(true)); - m_pImpl->SetDocumentSettingsProperty("FrameAutowidthWithMorePara", uno::makeAny(true)); - - m_pImpl->SetDocumentSettingsProperty("TabAtLeftIndentForParagraphsInList", uno::makeAny(true)); - - // Initialize RDF metadata, to be able to add statements during the import. - try - { - uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(xModel, uno::UNO_QUERY_THROW); - uno::Reference<embed::XStorage> xStorage = comphelper::OStorageHelper::GetTemporaryStorage(); - OUString aBaseURL = rMediaDesc.getUnpackedValueOrDefault("URL", OUString()); - const uno::Reference<frame::XModel> xModel_(xModel, - uno::UNO_QUERY_THROW); - const uno::Reference<rdf::XURI> xBaseURI(sfx2::createBaseURI(xContext, xModel_, aBaseURL, u"")); - const uno::Reference<task::XInteractionHandler> xHandler; - xDocumentMetadataAccess->loadMetadataFromStorage(xStorage, xBaseURI, xHandler); - } - catch (const uno::Exception&) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize RDF metadata"); - } - - if (eDocumentType == SourceDocumentType::OOXML) { - // tdf#108350 - // In Word since version 2007, the default document font is Calibri 11 pt. - // If a DOCX document doesn't contain font information, we should assume - // the intended font to provide best layout match. - try - { - uno::Reference< beans::XPropertySet > xDefProps(GetTextFactory()->createInstance("com.sun.star.text.Defaults"), - uno::UNO_QUERY_THROW); - xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), css::uno::Any(OUString("Calibri"))); - xDefProps->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), css::uno::Any(double(11))); - } - catch (const uno::Exception&) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "failed to initialize default font"); - } - } - - //import document properties - try - { - m_pImpl->m_xDocumentStorage = comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( - OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xContext, bRepairStorage); - - uno::Reference< uno::XInterface > xTemp = xContext->getServiceManager()->createInstanceWithContext( - "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(m_pImpl->m_xDocumentStorage, - xPropSupplier->getDocumentProperties()); - } - catch( const uno::Exception& ) {} -} - -DomainMapper::~DomainMapper() -{ - try - { - uno::Reference< text::XDocumentIndexesSupplier> xIndexesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY ); - sal_Int32 nIndexes = 0; - if( xIndexesSupplier.is() ) - { - uno::Reference< container::XIndexAccess > xIndexes = xIndexesSupplier->getDocumentIndexes(); - nIndexes = xIndexes->getCount(); - } - // If we have page references, those need updating as well, similar to the indexes. - uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(m_pImpl->GetTextDocument(), uno::UNO_QUERY); - if(xTextFieldsSupplier.is()) - { - uno::Reference<container::XEnumeration> xEnumeration = xTextFieldsSupplier->getTextFields()->createEnumeration(); - while(xEnumeration->hasMoreElements()) - { - ++nIndexes; - xEnumeration->nextElement(); - } - } - - mbHasControls |= m_pImpl->m_pSdtHelper->hasElements(); - if ( nIndexes || mbHasControls ) - { - //index update has to wait until first view is created - uno::Reference< document::XEventBroadcaster > xBroadcaster(xIndexesSupplier, uno::UNO_QUERY); - if (xBroadcaster.is()) - xBroadcaster->addEventListener(uno::Reference< document::XEventListener >(new ModelEventListener(nIndexes, mbHasControls))); - } - - - // Apply the document settings after everything else - m_pImpl->GetSettingsTable()->ApplyProperties( m_pImpl->GetTextDocument( ) ); - - // now that importing is finished, re-enable default styles for any that were never defined/imported. - m_pImpl->SetDocumentSettingsProperty("StylesNoDefault", uno::makeAny(false)); - - // Grab-bag handling - comphelper::SequenceAsHashMap aProperties; - - // Add the saved w:themeFontLang setting - aProperties["ThemeFontLangProps"] <<= m_pImpl->GetSettingsTable()->GetThemeFontLangProperties(); - - // Add the saved compat settings - aProperties["CompatSettings"] <<= m_pImpl->GetSettingsTable()->GetCompatSettings(); - - // Add the saved DocumentProtection settings - aProperties["DocumentProtection"] <<= m_pImpl->GetSettingsTable()->GetDocumentProtectionSettings(); - - // Add the saved w:hyphenationZone setting - aProperties["HyphenationZone"] <<= m_pImpl->GetSettingsTable()->GetHyphenationZone(); - - // Add the saved w:doNotHyphenateCaps setting - aProperties["NoHyphenateCaps"] <<= m_pImpl->GetSettingsTable()->GetNoHyphenateCaps(); - - uno::Reference<beans::XPropertySet> xDocProps(m_pImpl->GetTextDocument(), uno::UNO_QUERY); - if (xDocProps.is()) - { - comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue("InteropGrabBag")); - aGrabBag.update(aProperties); - xDocProps->setPropertyValue("InteropGrabBag", uno::Any(aGrabBag.getAsConstPropertyValueList())); - } - } - catch( const uno::Exception& ) {} - -#ifdef DBG_UTIL - TagLogger::getInstance().endDocument(); -#endif -} - -void DomainMapper::lcl_attribute(Id nName, Value & val) -{ - if (m_pImpl->hasTableManager() && m_pImpl->getTableManager().attribute(nName, val)) - return; - - static const int nSingleLineSpacing = 240; - sal_Int32 nIntValue = val.getInt(); - OUString sStringValue = val.getString(); - - SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext(); - switch( nName ) - { - case NS_ooxml::LN_CT_Lvl_start: - break; - case NS_ooxml::LN_CT_Lvl_numFmt: - break; - case NS_ooxml::LN_CT_Lvl_isLgl: - break; - case NS_ooxml::LN_CT_Lvl_legacy: - break; - case NS_ooxml::LN_CT_AbstractNum_nsid: - break; - case NS_ooxml::LN_CT_AbstractNum_tmpl: - break; - case NS_ooxml::LN_CT_Border_sz: - break; - case NS_ooxml::LN_CT_Border_val: - break; - case NS_ooxml::LN_CT_Border_space: - break; - case NS_ooxml::LN_CT_Border_shadow: - break; - case NS_ooxml::LN_CT_Border_frame: - break; - case NS_ooxml::LN_headerr: - break; - case NS_ooxml::LN_footerr: - break; - case NS_ooxml::LN_endnote: - break; - case NS_ooxml::LN_CT_Bookmark_name: - m_pImpl->SetBookmarkName( sStringValue ); - break; - case NS_ooxml::LN_CT_MarkupRangeBookmark_id: - // add a bookmark range -- this remembers a bookmark starting here - // or, if the bookmark was already started or, if the bookmark was - // already started before, writes out the bookmark - m_pImpl->StartOrEndBookmark( sStringValue ); - break; - case NS_ooxml::LN_CT_MarkupRange_displacedByCustomXml: - break; - case NS_ooxml::LN_NUMBERING: - break; - case NS_ooxml::LN_FONTTABLE: - break; - case NS_ooxml::LN_STYLESHEET: - break; - - case NS_ooxml::LN_CT_Sym_char: - m_pImpl->SetSymbolChar(nIntValue); - break; - case NS_ooxml::LN_CT_Sym_font: - m_pImpl->SetSymbolFont(sStringValue); - break; - case NS_ooxml::LN_CT_Underline_val: - if (m_pImpl->GetTopContext()) - handleUnderlineType(nIntValue, m_pImpl->GetTopContext()); - break; - case NS_ooxml::LN_CT_Color_val: - if (m_pImpl->GetTopContext()) - m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR, uno::makeAny( nIntValue ) ); - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", OUString::fromUtf8(msfilter::util::ConvertColor(Color(ColorTransparency,nIntValue)))); - break; - case NS_ooxml::LN_CT_Underline_color: - if (m_pImpl->GetTopContext()) - { - m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_HAS_COLOR, uno::makeAny( true ) ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_UNDERLINE_COLOR, 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, uno::makeAny( sStringValue )); - if (m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) && m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->isSet(PROP_NUMBERING_RULES)) - { - // Font of the paragraph mark should be used for the numbering as well. - uno::Reference<beans::XPropertySet> xCharStyle(m_pImpl->GetCurrentNumberingCharStyle()); - if (xCharStyle.is()) - xCharStyle->setPropertyValue("CharFontName", uno::makeAny(sStringValue)); - } - } - break; - case NS_ooxml::LN_CT_Fonts_asciiTheme: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeTable::getStringForTheme(nIntValue)); - if (m_pImpl->GetTopContext()) - { - uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, aPropValue ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_ASCII, aPropValue, true, CHAR_GRAB_BAG ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_ASCII, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); - } - break; - case NS_ooxml::LN_CT_Fonts_hAnsi: - break;//unsupported - case NS_ooxml::LN_CT_Fonts_hAnsiTheme: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "hAnsiTheme", ThemeTable::getStringForTheme(nIntValue)); - if (m_pImpl->GetTopContext()) - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_H_ANSI, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); - break; - case NS_ooxml::LN_CT_Fonts_eastAsia: - if (m_pImpl->GetTopContext()) - m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::makeAny( sStringValue )); - break; - case NS_ooxml::LN_CT_Fonts_eastAsiaTheme: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsiaTheme", ThemeTable::getStringForTheme(nIntValue)); - if (m_pImpl->GetTopContext()) - { - uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, aPropValue ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_EAST_ASIA, aPropValue, true, CHAR_GRAB_BAG ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_EAST_ASIA, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); - } - break; - case NS_ooxml::LN_CT_Fonts_cs: - if (m_pImpl->GetTopContext()) - m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, uno::makeAny( sStringValue )); - break; - case NS_ooxml::LN_CT_Fonts_cstheme: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "cstheme", ThemeTable::getStringForTheme(nIntValue)); - if (m_pImpl->GetTopContext()) - { - uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aPropValue ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_CS, aPropValue, true, CHAR_GRAB_BAG ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_CS, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); - } - break; - case NS_ooxml::LN_CT_Spacing_before: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "before", OUString::number(nIntValue)); - if (m_pImpl->GetTopContext()) - // Don't overwrite NS_ooxml::LN_CT_Spacing_beforeAutospacing. - m_pImpl->GetTopContext()->Insert( - PROP_PARA_TOP_MARGIN, - uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(nIntValue))), false); - break; - case NS_ooxml::LN_CT_Spacing_beforeLines: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "beforeLines", OUString::number(nIntValue)); - // We would need to make sure that this doesn't overwrite any - // NS_ooxml::LN_CT_Spacing_before in parent styles before style - // sheet support can be enabled. - if (m_pImpl->GetTopContext() && !IsStyleSheetImport()) - m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false); - break; - case NS_ooxml::LN_CT_Spacing_after: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "after", OUString::number(nIntValue)); - if (m_pImpl->GetTopContext()) - { - // Don't overwrite NS_ooxml::LN_CT_Spacing_afterAutospacing. - m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ), false); - - uno::Any aContextualSpacingFromStyle = m_pImpl->GetPropertyFromParaStyleSheet(PROP_PARA_CONTEXT_MARGIN); - if (aContextualSpacingFromStyle.hasValue()) - // Setting "after" spacing means Writer doesn't inherit - // contextual spacing anymore from style, but Word does. - m_pImpl->GetTopContext()->Insert(PROP_PARA_CONTEXT_MARGIN, aContextualSpacingFromStyle); - } - break; - case NS_ooxml::LN_CT_Spacing_afterLines: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "afterLines", OUString::number(nIntValue)); - // We would need to make sure that this doesn't overwrite any - // NS_ooxml::LN_CT_Spacing_after in parent styles before style - // sheet support can be enabled. - if (m_pImpl->GetTopContext() && !IsStyleSheetImport()) - m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(nIntValue * nSingleLineSpacing / 100)), false); - break; - case NS_ooxml::LN_CT_Spacing_line: //91434 - case NS_ooxml::LN_CT_Spacing_lineRule: //91435 - { - style::LineSpacing aSpacing; - PropertyMapPtr pTopContext = m_pImpl->GetTopContext(); - std::optional<PropertyMap::Property> aLineSpacingVal; - if (pTopContext && (aLineSpacingVal = pTopContext->getProperty(PROP_PARA_LINE_SPACING)) ) - { - aLineSpacingVal->second >>= aSpacing; - } - else - { - //default to single line spacing - aSpacing.Mode = style::LineSpacingMode::FIX; - aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nSingleLineSpacing )); - } - if( nName == NS_ooxml::LN_CT_Spacing_line ) - { - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "line", OUString::number(nIntValue)); - //now set the value depending on the Mode - if( aSpacing.Mode == style::LineSpacingMode::PROP ) - aSpacing.Height = sal_Int16(nIntValue * 100 / nSingleLineSpacing ); - 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_doc_ST_LineSpacingRule_auto) - { - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "auto"); - if (aSpacing.Height >= 0) - { - aSpacing.Mode = style::LineSpacingMode::PROP; - //reinterpret the already set value - aSpacing.Height = sal_Int16( aSpacing.Height * 100 / ConversionHelper::convertTwipToMM100( nSingleLineSpacing )); - } - else - { - // Negative value still means a positive height, - // just the mode is "exact". - aSpacing.Mode = style::LineSpacingMode::FIX; - aSpacing.Height *= -1; - } - } - else if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast) - { - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "atLeast"); - aSpacing.Mode = style::LineSpacingMode::MINIMUM; - } - else // NS_ooxml::LN_Value_doc_ST_LineSpacingRule_exact - { - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "exact"); - aSpacing.Mode = style::LineSpacingMode::FIX; - } - } - if (pTopContext) - pTopContext->Insert(PROP_PARA_LINE_SPACING, uno::makeAny( aSpacing )); - } - break; - case NS_ooxml::LN_CT_Ind_start: - case NS_ooxml::LN_CT_Ind_left: - if (m_pImpl->GetTopContext()) - { - // Word inherits FirstLineIndent property of the numbering, even if ParaLeftMargin is set, Writer does not. - // So copy it explicitly, if necessary. - sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent"); - sal_Int32 nIndentAt = m_pImpl->getCurrentNumberingProperty("IndentAt"); - - sal_Int32 nParaLeftMargin = ConversionHelper::convertTwipToMM100(nIntValue); - if (nParaLeftMargin != 0 && nIndentAt == nParaLeftMargin) - // Avoid direct left margin when it's the same as from the - // numbering. - break; - - if (nFirstLineIndent != 0) - m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false); - - m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, - uno::makeAny(nParaLeftMargin)); - } - break; - case NS_ooxml::LN_CT_Ind_end: - case NS_ooxml::LN_CT_Ind_right: - if (m_pImpl->GetTopContext()) - { - // Word inherits FirstLineIndent/ParaLeftMargin property of the numbering, even if ParaRightMargin is set, Writer does not. - // So copy it explicitly, if necessary. - sal_Int32 nFirstLineIndent = m_pImpl->getCurrentNumberingProperty("FirstLineIndent"); - sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt"); - - if (nFirstLineIndent != 0) - m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false); - if (nParaLeftMargin != 0) - m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false); - - m_pImpl->GetTopContext()->Insert( - PROP_PARA_RIGHT_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100(nIntValue ) )); - } - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "right", OUString::number(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, uno::makeAny( - nValue )); - - // See above, need to inherit left margin from list style when first is set. - sal_Int32 nParaLeftMargin = m_pImpl->getCurrentNumberingProperty("IndentAt"); - if (nParaLeftMargin != 0) - m_pImpl->GetTopContext()->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false); - } - break; - case NS_ooxml::LN_CT_Ind_firstLine: - if (m_pImpl->GetTopContext()) - { - sal_Int32 nFirstLineIndent - = m_pImpl->getCurrentNumberingProperty("FirstLineIndent"); - sal_Int32 nParaFirstLineIndent = ConversionHelper::convertTwipToMM100(nIntValue); - if (nParaFirstLineIndent != 0 && nFirstLineIndent == nParaFirstLineIndent) - // Avoid direct first margin when it's the same as from the - // numbering. - break; - m_pImpl->GetTopContext()->Insert(PROP_PARA_FIRST_LINE_INDENT, - uno::makeAny(nParaFirstLineIndent)); - } - break; - case NS_ooxml::LN_CT_Ind_rightChars: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "rightChars", OUString::number(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, uno::makeAny ( nIntValue != 0 )); - break; - case NS_ooxml::LN_CT_EastAsianLayout_combineBrackets: - if (m_pImpl->GetTopContext()) - { - OUString sCombinePrefix = getBracketStringFromEnum(nIntValue); - OUString sCombineSuffix = getBracketStringFromEnum(nIntValue, false); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_PREFIX, uno::makeAny ( sCombinePrefix )); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_COMBINE_SUFFIX, 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, 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, uno::makeAny ( nIntValue != 0 )); - break; - - case NS_ooxml::LN_CT_PageSz_code: - 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 != static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_PageOrientation_portrait)); - 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 - { - if (nName == NS_ooxml::LN_CT_Language_eastAsia) - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsia", sStringValue); - else if (nName == NS_ooxml::LN_CT_Language_val) - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", sStringValue); - else if (nName == NS_ooxml::LN_CT_Language_bidi) - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "bidi", sStringValue); - lang::Locale aLocale( LanguageTag::convertToLocale( sStringValue)); - 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, - uno::makeAny( aLocale ) ); - } - break; - // See SwWW8ImplReader::GetParagraphAutoSpace() on why these are 100 and 280 - case NS_ooxml::LN_CT_Spacing_beforeAutospacing: - { - sal_Int32 default_spacing = -1; - if (nIntValue) - { - m_pImpl->SetParaAutoBefore(true); - - default_spacing = 100; - if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing()) - { - // 49 is just the old value that should be removed, once the - // root cause in SwTabFrm::MakeAll() is fixed. - if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web) - default_spacing = 49; - else - default_spacing = 280; - } - // required at export (here mainly for StyleSheets) to determine if the setting has changed from grab_bag - m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(default_spacing))); - } - m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING, uno::makeAny( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG ); - } - break; - case NS_ooxml::LN_CT_Spacing_afterAutospacing: - { - sal_Int32 default_spacing = -1; - if (nIntValue) - { - default_spacing = 100; - if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing()) - { - if (m_pImpl->GetSettingsTable()->GetView() == NS_ooxml::LN_Value_doc_ST_View_web) - default_spacing = 49; - else - default_spacing = 280; - } - m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny(ConversionHelper::convertTwipToMM100(default_spacing))); - } - m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING, uno::makeAny( ConversionHelper::convertTwipToMM100(default_spacing) ),true, PARA_GRAB_BAG ); - } - break; - case NS_ooxml::LN_CT_SmartTagRun_uri: - m_pImpl->getSmartTagHandler().setURI(val.getString()); - break; - case NS_ooxml::LN_CT_SmartTagRun_element: - m_pImpl->getSmartTagHandler().setElement(val.getString()); - 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 ambiguous 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_TblBorders_right: - case NS_ooxml::LN_CT_TblBorders_top: - case NS_ooxml::LN_CT_TblBorders_left: - case NS_ooxml::LN_CT_TblBorders_bottom: - //todo: handle cell mar - break; - case NS_ooxml::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_Value_math_ST_Jc_centerGroup: - case NS_ooxml::LN_Value_math_ST_Jc_center: - m_pImpl->appendStarMath(val); - m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_CENTER)); - break; - case NS_ooxml::LN_Value_math_ST_Jc_left: - m_pImpl->appendStarMath(val); - m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_LEFT)); - break; - case NS_ooxml::LN_Value_math_ST_Jc_right: - m_pImpl->appendStarMath(val); - m_pImpl->adjustLastPara(sal_Int8(style::ParagraphAdjust::ParagraphAdjust_RIGHT)); - break; - case NS_ooxml::LN_starmath: - m_pImpl->appendStarMath(val); - 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_ooxml::LN_CT_FramePr_w: - case NS_ooxml::LN_CT_FramePr_h: - case NS_ooxml::LN_CT_FramePr_wrap: - case NS_ooxml::LN_CT_FramePr_hSpace: - case NS_ooxml::LN_CT_FramePr_vSpace: - { - ParagraphProperties* pParaProperties = nullptr; - // handle frame properties at styles - if( m_pImpl->GetTopContextType() == CONTEXT_STYLESHEET ) - pParaProperties = dynamic_cast< ParagraphProperties*>( m_pImpl->GetTopContextOfType( CONTEXT_STYLESHEET ).get() ); - else - pParaProperties = dynamic_cast< ParagraphProperties*>( m_pImpl->GetTopContextOfType( CONTEXT_PARAGRAPH ).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_doc_ST_HAnchor_text: //relative to column - nIntValue = text::RelOrientation::FRAME; break; - case NS_ooxml::LN_Value_doc_ST_HAnchor_margin: nIntValue = text::RelOrientation::PAGE_PRINT_AREA; break; - case NS_ooxml::LN_Value_doc_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_doc_ST_VAnchor_text: //relative to paragraph - nIntValue = text::RelOrientation::FRAME; break; - case NS_ooxml::LN_Value_doc_ST_VAnchor_margin:nIntValue = text::RelOrientation::PAGE_PRINT_AREA ; break; - case NS_ooxml::LN_Value_doc_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 )); - pParaProperties->SetxAlign( text::HoriOrientation::NONE ); - break; - case NS_ooxml::LN_CT_FramePr_xAlign: - switch( nIntValue ) - { - case NS_ooxml::LN_Value_doc_ST_XAlign_center : nIntValue = text::HoriOrientation::CENTER; break; - case NS_ooxml::LN_Value_doc_ST_XAlign_right : nIntValue = text::HoriOrientation::RIGHT; break; - case NS_ooxml::LN_Value_doc_ST_XAlign_inside : nIntValue = text::HoriOrientation::INSIDE; break; - case NS_ooxml::LN_Value_doc_ST_XAlign_outside : nIntValue = text::HoriOrientation::OUTSIDE; break; - case NS_ooxml::LN_Value_doc_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 )); - pParaProperties->SetyAlign( text::VertOrientation::NONE ); - break; - case NS_ooxml::LN_CT_FramePr_yAlign: - switch( nIntValue ) - { - case NS_ooxml::LN_Value_doc_ST_YAlign_top : - case NS_ooxml::LN_Value_doc_ST_YAlign_inside :nIntValue = text::VertOrientation::TOP; break; - case NS_ooxml::LN_Value_doc_ST_YAlign_center :nIntValue = text::VertOrientation::CENTER;break; - case NS_ooxml::LN_Value_doc_ST_YAlign_bottom : - case NS_ooxml::LN_Value_doc_ST_YAlign_outside :nIntValue = text::VertOrientation::BOTTOM;break; - case NS_ooxml::LN_Value_doc_ST_YAlign_inline : - { - // HACK: This is for bnc#780851, where a table has one cell that has w:framePr, - // which causes that paragraph to be converted to a text frame, and the original - // paragraph object no longer exists, which makes table creation fail and furthermore - // it would be missing in the table layout anyway. So actually no letting that paragraph - // be a text frame "fixes" it. I'm not sure what "inline" is supposed to mean in practice - // anyway, so as long as this doesn't cause trouble elsewhere ... - PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH); - if( pContext ) - { - ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() ); - if (pParaContext) - pParaContext->SetFrameMode(false); - } - nIntValue = text::VertOrientation::NONE; - break; - } - default: - nIntValue = text::VertOrientation::NONE; - break; - } - pParaProperties->SetyAlign( nIntValue ); - break; - case NS_ooxml::LN_CT_FramePr_hRule: - switch( nIntValue ) - { - case NS_ooxml::LN_Value_doc_ST_HeightRule_exact: - nIntValue = text::SizeType::FIX; - break; - case NS_ooxml::LN_Value_doc_ST_HeightRule_atLeast: - nIntValue = text::SizeType::MIN; - break; - case NS_ooxml::LN_Value_doc_ST_HeightRule_auto: - //no break; - default:; - nIntValue = text::SizeType::VARIABLE; - } - pParaProperties->SethRule( nIntValue ); - break; - case NS_ooxml::LN_CT_FramePr_wrap: - { - //should be either LN_Value_doc_ST_Wrap_notBeside or LN_Value_doc_ST_Wrap_around or LN_Value_doc_ST_Wrap_auto - OSL_ENSURE( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around || - sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_notBeside || - sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through || - sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none || - sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto, - "wrap not around, not_Beside, through, none or auto?"); - if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through || - sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto ) - pParaProperties->SetWrap ( text::WrapTextMode_DYNAMIC ) ; - else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around) - pParaProperties->SetWrap(text::WrapTextMode_PARALLEL); - else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none) - pParaProperties->SetWrap ( text::WrapTextMode_THROUGH ) ; - else - pParaProperties->SetWrap ( text::WrapTextMode_NONE ) ; - } - break; - case NS_ooxml::LN_CT_FramePr_w: - pParaProperties->Setw(ConversionHelper::convertTwipToMM100(nIntValue)); - break; - case NS_ooxml::LN_CT_FramePr_h: - pParaProperties->Seth(ConversionHelper::convertTwipToMM100(nIntValue)); - break; - case NS_ooxml::LN_CT_FramePr_hSpace: - pParaProperties->SethSpace( ConversionHelper::convertTwipToMM100(nIntValue )); - break; - case NS_ooxml::LN_CT_FramePr_vSpace: - pParaProperties->SetvSpace( ConversionHelper::convertTwipToMM100(nIntValue )); - break; - default:; - } - } - } - break; - 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_EG_RangeMarkupElements_commentRangeStart: - m_pImpl->AddAnnotationPosition( true, nIntValue ); - break; - case NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd: - m_pImpl->AddAnnotationPosition( false, nIntValue ); - break; - case NS_ooxml::LN_CT_Comment_initials: - m_pImpl->SetCurrentRedlineInitials(sStringValue); - break; - case NS_ooxml::LN_token: - m_pImpl->SetCurrentRedlineToken( nIntValue ); - break; - case NS_ooxml::LN_CT_LineNumber_start: - case NS_ooxml::LN_CT_LineNumber_distance: - 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; - OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); - if( pSectionContext ) - pSectionContext->SetLnnMod( nIntValue ); - break; - case NS_ooxml::LN_CT_LineNumber_start: - OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); - if( pSectionContext ) - pSectionContext->SetLnnMin( nIntValue ); - break; - case NS_ooxml::LN_CT_LineNumber_distance: - aSettings.nDistance = ConversionHelper::convertTwipToMM100( nIntValue ); - OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); - if( pSectionContext ) - pSectionContext->SetdxaLnn( nIntValue ); - break; - case NS_ooxml::LN_CT_LineNumber_restart: - aSettings.bRestartAtEachPage = nIntValue == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_LineNumberRestart_newPage); - OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); - if( pSectionContext ) - pSectionContext->SetLnc( nIntValue ); - break; - default:; - } - m_pImpl->SetLineNumberSettings( aSettings ); - } - break; - case NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows: - m_pImpl->StartCustomFootnote(m_pImpl->GetTopContext()); - break; - case NS_ooxml::LN_CT_FtnEdnRef_id: - // footnote or endnote reference id - not needed - break; - case NS_ooxml::LN_CT_Color_themeColor: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeColor", TDefTableHandler::getThemeColorTypeString(nIntValue)); - break; - case NS_ooxml::LN_CT_Color_themeTint: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeTint", OUString::number(nIntValue, 16)); - break; - case NS_ooxml::LN_CT_Color_themeShade: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "themeShade", OUString::number(nIntValue, 16)); - 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 != nullptr) - { - switch( nIntValue ) - { - case NS_ooxml::LN_Value_doc_ST_DocGrid_default: - pSectionContext->SetGridType(text::TextGridMode::NONE); - break; - case NS_ooxml::LN_Value_doc_ST_DocGrid_lines: - pSectionContext->SetGridType(text::TextGridMode::LINES); - break; - case NS_ooxml::LN_Value_doc_ST_DocGrid_linesAndChars: - pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS); - pSectionContext->SetGridSnapToChars( false ); - break; - case NS_ooxml::LN_Value_doc_ST_DocGrid_snapToChars: - pSectionContext->SetGridType(text::TextGridMode::LINES_AND_CHARS); - pSectionContext->SetGridSnapToChars( true ); - break; - default : - OSL_FAIL("unknown SwTextGrid value"); - } - } - } - break; - case NS_ooxml::LN_CT_SdtBlock_sdtContent: - m_pImpl->SetSdt(true); - break; - case NS_ooxml::LN_CT_SdtBlock_sdtEndContent: - m_pImpl->SetSdt(false); - - // It's not possible to insert the relevant property to the character context here: - // the previous, already sent character context may be still active, so the property would be lost. - if (m_pImpl->m_pSdtHelper->isOutsideAParagraph()) - m_pImpl->setParaSdtEndDeferred(true); - else - m_pImpl->setSdtEndDeferred(true); - - if (m_pImpl->m_pSdtHelper->isInsideDropDownControl()) - m_pImpl->m_pSdtHelper->createDropDownControl(); - else if (m_pImpl->m_pSdtHelper->validateDateFormat()) - m_pImpl->m_pSdtHelper->createDateContentControl(); - break; - case NS_ooxml::LN_CT_SdtListItem_displayText: - // TODO handle when this is != value - break; - case NS_ooxml::LN_CT_SdtListItem_value: - m_pImpl->m_pSdtHelper->getDropDownItems().push_back(sStringValue); - break; - case NS_ooxml::LN_CT_SdtDate_fullDate: - m_pImpl->m_pSdtHelper->getDate().append(sStringValue); - break; - case NS_ooxml::LN_CT_Background_color: - if (m_pImpl->GetSettingsTable()->GetDisplayBackgroundShape()) - m_pImpl->m_oBackgroundColor = nIntValue; - break; - case NS_ooxml::LN_CT_PageNumber_start: - if (pSectionContext != nullptr && !m_pImpl->IsAltChunk()) - pSectionContext->SetPageNumber(nIntValue); - break; - case NS_ooxml::LN_CT_PageNumber_fmt: - if (pSectionContext) - { - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_NumberFormat_decimal: - // 1, 2, ... - pSectionContext->SetPageNumberType(style::NumberingType::ARABIC); - break; - case NS_ooxml::LN_Value_ST_NumberFormat_upperLetter: - // A, B, ... - pSectionContext->SetPageNumberType(style::NumberingType::CHARS_UPPER_LETTER_N); - break; - case NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter: - // a, b, ... - pSectionContext->SetPageNumberType(style::NumberingType::CHARS_LOWER_LETTER_N); - break; - case NS_ooxml::LN_Value_ST_NumberFormat_upperRoman: - // I, II, ... - pSectionContext->SetPageNumberType(style::NumberingType::ROMAN_UPPER); - break; - case NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman: - // i, ii, ... - pSectionContext->SetPageNumberType(style::NumberingType::ROMAN_LOWER); - break; - } - } - break; - case NS_ooxml::LN_CT_FtnEdn_type: - // This is the "separator" footnote, ignore its linebreaks/text. - if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator) - m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::ON ); - else - m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF ); - break; - case NS_ooxml::LN_CT_FtnEdn_id: - { - SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState(); - if ( eSkip == SkipFootnoteSeparator::ON ) - m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING ); - else if ( eSkip == SkipFootnoteSeparator::SKIPPING ) - m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF ); - } - break; - case NS_ooxml::LN_CT_DataBinding_prefixMappings: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_prefixMappings", sStringValue); - break; - case NS_ooxml::LN_CT_DataBinding_xpath: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_xpath", sStringValue); - break; - case NS_ooxml::LN_CT_DataBinding_storeItemID: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_storeItemID", sStringValue); - break; - case NS_ooxml::LN_CT_PTab_leader: - case NS_ooxml::LN_CT_PTab_relativeTo: - case NS_ooxml::LN_CT_PTab_alignment: - break; - case NS_ooxml::LN_CT_Cnf_lastRowLastColumn: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowLastColumn", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_lastRowFirstColumn: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowFirstColumn", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_firstRowLastColumn: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowLastColumn", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_oddHBand: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddHBand", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_firstRowFirstColumn: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRowFirstColumn", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_evenVBand: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenVBand", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_evenHBand: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "evenHBand", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_lastColumn: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastColumn", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_firstColumn: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstColumn", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_oddVBand: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "oddVBand", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_lastRow: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRow", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_firstRow: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "firstRow", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Cnf_val: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "val", sStringValue); - break; - case NS_ooxml::LN_CT_DocPartName_val: - { - m_sGlossaryEntryName = sStringValue; - break; - } - case NS_ooxml::LN_CT_DocPartGallery_val: - { - const OUString& sGlossaryEntryGallery = sStringValue; - if(m_pImpl->GetTopContext()) - { - OUString sName = sGlossaryEntryGallery + ":" + m_sGlossaryEntryName; - // Add glossary entry name as a first paragraph in section - m_pImpl->appendTextPortion(sName, m_pImpl->GetTopContext()); - } - break; - } - case NS_ooxml::LN_CT_PermStart_ed: - { - m_pImpl->setPermissionRangeEd(sStringValue); - break; - } - case NS_ooxml::LN_CT_PermStart_edGrp: - { - m_pImpl->setPermissionRangeEdGrp(sStringValue); - break; - } - case NS_ooxml::LN_CT_PermStart_id: - { - m_pImpl->startOrEndPermissionRange(nIntValue); - break; - } - case NS_ooxml::LN_CT_PermEnd_id: - { - m_pImpl->startOrEndPermissionRange(nIntValue); - break; - } - case NS_ooxml::LN_CT_NumFmt_val: - { - try - { - uno::Reference<beans::XPropertySet> xFtnEdnSettings; - if (m_pImpl->IsInFootnoteProperties()) - { - uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier( - m_pImpl->GetTextDocument(), uno::UNO_QUERY); - if (xFootnotesSupplier.is()) - xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings(); - } - else - { - uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier( - m_pImpl->GetTextDocument(), uno::UNO_QUERY); - if (xEndnotesSupplier.is()) - xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings(); - } - if (xFtnEdnSettings.is()) - { - sal_Int16 nNumType = ConversionHelper::ConvertNumberingType(nIntValue); - xFtnEdnSettings->setPropertyValue(getPropertyName(PROP_NUMBERING_TYPE), - uno::makeAny(nNumType)); - } - } - catch (const uno::Exception&) - { - } - } - break; - case NS_ooxml::LN_CT_AltChunk: - { - m_pImpl->HandleAltChunk(sStringValue); - } - break; - default: - SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName); - } -} - -void DomainMapper::lcl_sprm(Sprm & rSprm) -{ - if (!m_pImpl->hasTableManager() || !m_pImpl->getTableManager().sprm(rSprm)) - sprmWithProps(rSprm, m_pImpl->GetTopContext()); -} - -// In rtl-paragraphs the meaning of left/right are to be exchanged -static bool ExchangeLeftRight(const PropertyMapPtr& rContext, DomainMapper_Impl& rImpl) -{ - bool bExchangeLeftRight = false; - sal_Int32 aAdjust; - uno::Any aPropPara = rImpl.GetAnyProperty(PROP_WRITING_MODE, rContext); - if( (aPropPara >>= aAdjust) && aAdjust == text::WritingMode2::RL_TB ) - bExchangeLeftRight = true; - return bExchangeLeftRight; -} - -void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) -{ - // These SPRM's are not specific to any section, so it's expected that there is no context yet. - switch (rSprm.getId()) - { - case NS_ooxml::LN_background_background: - return; - default: - break; - } - - OSL_ENSURE(rContext, "PropertyMap has to be valid!"); - if(!rContext) - return ; - - sal_uInt32 nSprmId = rSprm.getId(); - //needed for page properties - SectionPropertyMap * pSectionContext = m_pImpl->GetSectionContext(); - Value::Pointer_t pValue = rSprm.getValue(); - sal_Int32 nIntValue = pValue->getInt(); - const OUString sStringValue = pValue->getString(); - - switch(nSprmId) - { - case NS_ooxml::LN_CT_PPrBase_jc: - { - bool bExchangeLeftRight = !IsRTFImport() && ExchangeLeftRight(rContext, *m_pImpl); - handleParaJustification(nIntValue, rContext, bExchangeLeftRight); - break; - } - case NS_ooxml::LN_CT_PPrBase_keepLines: - rContext->Insert(PROP_PARA_SPLIT, uno::makeAny(nIntValue == 0)); - break; - case NS_ooxml::LN_CT_PPrBase_keepNext: - rContext->Insert(PROP_PARA_KEEP_TOGETHER, uno::makeAny( nIntValue != 0 ) ); - break; - case NS_ooxml::LN_CT_PPrBase_pageBreakBefore: - rContext->Insert(PROP_BREAK_TYPE, uno::makeAny(nIntValue ? style::BreakType_PAGE_BEFORE : style::BreakType_NONE), /*bOverwrite=*/bool(nIntValue)); - break; - case NS_ooxml::LN_CT_NumPr_ilvl: - if (nIntValue < 0 || 10 <= nIntValue) // Writer can't do everything - { - SAL_INFO("writerfilter", - "unsupported numbering level " << nIntValue); - break; - } - if( IsStyleSheetImport() ) - { - //style sheets cannot have a numbering rule attached - StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() ); - if (pStyleSheetPropertyMap) - pStyleSheetPropertyMap->SetListLevel( static_cast<sal_Int16>(nIntValue) ); - } - else - rContext->Insert( PROP_NUMBERING_LEVEL, uno::makeAny( static_cast<sal_Int16>(nIntValue) )); - break; - case NS_ooxml::LN_CT_NumPr_numId: - { - //convert the ListTable entry to a NumberingRules property and apply it - ListsManager::Pointer pListTable = m_pImpl->GetListTable(); - ListDef::Pointer pList = pListTable->GetList( nIntValue ); - if( IsStyleSheetImport() ) - { - //style sheets cannot have a numbering rule attached - StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() ); - if (pStyleSheetPropertyMap) - pStyleSheetPropertyMap->SetListId( nIntValue ); - } - if( pList ) - { - if( !IsStyleSheetImport() ) - { - uno::Any aRules = uno::makeAny( pList->GetNumberingRules( ) ); - rContext->Insert( PROP_NUMBERING_RULES, aRules ); - PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH); - if (pContext) - { - assert(dynamic_cast<ParagraphPropertyMap*>(pContext.get())); - static_cast<ParagraphPropertyMap*>(pContext.get())->SetListId(pList->GetId()); - } - - // Indentation can came from: - // 1) Paragraph style's numbering's indentation: the current non-style numId has priority over it. - // 2) Numbering's indentation: Writer handles that natively, so it should not be set on rContext. - // 3) Paragraph style's indentation: ditto. - // 4) Direct paragraph formatting: that will came later. - // So no situation where keeping indentation at this point would make sense -> erase. - rContext->Erase(PROP_PARA_FIRST_LINE_INDENT); - rContext->Erase(PROP_PARA_LEFT_MARGIN); - rContext->Erase(PROP_PARA_RIGHT_MARGIN); - } - } - else - { - if( !IsStyleSheetImport() ) - { - // eg. disabled numbering using non-existent numId "0" - rContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny( OUString() ) ); - // disable inheritance of indentation of parent styles - rContext->Insert( PROP_PARA_LEFT_MARGIN, uno::makeAny( sal_Int32(0) ), /*bOverwrite=*/false); - rContext->Insert( PROP_PARA_FIRST_LINE_INDENT, - uno::makeAny( sal_Int32(0) ), /*bOverwrite=*/false); - } - } - } - break; - case NS_ooxml::LN_CT_PPrBase_suppressLineNumbers: - rContext->Insert(PROP_PARA_LINE_NUMBER_COUNT, uno::makeAny( nIntValue == 0 ) ); - break; - case NS_ooxml::LN_inTbl: - break; - case NS_ooxml::LN_tblDepth: - //not handled via sprm but via text( 0x07 ) - break; - case NS_ooxml::LN_CT_FramePr_w: - break; - case NS_ooxml::LN_CT_FramePr_wrap: - break; - - case NS_ooxml::LN_CT_PrBase_pBdr: //paragraph border - resolveSprmProps(*this, rSprm); - break; - case NS_ooxml::LN_CT_PBdr_top: - case NS_ooxml::LN_CT_PBdr_left: - case NS_ooxml::LN_CT_PBdr_bottom: - case NS_ooxml::LN_CT_PBdr_right: - case NS_ooxml::LN_CT_PBdr_between: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - auto pBorderHandler = std::make_shared<BorderHandler>( true ); - pProperties->resolve(*pBorderHandler); - PropertyIds eBorderId = PropertyIds( 0 ); - PropertyIds eBorderDistId = PropertyIds( 0 ); - switch( nSprmId ) - { - case NS_ooxml::LN_CT_PBdr_top: - eBorderId = PROP_TOP_BORDER; - eBorderDistId = PROP_TOP_BORDER_DISTANCE; - break; - case NS_ooxml::LN_CT_PBdr_left: - eBorderId = PROP_LEFT_BORDER; - eBorderDistId = PROP_LEFT_BORDER_DISTANCE; - break; - case NS_ooxml::LN_CT_PBdr_bottom: - eBorderId = PROP_BOTTOM_BORDER ; - eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE; - break; - case NS_ooxml::LN_CT_PBdr_right: - eBorderId = PROP_RIGHT_BORDER; - eBorderDistId = PROP_RIGHT_BORDER_DISTANCE ; - break; - case NS_ooxml::LN_CT_PBdr_between: - //not supported - break; - default:; - } - if( eBorderId ) - rContext->Insert( eBorderId, uno::makeAny( pBorderHandler->getBorderLine()) ); - if(eBorderDistId) - rContext->Insert(eBorderDistId, uno::makeAny( pBorderHandler->getLineDistance())); - if ( nSprmId == NS_ooxml::LN_CT_PBdr_right ) - { - table::ShadowFormat aFormat; - // Word only allows shadows on visible borders - if ( pBorderHandler->getShadow() && pBorderHandler->getBorderLine().LineStyle != table::BorderLineStyle::NONE ) - aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine()); - rContext->Insert(PROP_PARA_SHADOW_FORMAT, uno::makeAny(aFormat)); - } - } - } - break; - case NS_ooxml::LN_CT_PBdr_bar: - break; - case NS_ooxml::LN_CT_PPrBase_suppressAutoHyphens: - rContext->Insert(PROP_PARA_IS_HYPHENATION, uno::makeAny( nIntValue == 0 )); - break; - case NS_ooxml::LN_CT_FramePr_h: - break; - case NS_ooxml::LN_CT_PrBase_shd: - { - //contains fore color, back color and shadow percentage, results in a brush - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - auto pCellColorHandler = std::make_shared<CellColorHandler>(); - pCellColorHandler->setOutputFormat( CellColorHandler::Paragraph ); - bool bEnableTempGrabBag = !pCellColorHandler->isInteropGrabBagEnabled(); - if( bEnableTempGrabBag ) - pCellColorHandler->enableInteropGrabBag( "TempShdPropsGrabBag" ); - - pProperties->resolve(*pCellColorHandler); - rContext->InsertProps(pCellColorHandler->getProperties().get()); - - rContext->Insert(PROP_CHAR_THEME_FILL, pCellColorHandler->getInteropGrabBag().Value, true, PARA_GRAB_BAG); - if(bEnableTempGrabBag) - pCellColorHandler->disableInteropGrabBag(); - } - } - break; - case NS_ooxml::LN_CT_FramePr_vSpace: - break; // sprmPDyaFromText - case NS_ooxml::LN_CT_FramePr_hSpace: - break; // sprmPDxaFromText - case NS_ooxml::LN_CT_FramePr_anchorLock: - break; - case NS_ooxml::LN_CT_PPrBase_widowControl: - { - uno::Any aVal( uno::makeAny( sal_Int8(nIntValue ? 2 : 0 ))); - rContext->Insert( PROP_PARA_WIDOWS, aVal ); - rContext->Insert( PROP_PARA_ORPHANS, aVal ); - } - break; // sprmPFWidowControl - case NS_ooxml::LN_CT_PPrBase_overflowPunct: - rContext->Insert(PROP_PARA_IS_HANGING_PUNCTUATION, uno::makeAny( nIntValue == 0 )); - break; - case NS_ooxml::LN_CT_PPrBase_topLinePunct: - break; - case NS_ooxml::LN_CT_PPrBase_autoSpaceDE: - break; - case NS_ooxml::LN_CT_PPrBase_autoSpaceDN: - break; - case NS_ooxml::LN_CT_PPrBase_textAlignment: - { - sal_Int16 nAlignment = 0; - switch (nIntValue) - { - case NS_ooxml::LN_Value_doc_ST_TextAlignment_top: - nAlignment = 2; - break; - case NS_ooxml::LN_Value_doc_ST_TextAlignment_center: - nAlignment = 3; - break; - case NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline: - nAlignment = 1; - break; - case NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom: - nAlignment = 4; - break; - case NS_ooxml::LN_Value_doc_ST_TextAlignment_auto: - default: - break; - } - rContext->Insert( PROP_PARA_VERT_ALIGNMENT, uno::makeAny( nAlignment) ); - } - break; - case NS_ooxml::LN_CT_PPrBase_textDirection: - { - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_TextDirection_tbRl: - { - m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL); - break; - } - case NS_ooxml::LN_Value_ST_TextDirection_btLr: - { - m_pImpl->SetFrameDirection(text::WritingMode2::BT_LR); - break; - } - case NS_ooxml::LN_Value_ST_TextDirection_lrTbV: - { - m_pImpl->SetFrameDirection(text::WritingMode2::LR_TB); - break; - } - case NS_ooxml::LN_Value_ST_TextDirection_tbRlV: - { - m_pImpl->SetFrameDirection(text::WritingMode2::TB_RL); - break; - } - case NS_ooxml::LN_Value_ST_TextDirection_lrTb: - case NS_ooxml::LN_Value_ST_TextDirection_tbLrV: - default: - SAL_WARN("writerfilter", "DomainMapper::sprmWithProps: unhandled textDirection"); - } - } - break; - case NS_ooxml::LN_CT_PPrBase_outlineLvl: - { - sal_Int16 nLvl = static_cast< sal_Int16 >( nIntValue ); - if( IsStyleSheetImport() ) - { - - StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() ); - if (pStyleSheetPropertyMap) - pStyleSheetPropertyMap->SetOutlineLevel( nLvl ); - } - else - { - nLvl = nLvl >= WW_OUTLINE_MIN && nLvl < WW_OUTLINE_MAX? nLvl+1 : 0; //0 means no outline level set on - rContext->Insert(PROP_OUTLINE_LEVEL, uno::makeAny ( nLvl )); - } - } - break; - case NS_ooxml::LN_CT_PPrBase_bidi: - { - // Four situations to handle: - // 1.) bidi same as previous setting: no adjust change - // 2.) no previous adjust: set appropriate default for this bidi - // 3.) previous adjust and bidi different from previous: swap adjusts - // 4.) previous adjust and no previous bidi: RTL swaps adjust - - const sal_Int16 nWritingMode = nIntValue ? text::WritingMode2::RL_TB : text::WritingMode2::LR_TB; - sal_Int16 nParentBidi = -1; - m_pImpl->GetPropertyFromParaStyleSheet(PROP_WRITING_MODE) >>= nParentBidi; - // Paragraph justification reverses its meaning in an RTL context. - // 1. Only make adjustments if the BiDi changes. - if ( nParentBidi != nWritingMode && !IsRTFImport() ) - { - style::ParagraphAdjust eAdjust = style::ParagraphAdjust(-1); - // 2. no adjust property exists yet - if ( !(m_pImpl->GetAnyProperty(PROP_PARA_ADJUST, rContext) >>= eAdjust) ) - { - // RTL defaults to right adjust - eAdjust = nIntValue ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT; - rContext->Insert(PROP_PARA_ADJUST, uno::makeAny( eAdjust ), /*bOverwrite=*/false); - } - // 3,4. existing adjust: if RTL, then swap. If LTR, but previous was RTL, also swap. - else if ( nIntValue || nParentBidi == sal_Int16(text::WritingMode2::RL_TB) ) - { - if ( eAdjust == style::ParagraphAdjust_RIGHT ) - rContext->Insert(PROP_PARA_ADJUST, uno::makeAny( style::ParagraphAdjust_LEFT )); - else if ( eAdjust == style::ParagraphAdjust_LEFT ) - rContext->Insert(PROP_PARA_ADJUST, uno::makeAny( style::ParagraphAdjust_RIGHT )); - } - } - rContext->Insert(PROP_WRITING_MODE, uno::makeAny( nWritingMode )); - } - - break; - case NS_ooxml::LN_EG_SectPrContents_bidi: - if (pSectionContext != nullptr) - { - const sal_Int16 writingMode = (nIntValue != 0) ? sal_Int16(text::WritingMode2::RL_TB) : sal_Int16(text::WritingMode2::LR_TB); - pSectionContext->Insert(PROP_WRITING_MODE, uno::makeAny(writingMode)); - } - break; - case NS_ooxml::LN_EG_RPrBase_highlight: - { - // MS Word completely ignores character highlighting in character styles. - if ( IsStyleSheetImport() ) - { - const StyleSheetEntryPtr pCurrStyle = GetStyleSheetTable()->GetCurrentEntry(); - if ( pCurrStyle && pCurrStyle->nStyleTypeCode == STYLE_TYPE_CHAR ) - break; - } - - // OOXML import uses an ID - if( IsOOXMLImport() ) - { - sal_Int32 nColor = 0; - if( getColorFromId(nIntValue, nColor) ) - rContext->Insert(PROP_CHAR_HIGHLIGHT, uno::makeAny( nColor )); - } - // RTF import uses the actual color value - else if( IsRTFImport() ) - { - rContext->Insert(PROP_CHAR_HIGHLIGHT, uno::makeAny( nIntValue )); - } - } - break; - case NS_ooxml::LN_EG_RPrBase_em: - rContext->Insert(PROP_CHAR_EMPHASIS, uno::makeAny ( getEmphasisValue (nIntValue))); - break; - case NS_ooxml::LN_EG_RPrBase_emboss: - case NS_ooxml::LN_EG_RPrBase_b: - case NS_ooxml::LN_EG_RPrBase_bCs: - case NS_ooxml::LN_EG_RPrBase_i: - case NS_ooxml::LN_EG_RPrBase_iCs: - case NS_ooxml::LN_EG_RPrBase_strike: - case NS_ooxml::LN_EG_RPrBase_dstrike: - case NS_ooxml::LN_EG_RPrBase_outline: - case NS_ooxml::LN_EG_RPrBase_shadow: - case NS_ooxml::LN_EG_RPrBase_caps: - case NS_ooxml::LN_EG_RPrBase_smallCaps: - case NS_ooxml::LN_EG_RPrBase_vanish: - case NS_ooxml::LN_EG_RPrBase_webHidden: - { - PropertyIds ePropertyId = PROP_CHAR_WEIGHT; //initialized to prevent warning! - switch( nSprmId ) - { - case NS_ooxml::LN_EG_RPrBase_b: - case NS_ooxml::LN_EG_RPrBase_bCs: - ePropertyId = nSprmId != NS_ooxml::LN_EG_RPrBase_bCs ? PROP_CHAR_WEIGHT : PROP_CHAR_WEIGHT_COMPLEX; - break; - case NS_ooxml::LN_EG_RPrBase_i: - case NS_ooxml::LN_EG_RPrBase_iCs: - ePropertyId = nSprmId == NS_ooxml::LN_EG_RPrBase_i ? PROP_CHAR_POSTURE : PROP_CHAR_POSTURE_COMPLEX; - break; - case NS_ooxml::LN_EG_RPrBase_strike: - case NS_ooxml::LN_EG_RPrBase_dstrike: - ePropertyId = PROP_CHAR_STRIKEOUT; - break; - case NS_ooxml::LN_EG_RPrBase_outline: - ePropertyId = PROP_CHAR_CONTOURED; - break; - case NS_ooxml::LN_EG_RPrBase_shadow: - ePropertyId = PROP_CHAR_SHADOWED; - break; - case NS_ooxml::LN_EG_RPrBase_caps: - case NS_ooxml::LN_EG_RPrBase_smallCaps: - ePropertyId = PROP_CHAR_CASE_MAP; - break; - case NS_ooxml::LN_EG_RPrBase_vanish: - case NS_ooxml::LN_EG_RPrBase_webHidden: - ePropertyId = PROP_CHAR_HIDDEN; - break; - case NS_ooxml::LN_EG_RPrBase_emboss: - 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; - uno::Any aStyleVal = m_pImpl->GetPropertyFromParaStyleSheet(ePropertyId); - if( !aStyleVal.hasValue() ) - { - nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ? - 4 : 1; - } - else if(aStyleVal.getValueTypeClass() == uno::TypeClass_FLOAT ) - { - double fDoubleValue = 0; - //only in case of awt::FontWeight - aStyleVal >>= fDoubleValue; - nIntValue = fDoubleValue > 100. ? 0 : 1; - } - else if((aStyleVal >>= nStyleValue) || - (nStyleValue = static_cast<sal_Int16>(comphelper::getEnumAsINT32(aStyleVal))) >= 0 ) - { - nIntValue = NS_ooxml::LN_EG_RPrBase_smallCaps == nSprmId ? - nStyleValue ? 0 : 4 : - nStyleValue ? 0 : 1; - } - else - { - OSL_FAIL( "what type was it"); - } - } - - switch( nSprmId ) - { - case NS_ooxml::LN_EG_RPrBase_b: - case NS_ooxml::LN_EG_RPrBase_bCs: - { - uno::Any aBold( uno::makeAny( nIntValue ? awt::FontWeight::BOLD : awt::FontWeight::NORMAL ) ); - - rContext->Insert(ePropertyId, aBold ); - if( nSprmId != NS_ooxml::LN_EG_RPrBase_bCs ) - rContext->Insert(PROP_CHAR_WEIGHT_ASIAN, aBold ); - - uno::Reference<beans::XPropertySet> xCharStyle(m_pImpl->GetCurrentNumberingCharStyle()); - if (xCharStyle.is()) - xCharStyle->setPropertyValue(getPropertyName(PROP_CHAR_WEIGHT), aBold); - if (nSprmId == NS_ooxml::LN_EG_RPrBase_b) - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "b", OUString::number(nIntValue)); - else if (nSprmId == NS_ooxml::LN_EG_RPrBase_bCs) - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "bCs", OUString::number(nIntValue)); - } - break; - case NS_ooxml::LN_EG_RPrBase_i: - case NS_ooxml::LN_EG_RPrBase_iCs: - { - uno::Any aPosture( uno::makeAny( nIntValue ? awt::FontSlant_ITALIC : awt::FontSlant_NONE ) ); - rContext->Insert( ePropertyId, aPosture ); - if (nSprmId != NS_ooxml::LN_EG_RPrBase_iCs) - rContext->Insert(PROP_CHAR_POSTURE_ASIAN, aPosture ); - if (nSprmId == NS_ooxml::LN_EG_RPrBase_i) - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "i", OUString::number(nIntValue)); - } - break; - case NS_ooxml::LN_EG_RPrBase_strike: - rContext->Insert(ePropertyId, - uno::makeAny( nIntValue ? awt::FontStrikeout::SINGLE : awt::FontStrikeout::NONE ) ); - break; - case NS_ooxml::LN_EG_RPrBase_dstrike: - rContext->Insert(ePropertyId, - uno::makeAny( nIntValue ? awt::FontStrikeout::DOUBLE : awt::FontStrikeout::NONE ) ); - break; - case NS_ooxml::LN_EG_RPrBase_outline: - case NS_ooxml::LN_EG_RPrBase_shadow: - case NS_ooxml::LN_EG_RPrBase_vanish: - case NS_ooxml::LN_EG_RPrBase_webHidden: - rContext->Insert(ePropertyId, uno::makeAny( nIntValue != 0 )); - break; - case NS_ooxml::LN_EG_RPrBase_smallCaps: - // If smallcaps would be just disabled and another casemap is already inserted, don't do anything. - if (nIntValue || !rContext->isSet(ePropertyId) ) - rContext->Insert(ePropertyId, uno::makeAny( nIntValue ? style::CaseMap::SMALLCAPS : style::CaseMap::NONE)); - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "smallCaps", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_EG_RPrBase_caps: - rContext->Insert(ePropertyId, - uno::makeAny( nIntValue ? style::CaseMap::UPPERCASE : style::CaseMap::NONE)); - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "caps", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_EG_RPrBase_emboss: - rContext->Insert(ePropertyId, - uno::makeAny( nIntValue ? awt::FontRelief::EMBOSSED : awt::FontRelief::NONE )); - break; - - } - } - } - break; - case NS_ooxml::LN_EG_RPrBase_sz: - case NS_ooxml::LN_EG_RPrBase_szCs: - { - //multiples of half points (12pt == 24) - double fVal = double(nIntValue) / 2.; - uno::Any aVal = uno::makeAny( fVal ); - if( NS_ooxml::LN_EG_RPrBase_szCs == nSprmId ) - { - rContext->Insert( PROP_CHAR_HEIGHT_COMPLEX, aVal ); - } - else - { - const RubyInfo &aInfo = m_pImpl->GetRubyInfo(); - if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt && aInfo.nHps > 0 ) - { - fVal = double(aInfo.nHps) / 2.; - aVal <<= fVal; - } - else if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase && aInfo.nHpsBaseText > 0 ) - { - fVal = double(aInfo.nHpsBaseText) / 2.; - aVal <<= fVal; - } - //Asian get the same value as Western - rContext->Insert( PROP_CHAR_HEIGHT, aVal ); - rContext->Insert( PROP_CHAR_HEIGHT_ASIAN, aVal ); - - uno::Reference<beans::XPropertySet> xCharStyle(m_pImpl->GetCurrentNumberingCharStyle()); - if (xCharStyle.is()) - xCharStyle->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), aVal); - } - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, (nSprmId == NS_ooxml::LN_EG_RPrBase_sz ? OUString("sz") : OUString("szCs")), OUString::number(nIntValue)); - } - break; - case NS_ooxml::LN_EG_RPrBase_position: - // The spec says 0 is the same as the lack of the value, so don't parse that. - if ( nIntValue ) - { - if ( !IsStyleSheetImport() ) - m_pImpl->deferCharacterProperty( nSprmId, uno::makeAny( nIntValue )); - else if (!m_pImpl->IsDocDefaultsImport()) - { - // For some undocumented reason, MS Word seems to ignore this in docDefaults - - // DON'T FIXME: Truly calculating this for Character Styles will be tricky, - // because it depends on the final fontsize - regardless of - // where it is set. So at the style level, - // the escapement value would need to be grabbagged. - // At appendText time the final fontsize needs to be determined, and then - // the escapement can be calculated from the grabbag'd half-point value - // and directly applied. Yuck. - // It seems best to just treat charstyle escapement like - // pre-commit e70df84352d3670508a4666c97df44f82c1ce934 - // which just assigned default values and ignored the actual/given escapement. - sal_Int16 nEscapement = nIntValue > 0 ? DFLT_ESC_AUTO_SUPER : DFLT_ESC_AUTO_SUB; - sal_Int8 nProp = DFLT_ESC_PROP; - rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::makeAny( nEscapement ) ); - rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::makeAny( nProp ) ); - } - } - break; - case NS_ooxml::LN_EG_RPrBase_spacing: - { - //Kerning half point values - //TODO: there are two kerning values - - // in ww8par6.cxx NS_sprm::LN_CHpsKern is used as boolean AutoKerning - sal_Int16 nResult = static_cast<sal_Int16>(ConversionHelper::convertTwipToMM100(nIntValue)); - if (m_pImpl->IsInComments()) - { - nResult = static_cast<sal_Int16>(nIntValue); - } - rContext->Insert(PROP_CHAR_CHAR_KERNING, uno::makeAny(nResult)); - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", OUString::number(nIntValue)); - } - break; - case NS_ooxml::LN_EG_RPrBase_kern: // auto kerning is bound to a minimum font size in Word - but not in Writer :-( - rContext->Insert(PROP_CHAR_AUTO_KERNING, uno::makeAny( nIntValue != 0 ) ); - break; - case NS_ooxml::LN_EG_RPrBase_w: - // ST_TextScale must fall between 1% and 600% according to spec, otherwise resets to 100% according to experience - if ((1 <= nIntValue) && (nIntValue <= 600)) - { - rContext->Insert(PROP_CHAR_SCALE_WIDTH, - uno::makeAny( sal_Int16(nIntValue) )); - } - else - { - rContext->Insert(PROP_CHAR_SCALE_WIDTH, - uno::makeAny( sal_Int16(100) )); - } - break; - case NS_ooxml::LN_EG_RPrBase_imprint: - // FontRelief: NONE, EMBOSSED, ENGRAVED - rContext->Insert(PROP_CHAR_RELIEF, - uno::makeAny( nIntValue ? awt::FontRelief::ENGRAVED : awt::FontRelief::NONE )); - break; - case NS_ooxml::LN_EG_RPrBase_effect: - // The file-format has many character animations. We have only - // one, so we use it always. Suboptimal solution though. - if (nIntValue != NS_ooxml::LN_Value_ST_TextEffect_none) - rContext->Insert(PROP_CHAR_FLASH, uno::makeAny( true )); - else - rContext->Insert(PROP_CHAR_FLASH, uno::makeAny( false )); - break; - case NS_ooxml::LN_EG_RPrBase_rtl: - break; - case NS_ooxml::LN_EG_RPrBase_shd: - { - //contains fore color, back color and shadow percentage, results in a brush - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - auto pCellColorHandler = std::make_shared<CellColorHandler>(); - pCellColorHandler->setOutputFormat( CellColorHandler::Character ); - pProperties->resolve(*pCellColorHandler); - rContext->InsertProps(pCellColorHandler->getProperties().get()); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_SHADING_MARKER, uno::makeAny(true), true, CHAR_GRAB_BAG ); - } - break; - } - case NS_ooxml::LN_EG_SectPrContents_type: - /* break type - 0 - No break - 1 - New Column - 2 - New page - 3 - Even page - 4 - odd page - */ - OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); - if(pSectionContext) - { - //continuous break only allowed if it is not the only section break - SectionPropertyMap* pLastContext = m_pImpl->GetLastSectionContext(); - if ( nIntValue != static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_continuous) || pLastContext || m_pImpl->GetParaSectpr() ) - pSectionContext->SetBreakType( nIntValue ); - } - break; - case NS_ooxml::LN_EG_SectPrContents_titlePg: - { - OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); - if(pSectionContext) - pSectionContext->SetTitlePage( nIntValue > 0 );//section has title page - } - break; - case 165: - { - //page height, rounded to default values, default: 0x3dc0 twip - sal_Int32 nHeight = ConversionHelper::convertTwipToMM100( nIntValue ); - rContext->Insert( PROP_HEIGHT, uno::makeAny( PaperInfo::sloppyFitPageDimension( nHeight ) ) ); - } - break; - 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 - */ - text::WritingMode nDirection = text::WritingMode_LR_TB; - switch( nIntValue ) - { - case NS_ooxml::LN_Value_ST_TextDirection_lrTb: - case NS_ooxml::LN_Value_ST_TextDirection_lrTbV: - nDirection = text::WritingMode_LR_TB; - break; - case NS_ooxml::LN_Value_ST_TextDirection_tbRl: - case NS_ooxml::LN_Value_ST_TextDirection_btLr: - nDirection = text::WritingMode_TB_RL; - break; - default:; - } - - PropertyMap * pTargetContext = rContext.get(); - - if (pSectionContext) - { - pTargetContext = pSectionContext; - } - - pTargetContext->Insert(PROP_WRITING_MODE, uno::makeAny( sal_Int16(nDirection) ) ); - } - break; // sprmSTextFlow - // the following are not part of the official documentation - 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 - // fdo#81033: for RTF, a tab stop is inherited from the style if it - // is also applied to the paragraph directly, and cleared if it is - // not applied to the paragraph directly => don't InitTabStopFromStyle - if ( !IsRTFImport() ) - { - uno::Any aValue = m_pImpl->GetPropertyFromParaStyleSheet(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, 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_EG_RPrBase_bdr: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - auto pBorderHandler = std::make_shared<BorderHandler>( true ); - pProperties->resolve(*pBorderHandler); - - rContext->Insert( PROP_CHAR_TOP_BORDER, uno::makeAny( pBorderHandler->getBorderLine())); - rContext->Insert( PROP_CHAR_BOTTOM_BORDER, uno::makeAny( pBorderHandler->getBorderLine())); - rContext->Insert( PROP_CHAR_LEFT_BORDER, uno::makeAny( pBorderHandler->getBorderLine())); - rContext->Insert( PROP_CHAR_RIGHT_BORDER, uno::makeAny( pBorderHandler->getBorderLine())); - - rContext->Insert( PROP_CHAR_TOP_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance())); - rContext->Insert( PROP_CHAR_BOTTOM_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance())); - rContext->Insert( PROP_CHAR_LEFT_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance())); - rContext->Insert( PROP_CHAR_RIGHT_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance())); - - table::ShadowFormat aFormat; - // Word only allows shadows on visible borders - if ( pBorderHandler->getShadow() && pBorderHandler->getBorderLine().LineStyle != table::BorderLineStyle::NONE ) - aFormat = writerfilter::dmapper::PropertyMap::getShadowFromBorder(pBorderHandler->getBorderLine()); - rContext->Insert(PROP_CHAR_SHADOW_FORMAT, uno::makeAny(aFormat)); - } - } - 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_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: - { - bool bTempGrabBag = !m_pImpl->isInteropGrabBagEnabled(); - if (nSprmId == NS_ooxml::LN_CT_PPr_sectPr) - m_pImpl->SetParaSectpr(true); - else if (nSprmId == NS_ooxml::LN_EG_RPrBase_color && bTempGrabBag) - // if DomainMapper grab bag is not enabled, enable it temporarily - m_pImpl->enableInteropGrabBag("TempColorPropsGrabBag"); - resolveSprmProps(*this, rSprm); - if (nSprmId == NS_ooxml::LN_CT_PPrBase_spacing) - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "spacing", m_pImpl->m_aSubInteropGrabBag); - else if (nSprmId == NS_ooxml::LN_EG_RPrBase_rFonts) - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "rFonts", m_pImpl->m_aSubInteropGrabBag); - else if (nSprmId == NS_ooxml::LN_EG_RPrBase_lang) - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lang", m_pImpl->m_aSubInteropGrabBag); - else if (nSprmId == NS_ooxml::LN_EG_RPrBase_color) - { - for (const auto& rItem : m_pImpl->m_aSubInteropGrabBag) - { - if (rItem.Name == "val") - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_ORIGINAL_COLOR, rItem.Value, true, CHAR_GRAB_BAG); - else if (rItem.Name == "themeColor") - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR, rItem.Value, true, CHAR_GRAB_BAG); - else if (rItem.Name == "themeShade") - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_SHADE, rItem.Value, true, CHAR_GRAB_BAG); - else if (rItem.Name == "themeTint") - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_COLOR_TINT, rItem.Value, true, CHAR_GRAB_BAG); - } - if (bTempGrabBag) - //disable and clear DomainMapper grab bag if it wasn't enabled before - m_pImpl->disableInteropGrabBag(); - - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "color", m_pImpl->m_aSubInteropGrabBag); - } - else if (nSprmId == NS_ooxml::LN_CT_PPrBase_ind) - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ind", m_pImpl->m_aSubInteropGrabBag); - } - break; - case NS_ooxml::LN_CT_PPrBase_wordWrap: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "wordWrap", ""); - 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(); - 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(); - if( aSettings.nInterval == 0 ) - xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::makeAny(false) ); - else - { - xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_IS_ON ), uno::makeAny(true) ); - if( aSettings.nInterval ) - xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_INTERVAL ), uno::makeAny(static_cast<sal_Int16>(aSettings.nInterval)) ); - if( aSettings.nDistance != -1 ) - xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::makeAny(aSettings.nDistance) ); - else - { - // set Auto value (0.5 cm) - xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_DISTANCE ), uno::makeAny(static_cast<sal_Int32>(500)) ); - if( pSectionContext ) - pSectionContext->SetdxaLnn( static_cast<sal_Int32>(283) ); - } - xLineNumberingPropSet->setPropertyValue(getPropertyName( PROP_RESTART_AT_EACH_PAGE ), uno::makeAny(aSettings.bRestartAtEachPage) ); - } - } - catch( const uno::Exception& ) - { - } - - } - break; - case NS_ooxml::LN_CT_PPrBase_framePr: - // Avoid frames if we're inside a structured document tag, would just cause outer tables fail to create. - if (!m_pImpl->GetSdt()) - { - PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH); - if( pContext ) - { - // If there is a deferred page break applied to this framed paragraph, - // create a dummy paragraph without extra properties, - // so that the anchored frame will be on the correct page (similar to shapes). - if (pContext->isSet(PROP_BREAK_TYPE)) - { - pContext->Erase(PROP_BREAK_TYPE); - - lcl_startParagraphGroup(); - m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE)); - lcl_startCharacterGroup(); - sal_uInt8 const sBreak[] = { 0xd }; - lcl_text(sBreak, 1); - lcl_endCharacterGroup(); - lcl_endParagraphGroup(); - } - - ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pContext.get() ); - if (pParaContext) - pParaContext->SetFrameMode(); - - if (!IsInHeaderFooter()) - m_pImpl->m_bIsActualParagraphFramed = true; - } - else - { - //TODO: What about style sheet import of frame properties - } - m_pImpl->NewFrameDirection(); - resolveSprmProps(*this, rSprm); - } - break; - case NS_ooxml::LN_EG_SectPrContents_pgSz: - { - 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) - { - if (!m_pImpl->IsAltChunk()) - { - pSectionContext->Insert(PROP_HEIGHT, uno::makeAny(CT_PageSz.h)); - } - pSectionContext->Insert( PROP_IS_LANDSCAPE, uno::makeAny( CT_PageSz.orient )); - if (!m_pImpl->IsAltChunk()) - { - pSectionContext->Insert(PROP_WIDTH, uno::makeAny(CT_PageSz.w)); - } - } - 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 ); - pSectionContext->SetGutterMargin(rPageMar.gutter); - } - break; - - case NS_ooxml::LN_EG_SectPrContents_cols: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - - tools::SvRef< SectionColumnHandler > pSectHdl( new SectionColumnHandler ); - pProperties->resolve(*pSectHdl); - if(pSectionContext && !m_pImpl->isInIndexContext()) - { - sal_Int16 nColumnCount = pSectHdl->GetNum() == 1 ? 0 : pSectHdl->GetNum(); - if( pSectHdl->IsEqualWidth() ) - { - pSectionContext->SetEvenlySpaced( true ); - pSectionContext->SetColumnCount( nColumnCount ); - pSectionContext->SetColumnDistance( pSectHdl->GetSpace() ); - pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() ); - } - else if( !pSectHdl->GetColumns().empty() ) - { - pSectionContext->SetEvenlySpaced( false ); - pSectionContext->SetColumnDistance( pSectHdl->GetSpace() ); - nColumnCount = pSectHdl->GetColumns().size(); - pSectionContext->SetColumnCount( nColumnCount == 1 ? 0 : nColumnCount ); - 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( nColumnCount ) - { - pSectionContext->SetColumnCount( nColumnCount ); - pSectionContext->SetColumnDistance( pSectHdl->GetSpace() ); - pSectionContext->SetSeparatorLine( pSectHdl->IsSeparator() ); - } - } - - else if ( pSectionContext ) - { - FieldContextPtr pContext = m_pImpl->GetTopFieldContext(); - uno::Reference< beans::XPropertySet > xTOC = pContext->GetTOC(); - if( xTOC.is() ) - { - uno::Reference<text::XTextColumns> xTextColumns; - xTOC->getPropertyValue(getPropertyName( PROP_TEXT_COLUMNS )) >>= xTextColumns; - if (xTextColumns.is()) - { - uno::Reference< beans::XPropertySet > xColumnPropSet( xTextColumns, uno::UNO_QUERY_THROW ); - xColumnPropSet->setPropertyValue( getPropertyName( PROP_AUTOMATIC_DISTANCE ), uno::makeAny( pSectHdl->GetSpace() )); - xTOC->setPropertyValue( getPropertyName( PROP_TEXT_COLUMNS ), uno::makeAny( xTextColumns ) ); - } - } - } - } - } - 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 && pSectionContext ) - { - tools::SvRef< PageBordersHandler > pHandler( new PageBordersHandler ); - pProperties->resolve( *pHandler ); - - // Set the borders to the context and apply them to the styles - pHandler->SetBorders( pSectionContext ); - } - } - break; - - case NS_ooxml::LN_CT_PPrBase_snapToGrid: - if (!IsStyleSheetImport()||!m_pImpl->isInteropGrabBagEnabled()) - { - rContext->Insert( PROP_SNAP_TO_GRID, uno::makeAny(bool(nIntValue))); - } - else - { - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "snapToGrid", OUString::number(nIntValue)); - } - break; - case NS_ooxml::LN_CT_PPrBase_pStyle: - { - StyleSheetTablePtr pStyleTable = m_pImpl->GetStyleSheetTable(); - const OUString sConvertedStyleName = pStyleTable->ConvertStyleName( sStringValue, true ); - m_pImpl->SetCurrentParaStyleName( sConvertedStyleName ); - if (m_pImpl->GetTopContext() && m_pImpl->GetTopContextType() != CONTEXT_SECTION) - m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::makeAny( sConvertedStyleName )); - } - break; - case NS_ooxml::LN_EG_RPrBase_rStyle: - { - OUString sConvertedName( m_pImpl->GetStyleSheetTable()->ConvertStyleName( sStringValue, true ) ); - if (m_pImpl->CheckFootnoteStyle() && m_pImpl->GetFootnoteContext()) - m_pImpl->SetHasFootnoteStyle(m_pImpl->GetFootnoteContext()->GetFootnoteStyle() == sConvertedName); - - // First check if the style exists in the document. - StyleSheetEntryPtr pEntry = m_pImpl->GetStyleSheetTable( )->FindStyleSheetByConvertedStyleName( sConvertedName ); - bool bExists = pEntry && ( pEntry->nStyleTypeCode == STYLE_TYPE_CHAR ); - // Add the property if the style exists, but do not add it elements in TOC: - // they will receive later another style references from TOC - if ( bExists && m_pImpl->GetTopContext() && !m_pImpl->IsInTOC()) - m_pImpl->GetTopContext()->Insert( PROP_CHAR_STYLE_NAME, 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_start: - case NS_ooxml::LN_CT_TblCellMar_left: - case NS_ooxml::LN_CT_TblCellMar_bottom: - case NS_ooxml::LN_CT_TblCellMar_end: - case NS_ooxml::LN_CT_TblCellMar_right: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - MeasureHandlerPtr pMeasureHandler( new MeasureHandler ); - pProperties->resolve(*pMeasureHandler); - sal_Int32 nMeasureValue = pMeasureHandler->getMeasureValue(); - PropertyIds eId = META_PROP_CELL_MAR_TOP; - bool rtl = false; // TODO - switch(nSprmId) - { - case NS_ooxml::LN_CT_TblCellMar_top: - break; - case NS_ooxml::LN_CT_TblCellMar_start: - eId = rtl ? META_PROP_CELL_MAR_RIGHT : META_PROP_CELL_MAR_LEFT; - 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_end: - eId = rtl ? META_PROP_CELL_MAR_LEFT : META_PROP_CELL_MAR_RIGHT; - break; - case NS_ooxml::LN_CT_TblCellMar_right: - eId = META_PROP_CELL_MAR_RIGHT; - break; - default:; - } - rContext->Insert( eId, uno::makeAny(nMeasureValue), false); - } - } - break; - case NS_ooxml::LN_EG_RPrBase_noProof: // 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 - { - if ( m_pImpl->IsDiscardHeaderFooter() ) - break; - //tdf112342: Break before images as well, if there are page break - if (m_pImpl->isBreakDeferred(BreakType::PAGE_BREAK)) - { - m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) - ->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE)); - m_pImpl->clearDeferredBreak(PAGE_BREAK); - } - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - 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 = DFLT_ESC_PROP; - if ( sStringValue == "superscript" ) - nEscapement = DFLT_ESC_AUTO_SUPER; - else if ( sStringValue == "subscript" ) - nEscapement = DFLT_ESC_AUTO_SUB; - else - nProp = 100; - - rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::makeAny( nEscapement ) ); - rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, 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_CT_FtnProps_numFmt: - case NS_ooxml::LN_CT_EdnProps_numFmt: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - { - pProperties->resolve(*this); - } - } - break; - case NS_ooxml::LN_EG_FtnEdnNumProps_numStart: - case NS_ooxml::LN_EG_FtnEdnNumProps_numRestart: - { - try - { - uno::Reference< beans::XPropertySet > xFtnEdnSettings; - if( m_pImpl->IsInFootnoteProperties() ) - { - uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY ); - if (xFootnotesSupplier.is()) - xFtnEdnSettings = xFootnotesSupplier->getFootnoteSettings(); - } - else - { - uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( m_pImpl->GetTextDocument(), uno::UNO_QUERY ); - if (xEndnotesSupplier.is()) - xFtnEdnSettings = xEndnotesSupplier->getEndnoteSettings(); - } - if( NS_ooxml::LN_EG_FtnEdnNumProps_numStart == nSprmId && xFtnEdnSettings.is()) - { - xFtnEdnSettings->setPropertyValue( - getPropertyName( PROP_START_AT), - uno::makeAny( sal_Int16( nIntValue - 1 ))); - } - else if( NS_ooxml::LN_EG_FtnEdnNumProps_numRestart == nSprmId && xFtnEdnSettings.is()) - { - sal_Int16 nFootnoteCounting = 0; - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_RestartNumber_continuous: nFootnoteCounting = text::FootnoteNumbering::PER_DOCUMENT; break; - case NS_ooxml::LN_Value_ST_RestartNumber_eachPage: nFootnoteCounting = text::FootnoteNumbering::PER_PAGE; break; - case NS_ooxml::LN_Value_ST_RestartNumber_eachSect: nFootnoteCounting = text::FootnoteNumbering::PER_CHAPTER; break; - default: break; - } - xFtnEdnSettings->setPropertyValue( - getPropertyName( PROP_FOOTNOTE_COUNTING ), - uno::makeAny( nFootnoteCounting )); - } - else if (xFtnEdnSettings.is()) - { - sal_Int16 nNumType = ConversionHelper::ConvertNumberingType( nIntValue ); - xFtnEdnSettings->setPropertyValue( - getPropertyName( PROP_NUMBERING_TYPE), - uno::makeAny( nNumType )); - } - } - catch( const uno::Exception& ) - { - } - } - break; - case NS_ooxml::LN_paratrackchange: - m_pImpl->StartParaMarkerChange( ); - [[fallthrough]]; - case NS_ooxml::LN_CT_PPr_pPrChange: - case NS_ooxml::LN_CT_ParaRPr_rPrChange: - case NS_ooxml::LN_trackchange: - case NS_ooxml::LN_EG_RPrContent_rPrChange: - case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeStart: - case NS_ooxml::LN_EG_RangeMarkupElements_customXmlDelRangeEnd: - case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeStart: - case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveFromRangeEnd: - case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeStart: - case NS_ooxml::LN_EG_RangeMarkupElements_customXmlMoveToRangeEnd: - { - HandleRedline( rSprm ); - } - break; - case NS_ooxml::LN_endtrackchange: - m_pImpl->RemoveTopRedline(); - break; - case NS_ooxml::LN_CT_RPrChange_rPr: - { - // Push all the current 'Character' properties to the stack, so that we don't store them - // as 'tracked changes' by mistake - m_pImpl->PushProperties(CONTEXT_CHARACTER); - - // Resolve all the properties that are under the 'rPrChange'->'rPr' XML node - resolveSprmProps(*this, rSprm ); - - // Get all the properties that were processed in the 'rPrChange'->'rPr' XML node - uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues(); - - // Pop back out the character properties that were on the run - m_pImpl->PopProperties(CONTEXT_CHARACTER); - - // Store these properties in the current redline object (do it after the PopProperties() above, since - // otherwise it'd be stored in the content dropped there). - m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties ); - } - break; - case NS_ooxml::LN_CT_PPrChange_pPr: - { - // Push all the current 'Paragraph' properties to the stack, so that we don't store them - // as 'tracked changes' by mistake - m_pImpl->PushProperties(CONTEXT_PARAGRAPH); - - // Resolve all the properties that are under the 'pPrChange'->'pPr' XML node - resolveSprmProps(*this, rSprm ); - - // Get all the properties that were processed in the 'pPrChange'->'pPr' XML node - uno::Sequence< beans::PropertyValue > currentRedlineRevertProperties = m_pImpl->GetTopContext()->GetPropertyValues(); - - // Pop back out the character properties that were on the run - m_pImpl->PopProperties(CONTEXT_PARAGRAPH); - - // Store these properties in the current redline object (do it after the PopProperties() above, since - // otherwise it'd be stored in the content dropped there). - m_pImpl->SetCurrentRedlineRevertProperties( currentRedlineRevertProperties ); - } - break; - case NS_ooxml::LN_object: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - auto pOLEHandler = std::make_shared<OLEHandler>(*this); - pProperties->resolve(*pOLEHandler); - if ( pOLEHandler->isOLEObject( ) ) - { - OUString sStreamName = pOLEHandler->copyOLEOStream( m_pImpl->GetTextDocument() ); - if( !sStreamName.isEmpty() ) - { - 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_ooxml::LN_CT_PPrBase_contextualSpacing: - rContext->Insert(PROP_PARA_CONTEXT_MARGIN, uno::makeAny( nIntValue != 0 )); - break; - case NS_ooxml::LN_CT_PPrBase_mirrorIndents: // mirrorIndents - rContext->Insert(PROP_MIRROR_INDENTS, uno::makeAny( nIntValue != 0 ), true, PARA_GRAB_BAG); - break; - case NS_ooxml::LN_EG_SectPrContents_formProt: //section protection - { - if( pSectionContext ) - pSectionContext->Insert( PROP_IS_PROTECTED, uno::makeAny( bool(nIntValue) ) ); - } - break; - case NS_ooxml::LN_EG_SectPrContents_vAlign: - { - OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); - if( pSectionContext ) - { - drawing::TextVerticalAdjust nVA = drawing::TextVerticalAdjust_TOP; - switch( nIntValue ) - { - case NS_ooxml::LN_Value_ST_VerticalJc_center: //92367 - nVA = drawing::TextVerticalAdjust_CENTER; - break; - case NS_ooxml::LN_Value_ST_VerticalJc_both: //92368 - justify - nVA = drawing::TextVerticalAdjust_BLOCK; - break; - case NS_ooxml::LN_Value_ST_VerticalJc_bottom: //92369 - nVA = drawing::TextVerticalAdjust_BOTTOM; - break; - default: - break; - } - pSectionContext->Insert( PROP_TEXT_VERTICAL_ADJUST, uno::makeAny( nVA ), true, PARA_GRAB_BAG ); - } - } - break; - case NS_ooxml::LN_EG_RPrBase_fitText: - break; - case NS_ooxml::LN_ffdata: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - { - FFDataHandler::Pointer_t pFFDataHandler(new FFDataHandler()); - - pProperties->resolve(*pFFDataHandler); - m_pImpl->SetFieldFFData(pFFDataHandler); - } - } - break; - case NS_ooxml::LN_CT_SdtPr_dropDownList: - case NS_ooxml::LN_CT_SdtPr_comboBox: - { - m_pImpl->m_pSdtHelper->setInsideDropDownControl(true); - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_SdtDropDownList_listItem: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_SdtPr_date: - { - resolveSprmProps(*this, rSprm); - m_pImpl->m_pSdtHelper->setDateFieldStartRange(GetCurrentTextRange()->getEnd()); - } - break; - case NS_ooxml::LN_CT_SdtDate_dateFormat: - { - m_pImpl->m_pSdtHelper->getDateFormat().append(sStringValue); - } - break; - case NS_ooxml::LN_CT_SdtDate_storeMappedDataAs: - { - } - break; - case NS_ooxml::LN_CT_SdtDate_calendar: - { - } - break; - case NS_ooxml::LN_CT_SdtDate_lid: - { - m_pImpl->m_pSdtHelper->getLocale().append(sStringValue); - } - break; - case NS_ooxml::LN_CT_SdtPr_dataBinding: - case NS_ooxml::LN_CT_SdtPr_equation: - case NS_ooxml::LN_CT_SdtPr_checkbox: - case NS_ooxml::LN_CT_SdtPr_docPartObj: - case NS_ooxml::LN_CT_SdtPr_docPartList: - case NS_ooxml::LN_CT_SdtPr_picture: - case NS_ooxml::LN_CT_SdtPr_citation: - case NS_ooxml::LN_CT_SdtPr_group: - case NS_ooxml::LN_CT_SdtPr_text: - case NS_ooxml::LN_CT_SdtPr_id: - case NS_ooxml::LN_CT_SdtPr_alias: - { - // this is an unsupported SDT property, create a grab bag for it - OUString sName; - switch (nSprmId) - { - case NS_ooxml::LN_CT_SdtPr_dataBinding: sName = "ooxml:CT_SdtPr_dataBinding"; break; - case NS_ooxml::LN_CT_SdtPr_equation: sName = "ooxml:CT_SdtPr_equation"; break; - case NS_ooxml::LN_CT_SdtPr_checkbox: sName = "ooxml:CT_SdtPr_checkbox"; break; - case NS_ooxml::LN_CT_SdtPr_docPartObj: sName = "ooxml:CT_SdtPr_docPartObj"; break; - case NS_ooxml::LN_CT_SdtPr_docPartList: sName = "ooxml:CT_SdtPr_docPartList"; break; - case NS_ooxml::LN_CT_SdtPr_picture: sName = "ooxml:CT_SdtPr_picture"; break; - case NS_ooxml::LN_CT_SdtPr_citation: sName = "ooxml:CT_SdtPr_citation"; break; - case NS_ooxml::LN_CT_SdtPr_group: sName = "ooxml:CT_SdtPr_group"; break; - case NS_ooxml::LN_CT_SdtPr_text: sName = "ooxml:CT_SdtPr_text"; break; - case NS_ooxml::LN_CT_SdtPr_id: sName = "ooxml:CT_SdtPr_id"; break; - case NS_ooxml::LN_CT_SdtPr_alias: sName = "ooxml:CT_SdtPr_alias"; break; - default: assert(false); - }; - enableInteropGrabBag(sName); - - // process subitems - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(*this); - - if (nSprmId == NS_ooxml::LN_CT_SdtPr_alias) - { - beans::PropertyValue aValue; - aValue.Name = sName; - aValue.Value <<= sStringValue; - m_pImpl->m_pSdtHelper->appendToInteropGrabBag(aValue); - } - else - m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag()); - m_pImpl->m_pSdtHelper->setOutsideAParagraph(m_pImpl->IsOutsideAParagraph()); - m_pImpl->disableInteropGrabBag(); - } - break; - case NS_ooxml::LN_CT_SdtCheckbox_checked: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checked", sStringValue); - break; - case NS_ooxml::LN_CT_SdtCheckbox_checkedState: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_checkedState", sStringValue); - break; - case NS_ooxml::LN_CT_SdtCheckbox_uncheckedState: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtCheckbox_uncheckedState", sStringValue); - break; - case NS_ooxml::LN_CT_SdtDocPart_docPartGallery: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartGallery", sStringValue); - break; - case NS_ooxml::LN_CT_SdtDocPart_docPartCategory: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartCategory", sStringValue); - break; - case NS_ooxml::LN_CT_SdtDocPart_docPartUnique: - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_SdtDocPart_docPartUnique", sStringValue); - break; - case NS_ooxml::LN_EG_SectPrContents_pgNumType: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - pProperties->resolve(*this); - } - } - break; - case NS_ooxml::LN_tblStart: - { - if (m_pImpl->hasTableManager()) - { - bool bTableStartsAtCellStart = m_pImpl->m_nTableDepth > 0 && m_pImpl->m_nTableCellDepth > m_pImpl->m_nLastTableCellParagraphDepth + 1; - m_pImpl->getTableManager().setTableStartsAtCellStart(bTableStartsAtCellStart); - } - /* - * Hack for Importing Section Properties - * LO is not able to import section properties if first element in the - * section is a table. So in case first element is a table add a dummy para - * and remove it again when lcl_endSectionGroup is called - */ - if(m_pImpl->m_nTableDepth == 0 && m_pImpl->GetIsFirstParagraphInSection() - && !m_pImpl->GetIsDummyParaAddedForTableInSection() && !m_pImpl->GetIsTextFrameInserted() - && !IsInHeaderFooter()) - { - m_pImpl->AddDummyParaForTableInSection(); - } - - // if first paragraph style in table has break-before-page, transfer that setting to the table itself. - if( m_pImpl->m_nTableDepth == 0 ) - { - const uno::Any aBreakType = uno::makeAny(style::BreakType_PAGE_BEFORE); - const PropertyMapPtr pParagraphProps = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH); - if( pParagraphProps && pParagraphProps->isSet(PROP_PARA_STYLE_NAME) ) - { - StyleSheetEntryPtr pStyle; - OUString sStyleName; - pParagraphProps->getProperty(PROP_PARA_STYLE_NAME)->second >>= sStyleName; - if( !sStyleName.isEmpty() && GetStyleSheetTable() ) - pStyle = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( sStyleName ); - - if( pStyle && pStyle->pProperties - && pStyle->pProperties->isSet(PROP_BREAK_TYPE) - && pStyle->pProperties->getProperty(PROP_BREAK_TYPE)->second == aBreakType ) - { - pParagraphProps->Insert(PROP_BREAK_TYPE, aBreakType); - } - } - } - - m_pImpl->m_nTableDepth++; - } - break; - case NS_ooxml::LN_tblEnd: - m_pImpl->m_nTableDepth--; - break; - case NS_ooxml::LN_tcStart: - m_pImpl->m_nTableCellDepth++; - break; - case NS_ooxml::LN_tcEnd: - m_pImpl->m_nTableCellDepth--; - m_pImpl->m_nLastTableCellParagraphDepth = 0; - break; - case NS_ooxml::LN_glow_glow: - case NS_ooxml::LN_shadow_shadow: - case NS_ooxml::LN_reflection_reflection: - case NS_ooxml::LN_textOutline_textOutline: - case NS_ooxml::LN_textFill_textFill: - case NS_ooxml::LN_scene3d_scene3d: - case NS_ooxml::LN_props3d_props3d: - case NS_ooxml::LN_ligatures_ligatures: - case NS_ooxml::LN_numForm_numForm: - case NS_ooxml::LN_numSpacing_numSpacing: - case NS_ooxml::LN_stylisticSets_stylisticSets: - case NS_ooxml::LN_cntxtAlts_cntxtAlts: - { - tools::SvRef<TextEffectsHandler> pTextEffectsHandlerPtr( new TextEffectsHandler(nSprmId) ); - std::optional<PropertyIds> aPropertyId = pTextEffectsHandlerPtr->getGrabBagPropertyId(); - if(aPropertyId) - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - pProperties->resolve(*pTextEffectsHandlerPtr); - - beans::PropertyValue aGrabBag = pTextEffectsHandlerPtr->getInteropGrabBag(); - rContext->Insert(*aPropertyId, uno::makeAny(aGrabBag), true, CHAR_GRAB_BAG); - - sal_Int16 nTransparency = TextEffectsHandler::GetTextFillSolidFillAlpha(aGrabBag); - if (nTransparency != 0) - { - rContext->Insert(PROP_CHAR_TRANSPARENCE, uno::makeAny(nTransparency)); - } - } - } - } - break; - case NS_ooxml::LN_CT_SdtPr_rPr: - { - // Make sure properties from a previous SDT are not merged with the current ones. - m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear(); - } - break; - case NS_ooxml::LN_CT_TblPrBase_tblLook: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - { - pProperties->resolve(*this); - m_pImpl->getTableManager().finishTableLook(); - } - } - break; - case NS_ooxml::LN_CT_TrPrBase_cnfStyle: - { - m_pImpl->enableInteropGrabBag("cnfStyle"); - resolveSprmProps(*this, rSprm); - - TablePropertyMapPtr pPropMap(new TablePropertyMap()); - pPropMap->Insert(PROP_ROW_CNF_STYLE, uno::makeAny(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, ROW_GRAB_BAG); - m_pImpl->getTableManager().insertRowProps(pPropMap); - - m_pImpl->disableInteropGrabBag(); - } - break; - case NS_ooxml::LN_CT_TcPrBase_cnfStyle: - { - m_pImpl->enableInteropGrabBag("cnfStyle"); - resolveSprmProps(*this, rSprm); - - TablePropertyMapPtr pPropMap(new TablePropertyMap()); - pPropMap->Insert(PROP_CELL_CNF_STYLE, uno::makeAny(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, CELL_GRAB_BAG); - m_pImpl->getTableManager().cellProps(pPropMap); - - m_pImpl->disableInteropGrabBag(); - } - break; - case NS_ooxml::LN_CT_PPrBase_cnfStyle: - { - m_pImpl->enableInteropGrabBag("cnfStyle"); - resolveSprmProps(*this, rSprm); - rContext->Insert(PROP_PARA_CNF_STYLE, uno::makeAny(comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag)), true, PARA_GRAB_BAG); - m_pImpl->disableInteropGrabBag(); - } - break; - case NS_ooxml::LN_EG_RunInnerContent_sym: - { - resolveSprmProps(*this, rSprm); - SymbolData aSymbolData = m_pImpl->GetSymbolData(); - uno::Any aVal = uno::makeAny( aSymbolData.sFont ); - auto xFootnote = rContext->GetFootnote(); - if (!xFootnote.is() && m_pImpl->IsInCustomFootnote()) - xFootnote = m_pImpl->GetFootnoteContext()->GetFootnote(); - if (xFootnote.is()) - { - // DOCX can have different labels for the footnote reference and the footnote area. - // This skips the one from the footnote area and just uses the reference one. - if (!m_pImpl->IsInFootOrEndnote()) - { - auto xAnchorRange = xFootnote->getAnchor(); - auto xAnchorCursor(xAnchorRange->getText()->createTextCursorByRange(xAnchorRange)); - - // append a dummy character, so the following properties will be set as - // as SwpHints::SwTextAttr instead of the SwAttrSet of the paragraph, - // which would be removed by SwXText::Impl::finishOrAppendParagraph - xAnchorCursor->collapseToEnd(); - uno::Reference<text::XTextRange> xHackRange(xAnchorCursor, uno::UNO_QUERY); - xHackRange->setString("x"); - - uno::Reference<beans::XPropertySet> xAnchorProps(xAnchorRange, uno::UNO_QUERY); - xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), aVal); - xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_ASIAN), aVal); - xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_COMPLEX), aVal); - xAnchorProps->setPropertyValue(getPropertyName(PROP_CHAR_FONT_CHAR_SET), uno::makeAny(awt::CharSet::SYMBOL)); - - // remove the dummy char - xHackRange->setString(""); - - OUString sLabel = xFootnote->getLabel() + OUStringChar(aSymbolData.cSymbol); - xFootnote->setLabel(sLabel); - } - } - else //it's a _real_ symbol - { - rContext->Insert(PROP_CHAR_FONT_NAME, aVal); - rContext->Insert(PROP_CHAR_FONT_NAME_ASIAN, aVal); - rContext->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aVal); - rContext->Insert(PROP_CHAR_FONT_CHAR_SET, uno::makeAny(awt::CharSet::SYMBOL)); - utext( reinterpret_cast < const sal_uInt8 * >( &(aSymbolData.cSymbol) ), 1 ); - } - } - break; - case NS_ooxml::LN_EG_RunInnerContent_ruby: - { - RubyInfo aInfo ; - m_pImpl->SetRubyInfo(aInfo); - } - break; - case NS_ooxml::LN_CT_RubyPr: - case NS_ooxml::LN_CT_Ruby_rt: - case NS_ooxml::LN_CT_Ruby_rubyBase: - { - m_pImpl->SetRubySprmId(nSprmId); - if (nSprmId == NS_ooxml::LN_CT_RubyPr) - { - resolveSprmProps(*this, rSprm); - } - } - break; - case NS_ooxml::LN_EG_RubyContent_r: - { - const RubyInfo & aInfo = m_pImpl->GetRubyInfo(); - if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rubyBase) - { - rContext->Insert(PROP_RUBY_TEXT, uno::makeAny(aInfo.sRubyText)); - rContext->Insert(PROP_RUBY_STYLE, uno::makeAny(aInfo.sRubyStyle)); - rContext->Insert(PROP_RUBY_ADJUST, uno::makeAny(static_cast<sal_Int16>(ConversionHelper::convertRubyAlign(aInfo.nRubyAlign)))); - if ( aInfo.nRubyAlign == NS_ooxml::LN_Value_ST_RubyAlign_rightVertical ) - rContext->Insert(PROP_RUBY_POSITION, uno::makeAny(css::text::RubyPosition::INTER_CHARACTER)); - - m_pImpl->SetRubySprmId(0); - } - } - break; - case NS_ooxml::LN_CT_RubyPr_rubyAlign: - case NS_ooxml::LN_CT_RubyPr_hps: - case NS_ooxml::LN_CT_RubyPr_hpsBaseText: - { - RubyInfo aInfo = m_pImpl->GetRubyInfo(); - switch(nSprmId) - { - case NS_ooxml::LN_CT_RubyPr_rubyAlign: - aInfo.nRubyAlign = nIntValue; - break; - case NS_ooxml::LN_CT_RubyPr_hps: - aInfo.nHps= nIntValue; - break; - case NS_ooxml::LN_CT_RubyPr_hpsBaseText: - aInfo.nHpsBaseText = nIntValue; - break; - } - m_pImpl->SetRubyInfo(aInfo); - } - break; - case NS_ooxml::LN_CT_SmartTagRun_smartTagPr: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties && m_pImpl->GetTopContextType() == CONTEXT_PARAGRAPH) - pProperties->resolve(m_pImpl->getSmartTagHandler()); - } - break; - case NS_ooxml::LN_CT_DocPartPr_name: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_DocPartPr_category: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_DocPartCategory_gallery: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(*this); - } - break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("unhandled"); - TagLogger::getInstance().attribute("id", nSprmId); - TagLogger::getInstance().attribute("name", rSprm.getName()); - TagLogger::getInstance().endElement(); -#endif - } - } -} - -void DomainMapper::processDeferredCharacterProperties( const std::map< sal_Int32, uno::Any >& deferredCharacterProperties ) -{ - assert( m_pImpl->GetTopContextType() == CONTEXT_CHARACTER ); - PropertyMapPtr rContext = m_pImpl->GetTopContext(); - for( const auto& rProp : deferredCharacterProperties ) - { - sal_Int32 Id = rProp.first; - sal_Int32 nIntValue = 0; - OUString sStringValue; - rProp.second >>= nIntValue; - rProp.second >>= sStringValue; - switch( Id ) - { - case NS_ooxml::LN_EG_RPrBase_position: - { - double nEscapement = 0; - sal_Int8 nProp = 0; - if ( nIntValue ) - { - nProp = 100; - double fFontSize = 0; - m_pImpl->GetAnyProperty(PROP_CHAR_HEIGHT, rContext) >>= fFontSize; - if ( fFontSize ) - // nIntValue is in half-points, fontsize is in points, escapement is a percentage. - nEscapement = round( nIntValue/2.0 / fFontSize * 100 ); - else - nEscapement = nIntValue > 0 ? DFLT_ESC_SUPER : DFLT_ESC_SUB; - } - if ( nEscapement > MAX_ESC_POS ) - nEscapement = MAX_ESC_POS; - else if ( nEscapement < -MAX_ESC_POS ) - nEscapement = -MAX_ESC_POS; - - rContext->Insert(PROP_CHAR_ESCAPEMENT, uno::makeAny( sal_Int16(nEscapement) ) ); - rContext->Insert(PROP_CHAR_ESCAPEMENT_HEIGHT, uno::makeAny( nProp ) ); - } - break; - default: - SAL_WARN( "writerfilter", "Unhandled property in processDeferredCharacterProperty()" ); - break; - } - } -} - -void DomainMapper::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) -{ - ref->resolve(*this); -} - -void DomainMapper::data(const sal_uInt8* /*buf*/, size_t /*len*/) -{ -} - -void DomainMapper::lcl_startSectionGroup() -{ - if (!m_pImpl->isInIndexContext() && !m_pImpl->isInBibliographyContext()) - { - m_pImpl->PushProperties(CONTEXT_SECTION); - } - m_pImpl->SetIsFirstParagraphInSection(true); - m_pImpl->SetIsFirstParagraphInSectionAfterRedline(true); -} - -void DomainMapper::lcl_endSectionGroup() -{ - if (m_pImpl->isInIndexContext() || m_pImpl->isInBibliographyContext()) - return; - - m_pImpl->CheckUnregisteredFrameConversion(); - m_pImpl->ExecuteFrameConversion(); - // When pasting, it's fine to not have any paragraph inside the document at all. - if (m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->IsNewDoc()) - { - // This section has no paragraph at all (e.g. they are all actually in a frame). - // If this section has a page break, there would be nothing to apply to the page - // style, so force a dummy paragraph. - lcl_startParagraphGroup(); - lcl_startCharacterGroup(); - sal_uInt8 const sBreak[] = { 0xd }; - lcl_text(sBreak, 1); - lcl_endCharacterGroup(); - lcl_endParagraphGroup(); - } - 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 ); - // Remove the dummy paragraph if added for - // handling the section properties if section starts with a table - if (m_pImpl->GetIsDummyParaAddedForTableInSection()) - m_pImpl->RemoveDummyParaForTableInSection(); - } - m_pImpl->SetIsTextFrameInserted( false ); - m_pImpl->PopProperties(CONTEXT_SECTION); -} - -void DomainMapper::lcl_startParagraphGroup() -{ - if (m_pImpl->hasTableManager()) - m_pImpl->getTableManager().startParagraphGroup(); - /* - * Add new para properties only if paragraph is not split - * or the top context is not of paragraph properties - * Set mbIsSplitPara to false as it has been handled - */ - if (!mbIsSplitPara) - m_pImpl->PushProperties(CONTEXT_PARAGRAPH); - mbIsSplitPara = false; - if (m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) != m_pImpl->GetTopContext()) - m_pImpl->PushProperties(CONTEXT_PARAGRAPH); - - if (m_pImpl->GetTopContext()) - { - if (!m_pImpl->IsInShape()) - { - const OUString& sDefaultParaStyle = m_pImpl->GetDefaultParaStyleName(); - m_pImpl->GetTopContext()->Insert( PROP_PARA_STYLE_NAME, uno::makeAny( sDefaultParaStyle ) ); - m_pImpl->SetCurrentParaStyleName( sDefaultParaStyle ); - } - if (m_pImpl->isBreakDeferred(PAGE_BREAK)) - m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE)); - else if (m_pImpl->isBreakDeferred(COLUMN_BREAK)) - m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE)); - - if (m_pImpl->isParaSdtEndDeferred()) - m_pImpl->GetTopContext()->Insert(PROP_PARA_SDT_END_BEFORE, uno::makeAny(true), true, PARA_GRAB_BAG); - } - m_pImpl->SetIsFirstRun(true); - m_pImpl->SetIsOutsideAParagraph(false); - m_pImpl->clearDeferredBreaks(); - m_pImpl->setParaSdtEndDeferred(false); -} - -void DomainMapper::lcl_endParagraphGroup() -{ - m_pImpl->PopProperties(CONTEXT_PARAGRAPH); - if (m_pImpl->hasTableManager()) - m_pImpl->getTableManager().endParagraphGroup(); - //frame conversion has to be executed after table conversion - m_pImpl->ExecuteFrameConversion(); - m_pImpl->SetIsOutsideAParagraph(true); -} - -void DomainMapper::markLastParagraphInSection( ) -{ - m_pImpl->SetIsLastParagraphInSection( true ); -} - -void DomainMapper::markLastSectionGroup( ) -{ - m_pImpl->SetIsLastSectionGroup( true ); -} - -void DomainMapper::lcl_startShape(uno::Reference<drawing::XShape> const& xShape) -{ - assert(xShape.is()); - - if (m_pImpl->GetTopContext()) - { - // If there is a deferred page break, handle it now, so that the - // started shape will be on the correct page. - if (m_pImpl->isBreakDeferred(PAGE_BREAK)) - { - m_pImpl->clearDeferredBreak(PAGE_BREAK); - lcl_startCharacterGroup(); - sal_uInt8 const sBreak[] = { 0xd }; - lcl_text(sBreak, 1); - lcl_endCharacterGroup(); - lcl_endParagraphGroup(); - lcl_startParagraphGroup(); - m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE)); - } - m_pImpl->PushShapeContext( xShape ); - lcl_startParagraphGroup(); - } - else - { - // No context? Then this image should not appear directly inside the - // document, just save it for later usage. - m_pImpl->PushPendingShape(xShape); - } - - m_pImpl->SetIsFirstParagraphInShape(true); - -} - -void DomainMapper::lcl_endShape( ) -{ - if (!m_pImpl->GetTopContext()) - return; - - // End the current table, if there are any. Otherwise the unavoidable - // empty paragraph at the end of the shape text will cause problems: if - // the shape text ends with a table, the extra paragraph will be - // handled as an additional row of the ending table. - if (m_pImpl->hasTableManager()) - m_pImpl->getTableManager().endTable(); - - lcl_endParagraphGroup(); - m_pImpl->PopShapeContext( ); - // A shape is always inside a paragraph (anchored or inline). - m_pImpl->SetIsOutsideAParagraph(false); -} - -void DomainMapper::PushStyleSheetProperties( const 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( const ::tools::SvRef<PropertyMap>& pListProperties ) -{ - m_pImpl->PushListProperties( pListProperties ); -} - -void DomainMapper::PopListProperties() -{ - m_pImpl->PopProperties( CONTEXT_LIST ); -} - -void DomainMapper::lcl_startCharacterGroup() -{ - m_pImpl->PushProperties(CONTEXT_CHARACTER); - if (m_pImpl->isSdtEndDeferred()) - { - // Fields have an empty character group before the real one, so don't - // call setSdtEndDeferred(false) here, that will happen only in lcl_utext(). - m_pImpl->GetTopContext()->Insert(PROP_SDT_END_BEFORE, uno::makeAny(true), true, CHAR_GRAB_BAG); - } -} - -void DomainMapper::lcl_endCharacterGroup() -{ - if (m_pImpl->CheckFootnoteStyle()) - { - m_pImpl->SetCheckFootnoteStyle(m_pImpl->IsInCustomFootnote()); - m_pImpl->SetHasFootnoteStyle(false); - } - m_pImpl->PopProperties(CONTEXT_CHARACTER); -} - -void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len) -{ - //TODO: Determine the right text encoding (FIB?) - OUString sText( reinterpret_cast<const char*>(data_), len, RTL_TEXTENCODING_MS_1252 ); -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("text"); - TagLogger::getInstance().chars(sText); - TagLogger::getInstance().endElement(); -#endif - - try - { - if(len == 1) - { - switch(*data_) - { - case 0x02: return; //footnote character - case 0x08: // Lock field if in field context - if (m_pImpl->IsOpenField()) - m_pImpl->SetFieldLocked(); - return; - case 0x0c: //page break - // page breaks aren't supported in footnotes and endnotes - if (!m_pImpl->IsInFootOrEndnote()) - m_pImpl->deferBreak(PAGE_BREAK); - return; - case 0x0e: //column break - m_pImpl->deferBreak(COLUMN_BREAK); - return; - case 0x07: - m_pImpl->getTableManager().text(data_, len); - return; - case 0x0d: - { - PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH); - if (pContext && m_pImpl->isBreakDeferred(COLUMN_BREAK)) - { - pContext->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE)); - m_pImpl->clearDeferredBreak(COLUMN_BREAK); - } - finishParagraph(); - return; - } - case cFieldStart: - m_pImpl->PushFieldContext(); - return; - case cFieldSep: - // delimiter not necessarily available - // appears only if field contains further content - m_pImpl->CloseFieldCommand(); - return; - case cFieldEnd: - m_pImpl->PopFieldContext(); - return; - default: - break; - } - } - - // GetTopContext() is changed by inserted breaks, but we want to keep the current context - PropertyMapPtr pContext = m_pImpl->GetTopContext(); - if (!m_pImpl->GetFootnoteContext()) - { - if (m_pImpl->isBreakDeferred(PAGE_BREAK)) - m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE)); - else if (m_pImpl->isBreakDeferred(COLUMN_BREAK)) - m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE)); - m_pImpl->clearDeferredBreaks(); - } - - if (pContext && pContext->GetFootnote().is() && m_pImpl->IsInCustomFootnote()) - { - pContext->GetFootnote()->setLabel(sText); - m_pImpl->EndCustomFootnote(); - //otherwise ignore sText - } - else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields()) - { - 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->AppendFieldResult(sText); - else - { - if (pContext == nullptr) - pContext = new PropertyMap(); - - m_pImpl->appendTextPortion( sText, pContext ); - } - } - catch( const uno::RuntimeException& ) - { - TOOLS_WARN_EXCEPTION("writerfilter", ""); - } -} - -void DomainMapper::lcl_positionOffset(const OUString& rText, bool bVertical) -{ - if (bVertical) - m_pImpl->m_aPositionOffsets.second = rText; - else - m_pImpl->m_aPositionOffsets.first = rText; -} - -awt::Point DomainMapper::getPositionOffset() -{ - awt::Point aRet; - aRet.X = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.first.toInt32()); - aRet.Y = oox::drawingml::convertEmuToHmm(m_pImpl->m_aPositionOffsets.second.toInt32()); - return aRet; -} - -void DomainMapper::lcl_align(const OUString& rText, bool bVertical) -{ - if (bVertical) - m_pImpl->m_aAligns.second = rText; - else - m_pImpl->m_aAligns.first = rText; -} - -void DomainMapper::lcl_positivePercentage(const OUString& rText) -{ - m_pImpl->m_aPositivePercentages.push(rText); -} - -void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) -{ - // All these fixed values are defined as static const sal_Unicode codepoints in the fast parser, - // like uFtnEdnRef = 0x2, uFtnEdnSep = 0x3, ... and have a len of 1, if they aren't valid unicode. - - OUString sText(reinterpret_cast<const sal_Unicode *>(data_), len); - const RubyInfo & aInfo = m_pImpl->GetRubyInfo(); - if (aInfo.nSprmId == NS_ooxml::LN_CT_Ruby_rt) - { - PropertyMapPtr pContext = m_pImpl->GetTopContext(); - PropertyValueVector_t aProps = comphelper::sequenceToContainer< PropertyValueVector_t >(pContext->GetPropertyValues()); - OUString sStyle = getOrCreateCharStyle(aProps, /*bAlwaysCreate=*/false); - m_pImpl->SetRubyText(sText,sStyle); - return; - } - - if (len == 1) - { - // preload all footnotes in separated footnotes - if (sText[0] == 0x5) - { - if (m_pImpl->IsInFootnote()) - { - if (m_pImpl->GetFootnoteCount() > -1) - { - m_pImpl->PopFootOrEndnote(); - m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/true); - } - m_pImpl->IncrementFootnoteCount(); - } - else - { - if (m_pImpl->GetEndnoteCount() > -1) - { - m_pImpl->PopFootOrEndnote(); - m_pImpl->PushFootOrEndnote(/*bIsFootnote=*/false); - } - m_pImpl->IncrementEndnoteCount(); - } - } - - // If the footnote contains a Footnote Reference Mark, it can't be a custom footnote - // ****** - // This code block is wrong, as it should also be in m_pImpl->IsInFootOrEndnote(). - // The main problem is that - // - // assert(len != 1 || sText[0] != 0x2) - // - // is triggered by the unit test SwLayoutWriter::testForcepoint75, so all these pseudo - // value handling is broken. - // But this is just a symptom, as I guess it's possible to generate broken DOCX documents, - // which might be problematic, triggering *funny* code paths left and right. - // ****** - if (sText[0] == 0x2) - { - m_pImpl->EndCustomFootnote(); - return; - } - - if (m_pImpl->IsInCustomFootnote()) - { - if (sText[0] != 0xd && sText[0] != 0x3) - { - // DOCX can have different labels for the footnote reference and the footnote area. - // This skips the one from the footnote area and just uses the reference one. - if (!m_pImpl->IsInFootOrEndnote()) - { - if (PropertyMapPtr pFootnoteContext = m_pImpl->GetFootnoteContext()) - { - auto xFootnote = pFootnoteContext->GetFootnote(); - xFootnote->setLabel(xFootnote->getLabel() + sText); - } - } - return; - } - else - m_pImpl->SetHasFootnoteStyle(true); - } - } - - if (m_pImpl->isSdtEndDeferred()) - { - // In case we have a field context, then save the property there, so - // SDT's ending right before a field start are handled as well. - PropertyMapPtr pContext = m_pImpl->GetTopContext(); - if (m_pImpl->IsOpenField()) - pContext = m_pImpl->GetTopFieldContext()->getProperties(); - pContext->Insert(PROP_SDT_END_BEFORE, uno::makeAny(true), true, CHAR_GRAB_BAG); - m_pImpl->setSdtEndDeferred(false); - } - - bool bNewLine = len == 1 && (sText[0] == 0x0d || sText[0] == 0x07); - if (m_pImpl->m_pSdtHelper->isInsideDropDownControl()) - { - if (bNewLine) - // Dropdown control has single-line texts, so in case of newline, create the control. - m_pImpl->m_pSdtHelper->createDropDownControl(); - else - { - m_pImpl->m_pSdtHelper->getSdtTexts().append(sText); - return; - } - } - else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty()) - { - // Ignore grabbag when we have a date field, it can conflict during export - if(m_pImpl->m_pSdtHelper->validateDateFormat()) - { - m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear(); - } - else - { - - // there are unsupported SDT properties in the document - // save them in the paragraph interop grab bag - if (m_pImpl->IsDiscardHeaderFooter()) - { - // Unless we're supposed to ignore this header/footer. - m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear(); - return; - } - if((m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") || - m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") || - m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") || - m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_citation") || - (m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") && - m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph()) - { - PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER); - - if (m_pImpl->IsOpenField()) - // We have a field, insert the SDT properties to the field's grab-bag, so they won't be lost. - pContext = m_pImpl->GetTopFieldContext()->getProperties(); - - pContext->Insert(PROP_SDTPR, uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, CHAR_GRAB_BAG); - } - else - m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR, - uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear()), true, PARA_GRAB_BAG); - } - } - else if (len == 1 && sText[0] == 0x03) - { - // This is the uFtnEdnSep, remember that the document has a separator. - m_pImpl->m_bHasFtnSep = true; - return; - } - else if (len == 1 && sText[0] == '\t' ) - { - if ( m_pImpl->m_bCheckFirstFootnoteTab && m_pImpl->IsInFootOrEndnote() ) - { - // Allow MSO to emulate LO footnote text starting at left margin - only meaningful with hanging indent - m_pImpl->m_bCheckFirstFootnoteTab = false; - sal_Int32 nFirstLineIndent = 0; - m_pImpl->GetAnyProperty(PROP_PARA_FIRST_LINE_INDENT, m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)) >>= nFirstLineIndent; - if ( nFirstLineIndent < 0 ) - m_pImpl->m_bIgnoreNextTab = true; - } - - if ( m_pImpl->m_bIgnoreNextTab ) - { - m_pImpl->m_bIgnoreNextTab = false; - return; - } - } - else if (m_pImpl->m_pSdtHelper->validateDateFormat()) - { - if(IsInHeaderFooter() && m_pImpl->IsDiscardHeaderFooter()) - { - m_pImpl->m_pSdtHelper->getDateFormat().truncate(); - m_pImpl->m_pSdtHelper->getLocale().truncate(); - return; - } - } - if (!m_pImpl->hasTableManager()) - return; - - SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState(); - if ( eSkip == SkipFootnoteSeparator::ON || eSkip == SkipFootnoteSeparator::SKIPPING ) - { - m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING ); - return; - } - - try - { - m_pImpl->getTableManager().utext(data_, len); - - if (bNewLine) - { - const bool bSingleParagraph = m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->GetIsLastParagraphInSection(); - const bool bSingleParagraphAfterRedline = m_pImpl->GetIsFirstParagraphInSection(/*bAfterRedline=*/true) && - m_pImpl->GetIsLastParagraphInSection(); - PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH); - if (!m_pImpl->GetFootnoteContext()) - { - if (m_pImpl->isBreakDeferred(PAGE_BREAK)) - { - if (m_pImpl->GetSettingsTable()->GetSplitPgBreakAndParaMark()) - { - if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() ) - { - m_pImpl->m_bIsSplitPara = true; - finishParagraph(); - lcl_startParagraphGroup(); - } - - - pContext->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE)); - m_pImpl->clearDeferredBreaks(); - } - } - else if (m_pImpl->isBreakDeferred(COLUMN_BREAK)) - { - if ( m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun() ) - { - mbIsSplitPara = true; - finishParagraph(); - lcl_startParagraphGroup(); - } - - pContext->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE)); - m_pImpl->clearDeferredBreaks(); - } - } - - // If the paragraph contains only the section properties and it has - // no runs, we should not create a paragraph for it in Writer, unless that would remove the whole section. - SectionPropertyMap* pSectionContext = m_pImpl->GetSectionContext(); - bool bRemove = (!m_pImpl->GetParaChanged() && m_pImpl->GetRemoveThisPara()) || - (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() - && !bSingleParagraphAfterRedline - && !m_pImpl->GetParaHadField() - && !m_pImpl->GetIsDummyParaAddedForTableInSection() - && !( pSectionContext && pSectionContext->GetBreakType() != -1 && pContext && pContext->isSet(PROP_BREAK_TYPE) ) - && !m_pImpl->GetIsPreviousParagraphFramed() - && !m_pImpl->HasTopAnchoredObjects() - && !m_pImpl->IsParaWithInlineObject()); - - const bool bNoNumbering = bRemove || (!m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() && bSingleParagraph); - PropertyMapPtr xContext = bNoNumbering ? m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH) : PropertyMapPtr(); - if (xContext) - { - // tdf#97417 delete numbering of the paragraph - // it will be deleted anyway, and the numbering would be copied - // to the next paragraph in sw SplitNode and then be applied to - // every following paragraph - xContext->Erase(PROP_NUMBERING_RULES); - static_cast<ParagraphPropertyMap*>(xContext.get())->SetListId(-1);; - xContext->Erase(PROP_NUMBERING_LEVEL); - } - m_pImpl->SetParaSectpr(false); - finishParagraph(bRemove, bNoNumbering); - if (bRemove) - m_pImpl->RemoveLastParagraph(); - } - else - { - // GetTopContext() is changed by inserted breaks, but we want to keep the current context - PropertyMapPtr pContext = m_pImpl->GetTopContext(); - if (!m_pImpl->GetFootnoteContext()) - { - if (m_pImpl->isBreakDeferred(PAGE_BREAK)) - { - /* If PAGEBREAK appears in first paragraph of the section or - * after first run of any paragraph then need to split paragraph - * to handle it properly. - */ - if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun()) - { - m_pImpl->m_bIsSplitPara = true; - finishParagraph(); - lcl_startParagraphGroup(); - } - m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_PAGE_BEFORE)); - } - else if (m_pImpl->isBreakDeferred(COLUMN_BREAK)) - { - if (m_pImpl->GetIsFirstParagraphInSection() || !m_pImpl->IsFirstRun()) - { - mbIsSplitPara = true; - finishParagraph(); - lcl_startParagraphGroup(); - } - m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, uno::makeAny(style::BreakType_COLUMN_BEFORE)); - } - m_pImpl->clearDeferredBreaks(); - } - - if (pContext && pContext->GetFootnote().is()) - { - pContext->GetFootnote()->setLabel( sText ); - //otherwise ignore sText - } - else if (m_pImpl->IsOpenFieldCommand() && !m_pImpl->IsForceGenericFields()) - { - 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->AppendFieldResult(sText); - else - { - if (pContext == nullptr) - pContext = new PropertyMap(); - - m_pImpl->appendTextPortion( sText, pContext ); - } - - } - m_pImpl->SetIsFirstRun(false); - } - catch( const uno::RuntimeException& ) - { - } -} - -void DomainMapper::lcl_props(writerfilter::Reference<Properties>::Pointer_t ref) -{ - ref->resolve(*this); -} - -void DomainMapper::lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t ref) -{ - m_pImpl->SetAnyTableImport(true); - switch(name) - { - case NS_ooxml::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_ooxml::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: - { - - //the same for list tables - ref->resolve( *m_pImpl->GetListTable() ); - m_pImpl->GetListTable( )->CreateNumberingRules( ); - } - break; - case NS_ooxml::LN_THEMETABLE: - m_pImpl->GetThemeTable()->setThemeFontLangProperties( - m_pImpl->GetSettingsTable()->GetThemeFontLangProperties() ); - 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->substream(rName, ref); -} - -void DomainMapper::lcl_startGlossaryEntry() -{ - uno::Reference< text::XTextRange > xTextRange = GetCurrentTextRange(); - m_pImpl->setGlossaryEntryStart(xTextRange); -} - -void DomainMapper::lcl_endGlossaryEntry() -{ - m_pImpl->appendGlossaryEntry(); -} - -void DomainMapper::handleUnderlineType(const Id nId, const ::tools::SvRef<PropertyMap>& rContext) -{ - sal_Int16 nUnderline = awt::FontUnderline::NONE; - - switch (nId) - { - case NS_ooxml::LN_Value_ST_Underline_none: - nUnderline = awt::FontUnderline::NONE; - break; - case NS_ooxml::LN_Value_ST_Underline_words: - rContext->Insert(PROP_CHAR_WORD_MODE, uno::makeAny(true)); - [[fallthrough]]; - case NS_ooxml::LN_Value_ST_Underline_single: - nUnderline = awt::FontUnderline::SINGLE; - break; - case NS_ooxml::LN_Value_ST_Underline_double: - nUnderline = awt::FontUnderline::DOUBLE; - break; - case NS_ooxml::LN_Value_ST_Underline_dotted: - nUnderline = awt::FontUnderline::DOTTED; - break; - case NS_ooxml::LN_Value_ST_Underline_dash: - nUnderline = awt::FontUnderline::DASH; - break; - case NS_ooxml::LN_Value_ST_Underline_dotDash: - nUnderline = awt::FontUnderline::DASHDOT; - break; - case NS_ooxml::LN_Value_ST_Underline_dotDotDash: - nUnderline = awt::FontUnderline::DASHDOTDOT; - break; - case NS_ooxml::LN_Value_ST_Underline_thick: - nUnderline = awt::FontUnderline::BOLD; - break; - case NS_ooxml::LN_Value_ST_Underline_wave: - nUnderline = awt::FontUnderline::WAVE; - break; - case NS_ooxml::LN_Value_ST_Underline_dottedHeavy: - nUnderline = awt::FontUnderline::BOLDDOTTED; - break; - case NS_ooxml::LN_Value_ST_Underline_dashedHeavy: - nUnderline = awt::FontUnderline::BOLDDASH; - break; - case NS_ooxml::LN_Value_ST_Underline_dashLong: - nUnderline = awt::FontUnderline::LONGDASH; - break; - case NS_ooxml::LN_Value_ST_Underline_dashLongHeavy: - nUnderline = awt::FontUnderline::BOLDLONGDASH; - break; - case NS_ooxml::LN_Value_ST_Underline_dashDotHeavy: - nUnderline = awt::FontUnderline::BOLDDASHDOT; - break; - case NS_ooxml::LN_Value_ST_Underline_dashDotDotHeavy: - nUnderline = awt::FontUnderline::BOLDDASHDOTDOT; - break; - case NS_ooxml::LN_Value_ST_Underline_wavyHeavy: - nUnderline = awt::FontUnderline::BOLDWAVE; - break; - case NS_ooxml::LN_Value_ST_Underline_wavyDouble: - nUnderline = awt::FontUnderline::DOUBLEWAVE; - break; - } - rContext->Insert(PROP_CHAR_UNDERLINE, uno::makeAny(nUnderline)); -} - -void DomainMapper::handleParaJustification(const sal_Int32 nIntValue, const ::tools::SvRef<PropertyMap>& rContext, const bool bExchangeLeftRight) -{ - style::ParagraphAdjust nAdjust = style::ParagraphAdjust_LEFT; - style::ParagraphAdjust nLastLineAdjust = style::ParagraphAdjust_LEFT; - OUString aStringValue = "left"; - switch(nIntValue) - { - case NS_ooxml::LN_Value_ST_Jc_center: - nAdjust = style::ParagraphAdjust_CENTER; - aStringValue = "center"; - break; - case NS_ooxml::LN_Value_ST_Jc_right: - case NS_ooxml::LN_Value_ST_Jc_end: - nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_LEFT : style::ParagraphAdjust_RIGHT; - aStringValue = "right"; - break; - case NS_ooxml::LN_Value_ST_Jc_distribute: - nLastLineAdjust = style::ParagraphAdjust_BLOCK; - [[fallthrough]]; - case NS_ooxml::LN_Value_ST_Jc_both: - nAdjust = style::ParagraphAdjust_BLOCK; - aStringValue = "both"; - break; - case NS_ooxml::LN_Value_ST_Jc_left: - case NS_ooxml::LN_Value_ST_Jc_start: - default: - nAdjust = bExchangeLeftRight ? style::ParagraphAdjust_RIGHT : style::ParagraphAdjust_LEFT; - break; - } - rContext->Insert( PROP_PARA_ADJUST, uno::makeAny( nAdjust ) ); - rContext->Insert( PROP_PARA_LAST_LINE_ADJUST, uno::makeAny( nLastLineAdjust ) ); - m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "jc", aStringValue); -} - -bool DomainMapper::getColorFromId(const Id nId, sal_Int32 &nColor) -{ - nColor = 0; - if ((nId < NS_ooxml::LN_Value_ST_HighlightColor_black) || (nId > NS_ooxml::LN_Value_ST_HighlightColor_none)) - return false; - - switch (nId) - { - case NS_ooxml::LN_Value_ST_HighlightColor_black: nColor=0x000000; break; - case NS_ooxml::LN_Value_ST_HighlightColor_blue: nColor=0x0000ff; break; - case NS_ooxml::LN_Value_ST_HighlightColor_cyan: nColor=0x00ffff; break; - case NS_ooxml::LN_Value_ST_HighlightColor_green: nColor=0x00ff00; break; - case NS_ooxml::LN_Value_ST_HighlightColor_magenta: nColor=0xff00ff; break; - case NS_ooxml::LN_Value_ST_HighlightColor_red: nColor=0xff0000; break; - case NS_ooxml::LN_Value_ST_HighlightColor_yellow: nColor=0xffff00; break; - case NS_ooxml::LN_Value_ST_HighlightColor_white: nColor=0xffffff; break; - case NS_ooxml::LN_Value_ST_HighlightColor_darkBlue: nColor=0x000080; break; - case NS_ooxml::LN_Value_ST_HighlightColor_darkCyan: nColor=0x008080; break; - case NS_ooxml::LN_Value_ST_HighlightColor_darkGreen: nColor=0x008000; break; - case NS_ooxml::LN_Value_ST_HighlightColor_darkMagenta: nColor=0x800080; break; - case NS_ooxml::LN_Value_ST_HighlightColor_darkRed: nColor=0x800000; break; - case NS_ooxml::LN_Value_ST_HighlightColor_darkYellow: nColor=0x808000; break; - case NS_ooxml::LN_Value_ST_HighlightColor_darkGray: nColor=0x808080; break; - case NS_ooxml::LN_Value_ST_HighlightColor_lightGray: nColor=0xC0C0C0; break; - case NS_ooxml::LN_Value_ST_HighlightColor_none: nColor=0xFFFFFFFF; break; //COL_AUTO - default: - return false; - } - return true; -} - -sal_Int16 DomainMapper::getEmphasisValue(const sal_Int32 nIntValue) -{ - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_Em_dot: - return text::FontEmphasis::DOT_ABOVE; - case NS_ooxml::LN_Value_ST_Em_comma: - return text::FontEmphasis::ACCENT_ABOVE; - case NS_ooxml::LN_Value_ST_Em_circle: - return text::FontEmphasis::CIRCLE_ABOVE; - case NS_ooxml::LN_Value_ST_Em_underDot: - return text::FontEmphasis::DOT_BELOW; - default: - return text::FontEmphasis::NONE; - } -} - -OUString DomainMapper::getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix) -{ - switch(nIntValue) - { - case NS_ooxml::LN_Value_ST_CombineBrackets_round: - if (bIsPrefix) - return "("; - return ")"; - - case NS_ooxml::LN_Value_ST_CombineBrackets_square: - if (bIsPrefix) - return "["; - return "]"; - - case NS_ooxml::LN_Value_ST_CombineBrackets_angle: - if (bIsPrefix) - return "<"; - return ">"; - - case NS_ooxml::LN_Value_ST_CombineBrackets_curly: - if (bIsPrefix) - return "{"; - return "}"; - - case NS_ooxml::LN_Value_ST_CombineBrackets_none: - default: - return OUString(); - } -} - -style::TabAlign DomainMapper::getTabAlignFromValue(const sal_Int32 nIntValue) -{ - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_TabJc_start: - case NS_ooxml::LN_Value_ST_TabJc_left: - case NS_ooxml::LN_Value_ST_TabJc_bar: // bar not supported - case NS_ooxml::LN_Value_ST_TabJc_num: // num not supported - return style::TabAlign_LEFT; - case NS_ooxml::LN_Value_ST_TabJc_center: - return style::TabAlign_CENTER; - case NS_ooxml::LN_Value_ST_TabJc_end: - case NS_ooxml::LN_Value_ST_TabJc_right: - return style::TabAlign_RIGHT; - case NS_ooxml::LN_Value_ST_TabJc_decimal: - return style::TabAlign_DECIMAL; - } - return style::TabAlign_LEFT; -} - -sal_Unicode DomainMapper::getFillCharFromValue(const sal_Int32 nIntValue) -{ - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_TabTlc_dot: - return u'.'; - case NS_ooxml::LN_Value_ST_TabTlc_hyphen: - return u'-'; - case NS_ooxml::LN_Value_ST_TabTlc_underscore: - case NS_ooxml::LN_Value_ST_TabTlc_heavy: // FIXME ??? - return u'_'; - case NS_ooxml::LN_Value_ST_TabTlc_middleDot: // middleDot - return u'\x00b7'; - case NS_ooxml::LN_Value_ST_TabTlc_none: - default: - return u' '; // blank space - } -} - -bool DomainMapper::IsOOXMLImport() const -{ - return m_pImpl->IsOOXMLImport(); -} - -bool DomainMapper::IsRTFImport() const -{ - return m_pImpl->IsRTFImport(); -} - -uno::Reference < lang::XMultiServiceFactory > const & DomainMapper::GetTextFactory() const -{ - return m_pImpl->GetTextFactory(); -} - -uno::Reference< text::XTextRange > DomainMapper::GetCurrentTextRange() -{ - if (m_pImpl->HasTopText()) - return m_pImpl->GetTopTextAppend()->getEnd(); - return m_pImpl->m_xInsertTextRange; -} - -OUString DomainMapper::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate ) -{ - StyleSheetTablePtr pStyleSheets = m_pImpl->GetStyleSheetTable(); - return pStyleSheets->getOrCreateCharStyle( rCharProperties, bAlwaysCreate ); -} - -StyleSheetTablePtr const & DomainMapper::GetStyleSheetTable( ) -{ - return m_pImpl->GetStyleSheetTable( ); -} - -SettingsTablePtr const & DomainMapper::GetSettingsTable() -{ - return m_pImpl->GetSettingsTable(); -} - -GraphicZOrderHelper* DomainMapper::graphicZOrderHelper() -{ - if (zOrderHelper == nullptr) - zOrderHelper.reset( new GraphicZOrderHelper ); - return zOrderHelper.get(); -} - -GraphicNamingHelper& DomainMapper::GetGraphicNamingHelper() -{ - if (m_pGraphicNamingHelper == nullptr) - m_pGraphicNamingHelper.reset(new GraphicNamingHelper()); - return *m_pGraphicNamingHelper; -} - -uno::Reference<drawing::XShape> DomainMapper::PopPendingShape() -{ - return m_pImpl->PopPendingShape(); -} - -bool DomainMapper::IsInHeaderFooter() const -{ - return m_pImpl->IsInHeaderFooter(); -} - -bool DomainMapper::IsInShape() const { return m_pImpl->IsInShape(); } - -bool DomainMapper::IsInTable() const -{ - return m_pImpl->hasTableManager() && m_pImpl->getTableManager().isInCell(); -} - -OUString DomainMapper::GetListStyleName(sal_Int32 nListId) const -{ - return m_pImpl->GetListStyleName( nListId ); -} - -void DomainMapper::SetDocDefaultsImport(bool bSet) -{ - m_pImpl->SetDocDefaultsImport(bSet); -} - -bool DomainMapper::IsStyleSheetImport() const -{ - return m_pImpl->IsStyleSheetImport(); -} - -void DomainMapper::enableInteropGrabBag(const OUString& aName) -{ - m_pImpl->m_aInteropGrabBagName = aName; -} - -beans::PropertyValue DomainMapper::getInteropGrabBag() -{ - beans::PropertyValue aRet; - aRet.Name = m_pImpl->m_aInteropGrabBagName; - aRet.Value <<= comphelper::containerToSequence(m_pImpl->m_aInteropGrabBag); - - m_pImpl->m_aInteropGrabBag.clear(); - m_pImpl->m_aInteropGrabBagName.clear(); - return aRet; -} - -void DomainMapper::HandleRedline( Sprm& rSprm ) -{ - sal_uInt32 nSprmId = rSprm.getId(); - - m_pImpl->AddNewRedline( nSprmId ); - - if (nSprmId == NS_ooxml::LN_CT_PPr_pPrChange) - { - m_pImpl->SetCurrentRedlineToken(XML_ParagraphFormat); - } - else if (nSprmId == NS_ooxml::LN_CT_TrPr_ins) - { - m_pImpl->SetCurrentRedlineToken(XML_tableRowInsert); - } - else if (nSprmId == NS_ooxml::LN_CT_TrPr_del) - { - m_pImpl->SetCurrentRedlineToken(XML_tableRowDelete); - } - else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellIns) - { - m_pImpl->SetCurrentRedlineToken(XML_tableCellInsert); - } - else if (nSprmId == NS_ooxml::LN_CT_TcPrBase_cellDel) - { - m_pImpl->SetCurrentRedlineToken(XML_tableCellDelete); - } - - resolveSprmProps(*this, rSprm ); - // now the properties author, date and id should be available - sal_Int32 nToken = m_pImpl->GetCurrentRedlineToken(); - switch( nToken & 0xffff ) - { - case XML_mod: - case XML_ins: - case XML_del: - case XML_moveTo: - case XML_moveFrom: - case XML_ParagraphFormat: - case XML_tableRowInsert: - case XML_tableRowDelete: - case XML_tableCellInsert: - case XML_tableCellDelete: - break; - default: OSL_FAIL( "redline token other than mod, ins, del, moveTo, moveFrom or table row" ); break; - } - m_pImpl->EndParaMarkerChange( ); - m_pImpl->SetCurrentRedlineIsRead(); -} - -void DomainMapper::finishParagraph(const bool bRemove, const bool bNoNumbering) -{ - if (m_pImpl->m_pSdtHelper->validateDateFormat()) - m_pImpl->m_pSdtHelper->createDateContentControl(); - m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH), bRemove, bNoNumbering); -} - -} //namespace writerfilter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper.hxx b/writerfilter/source/dmapper/DomainMapper.hxx deleted file mode 100644 index 46bbd2b39018..000000000000 --- a/writerfilter/source/dmapper/DomainMapper.hxx +++ /dev/null @@ -1,183 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#pragma once - -#include <dmapper/DomainMapperFactory.hxx> -#include "LoggedResources.hxx" -#include "PropertyMap.hxx" -#include "SettingsTable.hxx" -#include <com/sun/star/lang/XComponent.hpp> -#include <com/sun/star/style/TabAlign.hpp> - -#include <map> -#include <vector> -#include <memory> - -namespace com::sun::star{ - namespace beans{ - struct PropertyValue; - } - namespace io{ - class XInputStream; - } - namespace uno{ - class XComponentContext; - } - namespace lang{ - class XMultiServiceFactory; - } - namespace text{ - class XTextRange; - } -} - -namespace utl -{ -class MediaDescriptor; -} - -typedef std::vector<css::beans::PropertyValue> PropertyValueVector_t; - -namespace writerfilter::dmapper -{ - -class PropertyMap; -class DomainMapper_Impl; -class ListsManager; -class StyleSheetTable; -class GraphicZOrderHelper; -class GraphicNamingHelper; - -typedef tools::SvRef<StyleSheetTable> StyleSheetTablePtr; - -class DomainMapper : public LoggedProperties, public LoggedTable, - public BinaryObj, public LoggedStream -{ - std::unique_ptr<DomainMapper_Impl> m_pImpl; - -public: - DomainMapper(const css::uno::Reference<css::uno::XComponentContext>& xContext, - css::uno::Reference<css::io::XInputStream> const& xInputStream, - css::uno::Reference<css::lang::XComponent> const& xModel, - bool bRepairStorage, - SourceDocumentType eDocumentType, - utl::MediaDescriptor const & rMediaDesc); - virtual ~DomainMapper() override; - - // Stream - virtual void markLastParagraphInSection() override; - virtual void markLastSectionGroup() override; - - // BinaryObj - virtual void data(const sal_uInt8* buf, size_t len) override; - - void sprmWithProps( Sprm& sprm, const PropertyMapPtr& pContext ); - - void PushStyleSheetProperties( const PropertyMapPtr& pStyleProperties, bool bAffectTableMngr = false ); - void PopStyleSheetProperties( bool bAffectTableMngr = false ); - - void PushListProperties( const ::tools::SvRef<PropertyMap>& pListProperties ); - void PopListProperties(); - OUString GetListStyleName(sal_Int32 nListId) const; - - bool IsOOXMLImport() const; - bool IsRTFImport() const; - css::uno::Reference<css::lang::XMultiServiceFactory> const & GetTextFactory() const; - css::uno::Reference<css::text::XTextRange> GetCurrentTextRange(); - - OUString getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate ); - StyleSheetTablePtr const & GetStyleSheetTable( ); - SettingsTablePtr const & GetSettingsTable(); - GraphicZOrderHelper* graphicZOrderHelper(); - GraphicNamingHelper& GetGraphicNamingHelper(); - - /// Return the first from the pending (not inserted to the document) shapes, if there are any. - css::uno::Reference<css::drawing::XShape> PopPendingShape(); - - bool IsInHeaderFooter() const; - bool IsInTable() const; - void SetDocDefaultsImport(bool bSet); - bool IsStyleSheetImport() const; - bool IsInShape() const; - - void hasControls( const bool bSet ) { mbHasControls = bSet; } - - /** - @see DomainMapper_Impl::processDeferredCharacterProperties() - */ - void processDeferredCharacterProperties(const std::map<sal_Int32, css::uno::Any>& rDeferredCharacterProperties); - - /// Enable storing of seen tokens in a named grab bag. - void enableInteropGrabBag(const OUString& aName); - /// Get the stored tokens and clear the internal storage. - css::beans::PropertyValue getInteropGrabBag(); - - void HandleRedline( Sprm& rSprm ); - -private: - // Stream - virtual void lcl_startSectionGroup() override; - virtual void lcl_endSectionGroup() override; - virtual void lcl_startParagraphGroup() override; - virtual void lcl_endParagraphGroup() override; - virtual void lcl_startCharacterGroup() override; - virtual void lcl_endCharacterGroup() override; - virtual void lcl_startShape(css::uno::Reference<css::drawing::XShape> const& xShape) override; - virtual void lcl_endShape( ) override; - - virtual void lcl_text(const sal_uInt8 * data, size_t len) override; - virtual void lcl_utext(const sal_uInt8 * data, size_t len) override; - virtual void lcl_positionOffset(const OUString& rText, bool bVertical) override; - virtual css::awt::Point getPositionOffset() override; - virtual void lcl_align(const OUString& rText, bool bVertical) override; - virtual void lcl_positivePercentage(const OUString& rText) override; - virtual void lcl_props(writerfilter::Reference<Properties>::Pointer_t ref) override; - virtual void lcl_table(Id name, - writerfilter::Reference<Table>::Pointer_t ref) override; - virtual void lcl_substream(Id name, - ::writerfilter::Reference<Stream>::Pointer_t ref) override; - virtual void lcl_startGlossaryEntry() override; - virtual void lcl_endGlossaryEntry() override; - - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - - // Table - virtual void lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) override; - - void finishParagraph(const bool bRemove = false, const bool bNoNumbering = false); - - static void handleUnderlineType(const Id nId, const ::tools::SvRef<PropertyMap>& rContext); - void handleParaJustification(const sal_Int32 nIntValue, const ::tools::SvRef<PropertyMap>& rContext, const bool bExchangeLeftRight); - static bool getColorFromId(const Id, sal_Int32 &nColor); - static sal_Int16 getEmphasisValue(const sal_Int32 nIntValue); - static OUString getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix = true); - static css::style::TabAlign getTabAlignFromValue(const sal_Int32 nIntValue); - static sal_Unicode getFillCharFromValue(const sal_Int32 nIntValue); - bool mbIsSplitPara; - bool mbHasControls; - std::unique_ptr< GraphicZOrderHelper > zOrderHelper; - std::unique_ptr<GraphicNamingHelper> m_pGraphicNamingHelper; - OUString m_sGlossaryEntryName; -}; - -} // namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx deleted file mode 100644 index fd21827211bb..000000000000 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ /dev/null @@ -1,1697 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <sal/config.h> - -#include <string_view> - -#include "DomainMapperTableHandler.hxx" -#include "DomainMapper_Impl.hxx" -#include "StyleSheetTable.hxx" -#include <com/sun/star/style/ParagraphAdjust.hpp> -#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/table/BorderLineStyle.hpp> -#include <com/sun/star/table/XCellRange.hpp> -#include <com/sun/star/text/HoriOrientation.hpp> -#include <com/sun/star/text/SizeType.hpp> -#include <com/sun/star/text/XTextField.hpp> -#include <com/sun/star/text/XTextRangeCompare.hpp> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/beans/XPropertyState.hpp> -#include <com/sun/star/container/XEnumeration.hpp> -#include <com/sun/star/container/XEnumerationAccess.hpp> -#include <com/sun/star/drawing/FillStyle.hpp> -#include "TablePositionHandler.hxx" -#include "TagLogger.hxx" -#include "util.hxx" -#include <osl/diagnose.h> -#include <sal/log.hxx> -#include <tools/diagnose_ex.h> -#include <comphelper/sequence.hxx> -#include <comphelper/propertyvalue.hxx> -#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> -#include <boost/lexical_cast.hpp> - -#ifdef DBG_UTIL -#include "PropertyMapHelper.hxx" -#include <rtl/ustring.hxx> -#endif - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; -using namespace ::std; - -#define DEF_BORDER_DIST 190 //0,19cm -#define CNF_FIRST_ROW 0x800 -#define CNF_LAST_ROW 0x400 -#define CNF_FIRST_COLUMN 0x200 -#define CNF_LAST_COLUMN 0x100 -#define CNF_ODD_VBAND 0x080 -#define CNF_EVEN_VBAND 0x040 -#define CNF_ODD_HBAND 0x020 -#define CNF_EVEN_HBAND 0x010 -#define CNF_FIRST_ROW_LAST_COLUMN 0x008 -#define CNF_FIRST_ROW_FIRST_COLUMN 0x004 -#define CNF_LAST_ROW_LAST_COLUMN 0x002 -#define CNF_LAST_ROW_FIRST_COLUMN 0x001 -#define CNF_ALL 0xFFF - -// total number of table columns -#define MAXTABLECELLS 63 - -DomainMapperTableHandler::DomainMapperTableHandler( - css::uno::Reference<css::text::XTextAppendAndConvert> const& xText, - DomainMapper_Impl& rDMapper_Impl) - : m_xText(xText), - m_rDMapper_Impl( rDMapper_Impl ), - m_bHadFootOrEndnote(false) -{ -} - -DomainMapperTableHandler::~DomainMapperTableHandler() -{ -} - -void DomainMapperTableHandler::startTable(const TablePropertyMapPtr& pProps) -{ - m_aTableProperties = pProps; - m_aTableRanges.clear(); - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablehandler.table"); - - if (pProps) - pProps->dumpXml(); -#endif -} - -static void lcl_mergeBorder( PropertyIds nId, const PropertyMapPtr& pOrig, const PropertyMapPtr& pDest ) -{ - std::optional<PropertyMap::Property> pOrigVal = pOrig->getProperty(nId); - - if ( pOrigVal ) - { - pDest->Insert( nId, pOrigVal->second, false ); - } -} - -static void lcl_computeCellBorders( const PropertyMapPtr& pTableBorders, const PropertyMapPtr& pCellProps, - sal_uInt32 nCell, sal_uInt32 nFirstCell, sal_uInt32 nLastCell, sal_Int32 nRow, bool bIsEndRow, bool bMergedVertically ) -{ - const bool bIsStartCol = nCell == nFirstCell; - const bool bIsEndCol = nCell == nLastCell; - std::optional<PropertyMap::Property> pVerticalVal = pCellProps->getProperty(META_PROP_VERTICAL_BORDER); - std::optional<PropertyMap::Property> pHorizontalVal = pCellProps->getProperty(META_PROP_HORIZONTAL_BORDER); - - // Handle the vertical and horizontal borders - uno::Any aVertProp; - if ( !pVerticalVal) - { - pVerticalVal = pTableBorders->getProperty(META_PROP_VERTICAL_BORDER); - if ( pVerticalVal ) - aVertProp = pVerticalVal->second; - } - else - { - aVertProp = pVerticalVal->second; - pCellProps->Erase( pVerticalVal->first ); - } - - uno::Any aHorizProp; - if ( !pHorizontalVal ) - { - pHorizontalVal = pTableBorders->getProperty(META_PROP_HORIZONTAL_BORDER); - if ( pHorizontalVal ) - aHorizProp = pHorizontalVal->second; - } - else - { - aHorizProp = pHorizontalVal->second; - pCellProps->Erase( pHorizontalVal->first ); - } - - if ( bIsStartCol ) - lcl_mergeBorder( PROP_LEFT_BORDER, pTableBorders, pCellProps ); - - if ( bIsEndCol ) - lcl_mergeBorder( PROP_RIGHT_BORDER, pTableBorders, pCellProps ); - - // <w:insideV> counts if there are multiple cells in this row. - if ( pVerticalVal ) - { - if ( !bIsEndCol && nCell >= nFirstCell ) - pCellProps->Insert( PROP_RIGHT_BORDER, aVertProp, false ); - if ( !bIsStartCol && nCell <= nLastCell ) - pCellProps->Insert( PROP_LEFT_BORDER, aVertProp, false ); - } - - if ( nRow == 0 ) - { - lcl_mergeBorder( PROP_TOP_BORDER, pTableBorders, pCellProps ); - if ( pHorizontalVal && !bMergedVertically ) - pCellProps->Insert( PROP_BOTTOM_BORDER, aHorizProp, false ); - } - - if ( bMergedVertically ) - lcl_mergeBorder( PROP_BOTTOM_BORDER, pTableBorders, pCellProps ); - - if ( bIsEndRow ) - { - lcl_mergeBorder( PROP_BOTTOM_BORDER, pTableBorders, pCellProps ); - if ( pHorizontalVal ) - pCellProps->Insert( PROP_TOP_BORDER, aHorizProp, false ); - } - - if ( nRow > 0 && !bIsEndRow ) - { - if ( pHorizontalVal ) - { - pCellProps->Insert( PROP_TOP_BORDER, aHorizProp, false ); - pCellProps->Insert( PROP_BOTTOM_BORDER, aHorizProp, false ); - } - } -} - -#ifdef DBG_UTIL - -static void lcl_debug_BorderLine(table::BorderLine const & rLine) -{ - TagLogger::getInstance().startElement("BorderLine"); - TagLogger::getInstance().attribute("Color", rLine.Color); - TagLogger::getInstance().attribute("InnerLineWidth", rLine.InnerLineWidth); - TagLogger::getInstance().attribute("OuterLineWidth", rLine.OuterLineWidth); - TagLogger::getInstance().attribute("LineDistance", rLine.LineDistance); - TagLogger::getInstance().endElement(); -} - -static void lcl_debug_TableBorder(table::TableBorder const & rBorder) -{ - TagLogger::getInstance().startElement("TableBorder"); - lcl_debug_BorderLine(rBorder.TopLine); - TagLogger::getInstance().attribute("IsTopLineValid", sal_uInt32(rBorder.IsTopLineValid)); - lcl_debug_BorderLine(rBorder.BottomLine); - TagLogger::getInstance().attribute("IsBottomLineValid", sal_uInt32(rBorder.IsBottomLineValid)); - lcl_debug_BorderLine(rBorder.LeftLine); - TagLogger::getInstance().attribute("IsLeftLineValid", sal_uInt32(rBorder.IsLeftLineValid)); - lcl_debug_BorderLine(rBorder.RightLine); - TagLogger::getInstance().attribute("IsRightLineValid", sal_uInt32(rBorder.IsRightLineValid)); - lcl_debug_BorderLine(rBorder.VerticalLine); - TagLogger::getInstance().attribute("IsVerticalLineValid", sal_uInt32(rBorder.IsVerticalLineValid)); - lcl_debug_BorderLine(rBorder.HorizontalLine); - TagLogger::getInstance().attribute("IsHorizontalLineValid", sal_uInt32(rBorder.IsHorizontalLineValid)); - TagLogger::getInstance().attribute("Distance", rBorder.Distance); - TagLogger::getInstance().attribute("IsDistanceValid", sal_uInt32(rBorder.IsDistanceValid)); - TagLogger::getInstance().endElement(); -} -#endif - -struct TableInfo -{ - sal_Int32 nLeftBorderDistance; - sal_Int32 nRightBorderDistance; - sal_Int32 nTopBorderDistance; - sal_Int32 nBottomBorderDistance; - sal_Int32 nTblLook; - sal_Int32 nNestLevel; - PropertyMapPtr pTableDefaults; - PropertyMapPtr pTableBorders; - TableStyleSheetEntry* pTableStyle; - css::beans::PropertyValues aTableProperties; - std::vector< PropertyIds > aTablePropertyIds; - - TableInfo() - : nLeftBorderDistance(DEF_BORDER_DIST) - , nRightBorderDistance(DEF_BORDER_DIST) - , nTopBorderDistance(0) - , nBottomBorderDistance(0) - , nTblLook(0x4a0) - , nNestLevel(0) - , pTableDefaults(new PropertyMap) - , pTableBorders(new PropertyMap) - , pTableStyle(nullptr) - { - } - -}; - -namespace -{ - -bool lcl_extractTableBorderProperty(const PropertyMapPtr& pTableProperties, const PropertyIds nId, TableInfo const & rInfo, table::BorderLine2& rLine) -{ - if (!pTableProperties) - return false; - - const std::optional<PropertyMap::Property> aTblBorder = pTableProperties->getProperty(nId); - if( aTblBorder ) - { - OSL_VERIFY(aTblBorder->second >>= rLine); - - rInfo.pTableBorders->Insert( nId, uno::makeAny( rLine ) ); - rInfo.pTableDefaults->Erase( nId ); - - return true; - } - - return false; -} - -void lcl_extractHoriOrient(std::vector<beans::PropertyValue>& rFrameProperties, sal_Int32& nHoriOrient) -{ - // Shifts the frame left by the given value. - for (const beans::PropertyValue & rFrameProperty : rFrameProperties) - { - if (rFrameProperty.Name == "HoriOrient") - { - sal_Int32 nValue = rFrameProperty.Value.get<sal_Int32>(); - if (nValue != text::HoriOrientation::NONE) - nHoriOrient = nValue; - return; - } - } -} - -void lcl_DecrementHoriOrientPosition(std::vector<beans::PropertyValue>& rFrameProperties, sal_Int32 nAmount) -{ - // Shifts the frame left by the given value. - for (beans::PropertyValue & rPropertyValue : rFrameProperties) - { - if (rPropertyValue.Name == "HoriOrientPosition") - { - sal_Int32 nValue = rPropertyValue.Value.get<sal_Int32>(); - nValue -= nAmount; - rPropertyValue.Value <<= nValue; - return; - } - } -} - -void lcl_adjustBorderDistance(TableInfo& rInfo, const table::BorderLine2& rLeftBorder, - const table::BorderLine2& rRightBorder) -{ - // MS Word appears to do these things to adjust the cell horizontal area: - // - // bll = left borderline width - // blr = right borderline width - // cea = cell's edit area rectangle - // cea_w = cea width - // cml = cell's left margin (padding) defined in cell settings - // cmr = cell's right margin (padding) defined in cell settings - // cw = cell width (distance between middles of left borderline and right borderline) - // pad_l = actual cea left padding = (its left pos relative to middle of bll) - // pad_r = actual cea right padding = abs (its right pos relative to middle of blr) - // - // pad_l = max(bll/2, cml) -> cea does not overlap left borderline - // cea_w = cw-max(pad_l+blr/2, cml+cmr) -> cea does not overlap right borderline - // pad_r = max(pad_l+blr/2, cml+cmr) - pad_l - // - // It means that e.g. for border widths of 6 pt (~2.12 mm), left margin 0 mm, and right margin - // 2 mm, actual left and right margins will (unexpectedly) coincide with inner edges of cell's - // borderlines - the right margin won't create spacing between right of edit rectangle and the - // inner edge of right borderline. - - const sal_Int32 nActualL - = std::max<sal_Int32>(rLeftBorder.LineWidth / 2, rInfo.nLeftBorderDistance); - const sal_Int32 nActualR - = std::max<sal_Int32>(nActualL + rRightBorder.LineWidth / 2, - rInfo.nLeftBorderDistance + rInfo.nRightBorderDistance) - - nActualL; - rInfo.nLeftBorderDistance = nActualL; - rInfo.nRightBorderDistance = nActualR; -} - -} - -TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo, std::vector<beans::PropertyValue>& rFrameProperties) -{ - // will receive the table style if any - TableStyleSheetEntry* pTableStyle = nullptr; - - if( m_aTableProperties ) - { - //create properties from the table attributes - //...pPropMap->Insert( PROP_LEFT_MARGIN, uno::makeAny( m_nLeftMargin - m_nGapHalf )); - //pPropMap->Insert( PROP_HORI_ORIENT, uno::makeAny( text::HoriOrientation::RIGHT )); - sal_Int32 nGapHalf = 0; - sal_Int32 nLeftMargin = 0; - - comphelper::SequenceAsHashMap aGrabBag; - - if (nullptr != m_rDMapper_Impl.getTableManager().getCurrentTableRealPosition()) - { - TablePositionHandler *pTablePositions = m_rDMapper_Impl.getTableManager().getCurrentTableRealPosition(); - - uno::Sequence< beans::PropertyValue > aGrabBagTS( 10 ); - - aGrabBagTS[0].Name = "bottomFromText"; - aGrabBagTS[0].Value <<= pTablePositions->getBottomFromText(); - - aGrabBagTS[1].Name = "horzAnchor"; - aGrabBagTS[1].Value <<= pTablePositions->getHorzAnchor(); - - aGrabBagTS[2].Name = "leftFromText"; - aGrabBagTS[2].Value <<= pTablePositions->getLeftFromText(); - - aGrabBagTS[3].Name = "rightFromText"; - aGrabBagTS[3].Value <<= pTablePositions->getRightFromText(); - - aGrabBagTS[4].Name = "tblpX"; - aGrabBagTS[4].Value <<= pTablePositions->getX(); - - aGrabBagTS[5].Name = "tblpXSpec"; - aGrabBagTS[5].Value <<= pTablePositions->getXSpec(); - - aGrabBagTS[6].Name = "tblpY"; - aGrabBagTS[6].Value <<= pTablePositions->getY(); - - aGrabBagTS[7].Name = "tblpYSpec"; - aGrabBagTS[7].Value <<= pTablePositions->getYSpec(); - - aGrabBagTS[8].Name = "topFromText"; - aGrabBagTS[8].Value <<= pTablePositions->getTopFromText(); - - aGrabBagTS[9].Name = "vertAnchor"; - aGrabBagTS[9].Value <<= pTablePositions->getVertAnchor(); - - aGrabBag["TablePosition"] <<= aGrabBagTS; - } - - std::optional<PropertyMap::Property> aTableStyleVal = m_aTableProperties->getProperty(META_PROP_TABLE_STYLE_NAME); - if(aTableStyleVal) - { - // Apply table style properties recursively - OUString sTableStyleName; - aTableStyleVal->second >>= sTableStyleName; - StyleSheetTablePtr pStyleSheetTable = m_rDMapper_Impl.GetStyleSheetTable(); - const StyleSheetEntryPtr pStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( sTableStyleName ); - pTableStyle = dynamic_cast<TableStyleSheetEntry*>( pStyleSheet.get( ) ); - m_aTableProperties->Erase( aTableStyleVal->first ); - - aGrabBag["TableStyleName"] <<= sTableStyleName; - - if( pStyleSheet ) - { - // First get the style properties, then the table ones - PropertyMapPtr pTableProps( m_aTableProperties.get() ); - TablePropertyMapPtr pEmptyProps( new TablePropertyMap ); - - m_aTableProperties = pEmptyProps; - - PropertyMapPtr pMergedProperties = pStyleSheet->GetMergedInheritedProperties(pStyleSheetTable); - - table::BorderLine2 aBorderLine; - TableInfo rStyleInfo; - if (lcl_extractTableBorderProperty(pMergedProperties, PROP_TOP_BORDER, rStyleInfo, aBorderLine)) - { - aGrabBag["TableStyleTopBorder"] <<= aBorderLine; - } - if (lcl_extractTableBorderProperty(pMergedProperties, PROP_BOTTOM_BORDER, rStyleInfo, aBorderLine)) - { - aGrabBag["TableStyleBottomBorder"] <<= aBorderLine; - } - if (lcl_extractTableBorderProperty(pMergedProperties, PROP_LEFT_BORDER, rStyleInfo, aBorderLine)) - { - aGrabBag["TableStyleLeftBorder"] <<= aBorderLine; - } - if (lcl_extractTableBorderProperty(pMergedProperties, PROP_RIGHT_BORDER, rStyleInfo, aBorderLine)) - { - aGrabBag["TableStyleRightBorder"] <<= aBorderLine; - } - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("mergedProps"); - if (pMergedProperties) - pMergedProperties->dumpXml(); - TagLogger::getInstance().endElement(); -#endif - - m_aTableProperties->InsertProps(pMergedProperties); - m_aTableProperties->InsertProps(pTableProps); - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("TableProperties"); - m_aTableProperties->dumpXml(); - TagLogger::getInstance().endElement(); -#endif - if (pTableStyle) - { - // apply tblHeader setting of the table style - PropertyMapPtr pHeaderStyleProps = pTableStyle->GetProperties(CNF_FIRST_ROW); - if ( pHeaderStyleProps->getProperty(PROP_HEADER_ROW_COUNT) ) - m_aTableProperties->Insert(PROP_HEADER_ROW_COUNT, uno::makeAny( sal_Int32(1)), false); - } - } - } - - // This is the one preserving just all the table look attributes. - std::optional<PropertyMap::Property> oTableLook = m_aTableProperties->getProperty(META_PROP_TABLE_LOOK); - if (oTableLook) - { - aGrabBag["TableStyleLook"] = oTableLook->second; - m_aTableProperties->Erase(oTableLook->first); - } - - // This is just the "val" attribute's numeric value. - const std::optional<PropertyMap::Property> aTblLook = m_aTableProperties->getProperty(PROP_TBL_LOOK); - if(aTblLook) - { - aTblLook->second >>= rInfo.nTblLook; - m_aTableProperties->Erase( aTblLook->first ); - } - - // apply cell margin settings of the table style - const std::optional<PropertyMap::Property> oLeftMargin = m_aTableProperties->getProperty(META_PROP_CELL_MAR_LEFT); - if (oLeftMargin) - { - oLeftMargin->second >>= rInfo.nLeftBorderDistance; - m_aTableProperties->Erase(oLeftMargin->first); - } - const std::optional<PropertyMap::Property> oRightMargin = m_aTableProperties->getProperty(META_PROP_CELL_MAR_RIGHT); - if (oRightMargin) - { - oRightMargin->second >>= rInfo.nRightBorderDistance; - m_aTableProperties->Erase(oRightMargin->first); - } - const std::optional<PropertyMap::Property> oTopMargin = m_aTableProperties->getProperty(META_PROP_CELL_MAR_TOP); - if (oTopMargin) - { - oTopMargin->second >>= rInfo.nTopBorderDistance; - m_aTableProperties->Erase(oTopMargin->first); - } - const std::optional<PropertyMap::Property> oBottomMargin = m_aTableProperties->getProperty(META_PROP_CELL_MAR_BOTTOM); - if (oBottomMargin) - { - oBottomMargin->second >>= rInfo.nBottomBorderDistance; - m_aTableProperties->Erase(oBottomMargin->first); - } - - // Set the table default attributes for the cells - rInfo.pTableDefaults->InsertProps(m_aTableProperties.get()); - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("TableDefaults"); - rInfo.pTableDefaults->dumpXml(); - TagLogger::getInstance().endElement(); -#endif - - if (!aGrabBag.empty()) - { - m_aTableProperties->Insert( PROP_TABLE_INTEROP_GRAB_BAG, uno::makeAny( aGrabBag.getAsConstPropertyValueList() ) ); - } - - m_aTableProperties->getValue( TablePropertyMap::GAP_HALF, nGapHalf ); - - std::optional<PropertyMap::Property> oLeftMarginFromStyle = m_aTableProperties->getProperty(PROP_LEFT_MARGIN); - if (oLeftMarginFromStyle) - { - oLeftMarginFromStyle->second >>= nLeftMargin; - // don't need to erase, we will push back the adjusted value - // of this (or the direct formatting, if that exists) later - } - 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 = 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, uno::makeAny( aDistances ) ); - - if (!rFrameProperties.empty()) - lcl_DecrementHoriOrientPosition(rFrameProperties, rInfo.nLeftBorderDistance); - - // Set table above/bottom spacing to 0. - m_aTableProperties->Insert( PROP_TOP_MARGIN, uno::makeAny( sal_Int32( 0 ) ) ); - m_aTableProperties->Insert( PROP_BOTTOM_MARGIN, uno::makeAny( sal_Int32( 0 ) ) ); - - //table border settings - table::TableBorder aTableBorder; - table::BorderLine2 aBorderLine, aLeftBorder, aRightBorder; - - if (lcl_extractTableBorderProperty(m_aTableProperties.get(), PROP_TOP_BORDER, rInfo, aBorderLine)) - { - aTableBorder.TopLine = aBorderLine; - aTableBorder.IsTopLineValid = true; - } - if (lcl_extractTableBorderProperty(m_aTableProperties.get(), PROP_BOTTOM_BORDER, rInfo, aBorderLine)) - { - aTableBorder.BottomLine = aBorderLine; - aTableBorder.IsBottomLineValid = true; - } - if (lcl_extractTableBorderProperty(m_aTableProperties.get(), PROP_LEFT_BORDER, rInfo, aLeftBorder)) - { - aTableBorder.LeftLine = aLeftBorder; - aTableBorder.IsLeftLineValid = true; - } - if (lcl_extractTableBorderProperty(m_aTableProperties.get(), PROP_RIGHT_BORDER, rInfo, - aRightBorder)) - { - aTableBorder.RightLine = aRightBorder; - aTableBorder.IsRightLineValid = true; - } - if (lcl_extractTableBorderProperty(m_aTableProperties.get(), META_PROP_HORIZONTAL_BORDER, rInfo, aBorderLine)) - { - aTableBorder.HorizontalLine = aBorderLine; - aTableBorder.IsHorizontalLineValid = true; - } - if (lcl_extractTableBorderProperty(m_aTableProperties.get(), META_PROP_VERTICAL_BORDER, rInfo, aBorderLine)) - { - aTableBorder.VerticalLine = aBorderLine; - aTableBorder.IsVerticalLineValid = true; - } - - aTableBorder.Distance = 0; - aTableBorder.IsDistanceValid = false; - - m_aTableProperties->Insert( PROP_TABLE_BORDER, uno::makeAny( aTableBorder ) ); - -#ifdef DBG_UTIL - lcl_debug_TableBorder(aTableBorder); -#endif - - // Table position in Office is computed in 2 different ways : - // - top level tables: the goal is to have in-cell text starting at table indent pos (tblInd), - // so table's position depends on table's cells margin - // - nested tables: the goal is to have left-most border starting at table_indent pos - - // Only top level table position depends on border width of Column A. - if ( !m_aCellProperties.empty() && !m_aCellProperties[0].empty() ) - { - // aLeftBorder already contains tblBorder; overwrite if cell is different. - std::optional<PropertyMap::Property> aCellBorder - = m_aCellProperties[0][0]->getProperty(PROP_LEFT_BORDER); - if ( aCellBorder ) - aCellBorder->second >>= aLeftBorder; - aCellBorder = m_aCellProperties[0][0]->getProperty(PROP_RIGHT_BORDER); - if (aCellBorder) - aCellBorder->second >>= aRightBorder; - } - if (rInfo.nNestLevel == 1 && aLeftBorder.LineWidth && !rFrameProperties.empty()) - { - lcl_DecrementHoriOrientPosition(rFrameProperties, aLeftBorder.LineWidth * 0.5); - } - lcl_adjustBorderDistance(rInfo, aLeftBorder, aRightBorder); - - // tdf#106742: since MS Word 2013 (compatibilityMode >= 15), top-level tables are handled the same as nested tables; - // the default behavior when DOCX doesn't define "compatibilityMode" option is to add the cell spacing - - // Undefined should not be possible any more for DOCX, but it is for RTF. - // In any case, continue to treat undefined as version 12 during import. - sal_Int32 nMode = m_rDMapper_Impl.GetSettingsTable()->GetWordCompatibilityMode(); - - if (((nMode < 0) || (0 < nMode && nMode <= 14)) && rInfo.nNestLevel == 1) - { - const sal_Int32 nAdjustedMargin = nLeftMargin - nGapHalf - rInfo.nLeftBorderDistance; - m_aTableProperties->Insert( PROP_LEFT_MARGIN, uno::makeAny( nAdjustedMargin ) ); - } - else - { - // Writer starts a table in the middle of the border. - // Word starts a table at the left edge of the border, - // so emulate that by adding the half the width. (also see docxattributeoutput) - if ( rInfo.nNestLevel > 1 && nLeftMargin < 0 ) - nLeftMargin = 0; - const sal_Int32 nAdjustedMargin = nLeftMargin - nGapHalf + (aLeftBorder.LineWidth / 2); - m_aTableProperties->Insert( PROP_LEFT_MARGIN, uno::makeAny( nAdjustedMargin ) ); - } - - sal_Int32 nTableWidth = 0; - sal_Int32 nTableWidthType = text::SizeType::FIX; - m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH, nTableWidth ); - m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType ); - if( nTableWidthType == text::SizeType::FIX ) - { - if( nTableWidth > 0 ) - m_aTableProperties->Insert( PROP_WIDTH, uno::makeAny( nTableWidth )); - else - { - // tdf#109524: If there is no width for the table, make it simply 100% by default. - // TODO: use cell contents to evaluate width (according to ECMA-376-1:2016 17.18.87) - nTableWidth = 100; - nTableWidthType = text::SizeType::VARIABLE; - } - } - if (nTableWidthType != text::SizeType::FIX) - { - m_aTableProperties->Insert( PROP_RELATIVE_WIDTH, uno::makeAny( sal_Int16( nTableWidth ) ) ); - m_aTableProperties->Insert( PROP_IS_WIDTH_RELATIVE, uno::makeAny( true ) ); - } - - sal_Int32 nHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH; - // Fetch Horizontal Orientation in rFrameProperties if not set in m_aTableProperties - if ( !m_aTableProperties->getValue( TablePropertyMap::HORI_ORIENT, nHoriOrient ) ) - lcl_extractHoriOrient( rFrameProperties, nHoriOrient ); - m_aTableProperties->Insert( PROP_HORI_ORIENT, uno::makeAny( sal_Int16(nHoriOrient) ) ); - //fill default value - if not available - m_aTableProperties->Insert( PROP_HEADER_ROW_COUNT, uno::makeAny( sal_Int32(0)), false); - - // if table is only a single row, and row is set as don't split, set the same value for the whole table. - if( m_aRowProperties.size() == 1 && m_aRowProperties[0] ) - { - std::optional<PropertyMap::Property> oSplitAllowed = m_aRowProperties[0]->getProperty(PROP_IS_SPLIT_ALLOWED); - if( oSplitAllowed ) - { - bool bRowCanSplit = true; - oSplitAllowed->second >>= bRowCanSplit; - if( !bRowCanSplit ) - m_aTableProperties->Insert( PROP_SPLIT, uno::makeAny(bRowCanSplit) ); - } - } - - rInfo.aTableProperties = m_aTableProperties->GetPropertyValues(); - rInfo.aTablePropertyIds = m_aTableProperties->GetPropertyIds(); - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("debug.tableprops"); - m_aTableProperties->dumpXml(); - TagLogger::getInstance().endElement(); -#endif - - } - - return pTableStyle; -} - -CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo, std::vector<HorizontallyMergedCell>& rMerges) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("getCellProperties"); -#endif - - CellPropertyValuesSeq_t aCellProperties( m_aCellProperties.size() ); - - if ( m_aCellProperties.empty() ) - { - #ifdef DBG_UTIL - TagLogger::getInstance().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; - - css::uno::Sequence<css::beans::PropertyValues>* pCellProperties = aCellProperties.getArray(); - PropertyMapVector1::const_iterator aRowIter = m_aRowProperties.begin(); - while( aRowOfCellsIterator != aRowOfCellsIteratorEnd ) - { - //aRowOfCellsIterator points to a vector of PropertyMapPtr - PropertyMapVector1::const_iterator aCellIterator = aRowOfCellsIterator->begin(); - PropertyMapVector1::const_iterator aCellIteratorEnd = aRowOfCellsIterator->end(); - - sal_Int32 nRowStyleMask = 0; - - if (aRowOfCellsIterator==m_aCellProperties.begin()) - { - if(rInfo.nTblLook&0x20) - nRowStyleMask |= CNF_FIRST_ROW; // first row style used - } - else if (aRowOfCellsIterator==aLastRowIterator) - { - if(rInfo.nTblLook&0x40) - nRowStyleMask |= CNF_LAST_ROW; // last row style used - } - else if (*aRowIter && (*aRowIter)->isSet(PROP_TBL_HEADER)) - nRowStyleMask |= CNF_FIRST_ROW; // table header implies first row - if(!nRowStyleMask) // if no row style used yet - { - // banding used only if not first and or last row style used - if(!(rInfo.nTblLook&0x200)) - { // hbanding used - int n = nRow + 1; - if(rInfo.nTblLook&0x20) - n++; - if(n & 1) - nRowStyleMask = CNF_ODD_HBAND; - else - nRowStyleMask = CNF_EVEN_HBAND; - } - } - - // Note that this is intentionally called "cell" and not "column". - // Don't make the mistake that all cell x's will be in the same column. - // Merged cells (grid span) in a row will affect the actual column. (fake cells were added to handle gridBefore/After) - sal_Int32 nCell = 0; - pCellProperties[nRow].realloc( aRowOfCellsIterator->size() ); - beans::PropertyValues* pSingleCellProperties = pCellProperties[nRow].getArray(); - - while( aCellIterator != aCellIteratorEnd ) - { - PropertyMapPtr pAllCellProps( new PropertyMap ); - - PropertyMapVector1::const_iterator aLastCellIterator = aRowOfCellsIterator->end() - 1; - bool bIsEndCol = aCellIterator == aLastCellIterator; - bool bIsEndRow = aRowOfCellsIterator == aLastRowIterator; - - //aCellIterator points to a PropertyMapPtr; - if( *aCellIterator ) - { - // remove directly applied insideV/H borders since they are meaningless without a context (tdf#82177) - (*aCellIterator)->Erase(META_PROP_VERTICAL_BORDER); - (*aCellIterator)->Erase(META_PROP_HORIZONTAL_BORDER); - - pAllCellProps->InsertProps(rInfo.pTableDefaults); - - sal_Int32 nCellStyleMask = 0; - if (aCellIterator==aRowOfCellsIterator->begin()) - { - if(rInfo.nTblLook&0x80) - nCellStyleMask = CNF_FIRST_COLUMN; // first col style used - } - else if (bIsEndCol) - { - if(rInfo.nTblLook&0x100) - nCellStyleMask = CNF_LAST_COLUMN; // last col style used - } - if(!nCellStyleMask) // if no cell style is used yet - { - if(!(rInfo.nTblLook&0x400)) - { // vbanding used - int n = nCell + 1; - if(rInfo.nTblLook&0x80) - n++; - if(n & 1) - nCellStyleMask = CNF_ODD_VBAND; - else - nCellStyleMask = CNF_EVEN_VBAND; - } - } - sal_Int32 nCnfStyleMask = nCellStyleMask + nRowStyleMask; - if(nCnfStyleMask == CNF_FIRST_COLUMN + CNF_FIRST_ROW) - nCnfStyleMask |= CNF_FIRST_ROW_FIRST_COLUMN; - else if(nCnfStyleMask == CNF_FIRST_COLUMN + CNF_LAST_ROW) - nCnfStyleMask |= CNF_LAST_ROW_FIRST_COLUMN; - else if(nCnfStyleMask == CNF_LAST_COLUMN + CNF_FIRST_ROW) - nCnfStyleMask |= CNF_FIRST_ROW_LAST_COLUMN; - else if(nCnfStyleMask == CNF_LAST_COLUMN + CNF_LAST_ROW) - nCnfStyleMask |= CNF_LAST_ROW_LAST_COLUMN; - - if ( rInfo.pTableStyle ) - { - PropertyMapPtr pStyleProps = rInfo.pTableStyle->GetProperties( nCnfStyleMask ); - - // Check if we need to clean up some empty border definitions to match what Word does. - static const PropertyIds pBorders[] = - { - PROP_TOP_BORDER, PROP_LEFT_BORDER, PROP_BOTTOM_BORDER, PROP_RIGHT_BORDER - }; - for (const PropertyIds& rBorder : pBorders) - { - std::optional<PropertyMap::Property> oStyleCellBorder = pStyleProps->getProperty(rBorder); - std::optional<PropertyMap::Property> oDirectCellBorder = (*aCellIterator)->getProperty(rBorder); - if (oStyleCellBorder && oDirectCellBorder) - { - // We have a cell border from the table style and as direct formatting as well. - table::BorderLine2 aStyleCellBorder = oStyleCellBorder->second.get<table::BorderLine2>(); - table::BorderLine2 aDirectCellBorder = oDirectCellBorder->second.get<table::BorderLine2>(); - if (aStyleCellBorder.LineStyle != table::BorderLineStyle::NONE && aDirectCellBorder.LineStyle == table::BorderLineStyle::NONE) - { - // The style one would be visible, but then cleared away as direct formatting. - // Delete both, so that table formatting can become visible. - pStyleProps->Erase(rBorder); - (*aCellIterator)->Erase(rBorder); - } - else - { - std::optional<PropertyMap::Property> oTableBorder = rInfo.pTableBorders->getProperty(rBorder); - if (oTableBorder) - { - table::BorderLine2 aTableBorder = oTableBorder->second.get<table::BorderLine2>(); - // Both style and direct formatting says that the cell has no border. - bool bNoCellBorder = aStyleCellBorder.LineStyle == table::BorderLineStyle::NONE && aDirectCellBorder.LineStyle == table::BorderLineStyle::NONE; - if (aTableBorder.LineStyle != table::BorderLineStyle::NONE && bNoCellBorder) - { - // But at a table-level, there is a border, then again delete both cell properties. - pStyleProps->Erase(rBorder); - (*aCellIterator)->Erase(rBorder); - } - } - } - } - } - - pAllCellProps->InsertProps( pStyleProps ); - } - - // Remove properties from style/row that aren't allowed in cells - pAllCellProps->Erase( PROP_HEADER_ROW_COUNT ); - pAllCellProps->Erase( PROP_TBL_HEADER ); - - // Then add the cell properties - pAllCellProps->InsertProps(*aCellIterator); - std::swap(*(*aCellIterator), *pAllCellProps ); - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("cell"); - TagLogger::getInstance().attribute("cell", nCell); - TagLogger::getInstance().attribute("row", nRow); -#endif - - // Do not apply horizontal and vertical borders to a one cell table. - if (m_aCellProperties.size() <= 1 && aRowOfCellsIterator->size() <= 1) - { - rInfo.pTableBorders->Erase(META_PROP_HORIZONTAL_BORDER); - rInfo.pTableBorders->Erase(META_PROP_VERTICAL_BORDER); - } - // Do not apply vertical borders to a one column table. - else if (m_aCellProperties.size() > 1 && aRowOfCellsIterator->size() <= 1) - { - bool isOneCol = true; - for (size_t i = nRow; i < m_aCellProperties.size(); i++) - { - if (m_aCellProperties[i].size() > 1) - { - isOneCol = false; - break; - } - } - if (isOneCol) - rInfo.pTableBorders->Erase(META_PROP_VERTICAL_BORDER); - } - // Do not apply horizontal borders to a one row table. - else if (m_aCellProperties.size() == 1 && aRowOfCellsIterator->size() > 1) - { - rInfo.pTableBorders->Erase(META_PROP_HORIZONTAL_BORDER); - } - - // tdf#129452 Checking if current cell is vertically merged with all the other cells below to the bottom. - // This must be done in order to apply the bottom border of the table to the first cell in a vertical merge. - std::optional<PropertyMap::Property> oProp = m_aCellProperties[nRow][nCell]->getProperty(PROP_VERTICAL_MERGE); - bool bMergedVertically = oProp && oProp->second.get<bool>(); // starting cell - if ( bMergedVertically ) - { - const sal_uInt32 nColumn = m_rDMapper_Impl.getTableManager().findColumn(nRow, nCell); - sal_Int32 nLastMergedRow = 0; - for (size_t i = nRow + 1; bMergedVertically && i < m_aCellProperties.size(); i++) - { - const sal_uInt32 nColumnCell = m_rDMapper_Impl.getTableManager().findColumnCell(i, nColumn); - if ( m_aCellProperties[i].size() > sal::static_int_cast<std::size_t>(nColumnCell) ) - { - oProp = m_aCellProperties[i][nColumnCell]->getProperty(PROP_VERTICAL_MERGE); - bMergedVertically = oProp && !oProp->second.get<bool>(); //continuing cell - if ( bMergedVertically ) - nLastMergedRow = i; - } - else - bMergedVertically = false; - } - - // Only consider the bottom border setting from the last merged cell. - // Note: in MSO, left/right apply per-unmerged-row. Can't do that in LO, so just using the top cell's borders should be fine. - if ( nRow < nLastMergedRow ) - { - (*aCellIterator)->Erase(PROP_BOTTOM_BORDER); - const sal_uInt32 nColumnCell = m_rDMapper_Impl.getTableManager().findColumnCell(nLastMergedRow, nColumn); - lcl_mergeBorder( PROP_BOTTOM_BORDER, m_aCellProperties[nLastMergedRow][nColumnCell], *aCellIterator ); - } - } - - const sal_uInt32 nFirstCell = m_rDMapper_Impl.getTableManager().getGridBefore(nRow); - const sal_uInt32 nLastCell = m_aCellProperties[nRow].size() - m_rDMapper_Impl.getTableManager().getGridAfter(nRow) - 1; - lcl_computeCellBorders( rInfo.pTableBorders, *aCellIterator, nCell, nFirstCell, nLastCell, nRow, bIsEndRow, bMergedVertically ); - - //now set the default left+right border distance TODO: there's an sprm containing the default distance! - aCellIterator->get()->Insert( PROP_LEFT_BORDER_DISTANCE, - uno::makeAny(rInfo.nLeftBorderDistance ), false); - aCellIterator->get()->Insert( PROP_RIGHT_BORDER_DISTANCE, - uno::makeAny(rInfo.nRightBorderDistance ), false); - aCellIterator->get()->Insert( PROP_TOP_BORDER_DISTANCE, - uno::makeAny(rInfo.nTopBorderDistance ), false); - aCellIterator->get()->Insert( PROP_BOTTOM_BORDER_DISTANCE, - uno::makeAny(rInfo.nBottomBorderDistance ), false); - - // Horizontal merge is not a UNO property, extract that info here to rMerges, and then remove it from the map. - const std::optional<PropertyMap::Property> aHorizontalMergeVal = (*aCellIterator)->getProperty(PROP_HORIZONTAL_MERGE); - if (aHorizontalMergeVal) - { - if (aHorizontalMergeVal->second.get<bool>()) - { - // first cell in a merge - HorizontallyMergedCell aMerge(nRow, nCell); - rMerges.push_back(aMerge); - } - else if (!rMerges.empty()) - { - // resuming an earlier merge - HorizontallyMergedCell& rMerge = rMerges.back(); - rMerge.m_nLastRow = nRow; - rMerge.m_nLastCol = nCell; - } - (*aCellIterator)->Erase(PROP_HORIZONTAL_MERGE); - } - pSingleCellProperties[nCell] = (*aCellIterator)->GetPropertyValues(); -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif - } - ++nCell; - ++aCellIterator; - } - ++nRow; - ++aRowOfCellsIterator; - ++aRowIter; - } - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif - - return aCellProperties; -} - -/// Do all cells in this row have a CellHideMark property? -static bool lcl_hideMarks(PropertyMapVector1& rCellProperties) -{ - for (const PropertyMapPtr & p : rCellProperties) - { - // if anything is vertically merged, the row must not be set to fixed - // as Writer's layout doesn't handle that well - if (!p->isSet(PROP_CELL_HIDE_MARK) || p->isSet(PROP_VERTICAL_MERGE)) - return false; - } - return true; -} - -/// Are all cells in this row empty? -static bool lcl_emptyRow(std::vector<RowSequence_t>& rTableRanges, sal_Int32 nRow) -{ - if (nRow >= static_cast<sal_Int32>(rTableRanges.size())) - { - SAL_WARN("writerfilter.dmapper", "m_aCellProperties not in sync with rTableRanges?"); - return false; - } - - RowSequence_t rRowSeq = rTableRanges[nRow]; - if (!rRowSeq.hasElements()) - { - SAL_WARN("writerfilter.dmapper", "m_aCellProperties not in sync with rTableRanges?"); - return false; - } - - if (!rRowSeq[0][0].is()) - { - // This can happen when we can't import the table, e.g. we're inside a - // comment. - SAL_WARN("writerfilter.dmapper", "rRowSeq[0][0] is an empty reference"); - return false; - } - - uno::Reference<text::XTextRangeCompare> xTextRangeCompare(rRowSeq[0][0]->getText(), uno::UNO_QUERY); - try - { - // See SwXText::Impl::ConvertCell(), we need to compare the start of - // the start and the end of the end. However for our text ranges, only - // the starts are set, so compareRegionStarts() does what we need. - bool bRangesAreNotEqual = std::any_of(rRowSeq.begin(), rRowSeq.end(), - [&xTextRangeCompare](const CellSequence_t& rCellSeq) { - return xTextRangeCompare->compareRegionStarts(rCellSeq[0], rCellSeq[1]) != 0; }); - if (bRangesAreNotEqual) - return false; - } - catch (const lang::IllegalArgumentException&) - { - TOOLS_WARN_EXCEPTION( "writerfilter.dmapper", "compareRegionStarts() failed"); - return false; - } - return true; -} - -css::uno::Sequence<css::beans::PropertyValues> DomainMapperTableHandler::endTableGetRowProperties() -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("getRowProperties"); -#endif - - css::uno::Sequence<css::beans::PropertyValues> aRowProperties( m_aRowProperties.size() ); - sal_Int32 nRow = 0; - for( const auto& rRow : m_aRowProperties ) - { -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("rowProps.row"); -#endif - if (rRow) - { - //set default to 'break across pages" - rRow->Insert( PROP_IS_SPLIT_ALLOWED, uno::makeAny(true ), false ); - // tblHeader is only our property, remove before the property map hits UNO - rRow->Erase(PROP_TBL_HEADER); - - if (lcl_hideMarks(m_aCellProperties[nRow]) && lcl_emptyRow(m_aTableRanges, nRow)) - { - // We have CellHideMark on all cells, and also all cells are empty: - // Force the row height to be exactly as specified, and not just as the minimum suggestion. - rRow->Insert(PROP_SIZE_TYPE, uno::makeAny(text::SizeType::FIX)); - } - - aRowProperties[nRow] = rRow->GetPropertyValues(); -#ifdef DBG_UTIL - rRow->dumpXml(); - lcl_DumpPropertyValues(aRowProperties[nRow]); -#endif - } - ++nRow; -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif - } - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif - - return aRowProperties; -} - -// table style has got bigger precedence than docDefault style, -// but lower precedence than the paragraph styles and direct paragraph formatting -void DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableParagraph rParaProp, std::vector< PropertyIds > aAllTableParaProperties, css::beans::PropertyValues rCellProperties) -{ - for( auto const& eId : aAllTableParaProperties ) - { - // apply paragraph and character properties of the table style on table paragraphs - // if there is no direct paragraph formatting - bool bIsParaLevel = rParaProp.m_pPropertyMap->isSet(eId); - if ( !bIsParaLevel || isCharacterProperty(eId) ) - { - if ( (eId == PROP_PARA_LEFT_MARGIN || eId == PROP_PARA_FIRST_LINE_INDENT) && - rParaProp.m_pPropertyMap->isSet(PROP_NUMBERING_RULES) ) - { - // indentation of direct numbering has bigger precedence, than table style - continue; - } - - OUString sPropertyName = getPropertyName(eId); - - if ( bIsParaLevel && ( rParaProp.m_aParaOverrideApplied.find(sPropertyName) != rParaProp.m_aParaOverrideApplied.end() || - sPropertyName.startsWith("CharFontName") ) ) - { - // don't apply table style, if this character property was applied on paragraph level - // (or in the case of paragraph level font name settings to avoid regressions) - continue; - } - - auto pCellProp = std::find_if(rCellProperties.begin(), rCellProperties.end(), - [&](const beans::PropertyValue& rProp) { return rProp.Name == sPropertyName; }); - // this cell applies the table style property - if (pCellProp != rCellProperties.end()) - { - bool bDocDefault; - // handle paragraph background color defined in CellColorHandler - if (eId == PROP_FILL_COLOR) - { - // table style defines paragraph background color, use the correct property name - auto pFillStyleProp = std::find_if(rCellProperties.begin(), rCellProperties.end(), - [&](const beans::PropertyValue& rProp) { return rProp.Name == "FillStyle"; }); - if ( pFillStyleProp != rCellProperties.end() && - pFillStyleProp->Value == uno::makeAny(drawing::FillStyle_SOLID) ) - { - sPropertyName = "ParaBackColor"; - } - else - { - // FillStyle_NONE, skip table style usage for paragraph background color - continue; - } - } - OUString sParaStyleName; - rParaProp.m_rPropertySet->getPropertyValue("ParaStyleName") >>= sParaStyleName; - StyleSheetEntryPtr pEntry = m_rDMapper_Impl.GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(sParaStyleName); - uno::Any aParaStyle = m_rDMapper_Impl.GetPropertyFromStyleSheet(eId, pEntry, true, true, &bDocDefault); - // A very strange compatibility rule says that the DEFAULT style's specified fontsize of 11 or 12 - // or a specified left justify will always be overridden by the table-style. - // Normally this rule is applied, so always do this unless a compatSetting indicates otherwise. - bool bCompatOverride = false; - if ( (eId == PROP_CHAR_HEIGHT || eId == PROP_PARA_ADJUST) && sParaStyleName == m_rDMapper_Impl.GetDefaultParaStyleName() ) - { - if ( eId == PROP_CHAR_HEIGHT ) - bCompatOverride = aParaStyle == uno::Any(double(11)) || aParaStyle == uno::Any(double(12)); - else if ( eId == PROP_PARA_ADJUST ) - { - style::ParagraphAdjust eAdjust(style::ParagraphAdjust_CENTER); - aParaStyle >>= eAdjust; - bCompatOverride = eAdjust == style::ParagraphAdjust_LEFT; - } - - // The wording is confusing here. Normally, the paragraph style DOES override the table-style. - // But for these two special situations, do not override the table-style. So the default is false. - // If false, then "CompatOverride" the normal behaviour, and apply the table-style's value. - bCompatOverride &= !m_rDMapper_Impl.GetSettingsTable()->GetCompatSettingValue(u"overrideTableStyleFontSizeAndJustification"); - } - - // use table style when no paragraph style setting or a docDefault value is applied instead of it - if ( aParaStyle == uno::Any() || bDocDefault || bCompatOverride ) try - { - // check property state of paragraph - uno::Reference<text::XParagraphCursor> xParagraph( - rParaProp.m_rEndParagraph->getText()->createTextCursorByRange(rParaProp.m_rEndParagraph), uno::UNO_QUERY_THROW ); - // select paragraph - xParagraph->gotoStartOfParagraph( true ); - uno::Reference< beans::XPropertyState > xParaProperties( xParagraph, uno::UNO_QUERY_THROW ); - if ( xParaProperties->getPropertyState(sPropertyName) == css::beans::PropertyState_DEFAULT_VALUE ) - { - if ( eId != PROP_FILL_COLOR ) - { - // apply style setting when the paragraph doesn't modify it - rParaProp.m_rPropertySet->setPropertyValue( sPropertyName, pCellProp->Value ); - } - else - { - // we need this for complete import of table-style based paragraph background color - rParaProp.m_rPropertySet->setPropertyValue( "FillColor", pCellProp->Value ); - rParaProp.m_rPropertySet->setPropertyValue( "FillStyle", uno::makeAny(drawing::FillStyle_SOLID) ); - } - } - else - { - // apply style setting only on text portions without direct modification of it - uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xParagraph, uno::UNO_QUERY); - uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); - uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY); - uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration(); - while ( xRunEnum->hasMoreElements() ) - { - uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY); - uno::Reference< beans::XPropertyState > xRunProperties( xRun, uno::UNO_QUERY_THROW ); - if ( xRunProperties->getPropertyState(sPropertyName) == css::beans::PropertyState_DEFAULT_VALUE ) - { - uno::Reference< beans::XPropertySet > xRunPropertySet( xRun, uno::UNO_QUERY_THROW ); - xRunPropertySet->setPropertyValue( sPropertyName, pCellProp->Value ); - } - } - } - } - catch ( const uno::Exception & ) - { - TOOLS_INFO_EXCEPTION("writerfilter.dmapper", "Exception during table style correction"); - } - } - } - } -} - -// convert formula range identifier ABOVE, BELOW, LEFT and RIGHT -static void lcl_convertFormulaRanges(const uno::Reference<text::XTextTable> & xTable) -{ - uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY_THROW); - uno::Reference<container::XIndexAccess> xTableRows(xTable->getRows(), uno::UNO_QUERY_THROW); - sal_Int32 nRows = xTableRows->getCount(); - for (sal_Int32 nRow = 0; nRow < nRows; ++nRow) - { - for (sal_Int16 nCol = 0; nCol < MAXTABLECELLS; ++nCol) - { - try - { - uno::Reference<beans::XPropertySet> xCellProperties(xCellRange->getCellByPosition(nCol, nRow), uno::UNO_QUERY_THROW); - uno::Sequence<beans::PropertyValue> aCellGrabBag; - xCellProperties->getPropertyValue("CellInteropGrabBag") >>= aCellGrabBag; - OUString sFormula; - bool bReplace = false; - for (const auto& rProp : std::as_const(aCellGrabBag)) - { - if ( rProp.Name == "CellFormulaConverted" ) - { - rProp.Value >>= sFormula; - struct RangeDirection - { - OUString m_sName; - sal_Int16 m_nCol; - sal_Int16 m_nRow; - }; - static const RangeDirection pDirections[] = - { - { OUString(" LEFT "), -1, 0}, - { OUString(" RIGHT "), 1, 0}, - { OUString(" ABOVE "), 0, -1}, - { OUString(" BELOW "), 0, 1 } - }; - for (const RangeDirection& rRange : pDirections) - { - if ( sFormula.indexOf(rRange.m_sName) > -1 ) - { - // range starts at the first cell above/below/left/right, but ends at the - // table border or at the first non-value cell after a value cell - bool bFoundFirst = false; - OUString sNextCell; - OUString sLastCell; - OUString sLastValueCell; - // walk through the cells of the range - try - { - sal_Int32 nCell = 0; - while (++nCell) - { - uno::Reference<beans::XPropertySet> xCell( - xCellRange->getCellByPosition(nCol + nCell * rRange.m_nCol, nRow + nCell * rRange.m_nRow), - uno::UNO_QUERY_THROW); - // empty cell or cell with text content is end of the range - uno::Reference<text::XText> xText(xCell, uno::UNO_QUERY_THROW); - sLastCell = xCell->getPropertyValue("CellName").get<OUString>(); - if (sNextCell.isEmpty()) - sNextCell = sLastCell; - try - { - // accept numbers with comma and percent - OUString sCellText = xText->getString().replace(',', '.'); - if (sCellText.endsWith("%")) - sCellText = sCellText.copy(0, sCellText.getLength()-1); - boost::lexical_cast<double>(sCellText); - } - catch( boost::bad_lexical_cast const& ) - { - if ( !bFoundFirst ) - { - // still search value cells - continue; - } - else - { - // end of range - break; - } - } - sLastValueCell = sLastCell; - bFoundFirst = true; - } - } - catch ( const lang::IndexOutOfBoundsException & ) - { - } - - if ( !sNextCell.isEmpty() ) - { - OUString sRange = "<" + sNextCell + ":" + - ( sLastValueCell.isEmpty() ? sLastCell : sLastValueCell ) + ">"; - sFormula = sFormula.replaceAll(rRange.m_sName, sRange); - bReplace = true; - } - } - } - - // update formula field - if (bReplace) - { - uno::Reference<text::XText> xCell(xCellRange->getCellByPosition(nCol, nRow), uno::UNO_QUERY); - uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell, uno::UNO_QUERY); - uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); - uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY); - uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration(); - while ( xRunEnum->hasMoreElements() ) - { - uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY); - uno::Reference< beans::XPropertySet > xRunProperties( xRun, uno::UNO_QUERY_THROW ); - if ( xRunProperties->getPropertyValue("TextPortionType") == uno::makeAny(OUString("TextField")) ) - { - uno::Reference<text::XTextField> const xField(xRunProperties->getPropertyValue("TextField").get<uno::Reference<text::XTextField>>()); - uno::Reference< beans::XPropertySet > xFieldProperties( xField, uno::UNO_QUERY_THROW ); - // cell can contain multiple text fields, but only one is handled now (~formula cell) - if ( rProp.Value != xFieldProperties->getPropertyValue("Content") ) - continue; - xFieldProperties->setPropertyValue("Content", uno::makeAny(sFormula)); - // update grab bag - auto aGrabBag = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aCellGrabBag); - beans::PropertyValue aValue; - aValue.Name = "CellFormulaConverted"; - aValue.Value <<= sFormula; - aGrabBag.push_back(aValue); - xCellProperties->setPropertyValue("CellInteropGrabBag", uno::makeAny(comphelper::containerToSequence(aGrabBag))); - } - } - } - } - } - } - catch ( const lang::IndexOutOfBoundsException & ) - { - // jump to next table row - break; - } - } - } -} - -void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool bTableStartsAtCellStart) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablehandler.endTable"); -#endif - - // If we want to make this table a floating one. - std::vector<beans::PropertyValue> aFrameProperties = comphelper::sequenceToContainer<std::vector<beans::PropertyValue> > - (m_rDMapper_Impl.getTableManager().getCurrentTablePosition()); - TableInfo aTableInfo; - aTableInfo.nNestLevel = nestedTableLevel; - aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo, aFrameProperties); - // expands to uno::Sequence< Sequence< beans::PropertyValues > > - - std::vector<HorizontallyMergedCell> aMerges; - CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo, aMerges); - - css::uno::Sequence<css::beans::PropertyValues> aRowProperties = endTableGetRowProperties(); - -#ifdef DBG_UTIL - lcl_DumpPropertyValueSeq(aRowProperties); -#endif - - if (!m_aTableRanges.empty()) - { - uno::Reference<text::XTextRange> xStart; - uno::Reference<text::XTextRange> xEnd; - - bool bFloating = !aFrameProperties.empty(); - - // OOXML table style may contain paragraph properties, apply these on cell paragraphs - if ( m_aTableRanges[0].hasElements() && m_aTableRanges[0][0].hasElements() ) - { - // collect all paragraph properties used in table styles - PropertyMapPtr pAllTableProps( new PropertyMap ); - pAllTableProps->InsertProps(aTableInfo.pTableDefaults); - if ( aTableInfo.pTableStyle ) - pAllTableProps->InsertProps(aTableInfo.pTableStyle->GetProperties( CNF_ALL )); - for (const auto& eId : pAllTableProps->GetPropertyIds()) - { - if ( !isParagraphProperty(eId) && !isCharacterProperty(eId) ) - pAllTableProps->Erase(eId); - } - std::vector< PropertyIds > aAllTableParaProperties = pAllTableProps->GetPropertyIds(); - - if ( !aAllTableParaProperties.empty() ) - { - TableParagraphVectorPtr pTableParagraphs = m_rDMapper_Impl.getTableManager().getCurrentParagraphs(); - for (size_t nRow = 0; nRow < m_aTableRanges.size(); ++nRow) - { - // Note that this is "cell" since you must not treat it as "column". - for (size_t nCell = 0; nCell < m_aTableRanges[nRow].size(); ++nCell) - { - auto rStartPara = m_aTableRanges[nRow][nCell][0]; - if (!rStartPara.is()) - continue; - auto rEndPara = m_aTableRanges[nRow][nCell][1]; - uno::Reference<text::XTextRangeCompare> xTextRangeCompare(rStartPara->getText(), uno::UNO_QUERY); - bool bApply = false; - // search paragraphs of the cell - std::vector<TableParagraph>::iterator aIt = pTableParagraphs->begin(); - while ( aIt != pTableParagraphs->end() ) try - { - if (!bApply && xTextRangeCompare->compareRegionStarts(rStartPara, aIt->m_rStartParagraph) == 0) - bApply = true; - if (bApply) - { - bool bEndOfApply = (xTextRangeCompare->compareRegionEnds(rEndPara, aIt->m_rEndParagraph) == 0); - ApplyParagraphPropertiesFromTableStyle(*aIt, aAllTableParaProperties, aCellProperties[nRow][nCell]); - // erase processed paragraph from list of pending paragraphs - aIt = pTableParagraphs->erase(aIt); - if (bEndOfApply) - break; - } - else - ++aIt; - } - catch( const lang::IllegalArgumentException & ) - { - // skip compareRegion with nested tables - ++aIt; - } - } - } - } - } - - // Additional checks: if we can do this. - if (bFloating && m_aTableRanges[0].hasElements() && m_aTableRanges[0][0].hasElements()) - { - xStart = m_aTableRanges[0][0][0]; - uno::Sequence< uno::Sequence< uno::Reference<text::XTextRange> > >& rLastRow = m_aTableRanges[m_aTableRanges.size() - 1]; - if (rLastRow.hasElements()) - { - uno::Sequence< uno::Reference<text::XTextRange> >& rLastCell = rLastRow[rLastRow.getLength() - 1]; - xEnd = rLastCell[1]; - } - } - uno::Reference<text::XTextTable> xTable; - try - { - if (m_xText.is()) - { - xTable = m_xText->convertToTable(comphelper::containerToSequence(m_aTableRanges), aCellProperties, aRowProperties, aTableInfo.aTableProperties); - - if (xTable.is()) - { - if (!aMerges.empty()) - { - static const std::vector<std::u16string_view> aBorderNames - = { u"TopBorder", u"LeftBorder", u"BottomBorder", u"RightBorder" }; - - // Perform horizontal merges in reverse order, so the fact that merging changes the position of cells won't cause a problem for us. - for (std::vector<HorizontallyMergedCell>::reverse_iterator it = aMerges.rbegin(); it != aMerges.rend(); ++it) - { - uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY_THROW); - uno::Reference<beans::XPropertySet> xFirstCell( - xCellRange->getCellByPosition(it->m_nFirstCol, it->m_nFirstRow), - uno::UNO_QUERY_THROW); - OUString aFirst - = xFirstCell->getPropertyValue("CellName").get<OUString>(); - // tdf#105852: Only try to merge if m_nLastCol is set (i.e. there were some merge continuation cells) - if (it->m_nLastCol != -1) - { - // Save border properties of the first cell - // before merge. - table::BorderLine2 aBorderValues[4]; - for (size_t i = 0; i < aBorderNames.size(); ++i) - xFirstCell->getPropertyValue(OUString(aBorderNames[i])) - >>= aBorderValues[i]; - - uno::Reference<beans::XPropertySet> xLastCell( - xCellRange->getCellByPosition(it->m_nLastCol, it->m_nLastRow), - uno::UNO_QUERY_THROW); - OUString aLast - = xLastCell->getPropertyValue("CellName").get<OUString>(); - - uno::Reference<text::XTextTableCursor> xCursor = xTable->createCursorByCellName(aFirst); - xCursor->gotoCellByName(aLast, true); - - xCursor->mergeRange(); - - // Handle conflicting properties: mergeRange() - // takes the last cell, Word takes the first - // cell. - for (size_t i = 0; i < aBorderNames.size(); ++i) - { - if (aBorderValues[i].LineStyle != table::BorderLineStyle::NONE) - xFirstCell->setPropertyValue( - OUString(aBorderNames[i]), uno::makeAny(aBorderValues[i])); - } - } - } - } - - // convert special range IDs ABOVE, BELOW, LEFT and RIGHT - lcl_convertFormulaRanges(xTable); - } - } - } - catch ( const lang::IllegalArgumentException & ) - { - TOOLS_INFO_EXCEPTION("writerfilter.dmapper", "Conversion to table error"); -#ifdef DBG_UTIL - TagLogger::getInstance().chars(std::string("failed to import table!")); -#endif - } - catch ( const uno::Exception & ) - { - TOOLS_INFO_EXCEPTION("writerfilter.dmapper", "Exception during table creation"); - } - - // If we have a table with a start and an end position, we should make it a floating one. - // Unless the table had a foot or endnote, as Writer doesn't support those in TextFrames. - if (xTable.is() && xStart.is() && xEnd.is() && !m_bHadFootOrEndnote) - { - uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); - bool bIsRelative = false; - xTableProperties->getPropertyValue("IsWidthRelative") >>= bIsRelative; - if (!bIsRelative) - { - beans::PropertyValue aValue; - aValue.Name = "Width"; - aValue.Value = xTableProperties->getPropertyValue("Width"); - aFrameProperties.push_back(aValue); - } - else - { - beans::PropertyValue aValue; - aValue.Name = "FrameWidthPercent"; - aValue.Value = xTableProperties->getPropertyValue("RelativeWidth"); - aFrameProperties.push_back(aValue); - - // Applying the relative width to the frame, needs to have the table width to be 100% of the frame width - xTableProperties->setPropertyValue("RelativeWidth", uno::makeAny(sal_Int16(100))); - } - - // A non-zero left margin would move the table out of the frame, move the frame itself instead. - xTableProperties->setPropertyValue("LeftMargin", uno::makeAny(sal_Int32(0))); - - if (nestedTableLevel >= 2) - { - // Floating tables inside a table always stay inside the cell. - aFrameProperties.push_back( - comphelper::makePropertyValue("IsFollowingTextFlow", true)); - } - - // In case the document ends with a table, we're called after - // SectionPropertyMap::CloseSectionGroup(), so we'll have no idea - // about the text area width, nor can fix this by delaying the text - // frame conversion: just do it here. - // Also, when the anchor is within a table, then do it here as well, - // as xStart/xEnd would not point to the start/end at conversion - // time anyway. - // Next exception: it's pointless to delay the conversion if the - // table is not in the body text. - sal_Int32 nTableWidth = 0; - m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH, nTableWidth); - sal_Int32 nTableWidthType = text::SizeType::FIX; - m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType); - if (m_rDMapper_Impl.GetSectionContext() && nestedTableLevel <= 1 && !m_rDMapper_Impl.IsInHeaderFooter()) - m_rDMapper_Impl.m_aPendingFloatingTables.emplace_back(xStart, xEnd, comphelper::containerToSequence(aFrameProperties), nTableWidth, nTableWidthType); - else - { - // m_xText points to the body text, get the current xText from m_rDMapper_Impl, in case e.g. we would be in a header. - uno::Reference<text::XTextAppendAndConvert> xTextAppendAndConvert(m_rDMapper_Impl.GetTopTextAppend(), uno::UNO_QUERY); - // Only execute the conversion if the table is not anchored at - // the start of an outer table cell, that's not yet - // implemented. - if (xTextAppendAndConvert.is() && !bTableStartsAtCellStart) - xTextAppendAndConvert->convertToTextFrame(xStart, xEnd, comphelper::containerToSequence(aFrameProperties)); - } - } - - // We're right after a table conversion. - m_rDMapper_Impl.m_bConvertedTable = true; - } - - m_aTableProperties.clear(); - m_aCellProperties.clear(); - m_aRowProperties.clear(); - m_bHadFootOrEndnote = false; - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); - TagLogger::getInstance().endElement(); -#endif -} - -void DomainMapperTableHandler::startRow(const TablePropertyMapPtr& pProps) -{ - m_aRowProperties.push_back( pProps.get() ); - m_aCellProperties.emplace_back( ); - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("table.row"); - if (pProps != nullptr) - pProps->dumpXml(); -#endif - - m_aRowRanges.clear(); -} - -void DomainMapperTableHandler::endRow() -{ - m_aTableRanges.push_back(comphelper::containerToSequence(m_aRowRanges)); -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void DomainMapperTableHandler::startCell(const css::uno::Reference< css::text::XTextRange > & start, - const TablePropertyMapPtr& pProps ) -{ - sal_uInt32 nRow = m_aRowProperties.size(); - if ( pProps ) - m_aCellProperties[nRow - 1].push_back( pProps.get() ); - 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.get() ); - } - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("table.cell"); - TagLogger::getInstance().startElement("table.cell.start"); - TagLogger::getInstance().chars(XTextRangeToString(start)); - TagLogger::getInstance().endElement(); - if (pProps) - pProps->printProperties(); -#endif - - //add a new 'row' of properties - m_aCellRange.clear(); - uno::Reference<text::XTextRange> xStart; - if (start) - xStart = start->getStart(); - m_aCellRange.push_back(xStart); -} - -void DomainMapperTableHandler::endCell(const css::uno::Reference< css::text::XTextRange > & end) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("table.cell.end"); - TagLogger::getInstance().chars(XTextRangeToString(end)); - TagLogger::getInstance().endElement(); - TagLogger::getInstance().endElement(); -#endif - - uno::Reference<text::XTextRange> xEnd; - if (end) - xEnd = end->getEnd(); - m_aCellRange.push_back(xEnd); - m_aRowRanges.push_back(comphelper::containerToSequence(m_aCellRange)); -} - -void DomainMapperTableHandler::setHadFootOrEndnote(bool bHadFootOrEndnote) -{ - m_bHadFootOrEndnote = bHadFootOrEndnote; -} - -DomainMapper_Impl& DomainMapperTableHandler::getDomainMapperImpl() -{ - return m_rDMapper_Impl; -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx deleted file mode 100644 index 900ff747f4cc..000000000000 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#pragma once - -#include "PropertyMap.hxx" -#include <vector> - -#include <com/sun/star/text/XTextAppendAndConvert.hpp> - -namespace writerfilter::dmapper { - -typedef css::uno::Sequence< css::uno::Reference< css::text::XTextRange > > CellSequence_t; -typedef css::uno::Sequence<CellSequence_t> RowSequence_t; - -typedef css::uno::Sequence< css::uno::Sequence<css::beans::PropertyValues> > CellPropertyValuesSeq_t; - -typedef std::vector<PropertyMapPtr> PropertyMapVector1; -typedef std::vector<PropertyMapVector1> PropertyMapVector2; - -class DomainMapper_Impl; -class TableStyleSheetEntry; -struct TableInfo; - -/// A horizontally merged cell is in fact a range of cells till its merge is performed. -struct HorizontallyMergedCell -{ - sal_Int32 m_nFirstRow; - sal_Int32 m_nFirstCol; - sal_Int32 m_nLastRow; - sal_Int32 m_nLastCol; - HorizontallyMergedCell(sal_Int32 nFirstRow, sal_Int32 nFirstCol) - : m_nFirstRow(nFirstRow) - , m_nFirstCol(nFirstCol) - , m_nLastRow(nFirstRow) - , m_nLastCol(-1) - { - } -}; - -/// Class to handle events generated by TableManager::resolveCurrentTable(). -class DomainMapperTableHandler final : public virtual SvRefBase -{ - css::uno::Reference<css::text::XTextAppendAndConvert> m_xText; - DomainMapper_Impl& m_rDMapper_Impl; - std::vector< css::uno::Reference<css::text::XTextRange> > m_aCellRange; - std::vector<CellSequence_t> m_aRowRanges; - std::vector<RowSequence_t> m_aTableRanges; - - // properties - PropertyMapVector2 m_aCellProperties; - PropertyMapVector1 m_aRowProperties; - TablePropertyMapPtr m_aTableProperties; - - /// Did we have a foot or endnote in this table? - bool m_bHadFootOrEndnote; - - TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo, std::vector<css::beans::PropertyValue>& rFrameProperties); - CellPropertyValuesSeq_t endTableGetCellProperties(TableInfo & rInfo, std::vector<HorizontallyMergedCell>& rMerges); - css::uno::Sequence<css::beans::PropertyValues> endTableGetRowProperties(); - -public: - typedef tools::SvRef<DomainMapperTableHandler> Pointer_t; - - DomainMapperTableHandler(css::uno::Reference<css::text::XTextAppendAndConvert> const& xText, - DomainMapper_Impl& rDMapper_Impl); - ~DomainMapperTableHandler() override; - - /** - Handle start of table. - - @param pProps properties of the table - */ - void startTable(const TablePropertyMapPtr& pProps); - - void ApplyParagraphPropertiesFromTableStyle(TableParagraph rParaProp, std::vector< PropertyIds > aAllTableProperties, css::beans::PropertyValues rCellProperties); - - /// Handle end of table. - void endTable(unsigned int nestedTableLevel, bool bTableStartsAtCellStart); - /** - Handle start of row. - - @param pProps properties of the row - */ - void startRow(const TablePropertyMapPtr& pProps); - /// Handle end of row. - void endRow(); - /** - Handle start of cell. - - @param rT start handle of the cell - @param pProps properties of the cell - */ - void startCell(const css::uno::Reference< css::text::XTextRange > & start, const TablePropertyMapPtr& pProps); - /** - Handle end of cell. - - @param rT end handle of cell - */ - void endCell(const css::uno::Reference< css::text::XTextRange > & end); - - void setHadFootOrEndnote(bool bHadFootOrEndnote); - - DomainMapper_Impl& getDomainMapperImpl(); -}; - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx deleted file mode 100644 index da78cb682e5c..000000000000 --- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx +++ /dev/null @@ -1,827 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include <optional> -#include "DomainMapperTableManager.hxx" -#include "ConversionHelper.hxx" -#include "MeasureHandler.hxx" -#include "TagLogger.hxx" -#include <com/sun/star/text/SizeType.hpp> -#include <com/sun/star/text/TableColumnSeparator.hpp> -#include <com/sun/star/text/WritingMode2.hpp> -#include <o3tl/numeric.hxx> -#include <o3tl/safeint.hxx> -#include <ooxml/resourceids.hxx> -#include <rtl/math.hxx> -#include <sal/log.hxx> -#include <numeric> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; -using namespace ::std; - -DomainMapperTableManager::DomainMapperTableManager() : - m_nRow(0), - m_nCell(), - m_nGridSpan(1), - m_nHeaderRepeat(0), - m_nTableWidth(0), - m_bIsInShape(false), - m_aTmpPosition(), - m_aTmpTableProperties(), - m_bPushCurrentWidth(false), - m_bTableSizeTypeInserted(false), - m_nLayoutType(0), - m_aParagraphsToEndTable(), - m_pTablePropsHandler(new TablePropertiesHandler()) -{ - m_pTablePropsHandler->SetTableManager( this ); -} - - -DomainMapperTableManager::~DomainMapperTableManager() -{ -} - -bool DomainMapperTableManager::attribute(Id nName, Value const & rValue) -{ - bool bRet = true; - - switch (nName) - { - case NS_ooxml::LN_CT_TblLook_val: - { - TablePropertyMapPtr pPropMap(new TablePropertyMap()); - pPropMap->Insert(PROP_TBL_LOOK, uno::makeAny<sal_Int32>(rValue.getInt())); - insertTableProps(pPropMap); - m_aTableLook["val"] <<= static_cast<sal_Int32>(rValue.getInt()); - } - break; - case NS_ooxml::LN_CT_TblLook_noVBand: - m_aTableLook["noVBand"] <<= static_cast<sal_Int32>(rValue.getInt()); - break; - case NS_ooxml::LN_CT_TblLook_noHBand: - m_aTableLook["noHBand"] <<= static_cast<sal_Int32>(rValue.getInt()); - break; - case NS_ooxml::LN_CT_TblLook_lastColumn: - m_aTableLook["lastColumn"] <<= static_cast<sal_Int32>(rValue.getInt()); - break; - case NS_ooxml::LN_CT_TblLook_lastRow: - m_aTableLook["lastRow"] <<= static_cast<sal_Int32>(rValue.getInt()); - break; - case NS_ooxml::LN_CT_TblLook_firstColumn: - m_aTableLook["firstColumn"] <<= static_cast<sal_Int32>(rValue.getInt()); - break; - case NS_ooxml::LN_CT_TblLook_firstRow: - m_aTableLook["firstRow"] <<= static_cast<sal_Int32>(rValue.getInt()); - break; - default: - bRet = false; - } - - return bRet; -} - -void DomainMapperTableManager::finishTableLook() -{ - TablePropertyMapPtr pPropMap(new TablePropertyMap()); - pPropMap->Insert(META_PROP_TABLE_LOOK, uno::makeAny(m_aTableLook.getAsConstPropertyValueList())); - m_aTableLook.clear(); - insertTableProps(pPropMap); -} - -bool DomainMapperTableManager::sprm(Sprm & rSprm) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.sprm"); - string sSprm = rSprm.toString(); - TagLogger::getInstance().chars(sSprm); - TagLogger::getInstance().endElement(); -#endif - bool bRet = TableManager::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 ? pValue->getInt() : 0); - switch ( nSprmId ) - { - case NS_ooxml::LN_CT_TblPrBase_tblW: - case NS_ooxml::LN_CT_TblPrBase_tblInd: - { - //contains unit and value - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - MeasureHandlerPtr pMeasureHandler( new MeasureHandler ); - pProperties->resolve(*pMeasureHandler); - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - if (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_TYPE, text::SizeType::FIX ); - pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth ); - m_bTableSizeTypeInserted = true; - } - else if( sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_pct ) - { - sal_Int32 nPercent = pMeasureHandler->getValue() / 50; - if(nPercent > 100) - nPercent = 100; - pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::VARIABLE ); - pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, nPercent ); - m_bTableSizeTypeInserted = true; - } - else if( sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_auto ) - { - /* - This attribute specifies the width type of table. This is used as part of the table layout - algorithm specified by the tblLayout element.(See 17.4.64 and 17.4.65 of the ISO/IEC 29500-1:2011.) - If this value is 'auto', the table layout has to use the preferred widths on the table items to generate - the final sizing of the table, but then must use the contents of each cell to determine final column widths. - (See 17.18.87 of the ISO/IEC 29500-1:2011.) - */ - IntVectorPtr pCellWidths = getCurrentCellWidths(); - // Check whether all cells have fixed widths in the given row of table. - bool bFixed = std::find(pCellWidths->begin(), pCellWidths->end(), -1) == pCellWidths->end(); - if (!bFixed) - { - // Set the width type of table with 'Auto' and set the width value to 0 (as per grid values) - pPropMap->setValue( TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::VARIABLE ); - pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, 0 ); - m_bTableSizeTypeInserted = true; - } - else if (getTableDepth() > 1) - { - // tdf#131819 limiting the fix for nested tables temporarily - // TODO revert the fix for tdf#104876 and reopen it - m_bTableSizeTypeInserted = true; - } - } - } -#ifdef DBG_UTIL - pPropMap->dumpXml(); -#endif - insertTableProps(pPropMap); - } - } - break; - case NS_ooxml::LN_CT_TrPrBase_tblHeader: - // 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 == static_cast<int>(m_nRow) ) - { - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - - // FIXME: DOCX tables with more than 10 repeating header lines imported - // without repeating header lines to mimic an MSO workaround for its usability bug. - // Explanation: it's very hard to set and modify repeating header rows in Word, - // often resulting tables with a special workaround: setting all table rows as - // repeating header, because exceeding the pages by "unlimited" header rows turns off the - // table headers automatically in MSO. 10-row limit is a reasonable temporary limit - // to handle DOCX tables with "unlimited" repeating header, till the same "turn off - // exceeding header" feature is ready (see tdf#88496). -#define HEADER_ROW_LIMIT_FOR_MSO_WORKAROUND 10 - if ( m_nHeaderRepeat == HEADER_ROW_LIMIT_FOR_MSO_WORKAROUND ) - { - m_nHeaderRepeat = -1; - pPropMap->Insert( PROP_HEADER_ROW_COUNT, uno::makeAny(sal_Int32(0))); - } - else - { - ++m_nHeaderRepeat; - pPropMap->Insert( PROP_HEADER_ROW_COUNT, uno::makeAny( m_nHeaderRepeat )); - } - insertTableProps(pPropMap); - } - else - { - if ( nIntValue == 0 && m_nRow == 0 ) - { - // explicit tblHeader=0 in the first row must overwrite table style - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - pPropMap->Insert( PROP_HEADER_ROW_COUNT, uno::makeAny(sal_Int32(0))); - insertTableProps(pPropMap); - } - m_nHeaderRepeat = -1; - } - if (nIntValue) - { - // Store the info that this is a header, we'll need that when we apply table styles. - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - pPropMap->Insert( PROP_TBL_HEADER, uno::makeAny(nIntValue)); - insertRowProps(pPropMap); - } - break; - case NS_ooxml::LN_CT_TblPrBase_tblStyle: //table style name - { - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - pPropMap->Insert( META_PROP_TABLE_STYLE_NAME, uno::makeAny( pValue->getString() )); - insertTableProps(pPropMap); - } - break; - case NS_ooxml::LN_CT_TblGridBase_gridCol: - { - if (nIntValue == -1) - getCurrentGrid()->clear(); - else - getCurrentGrid()->push_back( 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, uno::makeAny( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Merge_restart ) ); - cellProps( pMergeProps); - } - break; - case NS_ooxml::LN_CT_TcPrBase_hMerge: - { - // 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_HORIZONTAL_MERGE, uno::makeAny( 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 - { -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.GridSpan"); - TagLogger::getInstance().attribute("gridSpan", nIntValue); - TagLogger::getInstance().endElement(); -#endif - m_nGridSpan = nIntValue; - } - break; - case NS_ooxml::LN_CT_TcPrBase_textDirection: - { - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - bool bInsertCellProps = true; - switch ( nIntValue ) - { - case NS_ooxml::LN_Value_ST_TextDirection_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, uno::makeAny( text::WritingMode2::TB_RL )); - SAL_INFO( "writerfilter", "Have inserted textDirection " << nIntValue ); - break; - case NS_ooxml::LN_Value_ST_TextDirection_btLr: - pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::BT_LR )); - break; - case NS_ooxml::LN_Value_ST_TextDirection_lrTbV: - pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::LR_TB )); - break; - case NS_ooxml::LN_Value_ST_TextDirection_tbRlV: - pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::TB_RL )); - break; - case NS_ooxml::LN_Value_ST_TextDirection_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: - { - // Contains unit and value, but unit is not interesting for - // us, later we'll just distribute these values in a - // 0..10000 scale. - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - MeasureHandlerPtr pMeasureHandler(new MeasureHandler()); - pProperties->resolve(*pMeasureHandler); - if (sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_auto) - getCurrentCellWidths()->push_back(sal_Int32(-1)); - else - // store the original value to limit rounding mistakes, if it's there in a recognized measure (twip) - getCurrentCellWidths()->push_back(pMeasureHandler->getMeasureValue() ? pMeasureHandler->getValue() : sal_Int32(0)); - if (getTableDepthDifference() > 0) - m_bPushCurrentWidth = true; - } - } - break; - case NS_ooxml::LN_CT_TblPrBase_tblpPr: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - // Ignore <w:tblpPr> in shape text, those tables should be always non-floating ones. - if (!m_bIsInShape && pProperties) - { - TablePositionHandlerPtr pHandler = m_aTmpPosition.back(); - if ( !pHandler ) - { - m_aTmpPosition.pop_back(); - pHandler = new TablePositionHandler; - m_aTmpPosition.push_back( pHandler ); - } - pProperties->resolve(*m_aTmpPosition.back()); - } - } - break; - case NS_ooxml::LN_CT_TrPrBase_gridBefore: - setCurrentGridBefore( nIntValue ); - break; - case NS_ooxml::LN_CT_TrPrBase_gridAfter: - setCurrentGridAfter( nIntValue ); - break; - case NS_ooxml::LN_CT_TblPrBase_tblCaption: - // To-Do: Not yet preserved - break; - case NS_ooxml::LN_CT_TblPrBase_tblDescription: - // To-Do: Not yet preserved - break; - case NS_ooxml::LN_CT_TrPrBase_tblCellSpacing: - // To-Do: Not yet preserved - break; - case NS_ooxml::LN_CT_TblPrBase_tblCellSpacing: - // To-Do: Not yet preserved - break; - case NS_ooxml::LN_CT_TblPrBase_bidiVisual: - { - TablePropertyMapPtr pPropMap(new TablePropertyMap()); - pPropMap->Insert(PROP_WRITING_MODE, uno::makeAny(sal_Int16(nIntValue ? text::WritingMode2::RL_TB : text::WritingMode2::LR_TB))); - insertTableProps(pPropMap); - break; - } - default: - bRet = false; - -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - } - } - return bRet; -} - -DomainMapperTableManager::IntVectorPtr const & DomainMapperTableManager::getCurrentGrid( ) -{ - return m_aTableGrid.back( ); -} - -DomainMapperTableManager::IntVectorPtr const & DomainMapperTableManager::getCurrentCellWidths( ) -{ - return m_aCellWidths.back( ); -} - -uno::Sequence<beans::PropertyValue> DomainMapperTableManager::getCurrentTablePosition( ) -{ - if ( !m_aTablePositions.empty( ) && m_aTablePositions.back() ) - return m_aTablePositions.back( )->getTablePosition(); - else - return uno::Sequence< beans::PropertyValue >(); -} - -TablePositionHandler* DomainMapperTableManager::getCurrentTableRealPosition() -{ - if ( !m_aTablePositions.empty( ) && m_aTablePositions.back() ) - return m_aTablePositions.back().get(); - else - return nullptr; -} - -const TableParagraphVectorPtr & DomainMapperTableManager::getCurrentParagraphs( ) -{ - return m_aParagraphsToEndTable.top( ); -} - -void DomainMapperTableManager::setIsInShape(bool bIsInShape) -{ - m_bIsInShape = bIsInShape; -} - -void DomainMapperTableManager::startLevel( ) -{ - TableManager::startLevel( ); - - // If requested, pop the value that was pushed too early. - std::optional<sal_Int32> oCurrentWidth; - if (m_bPushCurrentWidth && !m_aCellWidths.empty() && !m_aCellWidths.back()->empty()) - { - oCurrentWidth = m_aCellWidths.back()->back(); - m_aCellWidths.back()->pop_back(); - } - std::optional<TableParagraph> oParagraph; - if (getTableDepthDifference() > 0 && !m_aParagraphsToEndTable.empty() && !m_aParagraphsToEndTable.top()->empty()) - { - oParagraph = m_aParagraphsToEndTable.top()->back(); - m_aParagraphsToEndTable.top()->pop_back(); - } - - IntVectorPtr pNewGrid = std::make_shared<vector<sal_Int32>>(); - IntVectorPtr pNewCellWidths = std::make_shared<vector<sal_Int32>>(); - TablePositionHandlerPtr pNewPositionHandler; - m_aTableGrid.push_back( pNewGrid ); - m_aCellWidths.push_back( pNewCellWidths ); - m_aTablePositions.push_back( pNewPositionHandler ); - // empty name will be replaced by the table style name, if it exists - m_aTableStyleNames.push_back( OUString() ); - - TablePositionHandlerPtr pTmpPosition; - TablePropertyMapPtr pTmpProperties( new TablePropertyMap( ) ); - m_aTmpPosition.push_back( pTmpPosition ); - m_aTmpTableProperties.push_back( pTmpProperties ); - m_nCell.push_back( 0 ); - m_nTableWidth = 0; - m_nLayoutType = 0; - TableParagraphVectorPtr pNewParagraphs = std::make_shared<vector<TableParagraph>>(); - m_aParagraphsToEndTable.push( pNewParagraphs ); - - // And push it back to the right level. - if (oCurrentWidth) - m_aCellWidths.back()->push_back(*oCurrentWidth); - if (oParagraph) - m_aParagraphsToEndTable.top()->push_back(*oParagraph); -} - -void DomainMapperTableManager::endLevel( ) -{ - if (m_aTableGrid.empty()) - { - SAL_WARN("writerfilter.dmapper", "Table stack is empty"); - return; - } - - m_aTableGrid.pop_back( ); - - // Do the same trick as in startLevel(): pop the value that was pushed too early. - std::optional<sal_Int32> oCurrentWidth; - if (m_bPushCurrentWidth && !m_aCellWidths.empty() && !m_aCellWidths.back()->empty()) - oCurrentWidth = m_aCellWidths.back()->back(); - m_aCellWidths.pop_back( ); - // And push it back to the right level. - if (oCurrentWidth && !m_aCellWidths.empty() && !m_aCellWidths.back()->empty()) - m_aCellWidths.back()->push_back(*oCurrentWidth); - - m_nCell.pop_back( ); - m_nTableWidth = 0; - m_nLayoutType = 0; - - m_aTmpPosition.pop_back( ); - m_aTmpTableProperties.pop_back( ); - - TableManager::endLevel( ); -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("dmappertablemanager.endLevel"); - PropertyMapPtr pProps = getTableProps().get(); - if (pProps) - getTableProps()->dumpXml(); - - TagLogger::getInstance().endElement(); -#endif - - // Pop back the table position after endLevel as it's used - // in the endTable method called in endLevel. - m_aTablePositions.pop_back(); - m_aTableStyleNames.pop_back(); - m_aParagraphsToEndTable.pop(); -} - -void DomainMapperTableManager::endOfCellAction() -{ -#ifdef DBG_UTIL - TagLogger::getInstance().element("endOFCellAction"); -#endif - - if ( !isInTable() ) - throw std::out_of_range("cell without a table"); - if ( m_nGridSpan > 1 ) - setCurrentGridSpan( m_nGridSpan ); - m_nGridSpan = 1; - ++m_nCell.back( ); -} - -bool DomainMapperTableManager::shouldInsertRow(IntVectorPtr pCellWidths, IntVectorPtr pTableGrid, size_t nGrids, bool& rIsIncompleteGrid) -{ - if (pCellWidths->empty()) - return false; - if (m_nLayoutType == NS_ooxml::LN_Value_doc_ST_TblLayout_fixed) - return true; - if (pCellWidths->size() == nGrids) - return true; - rIsIncompleteGrid = true; - return nGrids > pTableGrid->size(); -} - -void DomainMapperTableManager::endOfRowAction() -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("endOfRowAction"); -#endif - - // Compare the table position and style with the previous ones. We may need to split - // into two tables if those are different. We surely don't want to do anything - // if we don't have any row yet. - TablePositionHandlerPtr pTmpPosition = m_aTmpPosition.back(); - TablePropertyMapPtr pTablePropMap = m_aTmpTableProperties.back( ); - TablePositionHandlerPtr pCurrentPosition = m_aTablePositions.back(); - bool bSamePosition = ( pTmpPosition == pCurrentPosition ) || - ( pTmpPosition && pCurrentPosition && *pTmpPosition == *pCurrentPosition ); - bool bIsSetTableStyle = pTablePropMap->isSet(META_PROP_TABLE_STYLE_NAME); - OUString sTableStyleName; - bool bSameTableStyle = ( !bIsSetTableStyle && m_aTableStyleNames.back().isEmpty()) || - ( bIsSetTableStyle && - (pTablePropMap->getProperty(META_PROP_TABLE_STYLE_NAME)->second >>= sTableStyleName) && - sTableStyleName == m_aTableStyleNames.back() ); - if ( (!bSamePosition || !bSameTableStyle) && m_nRow > 0 ) - { - // Save the grid infos to have them survive the end/start level - IntVectorPtr pTmpTableGrid = m_aTableGrid.back(); - IntVectorPtr pTmpCellWidths = m_aCellWidths.back(); - sal_uInt32 nTmpCell = m_nCell.back(); - TableParagraphVectorPtr pTableParagraphs = getCurrentParagraphs(); - - // endLevel and startLevel are taking care of the non finished row - // to carry it over to the next table - setKeepUnfinishedRow( true ); - endLevel(); - setKeepUnfinishedRow( false ); - startLevel(); - - m_aTableGrid.pop_back(); - m_aCellWidths.pop_back(); - m_nCell.pop_back(); - m_aTableGrid.push_back(pTmpTableGrid); - m_aCellWidths.push_back(pTmpCellWidths); - m_nCell.push_back(nTmpCell); - m_aParagraphsToEndTable.pop( ); - m_aParagraphsToEndTable.push( pTableParagraphs ); - } - // save table style in the first row for comparison - if ( m_nRow == 0 && pTablePropMap->isSet(META_PROP_TABLE_STYLE_NAME) ) - { - pTablePropMap->getProperty(META_PROP_TABLE_STYLE_NAME)->second >>= sTableStyleName; - m_aTableStyleNames.pop_back(); - m_aTableStyleNames.push_back( sTableStyleName ); - } - - // Push the tmp position now that we compared it - m_aTablePositions.pop_back(); - m_aTablePositions.push_back( pTmpPosition ); - m_aTmpPosition.back().clear( ); - - - IntVectorPtr pTableGrid = getCurrentGrid( ); - IntVectorPtr pCellWidths = getCurrentCellWidths( ); - if(!m_nTableWidth && !pTableGrid->empty()) - { -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tableWidth"); -#endif - - for( const auto& rCell : *pTableGrid ) - { -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("col"); - TagLogger::getInstance().attribute("width", rCell); - TagLogger::getInstance().endElement(); -#endif - - m_nTableWidth = o3tl::saturating_add(m_nTableWidth, rCell); - } - if (m_nTableWidth) - // convert sum of grid twip values to 1/100 mm with rounding up to avoid table width loss - m_nTableWidth = static_cast<sal_Int32>(ceil(ConversionHelper::convertTwipToMM100Double(m_nTableWidth))); - - if (m_nTableWidth > 0 && !m_bTableSizeTypeInserted) - { - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth ); - insertTableProps(pPropMap); - } - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif - } - - std::vector<sal_uInt32> rCurrentSpans = getCurrentGridSpans(); - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("gridSpans"); - { - for (const auto& rGridSpan : rCurrentSpans) - { - TagLogger::getInstance().startElement("gridSpan"); - TagLogger::getInstance().attribute("span", rGridSpan); - TagLogger::getInstance().endElement(); - } - } - TagLogger::getInstance().endElement(); -#endif - - //calculate number of used grids - it has to match the size of m_aTableGrid - size_t nGrids = std::accumulate(rCurrentSpans.begin(), rCurrentSpans.end(), sal::static_int_cast<size_t>(0)); - - // sj: the grid is having no units... it is containing only relative values. - // a table with a grid of "1:2:1" looks identical as if the table is having - // a grid of "20:40:20" and it doesn't have to do something with the tableWidth - // -> so we have get the sum of each grid entry for the fullWidthRelative: - int nFullWidthRelative = 0; - for (int i : (*pTableGrid)) - nFullWidthRelative = o3tl::saturating_add(nFullWidthRelative, i); - - bool bIsIncompleteGrid = false; - if( pTableGrid->size() == nGrids && m_nCell.back( ) > 0 ) - { - /* - * If table width property set earlier is smaller than the current table width, - * then replace the TABLE_WIDTH property, set earlier. - */ - sal_Int32 nTableWidth(0); - sal_Int32 nTableWidthType(text::SizeType::VARIABLE); - pTablePropMap->getValue(TablePropertyMap::TABLE_WIDTH, nTableWidth); - pTablePropMap->getValue(TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType); - if ((nTableWidthType == text::SizeType::FIX) && (nTableWidth < m_nTableWidth)) - { - pTablePropMap->setValue(TablePropertyMap::TABLE_WIDTH, m_nTableWidth); - } - if (nTableWidthType == text::SizeType::VARIABLE ) - { - if(nTableWidth > 100 || nTableWidth <= 0) - { - if(getTableDepth() > 1 && !m_bTableSizeTypeInserted) - { - pTablePropMap->setValue(TablePropertyMap::TABLE_WIDTH, sal_Int32(100)); - pTablePropMap->setValue(TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::VARIABLE); - } - else - { - pTablePropMap->setValue(TablePropertyMap::TABLE_WIDTH, m_nTableWidth); - pTablePropMap->setValue(TablePropertyMap::TABLE_WIDTH_TYPE, text::SizeType::FIX); - } - } - } - uno::Sequence< text::TableColumnSeparator > aSeparators( getCurrentGridBefore() + m_nCell.back() - 1 ); - text::TableColumnSeparator* pSeparators = aSeparators.getArray(); - double nLastRelPos = 0.0; - sal_uInt32 nBorderGridIndex = 0; - - size_t nWidthsBound = getCurrentGridBefore() + m_nCell.back() - 1; - if (nWidthsBound) - { - if (nFullWidthRelative == 0) - throw o3tl::divide_by_zero(); - - ::std::vector< sal_uInt32 >::const_iterator aSpansIter = rCurrentSpans.begin(); - for( size_t nBorder = 0; nBorder < nWidthsBound; ++nBorder ) - { - double fGridWidth = 0.; - for ( sal_Int32 nGridCount = *aSpansIter; nGridCount > 0; --nGridCount ) - fGridWidth += (*pTableGrid)[nBorderGridIndex++]; - - double nRelPos = (fGridWidth * 10000) / nFullWidthRelative; - - pSeparators[nBorder].Position = rtl::math::round(nRelPos + nLastRelPos); - pSeparators[nBorder].IsVisible = true; - nLastRelPos = nLastRelPos + nRelPos; - ++aSpansIter; - } - } - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, uno::makeAny( aSeparators ) ); - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("rowProperties"); - pPropMap->dumpXml(); - TagLogger::getInstance().endElement(); -#endif - insertRowProps(pPropMap); - } - else if (shouldInsertRow(pCellWidths, pTableGrid, nGrids, bIsIncompleteGrid)) - { - // If we're here, then the number of cells does not equal to the amount - // defined by the grid, even after taking care of - // gridSpan/gridBefore/gridAfter. Handle this by ignoring the grid and - // providing the separators based on the provided cell widths, as long - // as we have a fixed layout; - // On the other hand even if the layout is not fixed, but the cell widths - // provided equal the total number of cells, and there are no after/before cells - // then use the cell widths to calculate the column separators. - // Also handle autofit tables with incomplete grids, when rows can have - // different widths and last cells can be wider, than their values. - uno::Sequence< text::TableColumnSeparator > aSeparators(pCellWidths->size() - 1); - text::TableColumnSeparator* pSeparators = aSeparators.getArray(); - sal_Int16 nSum = 0; - sal_uInt32 nPos = 0; - - if (bIsIncompleteGrid) - nFullWidthRelative = 0; - - // Avoid divide by zero (if there's no grid, position using cell widths). - if( nFullWidthRelative == 0 ) - for (size_t i = 0; i < pCellWidths->size(); ++i) - nFullWidthRelative += (*pCellWidths)[i]; - - if (bIsIncompleteGrid) - { - /* - * If table width property set earlier is smaller than the current table row width, - * then replace the TABLE_WIDTH property, set earlier. - */ - sal_Int32 nFullWidth = static_cast<sal_Int32>(ceil(ConversionHelper::convertTwipToMM100Double(nFullWidthRelative))); - sal_Int32 nTableWidth(0); - sal_Int32 nTableWidthType(text::SizeType::VARIABLE); - pTablePropMap->getValue(TablePropertyMap::TABLE_WIDTH, nTableWidth); - pTablePropMap->getValue(TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType); - if (nTableWidth < nFullWidth) - { - pTablePropMap->setValue(TablePropertyMap::TABLE_WIDTH, nFullWidth); - } - } - - size_t nWidthsBound = pCellWidths->size() - 1; - if (nWidthsBound) - { - if (nFullWidthRelative == 0) - throw o3tl::divide_by_zero(); - - // At incomplete table grids, last cell width can be smaller, than its final width. - // Correct it based on the last but one column width and their span values. - if ( bIsIncompleteGrid && rCurrentSpans.size()-1 == nWidthsBound ) - { - auto aSpansIter = std::next(rCurrentSpans.begin(), nWidthsBound - 1); - sal_Int32 nFixLastCellWidth = (*pCellWidths)[nWidthsBound-1] / *aSpansIter * *std::next(aSpansIter); - if (nFixLastCellWidth > (*pCellWidths)[nWidthsBound]) - nFullWidthRelative += nFixLastCellWidth - (*pCellWidths)[nWidthsBound]; - } - - for (size_t i = 0; i < nWidthsBound; ++i) - { - nSum += (*pCellWidths)[i]; - pSeparators[nPos].Position = (nSum * 10000) / nFullWidthRelative; // Relative position - pSeparators[nPos].IsVisible = true; - nPos++; - } - } - - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, uno::makeAny( aSeparators ) ); -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("rowProperties"); - pPropMap->dumpXml(); - TagLogger::getInstance().endElement(); -#endif - insertRowProps(pPropMap); - } - - // Now that potentially opened table is closed, save the table properties - TableManager::insertTableProps(pTablePropMap); - - m_aTmpTableProperties.pop_back(); - TablePropertyMapPtr pEmptyTableProps( new TablePropertyMap() ); - m_aTmpTableProperties.push_back( pEmptyTableProps ); - - ++m_nRow; - m_nCell.back( ) = 0; - getCurrentGrid()->clear(); - pCellWidths->clear(); - - m_bTableSizeTypeInserted = false; - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void DomainMapperTableManager::clearData() -{ - m_nRow = m_nHeaderRepeat = m_nTableWidth = m_nLayoutType = 0; -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx deleted file mode 100644 index 9b30e6dd8315..000000000000 --- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_DOMAINMAPPERTABLEMANAGER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_DOMAINMAPPERTABLEMANAGER_HXX - -#include "TablePropertiesHandler.hxx" -#include "TablePositionHandler.hxx" - -#include "TableManager.hxx" -#include "PropertyMap.hxx" -#include <vector> -#include <memory> -#include <comphelper/sequenceashashmap.hxx> - -namespace writerfilter::dmapper { - -class DomainMapper; - -class DomainMapperTableManager : public TableManager -{ - typedef std::shared_ptr< std::vector<sal_Int32> > IntVectorPtr; - - sal_uInt32 m_nRow; - ::std::vector< sal_uInt32 > m_nCell; - sal_uInt32 m_nGridSpan; - 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 - /// Are we in a shape (text append stack is not empty) or in the body document? - bool m_bIsInShape; - std::vector< OUString > m_aTableStyleNames; - /// Grab-bag of table look attributes for preserving. - comphelper::SequenceAsHashMap m_aTableLook; - std::vector< TablePositionHandlerPtr > m_aTablePositions; - std::vector< TablePositionHandlerPtr > m_aTmpPosition; ///< Temporarily stores the position to compare it later - std::vector< TablePropertyMapPtr > m_aTmpTableProperties; ///< Temporarily stores the table properties until end of row - - ::std::vector< IntVectorPtr > m_aTableGrid; - /// If this is true, then we pushed a width before the next level started, and that should be carried over when starting the next level. - bool m_bPushCurrentWidth; - /// Individual table cell width values, used only in case the number of cells doesn't match the table grid. - ::std::vector< IntVectorPtr > m_aCellWidths; - /// Remember if table width was already set, when we lack a w:tblW, it should be set manually at the end. - bool m_bTableSizeTypeInserted; - /// Table layout algorithm, IOW if we should consider fixed column width or not. - sal_uInt32 m_nLayoutType; - /// Collected table paragraphs for table style handling - std::stack< TableParagraphVectorPtr > m_aParagraphsToEndTable; - - std::unique_ptr<TablePropertiesHandler> m_pTablePropsHandler; - PropertyMapPtr m_pStyleProps; - - bool shouldInsertRow(IntVectorPtr pCellWidths, IntVectorPtr pTableGrid, size_t nGrids, bool& rIsIncompleteGrid); - - virtual void clearData() override; - -public: - - DomainMapperTableManager(); - virtual ~DomainMapperTableManager() override; - - // use this method to avoid adding the properties for the table - // but in the provided properties map. - void SetStyleProperties( PropertyMapPtr pProperties ) { m_pStyleProps = pProperties; }; - - virtual bool sprm(Sprm & rSprm) override; - bool attribute(Id nName, Value const & val); - - virtual void startLevel( ) override; - virtual void endLevel( ) override; - - virtual void endOfCellAction() override; - virtual void endOfRowAction() override; - - IntVectorPtr const & getCurrentGrid( ); - IntVectorPtr const & getCurrentCellWidths( ); - const TableParagraphVectorPtr & getCurrentParagraphs( ); - - /// Turn the attributes collected so far in m_aTableLook into a property and clear the container. - void finishTableLook(); - css::uno::Sequence<css::beans::PropertyValue> getCurrentTablePosition(); - TablePositionHandler* getCurrentTableRealPosition(); - - virtual void cellProps(const TablePropertyMapPtr& pProps) override - { - if ( m_pStyleProps ) - m_pStyleProps->InsertProps(pProps.get()); - else - TableManager::cellProps( pProps ); - }; - - virtual void insertRowProps(const TablePropertyMapPtr& pProps) override - { - if ( m_pStyleProps ) - m_pStyleProps->InsertProps(pProps.get()); - else - TableManager::insertRowProps( pProps ); - }; - - virtual void insertTableProps(const TablePropertyMapPtr& pProps) override - { - if ( m_pStyleProps ) - m_pStyleProps->InsertProps(pProps.get()); - else - m_aTmpTableProperties.back()->InsertProps(pProps.get()); - }; - - void SetLayoutType(sal_uInt32 nLayoutType) - { - m_nLayoutType = nLayoutType; - } - - using TableManager::isInCell; - - void setIsInShape(bool bIsInShape); - -}; - -} - -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_DOMAINMAPPERTABLEMANAGER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx deleted file mode 100644 index c102d7bcc565..000000000000 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ /dev/null @@ -1,7653 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/document/XDocumentProperties.hpp> -#include <ooxml/resourceids.hxx> -#include "DomainMapper_Impl.hxx" -#include "ConversionHelper.hxx" -#include "SdtHelper.hxx" -#include "DomainMapperTableHandler.hxx" -#include "TagLogger.hxx" -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/graphic/XGraphic.hpp> -#include <com/sun/star/beans/XPropertyState.hpp> -#include <com/sun/star/container/XNamed.hpp> -#include <com/sun/star/document/PrinterIndependentLayout.hpp> -#include <com/sun/star/document/IndexedPropertyValues.hpp> -#include <com/sun/star/drawing/XDrawPageSupplier.hpp> -#include <com/sun/star/embed/XEmbeddedObject.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/LineSpacing.hpp> -#include <com/sun/star/style/LineSpacingMode.hpp> -#include <com/sun/star/text/ChapterFormat.hpp> -#include <com/sun/star/text/FilenameDisplayFormat.hpp> -#include <com/sun/star/text/SetVariableType.hpp> -#include <com/sun/star/text/XDocumentIndex.hpp> -#include <com/sun/star/text/XDocumentIndexesSupplier.hpp> -#include <com/sun/star/text/XFootnote.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/style/XStyle.hpp> -#include <com/sun/star/text/PageNumberType.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/RelOrientation.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/XTextFieldsSupplier.hpp> -#include <com/sun/star/text/XTextFrame.hpp> -#include <com/sun/star/text/RubyPosition.hpp> -#include <com/sun/star/text/XTextRangeCompare.hpp> -#include <com/sun/star/style/DropCapFormat.hpp> -#include <com/sun/star/util/NumberFormatter.hpp> -#include <com/sun/star/util/XNumberFormatsSupplier.hpp> -#include <com/sun/star/util/XNumberFormatter.hpp> -#include <com/sun/star/document/XViewDataSupplier.hpp> -#include <com/sun/star/container/XIndexContainer.hpp> -#include <com/sun/star/text/ControlCharacter.hpp> -#include <com/sun/star/text/XTextColumns.hpp> -#include <com/sun/star/awt/CharSet.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp> -#include <com/sun/star/embed/ElementModes.hpp> -#include <com/sun/star/document/XImporter.hpp> -#include <com/sun/star/document/XFilter.hpp> -#include <editeng/flditem.hxx> -#include <editeng/unotext.hxx> -#include <o3tl/safeint.hxx> -#include <o3tl/temporary.hxx> -#include <oox/mathml/import.hxx> -#include <xmloff/odffields.hxx> -#include <rtl/uri.hxx> -#include <unotools/ucbstreamhelper.hxx> -#include <unotools/streamwrap.hxx> - -#include <dmapper/GraphicZOrderHelper.hxx> - -#include <oox/token/tokens.hxx> - -#include <cmath> -#include <optional> -#include <map> -#include <tuple> -#include <unordered_map> -#include <regex> -#include <algorithm> - -#include <officecfg/Office/Common.hxx> -#include <filter/msfilter/util.hxx> -#include <filter/msfilter/ww8fields.hxx> -#include <comphelper/sequence.hxx> -#include <comphelper/propertyvalue.hxx> -#include <comphelper/propertysequence.hxx> -#include <unotools/configmgr.hxx> -#include <unotools/mediadescriptor.hxx> -#include <tools/diagnose_ex.h> -#include <sal/log.hxx> -#include <com/sun/star/drawing/FillStyle.hpp> - -#include <unicode/errorcode.h> -#include <unicode/regex.h> - -using namespace ::com::sun::star; -using namespace oox; -namespace writerfilter::dmapper{ - -//line numbering for header/footer -static void lcl_linenumberingHeaderFooter( const uno::Reference<container::XNameContainer>& xStyles, const OUString& rname, DomainMapper_Impl* dmapper ) -{ - const StyleSheetEntryPtr pEntry = dmapper->GetStyleSheetTable()->FindStyleSheetByISTD( rname ); - if (!pEntry) - return; - const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>( pEntry->pProperties.get() ); - if ( !pStyleSheetProperties ) - return; - sal_Int32 nListId = pStyleSheetProperties->GetListId(); - if( xStyles.is() ) - { - if( xStyles->hasByName( rname ) ) - { - uno::Reference< style::XStyle > xStyle; - xStyles->getByName( rname ) >>= xStyle; - if( !xStyle.is() ) - return; - uno::Reference<beans::XPropertySet> xPropertySet( xStyle, uno::UNO_QUERY ); - xPropertySet->setPropertyValue( getPropertyName( PROP_PARA_LINE_NUMBER_COUNT ), uno::makeAny( nListId >= 0 ) ); - } - } -} - -// Populate Dropdown Field properties from FFData structure -static void lcl_handleDropdownField( const uno::Reference< beans::XPropertySet >& rxFieldProps, const FFDataHandler::Pointer_t& pFFDataHandler ) -{ - if ( !rxFieldProps.is() ) - return; - - if ( !pFFDataHandler->getName().isEmpty() ) - rxFieldProps->setPropertyValue( "Name", uno::makeAny( pFFDataHandler->getName() ) ); - - const FFDataHandler::DropDownEntries_t& rEntries = pFFDataHandler->getDropDownEntries(); - uno::Sequence< OUString > sItems( rEntries.size() ); - ::std::copy( rEntries.begin(), rEntries.end(), sItems.begin()); - if ( sItems.hasElements() ) - rxFieldProps->setPropertyValue( "Items", uno::makeAny( sItems ) ); - - sal_Int32 nResult = pFFDataHandler->getDropDownResult().toInt32(); - if (nResult > 0 && o3tl::make_unsigned(nResult) < sItems.size()) - rxFieldProps->setPropertyValue( "SelectedItem", uno::makeAny( sItems[ nResult ] ) ); - if ( !pFFDataHandler->getHelpText().isEmpty() ) - rxFieldProps->setPropertyValue( "Help", uno::makeAny( pFFDataHandler->getHelpText() ) ); -} - -static void lcl_handleTextField( const uno::Reference< beans::XPropertySet >& rxFieldProps, const FFDataHandler::Pointer_t& pFFDataHandler ) -{ - if ( rxFieldProps.is() && pFFDataHandler ) - { - rxFieldProps->setPropertyValue - (getPropertyName(PROP_HINT), - uno::makeAny(pFFDataHandler->getStatusText())); - rxFieldProps->setPropertyValue - (getPropertyName(PROP_HELP), - uno::makeAny(pFFDataHandler->getHelpText())); - rxFieldProps->setPropertyValue - (getPropertyName(PROP_CONTENT), - uno::makeAny(pFFDataHandler->getTextDefault())); - } -} - -namespace { - -struct FieldConversion -{ - const char* cFieldServiceName; - FieldId eFieldId; -}; - -} - -typedef std::unordered_map<OUString, FieldConversion> FieldConversionMap_t; - -/// Gives access to the parent field context of the topmost one, if there is any. -static FieldContextPtr GetParentFieldContext(const std::deque<FieldContextPtr>& rFieldStack) -{ - if (rFieldStack.size() < 2) - { - return nullptr; - } - - return rFieldStack[rFieldStack.size() - 2]; -} - -/// Decides if the pInner field inside pOuter is allowed in Writer core, depending on their type. -static bool IsFieldNestingAllowed(const FieldContextPtr& pOuter, const FieldContextPtr& pInner) -{ - std::optional<FieldId> oOuterFieldId = pOuter->GetFieldId(); - OUString aCommand = pOuter->GetCommand(); - - // Ignore leading space before the field name, but don't accept IFF when we check for IF. - if (!aCommand.isEmpty() && aCommand[0] == ' ') - { - aCommand = aCommand.subView(1); - } - - if (!oOuterFieldId && aCommand.startsWith("IF ")) - { - // This will be FIELD_IF once the command is closed. - oOuterFieldId = FIELD_IF; - } - - if (!oOuterFieldId) - { - return true; - } - - if (!pInner->GetFieldId()) - { - return true; - } - - switch (*oOuterFieldId) - { - case FIELD_IF: - { - switch (*pInner->GetFieldId()) - { - case FIELD_DOCVARIABLE: - case FIELD_FORMULA: - case FIELD_IF: - case FIELD_MERGEFIELD: - { - return false; - } - default: - break; - } - break; - } - default: - break; - } - - return true; -} - -uno::Any FloatingTableInfo::getPropertyValue(std::u16string_view propertyName) -{ - for( beans::PropertyValue const & propVal : std::as_const(m_aFrameProperties) ) - if( propVal.Name == propertyName ) - return propVal.Value ; - return uno::Any() ; -} - -DomainMapper_Impl::DomainMapper_Impl( - DomainMapper& rDMapper, - uno::Reference<uno::XComponentContext> const& xContext, - uno::Reference<lang::XComponent> const& xModel, - SourceDocumentType eDocumentType, - utl::MediaDescriptor const & rMediaDesc) : - m_eDocumentType( eDocumentType ), - m_rDMapper( rDMapper ), - m_xTextDocument( xModel, uno::UNO_QUERY ), - m_xTextFactory( xModel, uno::UNO_QUERY ), - m_xComponentContext( xContext ), - m_bForceGenericFields(!utl::ConfigManager::IsFuzzing() && officecfg::Office::Common::Filter::Microsoft::Import::ForceImportWWFieldsAsGenericFields::get(m_xComponentContext)), - m_bSetUserFieldContent( false ), - m_bSetCitation( false ), - m_bSetDateValue( false ), - m_bIsFirstSection( true ), - m_bIsColumnBreakDeferred( false ), - m_bIsPageBreakDeferred( false ), - m_bSdtEndDeferred(false), - m_bParaSdtEndDeferred(false), - m_bStartTOC(false), - m_bStartTOCHeaderFooter(false), - m_bStartedTOC(false), - m_bStartIndex(false), - m_bStartBibliography(false), - m_nStartGenericField(0), - m_bTextInserted(false), - m_sCurrentPermId(0), - m_bFrameDirectionSet(false), - m_pLastSectionContext( ), - m_pLastCharacterContext(), - m_sCurrentParaStyleName(), - m_sDefaultParaStyleName(), - m_bInDocDefaultsImport(false), - m_bInStyleSheetImport( false ), - m_bInAnyTableImport( false ), - m_eInHeaderFooterImport( HeaderFooterImportState::none ), - m_bDiscardHeaderFooter( false ), - m_bInFootOrEndnote(false), - m_bInFootnote(false), - m_bHasFootnoteStyle(false), - m_bCheckFootnoteStyle(false), - m_eSkipFootnoteState(SkipFootnoteSeparator::OFF), - m_nFootnotes(-1), - m_nEndnotes(-1), - m_bLineNumberingSet( false ), - m_bIsInFootnoteProperties( false ), - m_bIsParaMarkerChange( false ), - m_bParaChanged( false ), - m_bIsFirstParaInSection( true ), - m_bIsFirstParaInSectionAfterRedline( true ), - m_bDummyParaAddedForTableInSection( false ), - m_bTextFrameInserted(false), - m_bIsPreviousParagraphFramed( false ), - m_bIsLastParaInSection( false ), - m_bIsLastSectionGroup( false ), - m_bIsInComments( false ), - m_bParaSectpr( false ), - m_bUsingEnhancedFields( false ), - m_bSdt(false), - m_bIsFirstRun(false), - m_bIsOutsideAParagraph(true), - m_xAnnotationField(), - m_nAnnotationId( -1 ), - m_aAnnotationPositions(), - m_aSmartTagHandler(m_xComponentContext, m_xTextDocument), - m_xInsertTextRange(rMediaDesc.getUnpackedValueOrDefault("TextInsertModeRange", uno::Reference<text::XTextRange>())), - m_xAltChunkStartingRange(rMediaDesc.getUnpackedValueOrDefault("AltChunkStartingRange", uno::Reference<text::XTextRange>())), - m_bIsNewDoc(!rMediaDesc.getUnpackedValueOrDefault("InsertMode", false)), - m_bIsAltChunk(rMediaDesc.getUnpackedValueOrDefault("AltChunkMode", false)), - m_bIsReadGlossaries(rMediaDesc.getUnpackedValueOrDefault("ReadGlossaries", false)), - m_nTableDepth(0), - m_nTableCellDepth(0), - m_nLastTableCellParagraphDepth(0), - m_bHasFtn(false), - m_bHasFtnSep(false), - m_bCheckFirstFootnoteTab(false), - m_bIgnoreNextTab(false), - m_bIsSplitPara(false), - m_bIsActualParagraphFramed( false ), - m_vTextFramesForChaining(), - m_bParaHadField(false), - m_bSaveParaHadField(false), - m_bParaAutoBefore(false), - m_bFirstParagraphInCell(true), - m_bSaveFirstParagraphInCell(false), - m_bParaWithInlineObject(false) - -{ - m_aBaseUrl = rMediaDesc.getUnpackedValueOrDefault( - utl::MediaDescriptor::PROP_DOCUMENTBASEURL(), OUString()); - if (m_aBaseUrl.isEmpty()) { - m_aBaseUrl = rMediaDesc.getUnpackedValueOrDefault( - utl::MediaDescriptor::PROP_URL(), OUString()); - } - - appendTableManager( ); - GetBodyText(); - uno::Reference< text::XTextAppend > xBodyTextAppend( m_xBodyText, uno::UNO_QUERY ); - m_aTextAppendStack.push(TextAppendContext(xBodyTextAppend, - m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(m_xInsertTextRange))); - - //todo: does it makes sense to set the body text as static text interface? - uno::Reference< text::XTextAppendAndConvert > xBodyTextAppendAndConvert( m_xBodyText, uno::UNO_QUERY ); - m_pTableHandler = new DomainMapperTableHandler(xBodyTextAppendAndConvert, *this); - getTableManager( ).setHandler(m_pTableHandler); - - getTableManager( ).startLevel(); - m_bUsingEnhancedFields = !utl::ConfigManager::IsFuzzing() && officecfg::Office::Common::Filter::Microsoft::Import::ImportWWFieldsAsEnhancedFields::get(m_xComponentContext); - - m_pSdtHelper = new SdtHelper(*this); - - m_aRedlines.push(std::vector<RedlineParamsPtr>()); - - if (m_bIsAltChunk) - { - m_bIsFirstSection = false; - } -} - - -DomainMapper_Impl::~DomainMapper_Impl() -{ - ChainTextFrames(); - // Don't remove last paragraph when pasting, sw expects that empty paragraph. - if (m_bIsNewDoc) - RemoveLastParagraph(); - if (hasTableManager()) - { - getTableManager().endLevel(); - popTableManager(); - } -} - -uno::Reference< container::XNameContainer > const & DomainMapper_Impl::GetPageStyles() -{ - if(!m_xPageStyles1.is()) - { - uno::Reference< style::XStyleFamiliesSupplier > xSupplier( m_xTextDocument, uno::UNO_QUERY ); - if (xSupplier.is()) - xSupplier->getStyleFamilies()->getByName("PageStyles") >>= m_xPageStyles1; - } - return m_xPageStyles1; -} - -OUString DomainMapper_Impl::GetUnusedPageStyleName() -{ - static const char DEFAULT_STYLE[] = "Converted"; - if (!m_xNextUnusedPageStyleNo) - { - const uno::Sequence< OUString > aPageStyleNames = GetPageStyles()->getElementNames(); - sal_Int32 nMaxIndex = 0; - // find the highest number x in each style with the name "DEFAULT_STYLE+x" and - // return an incremented name - - for ( const auto& rStyleName : aPageStyleNames ) - { - if ( rStyleName.startsWith( DEFAULT_STYLE ) ) - { - sal_Int32 nIndex = rStyleName.copy( strlen( DEFAULT_STYLE ) ).toInt32(); - if ( nIndex > nMaxIndex ) - nMaxIndex = nIndex; - } - } - m_xNextUnusedPageStyleNo = nMaxIndex + 1; - } - - OUString sPageStyleName = DEFAULT_STYLE + OUString::number( *m_xNextUnusedPageStyleNo ); - *m_xNextUnusedPageStyleNo = *m_xNextUnusedPageStyleNo + 1; - return sPageStyleName; -} - -uno::Reference< text::XText > const & DomainMapper_Impl::GetBodyText() -{ - if(!m_xBodyText.is()) - { - if (m_xInsertTextRange.is()) - m_xBodyText = m_xInsertTextRange->getText(); - else if (m_xTextDocument.is()) - m_xBodyText = m_xTextDocument->getText(); - } - return m_xBodyText; -} - - -uno::Reference< beans::XPropertySet > const & DomainMapper_Impl::GetDocumentSettings() -{ - if( !m_xDocumentSettings.is() && m_xTextFactory.is()) - { - m_xDocumentSettings.set( m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY ); - } - return m_xDocumentSettings; -} - - -void DomainMapper_Impl::SetDocumentSettingsProperty( const 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::RemoveDummyParaForTableInSection() -{ - SetIsDummyParaAddedForTableInSection(false); - PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_SECTION); - SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() ); - if (!pSectionContext) - return; - - if (m_aTextAppendStack.empty()) - return; - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if (!xTextAppend.is()) - return; - - uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange(pSectionContext->GetStartingRange()); - - // Remove the extra NumPicBullets from the document, - // which get attached to the first paragraph in the - // document - ListsManager::Pointer pListTable = GetListTable(); - pListTable->DisposeNumPicBullets(); - - uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCursor, uno::UNO_QUERY); - if (xEnumerationAccess.is() && m_aTextAppendStack.size() == 1 ) - { - uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration(); - uno::Reference<lang::XComponent> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY); - xParagraph->dispose(); - } -} -void DomainMapper_Impl::AddDummyParaForTableInSection() -{ - // Shapes can't have sections. - if (IsInShape()) - return; - - if (!m_aTextAppendStack.empty()) - { - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if (xTextAppend.is()) - { - xTextAppend->finishParagraph( uno::Sequence< beans::PropertyValue >() ); - SetIsDummyParaAddedForTableInSection(true); - } - } -} - -void DomainMapper_Impl::RemoveLastParagraph( ) -{ - if (m_bDiscardHeaderFooter) - return; - - if (m_aTextAppendStack.empty()) - return; - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if (!xTextAppend.is()) - return; - try - { - uno::Reference< text::XTextCursor > xCursor; - if (m_bIsNewDoc) - { - xCursor = xTextAppend->createTextCursor(); - xCursor->gotoEnd(false); - } - else - xCursor = m_aTextAppendStack.top().xCursor; - uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCursor, uno::UNO_QUERY); - // Keep the character properties of the last but one paragraph, even if - // it's empty. This works for headers/footers, and maybe in other cases - // as well, but surely not in textboxes. - // fdo#58327: also do this at the end of the document: when pasting, - // a table before the cursor position would be deleted - // (but only for paste/insert, not load; otherwise it can happen that - // flys anchored at the disposed paragraph are deleted (fdo47036.rtf)) - bool const bEndOfDocument(m_aTextAppendStack.size() == 1); - if ((IsInHeaderFooter() || (bEndOfDocument && !m_bIsNewDoc)) - && xEnumerationAccess.is()) - { - uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration(); - uno::Reference<lang::XComponent> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY); - xParagraph->dispose(); - } - else if (xCursor.is()) - { - xCursor->goLeft( 1, true ); - // If this is a text on a shape, possibly the text has the trailing - // newline removed already. - if (xCursor->getString() == SAL_NEWLINE_STRING || - // tdf#105444 comments need an exception, if SAL_NEWLINE_STRING defined as "\r\n" - (sizeof(SAL_NEWLINE_STRING)-1 == 2 && xCursor->getString() == "\n")) - { - uno::Reference<beans::XPropertySet> xDocProps(GetTextDocument(), uno::UNO_QUERY); - const OUString aRecordChanges("RecordChanges"); - uno::Any aPreviousValue(xDocProps->getPropertyValue(aRecordChanges)); - - // disable redlining for this operation, otherwise we might - // end up with an unwanted recorded deletion - xDocProps->setPropertyValue(aRecordChanges, uno::Any(false)); - - // delete - xCursor->setString(OUString()); - - // restore again - xDocProps->setPropertyValue(aRecordChanges, aPreviousValue); - } - } - } - catch( const uno::Exception& ) - { - } -} - - -void DomainMapper_Impl::SetIsLastSectionGroup( bool bIsLast ) -{ - m_bIsLastSectionGroup = bIsLast; -} - -void DomainMapper_Impl::SetIsLastParagraphInSection( bool bIsLast ) -{ - m_bIsLastParaInSection = bIsLast; -} - - -void DomainMapper_Impl::SetIsFirstParagraphInSection( bool bIsFirst ) -{ - m_bIsFirstParaInSection = bIsFirst; -} - -void DomainMapper_Impl::SetIsFirstParagraphInSectionAfterRedline( bool bIsFirstAfterRedline ) -{ - m_bIsFirstParaInSectionAfterRedline = bIsFirstAfterRedline; -} - -bool DomainMapper_Impl::GetIsFirstParagraphInSection( bool bAfterRedline ) const -{ - // Anchored objects may include multiple paragraphs, - // and none of them should be considered the first para in section. - return ( bAfterRedline ? m_bIsFirstParaInSectionAfterRedline : m_bIsFirstParaInSection ) - && !IsInShape() - && !m_bIsInComments - && !IsInFootOrEndnote(); -} - -void DomainMapper_Impl::SetIsFirstParagraphInShape(bool bIsFirst) -{ - m_bIsFirstParaInShape = bIsFirst; -} - -void DomainMapper_Impl::SetIsDummyParaAddedForTableInSection( bool bIsAdded ) -{ - m_bDummyParaAddedForTableInSection = bIsAdded; -} - - -void DomainMapper_Impl::SetIsTextFrameInserted( bool bIsInserted ) -{ - m_bTextFrameInserted = bIsInserted; -} - - -void DomainMapper_Impl::SetParaSectpr(bool bParaSectpr) -{ - m_bParaSectpr = bParaSectpr; -} - - -void DomainMapper_Impl::SetSdt(bool bSdt) -{ - m_bSdt = bSdt; - - if (m_bSdt && !m_aTextAppendStack.empty()) - { - m_xSdtEntryStart = GetTopTextAppend()->getEnd(); - } - else - { - m_xSdtEntryStart.clear(); - } -} - - -void DomainMapper_Impl::PushProperties(ContextType eId) -{ - PropertyMapPtr pInsert(eId == CONTEXT_SECTION ? - (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() ); - if (!m_aTextAppendStack.empty()) - { - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if (xTextAppend.is() && pSectionContext_) - pSectionContext_->SetStart( xTextAppend->getEnd() ); - } - } - if(eId == CONTEXT_PARAGRAPH && m_bIsSplitPara) - { - m_aPropertyStacks[eId].push( GetTopContextOfType(eId)); - m_bIsSplitPara = false; - } - else - { - m_aPropertyStacks[eId].push( pInsert ); - } - m_aContextStack.push(eId); - - m_pTopContext = m_aPropertyStacks[eId].top(); -} - - -void DomainMapper_Impl::PushStyleProperties( const PropertyMapPtr& pStyleProperties ) -{ - m_aPropertyStacks[CONTEXT_STYLESHEET].push( pStyleProperties ); - m_aContextStack.push(CONTEXT_STYLESHEET); - - m_pTopContext = m_aPropertyStacks[CONTEXT_STYLESHEET].top(); -} - - -void DomainMapper_Impl::PushListProperties(const 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 ( m_aPropertyStacks[eId].empty() ) - return; - - if ( eId == CONTEXT_SECTION ) - { - if (m_aPropertyStacks[eId].size() == 1) // tdf#112202 only top level !!! - { - m_pLastSectionContext = m_aPropertyStacks[eId].top(); - } - } - else if (eId == CONTEXT_CHARACTER) - { - m_pLastCharacterContext = m_aPropertyStacks[eId].top(); - // Sadly an assert about deferredCharacterProperties being empty is not possible - // here, because appendTextPortion() may not be called for every character section. - deferredCharacterProperties.clear(); - } - - if (!IsInFootOrEndnote() && IsInCustomFootnote() && !m_aPropertyStacks[eId].empty()) - { - PropertyMapPtr pRet = m_aPropertyStacks[eId].top(); - if (pRet->GetFootnote().is() && m_pFootnoteContext.is()) - EndCustomFootnote(); - } - - 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.clear(); - } -} - - -PropertyMapPtr DomainMapper_Impl::GetTopContextOfType(ContextType eId) -{ - PropertyMapPtr pRet; - if(!m_aPropertyStacks[eId].empty()) - pRet = m_aPropertyStacks[eId].top(); - return pRet; -} - -bool DomainMapper_Impl::HasTopText() const -{ - return !m_aTextAppendStack.empty(); -} - -uno::Reference< text::XTextAppend > const & DomainMapper_Impl::GetTopTextAppend() -{ - OSL_ENSURE(!m_aTextAppendStack.empty(), "text append stack is empty" ); - return m_aTextAppendStack.top().xTextAppend; -} - -FieldContextPtr const & DomainMapper_Impl::GetTopFieldContext() -{ - SAL_WARN_IF(m_aFieldStack.empty(), "writerfilter.dmapper", "Field stack is empty"); - return m_aFieldStack.back(); -} - -bool DomainMapper_Impl::HasTopAnchoredObjects() const -{ - return !m_aTextAppendStack.empty() && !m_aTextAppendStack.top().m_aAnchoredObjects.empty(); -} - -void DomainMapper_Impl::InitTabStopFromStyle( const uno::Sequence< style::TabStop >& rInitTabStops ) -{ - OSL_ENSURE(m_aCurrentTabStops.empty(), "tab stops already initialized"); - for( const auto& rTabStop : rInitTabStops) - { - m_aCurrentTabStops.emplace_back(rTabStop); - } -} - -void DomainMapper_Impl::IncorporateTabStop( const DeletableTabStop & rTabStop ) -{ - sal_Int32 nConverted = rTabStop.Position; - auto aIt = std::find_if(m_aCurrentTabStops.begin(), m_aCurrentTabStops.end(), - [&nConverted](const DeletableTabStop& rCurrentTabStop) { return rCurrentTabStop.Position == nConverted; }); - if( aIt != m_aCurrentTabStops.end() ) - { - if( rTabStop.bDeleted ) - m_aCurrentTabStops.erase( aIt ); - else - *aIt = rTabStop; - } - else - m_aCurrentTabStops.push_back( rTabStop ); -} - - -uno::Sequence< style::TabStop > DomainMapper_Impl::GetCurrentTabStopAndClear() -{ - std::vector<style::TabStop> aRet; - for (const DeletableTabStop& rStop : m_aCurrentTabStops) - { - if (!rStop.bDeleted) - aRet.push_back(rStop); - } - m_aCurrentTabStops.clear(); - return comphelper::containerToSequence(aRet); -} - -OUString DomainMapper_Impl::GetCurrentParaStyleName() -{ - OUString sName; - // use saved currParaStyleName as a fallback, in case no particular para style name applied. - // tdf#134784 except in the case of first paragraph of shapes to avoid bad fallback. - // TODO fix this "highly inaccurate" m_sCurrentParaStyleName - if ( !IsInShape() ) - sName = m_sCurrentParaStyleName; - - PropertyMapPtr pParaContext = GetTopContextOfType(CONTEXT_PARAGRAPH); - if ( pParaContext && pParaContext->isSet(PROP_PARA_STYLE_NAME) ) - pParaContext->getProperty(PROP_PARA_STYLE_NAME)->second >>= sName; - - // In rare situations the name might still be blank, so use the default style, - // despite documentation that states, "If this attribute is not specified for any style, - // then no properties shall be applied to objects of the specified type." - // Word, however, assigns "Normal" style even in these situations. - if ( !m_bInStyleSheetImport && sName.isEmpty() ) - sName = GetDefaultParaStyleName(); - - return sName; -} - -OUString DomainMapper_Impl::GetDefaultParaStyleName() -{ - // After import the default style won't change and is frequently requested: cache the LO style name. - // TODO assert !InStyleSheetImport? This function really only makes sense once import is finished anyway. - if ( m_sDefaultParaStyleName.isEmpty() ) - { - const StyleSheetEntryPtr pEntry = GetStyleSheetTable()->FindDefaultParaStyle(); - if ( pEntry && !pEntry->sConvertedStyleName.isEmpty() ) - { - if ( !m_bInStyleSheetImport ) - m_sDefaultParaStyleName = pEntry->sConvertedStyleName; - return pEntry->sConvertedStyleName; - } - else - return "Standard"; - } - return m_sDefaultParaStyleName; -} - -uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara, bool* pIsDocDefault) -{ - while(pEntry) - { - if(pEntry->pProperties) - { - std::optional<PropertyMap::Property> aProperty = - pEntry->pProperties->getProperty(eId); - if( aProperty ) - { - if (pIsDocDefault) - *pIsDocDefault = pEntry->pProperties->isDocDefault(eId); - - return aProperty->second; - } - } - //search until the property is set or no parent is available - StyleSheetEntryPtr pNewEntry; - if ( !pEntry->sBaseStyleIdentifier.isEmpty() ) - pNewEntry = GetStyleSheetTable()->FindStyleSheetByISTD(pEntry->sBaseStyleIdentifier); - - SAL_WARN_IF( pEntry == pNewEntry, "writerfilter.dmapper", "circular loop in style hierarchy?"); - - if (pEntry == pNewEntry) //fdo#49587 - break; - - pEntry = pNewEntry; - } - // not found in style, try the document's DocDefault properties - if ( bDocDefaults && bPara ) - { - const PropertyMapPtr& pDefaultParaProps = GetStyleSheetTable()->GetDefaultParaProps(); - if ( pDefaultParaProps ) - { - std::optional<PropertyMap::Property> aProperty = pDefaultParaProps->getProperty(eId); - if ( aProperty ) - { - if (pIsDocDefault) - *pIsDocDefault = true; - - return aProperty->second; - } - } - } - if ( bDocDefaults && isCharacterProperty(eId) ) - { - const PropertyMapPtr& pDefaultCharProps = GetStyleSheetTable()->GetDefaultCharProps(); - if ( pDefaultCharProps ) - { - std::optional<PropertyMap::Property> aProperty = pDefaultCharProps->getProperty(eId); - if ( aProperty ) - { - if (pIsDocDefault) - *pIsDocDefault = true; - - return aProperty->second; - } - } - } - - if (pIsDocDefault) - *pIsDocDefault = false; - - return uno::Any(); -} - -uno::Any DomainMapper_Impl::GetPropertyFromParaStyleSheet(PropertyIds eId) -{ - StyleSheetEntryPtr pEntry; - if ( m_bInStyleSheetImport ) - pEntry = GetStyleSheetTable()->GetCurrentEntry(); - else - pEntry = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(GetCurrentParaStyleName()); - return GetPropertyFromStyleSheet(eId, pEntry, /*bDocDefaults=*/true, /*bPara=*/true); -} - -uno::Any DomainMapper_Impl::GetPropertyFromCharStyleSheet(PropertyIds eId, const PropertyMapPtr& rContext) -{ - if ( m_bInStyleSheetImport || eId == PROP_CHAR_STYLE_NAME || !isCharacterProperty(eId) ) - return uno::Any(); - - StyleSheetEntryPtr pEntry; - OUString sCharStyleName; - if ( GetAnyProperty(PROP_CHAR_STYLE_NAME, rContext) >>= sCharStyleName ) - pEntry = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(sCharStyleName); - return GetPropertyFromStyleSheet(eId, pEntry, /*bDocDefaults=*/false, /*bPara=*/false); -} - -uno::Any DomainMapper_Impl::GetAnyProperty(PropertyIds eId, const PropertyMapPtr& rContext) -{ - // first look in directly applied attributes - if ( rContext ) - { - std::optional<PropertyMap::Property> aProperty = rContext->getProperty(eId); - if ( aProperty ) - return aProperty->second; - } - - // then look whether it was inherited from a directly applied character style - if ( eId != PROP_CHAR_STYLE_NAME && isCharacterProperty(eId) ) - { - uno::Any aRet = GetPropertyFromCharStyleSheet(eId, rContext); - if ( aRet.hasValue() ) - return aRet; - } - - // then look in current paragraph style, and docDefaults - return GetPropertyFromParaStyleSheet(eId); -} - -OUString DomainMapper_Impl::GetListStyleName(sal_Int32 nListId) -{ - auto const pList(GetListTable()->GetList( nListId )); - return pList ? pList->GetStyleName() : OUString(); -} - -ListsManager::Pointer const & DomainMapper_Impl::GetListTable() -{ - if(!m_pListTable) - m_pListTable = - 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: - // See SwWW8ImplReader::HandlePageBreakChar(), page break should be - // ignored inside tables. - if (m_nTableDepth > 0) - return; - - 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::clearDeferredBreak(BreakType deferredBreakType) -{ - switch (deferredBreakType) - { - case COLUMN_BREAK: - m_bIsColumnBreakDeferred = false; - break; - case PAGE_BREAK: - m_bIsPageBreakDeferred = false; - break; - default: - break; - } -} - -void DomainMapper_Impl::clearDeferredBreaks() -{ - m_bIsColumnBreakDeferred = false; - m_bIsPageBreakDeferred = false; -} - -void DomainMapper_Impl::setSdtEndDeferred(bool bSdtEndDeferred) -{ - m_bSdtEndDeferred = bSdtEndDeferred; -} - -bool DomainMapper_Impl::isSdtEndDeferred() const -{ - return m_bSdtEndDeferred; -} - -void DomainMapper_Impl::setParaSdtEndDeferred(bool bParaSdtEndDeferred) -{ - m_bParaSdtEndDeferred = bParaSdtEndDeferred; -} - -bool DomainMapper_Impl::isParaSdtEndDeferred() const -{ - return m_bParaSdtEndDeferred; -} - -static void lcl_MoveBorderPropertiesToFrame(std::vector<beans::PropertyValue>& rFrameProperties, - uno::Reference<text::XTextRange> const& xStartTextRange, - uno::Reference<text::XTextRange> const& xEndTextRange ) -{ - try - { - if (!xStartTextRange.is()) //rhbz#1077780 - return; - 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 ; - - static PropertyIds const 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 - }; - - for( size_t nProperty = 0; nProperty < SAL_N_ELEMENTS( aBorderProperties ); ++nProperty) - { - OUString sPropertyName = getPropertyName(aBorderProperties[nProperty]); - beans::PropertyValue aValue; - aValue.Name = sPropertyName; - aValue.Value = xTextRangeProperties->getPropertyValue(sPropertyName); - rFrameProperties.push_back(aValue); - if( nProperty < 4 ) - xTextRangeProperties->setPropertyValue( sPropertyName, uno::makeAny(table::BorderLine2())); - } - } - catch( const uno::Exception& ) - { - } -} - - -static void lcl_AddRangeAndStyle( - ParagraphPropertiesPtr const & pToBeSavedProperties, - uno::Reference< text::XTextAppend > const& xTextAppend, - const PropertyMapPtr& pPropertyMap, - TextAppendContext const & rAppendContext) -{ - uno::Reference<text::XParagraphCursor> xParaCursor( - xTextAppend->createTextCursorByRange( rAppendContext.xInsertPosition.is() ? rAppendContext.xInsertPosition : xTextAppend->getEnd()), uno::UNO_QUERY_THROW ); - pToBeSavedProperties->SetEndingRange(xParaCursor->getStart()); - xParaCursor->gotoStartOfParagraph( false ); - - pToBeSavedProperties->SetStartingRange(xParaCursor->getStart()); - if(pPropertyMap) - { - std::optional<PropertyMap::Property> aParaStyle = pPropertyMap->getProperty(PROP_PARA_STYLE_NAME); - if( aParaStyle ) - { - OUString sName; - aParaStyle->second >>= sName; - pToBeSavedProperties->SetParaStyleName(sName); - } - } -} - - -//define some default frame width - 0cm ATM: this allow the frame to be wrapped around the text -constexpr sal_Int32 DEFAULT_FRAME_MIN_WIDTH = 0; -constexpr sal_Int32 DEFAULT_FRAME_MIN_HEIGHT = 0; -constexpr sal_Int32 DEFAULT_VALUE = 0; - -void DomainMapper_Impl::CheckUnregisteredFrameConversion( ) -{ - if (m_aTextAppendStack.empty()) - return; - TextAppendContext& rAppendContext = m_aTextAppendStack.top(); - // n#779642: ignore fly frame inside table as it could lead to messy situations - if (!rAppendContext.pLastParagraphProperties) - return; - if (!rAppendContext.pLastParagraphProperties->IsFrameMode()) - return; - if (!hasTableManager()) - return; - if (getTableManager().isInTable()) - return; - try - { - StyleSheetEntryPtr pParaStyle = - GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(rAppendContext.pLastParagraphProperties->GetParaStyleName()); - - std::vector<beans::PropertyValue> aFrameProperties; - - if ( pParaStyle ) - { - const ParagraphProperties* pStyleProperties = dynamic_cast<const ParagraphProperties*>( pParaStyle->pProperties.get() ); - if (!pStyleProperties) - return; - sal_Int32 nWidth = - rAppendContext.pLastParagraphProperties->Getw() > 0 ? - rAppendContext.pLastParagraphProperties->Getw() : - pStyleProperties->Getw(); - bool bAutoWidth = nWidth < 1; - if( bAutoWidth ) - nWidth = DEFAULT_FRAME_MIN_WIDTH; - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_WIDTH), nWidth)); - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HEIGHT), - rAppendContext.pLastParagraphProperties->Geth() > 0 ? - rAppendContext.pLastParagraphProperties->Geth() : - pStyleProperties->Geth() > 0 ? pStyleProperties->Geth() : DEFAULT_FRAME_MIN_HEIGHT)); - - sal_Int16 nhRule = sal_Int16( - rAppendContext.pLastParagraphProperties->GethRule() >= 0 ? - rAppendContext.pLastParagraphProperties->GethRule() : - pStyleProperties->GethRule()); - if ( nhRule < 0 ) - { - if ( rAppendContext.pLastParagraphProperties->Geth() >= 0 || - pStyleProperties->GethRule() >= 0 ) - { - // [MS-OE376] Word uses a default value of "atLeast" for - // this attribute when the value of the h attribute is not 0. - nhRule = text::SizeType::MIN; - } - else - { - nhRule = text::SizeType::VARIABLE; - } - } - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SIZE_TYPE), nhRule)); - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_WIDTH_TYPE), bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX)); - - if (const std::optional<sal_Int16> nDirection = PopFrameDirection()) - { - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_FRM_DIRECTION), *nDirection)); - } - - sal_Int16 nHoriOrient = sal_Int16( - rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ? - rAppendContext.pLastParagraphProperties->GetxAlign() : - pStyleProperties->GetxAlign() >= 0 ? pStyleProperties->GetxAlign() : text::HoriOrientation::NONE ); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT), nHoriOrient)); - - //set a non negative default value - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT_POSITION), - rAppendContext.pLastParagraphProperties->IsxValid() ? - rAppendContext.pLastParagraphProperties->Getx() : - pStyleProperties->IsxValid() ? pStyleProperties->Getx() : DEFAULT_VALUE)); - - //Default the anchor in case FramePr_hAnchor is missing ECMA 17.3.1.11 - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT_RELATION), sal_Int16( - rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 ? - rAppendContext.pLastParagraphProperties->GethAnchor() : - pStyleProperties->GethAnchor() >=0 ? pStyleProperties->GethAnchor() : text::RelOrientation::FRAME ))); - - sal_Int16 nVertOrient = sal_Int16( - rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ? - rAppendContext.pLastParagraphProperties->GetyAlign() : - pStyleProperties->GetyAlign() >= 0 ? pStyleProperties->GetyAlign() : text::VertOrientation::NONE ); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT), nVertOrient)); - - //set a non negative default value - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_POSITION), - rAppendContext.pLastParagraphProperties->IsyValid() ? - rAppendContext.pLastParagraphProperties->Gety() : - pStyleProperties->IsyValid() ? pStyleProperties->Gety() : DEFAULT_VALUE)); - - //Default the anchor in case FramePr_vAnchor is missing ECMA 17.3.1.11 - if (rAppendContext.pLastParagraphProperties->GetWrap() == text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE && - pStyleProperties->GetWrap() == text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE) - { - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_RELATION), sal_Int16( - rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ? - rAppendContext.pLastParagraphProperties->GetvAnchor() : - pStyleProperties->GetvAnchor() >= 0 ? pStyleProperties->GetvAnchor() : text::RelOrientation::FRAME))); - } - else - { - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_RELATION), sal_Int16( - rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ? - rAppendContext.pLastParagraphProperties->GetvAnchor() : - pStyleProperties->GetvAnchor() >= 0 ? pStyleProperties->GetvAnchor() : text::RelOrientation::PAGE_PRINT_AREA))); - } - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SURROUND), - rAppendContext.pLastParagraphProperties->GetWrap() != text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE - ? rAppendContext.pLastParagraphProperties->GetWrap() - : pStyleProperties->GetWrap() != text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE - ? pStyleProperties->GetWrap() - : text::WrapTextMode_NONE )); - - /** FDO#73546 : distL & distR should be unsigned integers <Ecma 20.4.3.6> - Swapped the array elements 11,12 & 13,14 since 11 & 12 are - LEFT & RIGHT margins and 13,14 are TOP and BOTTOM margins respectively. - */ - sal_Int32 nRightDist; - sal_Int32 nLeftDist = nRightDist = - rAppendContext.pLastParagraphProperties->GethSpace() >= 0 ? - rAppendContext.pLastParagraphProperties->GethSpace() : - pStyleProperties->GethSpace() >= 0 ? pStyleProperties->GethSpace() : 0; - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_LEFT_MARGIN), nHoriOrient == text::HoriOrientation::LEFT ? 0 : nLeftDist)); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_RIGHT_MARGIN), nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nRightDist)); - - sal_Int32 nBottomDist; - sal_Int32 nTopDist = nBottomDist = - rAppendContext.pLastParagraphProperties->GetvSpace() >= 0 ? - rAppendContext.pLastParagraphProperties->GetvSpace() : - pStyleProperties->GetvSpace() >= 0 ? pStyleProperties->GetvSpace() : 0; - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_TOP_MARGIN), nVertOrient == text::VertOrientation::TOP ? 0 : nTopDist)); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_BOTTOM_MARGIN), nVertOrient == text::VertOrientation::BOTTOM ? 0 : nBottomDist)); - // If there is no fill, the Word default is 100% transparency. - // Otherwise CellColorHandler has priority, and this setting - // will be ignored. - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_BACK_COLOR_TRANSPARENCY), sal_Int32(100))); - - uno::Sequence<beans::PropertyValue> aGrabBag( comphelper::InitPropertySequence({ - { "ParaFrameProperties", uno::Any(rAppendContext.pLastParagraphProperties->IsFrameMode()) } - })); - aFrameProperties.push_back(comphelper::makePropertyValue("FrameInteropGrabBag", aGrabBag)); - - lcl_MoveBorderPropertiesToFrame(aFrameProperties, - rAppendContext.pLastParagraphProperties->GetStartingRange(), - rAppendContext.pLastParagraphProperties->GetEndingRange()); - } - else - { - sal_Int32 nWidth = rAppendContext.pLastParagraphProperties->Getw(); - bool bAutoWidth = nWidth < 1; - if( bAutoWidth ) - nWidth = DEFAULT_FRAME_MIN_WIDTH; - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_WIDTH), nWidth)); - - sal_Int16 nhRule = sal_Int16(rAppendContext.pLastParagraphProperties->GethRule()); - if ( nhRule < 0 ) - { - if ( rAppendContext.pLastParagraphProperties->Geth() >= 0 ) - { - // [MS-OE376] Word uses a default value of atLeast for - // this attribute when the value of the h attribute is not 0. - nhRule = text::SizeType::MIN; - } - else - { - nhRule = text::SizeType::VARIABLE; - } - } - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SIZE_TYPE), nhRule)); - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_WIDTH_TYPE), bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX)); - - sal_Int16 nHoriOrient = sal_Int16( - rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ? - rAppendContext.pLastParagraphProperties->GetxAlign() : - text::HoriOrientation::NONE ); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT), nHoriOrient)); - - sal_Int16 nVertOrient = sal_Int16( - rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ? - rAppendContext.pLastParagraphProperties->GetyAlign() : - text::VertOrientation::NONE ); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT), nVertOrient)); - - sal_Int32 nVertDist = rAppendContext.pLastParagraphProperties->GethSpace(); - if( nVertDist < 0 ) - nVertDist = 0; - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_LEFT_MARGIN), nVertOrient == text::VertOrientation::TOP ? 0 : nVertDist)); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_RIGHT_MARGIN), nVertOrient == text::VertOrientation::BOTTOM ? 0 : nVertDist)); - - sal_Int32 nHoriDist = rAppendContext.pLastParagraphProperties->GetvSpace(); - if( nHoriDist < 0 ) - nHoriDist = 0; - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_TOP_MARGIN), nHoriOrient == text::HoriOrientation::LEFT ? 0 : nHoriDist)); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_BOTTOM_MARGIN), nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nHoriDist)); - - if( rAppendContext.pLastParagraphProperties->Geth() > 0 ) - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HEIGHT), rAppendContext.pLastParagraphProperties->Geth())); - - if( rAppendContext.pLastParagraphProperties->IsxValid() ) - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT_POSITION), rAppendContext.pLastParagraphProperties->Getx())); - - if( rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 ) - aFrameProperties.push_back(comphelper::makePropertyValue("HoriOrientRelation", sal_Int16(rAppendContext.pLastParagraphProperties->GethAnchor()))); - - if( rAppendContext.pLastParagraphProperties->IsyValid() ) - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_POSITION), rAppendContext.pLastParagraphProperties->Gety())); - - if( rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ) - aFrameProperties.push_back(comphelper::makePropertyValue("VertOrientRelation", sal_Int16(rAppendContext.pLastParagraphProperties->GetvAnchor()))); - - if( rAppendContext.pLastParagraphProperties->GetWrap() >= text::WrapTextMode_NONE ) - aFrameProperties.push_back(comphelper::makePropertyValue("Surround", rAppendContext.pLastParagraphProperties->GetWrap())); - - 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 ); - } - catch( const uno::Exception& ) - { - } -} - -/// Check if the style or its parent has a list id, recursively. -static sal_Int32 lcl_getListId(const StyleSheetEntryPtr& rEntry, const StyleSheetTablePtr& rStyleTable, bool & rNumberingFromBaseStyle) -{ - const StyleSheetPropertyMap* pEntryProperties = dynamic_cast<const StyleSheetPropertyMap*>(rEntry->pProperties.get()); - if (!pEntryProperties) - return -1; - - sal_Int32 nListId = pEntryProperties->GetListId(); - // The style itself has a list id. - if (nListId >= 0) - return nListId; - - // The style has no parent. - if (rEntry->sBaseStyleIdentifier.isEmpty()) - return -1; - - const StyleSheetEntryPtr pParent = rStyleTable->FindStyleSheetByISTD(rEntry->sBaseStyleIdentifier); - // No such parent style or loop in the style hierarchy. - if (!pParent || pParent == rEntry) - return -1; - - rNumberingFromBaseStyle = true; - - return lcl_getListId(pParent, rStyleTable, rNumberingFromBaseStyle); -} - -void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, const bool bRemove, const bool bNoNumbering ) -{ - if (m_bDiscardHeaderFooter) - return; - - if (!m_aFieldStack.empty()) - { - FieldContextPtr pFieldContext = m_aFieldStack.back(); - if (pFieldContext && !pFieldContext->IsCommandCompleted()) - { - std::vector<OUString> aCommandParts = pFieldContext->GetCommandParts(); - if (!aCommandParts.empty() && aCommandParts[0] == "IF") - { - // Conditional text field conditions don't support linebreaks in Writer. - return; - } - } - - if (pFieldContext && pFieldContext->IsCommandCompleted()) - { - if (pFieldContext->GetFieldId() == FIELD_IF) - { - // Conditional text fields can't contain newlines, finish the paragraph later. - FieldParagraph aFinish{pPropertyMap, bRemove}; - pFieldContext->GetParagraphsToFinish().push_back(aFinish); - return; - } - } - } - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("finishParagraph"); -#endif - - m_nLastTableCellParagraphDepth = m_nTableCellDepth; - ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pPropertyMap.get() ); - if (m_aTextAppendStack.empty()) - return; - TextAppendContext& rAppendContext = m_aTextAppendStack.top(); - uno::Reference< text::XTextAppend > xTextAppend(rAppendContext.xTextAppend); -#ifdef DBG_UTIL - TagLogger::getInstance().attribute("isTextAppend", sal_uInt32(xTextAppend.is())); -#endif - - const StyleSheetEntryPtr pEntry = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( GetCurrentParaStyleName() ); - OSL_ENSURE( pEntry, "no style sheet found" ); - const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : nullptr); - bool isNumberingViaStyle(false); - bool isNumberingViaRule = pParaContext && pParaContext->GetListId() > -1; - sal_Int32 nListId = -1; - if ( !bRemove && pStyleSheetProperties && pParaContext ) - { - //apply numbering level/style to paragraph if it was set at the style, but only if the paragraph itself - //does not specify the numbering - const sal_Int16 nListLevel = pStyleSheetProperties->GetListLevel(); - if ( !bNoNumbering && !isNumberingViaRule && nListLevel >= 0 ) - pParaContext->Insert( PROP_NUMBERING_LEVEL, uno::makeAny(nListLevel), false ); - - bool bNumberingFromBaseStyle = false; - nListId = pEntry ? lcl_getListId(pEntry, GetStyleSheetTable(), bNumberingFromBaseStyle) : -1; - auto const pList(GetListTable()->GetList(nListId)); - if (pList && nListId >= 0 && !pParaContext->isSet(PROP_NUMBERING_STYLE_NAME)) - { - if ( bNoNumbering ) - pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny(OUString()) ); - else if ( !isNumberingViaRule ) - { - isNumberingViaStyle = true; - // Since LO7.0/tdf#131321 fixed the loss of numbering in styles, this OUGHT to be obsolete, - // but now other new/critical LO7.0 code expects it, and perhaps some corner cases still need it as well. - // So we skip it only for default outline styles, which are recognized by NumberingManager. - if (!GetCurrentParaStyleName().startsWith("Heading ") || nListLevel >= pList->GetDefaultParentLevels()) - pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny(pList->GetStyleName()), true ); - } - else if ( !pList->isOutlineNumbering(nListLevel) ) - { - // After ignoring anything related to the special Outline levels, - // we have direct numbering, as well as paragraph-style numbering. - // Apply the style if it uses the same list as the direct numbering, - // otherwise the directly-applied-to-paragraph status will be lost, - // and the priority of the numbering-style-indents will be lowered. tdf#133000 - if ( nListId == pParaContext->GetListId() ) - pParaContext->Insert( PROP_NUMBERING_STYLE_NAME, uno::makeAny(pList->GetStyleName()), true ); - } - } - - if ( isNumberingViaStyle ) - { - // When numbering is defined by the paragraph style, then the para-style indents have priority. - // But since import has just copied para-style's PROP_NUMBERING_STYLE_NAME directly onto the paragraph, - // the numbering indents now have the priority. - // So now import must also copy the para-style indents directly onto the paragraph to compensate. - std::optional<PropertyMap::Property> oProperty; - const StyleSheetEntryPtr pParent = (!pEntry->sBaseStyleIdentifier.isEmpty()) ? GetStyleSheetTable()->FindStyleSheetByISTD(pEntry->sBaseStyleIdentifier) : nullptr; - const StyleSheetPropertyMap* pParentProperties = dynamic_cast<const StyleSheetPropertyMap*>(pParent ? pParent->pProperties.get() : nullptr); - if (!pEntry->sBaseStyleIdentifier.isEmpty()) - { - oProperty = pStyleSheetProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT); - if ( oProperty - // If the numbering comes from a base style, indent of the base style has also priority. - || (bNumberingFromBaseStyle && pParentProperties && (oProperty = pParentProperties->getProperty(PROP_PARA_FIRST_LINE_INDENT))) ) - pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, oProperty->second, /*bOverwrite=*/false); - } - oProperty = pStyleSheetProperties->getProperty(PROP_PARA_LEFT_MARGIN); - if ( oProperty - || (bNumberingFromBaseStyle && pParentProperties && (oProperty = pParentProperties->getProperty(PROP_PARA_LEFT_MARGIN))) ) - pParaContext->Insert(PROP_PARA_LEFT_MARGIN, oProperty->second, /*bOverwrite=*/false); - - // We're inheriting properties from a numbering style. Make sure a possible right margin is inherited from the base style. - sal_Int32 nParaRightMargin; - if ( pParentProperties && (oProperty = pParentProperties->getProperty(PROP_PARA_RIGHT_MARGIN)) && (nParaRightMargin = oProperty->second.get<sal_Int32>()) != 0 ) - { - // If we're setting the right margin, we should set the first / left margin as well from the numbering style. - const sal_Int32 nFirstLineIndent = getNumberingProperty(nListId, nListLevel, "FirstLineIndent"); - const sal_Int32 nParaLeftMargin = getNumberingProperty(nListId, nListLevel, "IndentAt"); - if (nFirstLineIndent != 0) - pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false); - if (nParaLeftMargin != 0) - pParaContext->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false); - - pParaContext->Insert(PROP_PARA_RIGHT_MARGIN, uno::makeAny(nParaRightMargin), /*bOverwrite=*/false); - } - } - // Paragraph style based right paragraph indentation affects not paragraph style based lists in DOCX. - // Apply it as direct formatting, also left and first line indentation of numbering to keep them. - else if (isNumberingViaRule) - { - uno::Any aRightMargin = GetPropertyFromParaStyleSheet(PROP_PARA_RIGHT_MARGIN); - if ( aRightMargin != uno::Any() ) - { - pParaContext->Insert(PROP_PARA_RIGHT_MARGIN, aRightMargin, /*bOverwrite=*/false); - - sal_Int32 nListId2(static_cast<ParagraphPropertyMap*>(pPropertyMap.get())->GetListId()); - - const sal_Int32 nFirstLineIndent = getNumberingProperty(nListId2, nListLevel, "FirstLineIndent"); - const sal_Int32 nParaLeftMargin = getNumberingProperty(nListId2, nListLevel, "IndentAt"); - if (nFirstLineIndent != 0) - pParaContext->Insert(PROP_PARA_FIRST_LINE_INDENT, uno::makeAny(nFirstLineIndent), /*bOverwrite=*/false); - if (nParaLeftMargin != 0) - pParaContext->Insert(PROP_PARA_LEFT_MARGIN, uno::makeAny(nParaLeftMargin), /*bOverwrite=*/false); - } - } - } - - // apply AutoSpacing: it has priority over all other margin settings - // (note that numbering with autoSpacing is handled separately later on) - const bool bAllowAdjustments = !GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing(); - sal_Int32 nBeforeAutospacing = -1; - bool bIsAutoSet = pParaContext && pParaContext->isSet(PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING); - bool bIsZeroAutospacingWithoutTopmargin = false; - const bool bNoTopmargin = pParaContext && !pParaContext->isSet(PROP_PARA_TOP_MARGIN); - // apply INHERITED autospacing only if top margin is not set - if ( bIsAutoSet || bNoTopmargin ) - { - GetAnyProperty(PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING, pPropertyMap) >>= nBeforeAutospacing; - // tdf#137655 only w:beforeAutospacing=0 was specified, but not PARA_TOP_MARGIN - // (see default_spacing = -1 in processing of LN_CT_Spacing_beforeAutospacing) - if ( bNoTopmargin && nBeforeAutospacing == ConversionHelper::convertTwipToMM100(-1) ) - { - nBeforeAutospacing = 0; - bIsZeroAutospacingWithoutTopmargin = true; - } - } - if ( nBeforeAutospacing > -1 && pParaContext ) - { - if ( bAllowAdjustments && !bIsZeroAutospacingWithoutTopmargin ) - { - if ( GetIsFirstParagraphInShape() || - (GetIsFirstParagraphInSection() && GetSectionContext() && GetSectionContext()->IsFirstSection()) || - (m_bFirstParagraphInCell && m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth) ) - { - nBeforeAutospacing = 0; - // export requires grabbag to match top_margin, so keep them in sync - if ( bIsAutoSet ) - pParaContext->Insert( PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING, uno::makeAny( sal_Int32(0) ),true, PARA_GRAB_BAG ); - } - } - if ( !bIsZeroAutospacingWithoutTopmargin || (m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth) ) - pParaContext->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny(nBeforeAutospacing)); - } - - sal_Int32 nAfterAutospacing = -1; - bIsAutoSet = pParaContext && pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING); - bool bApplyAutospacing = bIsAutoSet || (pParaContext && !pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN)); - if ( bApplyAutospacing ) - GetAnyProperty(PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING, pPropertyMap) >>= nAfterAutospacing; - if ( nAfterAutospacing > -1 && pParaContext ) - { - pParaContext->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny(nAfterAutospacing)); - bApplyAutospacing = bAllowAdjustments; - } - else - bApplyAutospacing = false; - - // tell TableManager to reset the bottom margin if it determines that this is the cell's last paragraph. - if ( hasTableManager() && getTableManager().isInCell() ) - getTableManager().setCellLastParaAfterAutospacing( bApplyAutospacing ); - - if (xTextAppend.is() && pParaContext && hasTableManager() && !getTableManager().isIgnore()) - { - 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_doc_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(getPropertyName(PROP_CHAR_ESCAPEMENT)); - xParaProperties->setPropertyToDefault(getPropertyName(PROP_CHAR_HEIGHT)); - //handles (2) and part of (6) - pToBeSavedProperties = new ParagraphProperties(*pParaContext); - sal_Int32 nCount = xParaCursor->getString().getLength(); - pToBeSavedProperties->SetDropCapLength(nCount > 0 && nCount < 255 ? static_cast<sal_Int8>(nCount) : 1); - } - if( rAppendContext.pLastParagraphProperties ) - { - if( sal::static_int_cast<Id>(rAppendContext.pLastParagraphProperties->GetDropCap()) != NS_ooxml::LN_Value_doc_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 < SAL_MAX_INT8 ? static_cast<sal_Int8>(nLines) : 2; - aDrop.Count = rAppendContext.pLastParagraphProperties->GetDropCapLength(); - sal_Int32 nHSpace = rAppendContext.pLastParagraphProperties->GethSpace(); - aDrop.Distance = nHSpace > 0 && nHSpace < SAL_MAX_INT16 ? static_cast<sal_Int16>(nHSpace) : 0; - //completes (5) - if( pParaContext->IsFrameMode() ) - pToBeSavedProperties = new ParagraphProperties(*pParaContext); - } - else if(*rAppendContext.pLastParagraphProperties == *pParaContext ) - { - //handles (7) - rAppendContext.pLastParagraphProperties->SetEndingRange(rAppendContext.xInsertPosition.is() ? rAppendContext.xInsertPosition : xTextAppend->getEnd()); - bKeepLastParagraphProperties = true; - } - else - { - //handles (8)(9) and completes (6) - CheckUnregisteredFrameConversion( ); - - // If different frame properties are set on this paragraph, keep them. - if ( !bIsDropCap && pParaContext->IsFrameMode() ) - { - pToBeSavedProperties = new ParagraphProperties(*pParaContext); - lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap, rAppendContext); - } - } - } - else - { - // (1) doesn't need handling - - if( !bIsDropCap && pParaContext->IsFrameMode() ) - { - pToBeSavedProperties = new ParagraphProperties(*pParaContext); - lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap, rAppendContext); - } - } - std::vector<beans::PropertyValue> aProperties; - if (pPropertyMap) - { - aProperties = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(pPropertyMap->GetPropertyValues()); - } - // TODO: this *should* work for RTF but there are test failures, maybe rtftok doesn't distinguish between formatting for the paragraph marker and for the paragraph as a whole; needs investigation - if (pPropertyMap && IsOOXMLImport()) - { - // tdf#64222 filter out the "paragraph marker" formatting and - // set it as a separate paragraph property, not a empty hint at - // end of paragraph - std::vector<beans::NamedValue> charProperties; - for (auto it = aProperties.begin(); it != aProperties.end(); ) - { - // this condition isn't ideal but as it happens all - // RES_CHRATR_* have names that start with "Char" - if (it->Name.startsWith("Char")) - { - charProperties.emplace_back(it->Name, it->Value); - // as testN793262 demonstrates, font size in rPr must - // affect the paragraph size => also insert empty hint! -// it = aProperties.erase(it); - } - ++it; - } - if (!charProperties.empty()) - { - aProperties.push_back(beans::PropertyValue("ListAutoFormat", - 0, uno::makeAny(comphelper::containerToSequence(charProperties)), beans::PropertyState_DIRECT_VALUE)); - } - } - if( !bIsDropCap ) - { - if( aDrop.Lines > 1 ) - { - beans::PropertyValue aValue; - aValue.Name = getPropertyName(PROP_DROP_CAP_FORMAT); - aValue.Value <<= aDrop; - aProperties.push_back(aValue); - } - uno::Reference< text::XTextRange > xTextRange; - if (rAppendContext.xInsertPosition.is()) - { - xTextRange = xTextAppend->finishParagraphInsert( comphelper::containerToSequence(aProperties), rAppendContext.xInsertPosition ); - rAppendContext.xCursor->gotoNextParagraph(false); - if (rAppendContext.pLastParagraphProperties) - rAppendContext.pLastParagraphProperties->SetEndingRange(xTextRange->getEnd()); - } - else - { - uno::Reference<text::XTextCursor> xCursor; - if (m_bParaHadField && !m_bIsInComments && !xTOCMarkerCursor.is()) - { - // Workaround to make sure char props of the field are not lost. - // Not relevant for editeng-based comments. - // Not relevant for fields inside a TOC field. - xCursor = xTextAppend->getText()->createTextCursor(); - if (xCursor.is()) - xCursor->gotoEnd(false); - PropertyMapPtr pEmpty(new PropertyMap()); - appendTextPortion("X", pEmpty); - } - - // Check if top / bottom margin has to be updated, now that we know the numbering status of both the previous and - // the current text node. - auto itNumberingRules = std::find_if(aProperties.begin(), aProperties.end(), [](const beans::PropertyValue& rValue) - { - return rValue.Name == "NumberingRules"; - }); - - assert( isNumberingViaRule == (itNumberingRules != aProperties.end()) ); - isNumberingViaRule = (itNumberingRules != aProperties.end()); - if (m_xPreviousParagraph.is() && (isNumberingViaRule || isNumberingViaStyle)) - { - // This textnode has numbering. Look up the numbering style name of the current and previous paragraph. - OUString aCurrentNumberingName; - OUString aPreviousNumberingName; - if (isNumberingViaRule) - { - assert(itNumberingRules != aProperties.end() && "by definition itNumberingRules is valid if isNumberingViaRule is true"); - uno::Reference<container::XNamed> xCurrentNumberingRules(itNumberingRules->Value, uno::UNO_QUERY); - if (xCurrentNumberingRules.is()) - aCurrentNumberingName = xCurrentNumberingRules->getName(); - if (m_xPreviousParagraph.is()) - { - uno::Reference<container::XNamed> xPreviousNumberingRules(m_xPreviousParagraph->getPropertyValue("NumberingRules"), uno::UNO_QUERY); - if (xPreviousNumberingRules.is()) - aPreviousNumberingName = xPreviousNumberingRules->getName(); - } - } - else if ( m_xPreviousParagraph->getPropertySetInfo()->hasPropertyByName("NumberingStyleName") && - // don't update before tables - (m_nTableDepth == 0 || !m_bFirstParagraphInCell)) - { - aCurrentNumberingName = GetListStyleName(nListId); - m_xPreviousParagraph->getPropertyValue("NumberingStyleName") >>= aPreviousNumberingName; - } - - if (!aPreviousNumberingName.isEmpty() && aCurrentNumberingName == aPreviousNumberingName) - { - uno::Sequence<beans::PropertyValue> aPrevPropertiesSeq; - m_xPreviousParagraph->getPropertyValue("ParaInteropGrabBag") >>= aPrevPropertiesSeq; - auto aPrevProperties = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aPrevPropertiesSeq); - bool bParaAutoBefore = m_bParaAutoBefore || std::any_of(aPrevProperties.begin(), aPrevProperties.end(), [](const beans::PropertyValue& rValue) - { - return rValue.Name == "ParaTopMarginBeforeAutoSpacing"; - }); - // if style based spacing was set to auto in the previous paragraph, style of the actual paragraph must be the same - if (bParaAutoBefore && !m_bParaAutoBefore && m_xPreviousParagraph->getPropertySetInfo()->hasPropertyByName("ParaStyleName")) - { - auto itParaStyle = std::find_if(aProperties.begin(), aProperties.end(), [](const beans::PropertyValue& rValue) - { - return rValue.Name == "ParaStyleName"; - }); - bParaAutoBefore = itParaStyle != aProperties.end() && - m_xPreviousParagraph->getPropertyValue("ParaStyleName") == itParaStyle->Value; - } - // There was a previous textnode and it had the same numbering. - if (bParaAutoBefore) - { - // This before spacing is set to auto, set before space to 0. - auto itParaTopMargin = std::find_if(aProperties.begin(), aProperties.end(), [](const beans::PropertyValue& rValue) - { - return rValue.Name == "ParaTopMargin"; - }); - if (itParaTopMargin != aProperties.end()) - itParaTopMargin->Value <<= static_cast<sal_Int32>(0); - else - aProperties.push_back(comphelper::makePropertyValue("ParaTopMargin", static_cast<sal_Int32>(0))); - } - - bool bPrevParaAutoAfter = std::any_of(aPrevProperties.begin(), aPrevProperties.end(), [](const beans::PropertyValue& rValue) - { - return rValue.Name == "ParaBottomMarginAfterAutoSpacing"; - }); - if (bPrevParaAutoAfter) - { - // Previous after spacing is set to auto, set previous after space to 0. - m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", uno::makeAny(static_cast<sal_Int32>(0))); - } - } - } - - xTextRange = xTextAppend->finishParagraph( comphelper::containerToSequence(aProperties) ); - m_xPreviousParagraph.set(xTextRange, uno::UNO_QUERY); - - if (m_xPreviousParagraph.is() && // null for SvxUnoTextBase - (isNumberingViaStyle || isNumberingViaRule)) - { - assert(dynamic_cast<ParagraphPropertyMap*>(pPropertyMap.get())); - // Use lcl_getListId(), so we find the list ID in parent styles as well. - bool bNumberingFromBaseStyle = false; - sal_Int32 const nListId2( isNumberingViaStyle - ? lcl_getListId(pEntry, GetStyleSheetTable(), bNumberingFromBaseStyle) - : static_cast<ParagraphPropertyMap*>(pPropertyMap.get())->GetListId()); - if (ListDef::Pointer const& pList = m_pListTable->GetList(nListId2)) - { // styles could refer to non-existing lists... - AbstractListDef::Pointer const& pAbsList = - pList->GetAbstractDefinition(); - if (pAbsList && - // SvxUnoTextRange doesn't have ListId - m_xPreviousParagraph->getPropertySetInfo()->hasPropertyByName("ListId")) - { - OUString paraId; - m_xPreviousParagraph->getPropertyValue("ListId") >>= paraId; - if (!paraId.isEmpty()) // must be on some list? - { - OUString const listId = pAbsList->MapListId(paraId); - if (listId != paraId) - { - m_xPreviousParagraph->setPropertyValue("ListId", uno::makeAny(listId)); - } - } - } - if (pList->GetCurrentLevel()) - { - sal_Int16 nOverrideLevel = pList->GetCurrentLevel()->GetStartOverride(); - if (nOverrideLevel != -1 && m_aListOverrideApplied.find(nListId2) == m_aListOverrideApplied.end()) - { - // Apply override: we have override instruction for this level - // And this was not done for this list before: we can do this only once on first occurrence - // of list with override - // TODO: Not tested variant with different levels override in different lists. - // Probably m_aListOverrideApplied as a set of overridden listids is not sufficient - // and we need to register level overrides separately. - m_xPreviousParagraph->setPropertyValue("ParaIsNumberingRestart", uno::makeAny(true)); - m_xPreviousParagraph->setPropertyValue("NumberingStartValue", uno::makeAny(nOverrideLevel)); - m_aListOverrideApplied.insert(nListId2); - } - } - } - } - - if (!rAppendContext.m_aAnchoredObjects.empty() && !IsInHeaderFooter()) - { - // Remember what objects are anchored to this paragraph. - // That list is only used for Word compat purposes, and - // it is only relevant for body text. - AnchoredObjectsInfo aInfo; - aInfo.m_xParagraph = xTextRange; - aInfo.m_aAnchoredObjects = rAppendContext.m_aAnchoredObjects; - m_aAnchoredObjectAnchors.push_back(aInfo); - rAppendContext.m_aAnchoredObjects.clear(); - } - - // We're no longer right after a table conversion. - m_bConvertedTable = false; - - if (xCursor.is()) - { - xCursor->goLeft(1, true); - xCursor->setString(OUString()); - } - } - getTableManager( ).handle(xTextRange); - m_aSmartTagHandler.handle(xTextRange); - - if (xTextRange.is()) - { - // Get the end of paragraph character inserted - uno::Reference< text::XTextCursor > xCur = xTextRange->getText( )->createTextCursor( ); - if (rAppendContext.xInsertPosition.is()) - xCur->gotoRange( rAppendContext.xInsertPosition, false ); - else - xCur->gotoEnd( false ); - - // tdf#77417 trim right white spaces in table cells in 2010 compatibility mode - sal_Int32 nMode = GetSettingsTable()->GetWordCompatibilityMode(); - if ( m_nTableDepth > 0 && nMode > 0 && nMode <= 14 ) - { - // skip new line - xCur->goLeft(1, false); - while ( xCur->goLeft(1, true) ) - { - OUString sChar = xCur->getString(); - if ( sChar == " " || sChar == "\t" || sChar == OUStringChar(u'\x00A0') ) - xCur->setString(""); - else - break; - } - xCur->goRight(2, false); - } - - xCur->goLeft( 1 , true ); - // Extend the redline ranges for empty paragraphs - if ( !m_bParaChanged && m_previousRedline ) - CreateRedline( xCur, m_previousRedline ); - CheckParaMarkerRedline( xCur ); - } - - css::uno::Reference<css::beans::XPropertySet> xParaProps(xTextRange, uno::UNO_QUERY); - - // table style precedence and not hidden shapes anchored to hidden empty table paragraphs - if (xParaProps && (m_nTableDepth > 0 || !m_aAnchoredObjectAnchors.empty()) ) - { - // table style has got bigger precedence than docDefault style - // collect these pending paragraph properties to process in endTable() - uno::Reference<text::XTextCursor> xCur = xTextRange->getText( )->createTextCursor( ); - xCur->gotoEnd(false); - xCur->goLeft(1, false); - uno::Reference<text::XTextCursor> xCur2 = xTextRange->getText()->createTextCursorByRange(xCur); - uno::Reference<text::XParagraphCursor> xParaCursor(xCur2, uno::UNO_QUERY_THROW); - xParaCursor->gotoStartOfParagraph(false); - if (m_nTableDepth > 0) - { - TableParagraph aPending{xParaCursor, xCur, pParaContext, xParaProps, std::set<OUString>()}; - getTableManager().getCurrentParagraphs()->push_back(aPending); - } - - // hidden empty paragraph with a not hidden shape, set as not hidden - std::optional<PropertyMap::Property> pHidden; - if ( !m_aAnchoredObjectAnchors.empty() && (pHidden = pParaContext->getProperty(PROP_CHAR_HIDDEN)) ) - { - bool bIsHidden = {}; // -Werror=maybe-uninitialized - pHidden->second >>= bIsHidden; - if (bIsHidden) - { - bIsHidden = false; - pHidden = GetTopContext()->getProperty(PROP_CHAR_HIDDEN); - if (pHidden) - pHidden->second >>= bIsHidden; - if (!bIsHidden) - { - uno::Reference<text::XTextCursor> xCur3 = xTextRange->getText()->createTextCursorByRange(xParaCursor); - xCur3->goRight(1, true); - if (xCur3->getString() == SAL_NEWLINE_STRING) - { - uno::Reference< beans::XPropertySet > xProp( xCur3, uno::UNO_QUERY ); - xProp->setPropertyValue(getPropertyName(PROP_CHAR_HIDDEN), uno::makeAny(false)); - } - } - } - } - } - - // tdf#118521 set paragraph top or bottom margin based on the paragraph style - // if we already set the other margin with direct formatting - if (xParaProps) - { - const bool bTopSet = pParaContext->isSet(PROP_PARA_TOP_MARGIN); - const bool bBottomSet = pParaContext->isSet(PROP_PARA_BOTTOM_MARGIN); - const bool bContextSet = pParaContext->isSet(PROP_PARA_CONTEXT_MARGIN); - if ( bTopSet != bBottomSet || bBottomSet != bContextSet ) - { - - if ( !bTopSet ) - { - uno::Any aMargin = GetPropertyFromParaStyleSheet(PROP_PARA_TOP_MARGIN); - if ( aMargin != uno::Any() ) - xParaProps->setPropertyValue("ParaTopMargin", aMargin); - } - if ( !bBottomSet ) - { - uno::Any aMargin = GetPropertyFromParaStyleSheet(PROP_PARA_BOTTOM_MARGIN); - if ( aMargin != uno::Any() ) - xParaProps->setPropertyValue("ParaBottomMargin", aMargin); - } - if ( !bContextSet ) - { - uno::Any aMargin = GetPropertyFromParaStyleSheet(PROP_PARA_CONTEXT_MARGIN); - if ( aMargin != uno::Any() ) - xParaProps->setPropertyValue("ParaContextMargin", aMargin); - } - } - } - - // Left, Right, and Hanging settings are also grouped. Ensure that all or none are set. - if (xParaProps) - { - const bool bLeftSet = pParaContext->isSet(PROP_PARA_LEFT_MARGIN); - const bool bRightSet = pParaContext->isSet(PROP_PARA_RIGHT_MARGIN); - const bool bFirstSet = pParaContext->isSet(PROP_PARA_FIRST_LINE_INDENT); - if ( bLeftSet != bRightSet || bRightSet != bFirstSet ) - { - if ( !bLeftSet ) - { - uno::Any aMargin = GetPropertyFromParaStyleSheet(PROP_PARA_LEFT_MARGIN); - if ( aMargin != uno::Any() ) - xParaProps->setPropertyValue("ParaLeftMargin", aMargin); - else if (isNumberingViaStyle) - { - const sal_Int32 nParaLeftMargin = getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), "IndentAt"); - if (nParaLeftMargin != 0) - xParaProps->setPropertyValue("ParaLeftMargin", uno::makeAny(nParaLeftMargin)); - } - } - if ( !bRightSet ) - { - uno::Any aMargin = GetPropertyFromParaStyleSheet(PROP_PARA_RIGHT_MARGIN); - if ( aMargin != uno::Any() ) - xParaProps->setPropertyValue("ParaRightMargin", aMargin); - } - if ( !bFirstSet ) - { - uno::Any aMargin = GetPropertyFromParaStyleSheet(PROP_PARA_FIRST_LINE_INDENT); - if ( aMargin != uno::Any() ) - xParaProps->setPropertyValue("ParaFirstLineIndent", aMargin); - else if (isNumberingViaStyle) - { - const sal_Int32 nFirstLineIndent = getNumberingProperty(nListId, pStyleSheetProperties->GetListLevel(), "FirstLineIndent"); - if (nFirstLineIndent != 0) - xParaProps->setPropertyValue("ParaFirstLineIndent", uno::makeAny(nFirstLineIndent)); - } - } - } - } - - // fix table paragraph properties - if ( xTextRange.is() && xParaProps && m_nTableDepth > 0 ) - { - uno::Sequence< beans::PropertyValue > aParaProps = pParaContext->GetPropertyValues(false); - uno::Reference<text::XTextCursor> xCur = xTextRange->getText()->createTextCursorByRange(xTextRange); - uno::Reference< beans::XPropertyState > xRunProperties( xCur, uno::UNO_QUERY_THROW ); - // tdf#90069 in tables, apply paragraph level character style also on - // paragraph level to support its copy during insertion of new table rows - for( const auto& rParaProp : std::as_const(aParaProps) ) - { - if ( rParaProp.Name.startsWith("Char") && rParaProp.Name != "CharStyleName" && rParaProp.Name != "CharInteropGrabBag" && - // all text portions contain the same value, so next setPropertyValue() won't overwrite part of them - xRunProperties->getPropertyState(rParaProp.Name) == css::beans::PropertyState_DIRECT_VALUE ) - { - uno::Reference<beans::XPropertySet> xRunPropertySet(xCur, uno::UNO_QUERY); - xParaProps->setPropertyValue( rParaProp.Name, xRunPropertySet->getPropertyValue(rParaProp.Name) ); - // remember this for table style handling - getTableManager().getCurrentParagraphs()->back().m_aParaOverrideApplied.insert(rParaProp.Name); - } - } - - // tdf#128959 table paragraphs haven't got window and orphan controls - uno::Any aAny = uno::makeAny(static_cast<sal_Int8>(0)); - xParaProps->setPropertyValue("ParaOrphans", aAny); - xParaProps->setPropertyValue("ParaWidows", aAny); - } - } - if( !bKeepLastParagraphProperties ) - rAppendContext.pLastParagraphProperties = pToBeSavedProperties; - } - catch(const lang::IllegalArgumentException&) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "DomainMapper_Impl::finishParagraph" ); - } - catch(const uno::Exception&) - { - TOOLS_WARN_EXCEPTION( "writerfilter.dmapper", "finishParagraph()" ); - } - - } - - bool bIgnoreFrameState = IsInHeaderFooter(); - if( (!bIgnoreFrameState && pParaContext && pParaContext->IsFrameMode()) || (bIgnoreFrameState && GetIsPreviousParagraphFramed()) ) - SetIsPreviousParagraphFramed(true); - else - SetIsPreviousParagraphFramed(false); - - m_bRemoveThisParagraph = false; - if( !IsInHeaderFooter() && !IsInShape() && (!pParaContext || !pParaContext->IsFrameMode()) ) - { // If the paragraph is in a frame, shape or header/footer, it's not a paragraph of the section itself. - SetIsFirstParagraphInSection(false); - // don't count an empty deleted paragraph as first paragraph in section to avoid of - // the deletion of the next empty paragraph later, resulting loss of the associated page break - if (!m_previousRedline || m_bParaChanged) - { - SetIsFirstParagraphInSectionAfterRedline(false); - SetIsLastParagraphInSection(false); - } - } - m_previousRedline.clear(); - m_bParaChanged = false; - - if (m_bIsFirstParaInShape) - m_bIsFirstParaInShape = false; - - if (pParaContext) - { - // Reset the frame properties for the next paragraph - pParaContext->ResetFrameProperties(); - } - - SetIsOutsideAParagraph(true); - m_bParaHadField = false; - - // don't overwrite m_bFirstParagraphInCell in table separator nodes - // and in text boxes anchored to the first paragraph of table cells - if (m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth && !IsInShape()) - m_bFirstParagraphInCell = false; - - m_bParaAutoBefore = false; - m_bParaWithInlineObject = false; - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif - -} - -void DomainMapper_Impl::appendTextPortion( const OUString& rString, const PropertyMapPtr& pPropertyMap ) -{ - if (m_bDiscardHeaderFooter) - return; - - if (m_aTextAppendStack.empty()) - return; - // Before placing call to processDeferredCharacterProperties(), TopContextType should be CONTEXT_CHARACTER - // processDeferredCharacterProperties() invokes only if character inserted - if( pPropertyMap == m_pTopContext && !deferredCharacterProperties.empty() && (GetTopContextType() == CONTEXT_CHARACTER) ) - processDeferredCharacterProperties(); - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if (!xTextAppend.is() || !hasTableManager() || getTableManager().isIgnore()) - return; - - try - { - // If we are in comments, then disable CharGrabBag, comment text doesn't support that. - uno::Sequence< beans::PropertyValue > aValues = pPropertyMap->GetPropertyValues(/*bCharGrabBag=*/!m_bIsInComments); - - if (m_bStartTOC || m_bStartIndex || m_bStartBibliography) - for( auto& rValue : aValues ) - { - if (rValue.Name == "CharHidden") - rValue.Value <<= false; - } - - uno::Reference< text::XTextRange > xTextRange; - if (m_aTextAppendStack.top().xInsertPosition.is()) - { - xTextRange = xTextAppend->insertTextPortion(rString, aValues, m_aTextAppendStack.top().xInsertPosition); - m_aTextAppendStack.top().xCursor->gotoRange(xTextRange->getEnd(), true); - } - else - { - if (m_bStartTOC || m_bStartIndex || m_bStartBibliography || m_nStartGenericField != 0) - { - if (IsInHeaderFooter() && !m_bStartTOCHeaderFooter) - { - xTextRange = xTextAppend->appendTextPortion(rString, aValues); - } - else - { - m_bStartedTOC = true; - uno::Reference< text::XTextCursor > xTOCTextCursor = xTextAppend->getEnd()->getText( )->createTextCursor( ); - assert(xTOCTextCursor.is()); - xTOCTextCursor->gotoEnd(false); - if (m_nStartGenericField != 0) - { - xTOCTextCursor->goLeft(1, false); - } - xTextRange = xTextAppend->insertTextPortion(rString, aValues, xTOCTextCursor); - SAL_WARN_IF(!xTextRange.is(), "writerfilter.dmapper", "insertTextPortion failed"); - if (!xTextRange.is()) - throw uno::Exception("insertTextPortion failed", nullptr); - m_bTextInserted = true; - xTOCTextCursor->gotoRange(xTextRange->getEnd(), true); - if (m_nStartGenericField == 0) - { - m_aTextAppendStack.push(TextAppendContext(xTextAppend, xTOCTextCursor)); - } - } - } - else - { -#if !defined(MACOSX) // TODO: check layout differences and support all platforms, if needed - sal_Int32 nPos = 0; - OUString sFontName; - OUString sDoubleSpace(" "); - PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_CHARACTER); - // tdf#123703 workaround for longer space sequences of the old or compatible RTF documents - if (GetSettingsTable()->GetLongerSpaceSequence() && !IsOpenFieldCommand() && (nPos = rString.indexOf(sDoubleSpace)) != -1 && - // monospaced fonts have no longer space sequences, regardless of \fprq2 (not monospaced) font setting - // fix for the base monospaced font Courier - (!pContext || !pContext->isSet(PROP_CHAR_FONT_NAME) || - ((pContext->getProperty(PROP_CHAR_FONT_NAME)->second >>= sFontName) && sFontName.indexOf("Courier") == -1))) - { - // an RTF space character is longer by an extra six-em-space in an old-style RTF space sequence, - // insert them to keep RTF document layout formatted by consecutive spaces - const sal_Unicode aExtraSpace[5] = { 0x2006, 0x20, 0x2006, 0x20, 0 }; - const sal_Unicode aExtraSpace2[4] = { 0x20, 0x2006, 0x20, 0 }; - xTextRange = xTextAppend->appendTextPortion(rString.replaceAll(sDoubleSpace, aExtraSpace, nPos) - .replaceAll(sDoubleSpace, aExtraSpace2, nPos), aValues); - } - else -#endif - xTextRange = xTextAppend->appendTextPortion(rString, aValues); - } - } - - // reset moveFrom data of non-terminating runs of the paragraph - if ( m_pParaMarkerRedlineMoveFrom ) - { - m_pParaMarkerRedlineMoveFrom.clear(); - } - CheckRedline( xTextRange ); - m_bParaChanged = true; - - //getTableManager( ).handle(xTextRange); - } - catch(const lang::IllegalArgumentException&) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "DomainMapper_Impl::appendTextPortion" ); - } - catch(const uno::Exception&) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "DomainMapper_Impl::appendTextPortion" ); - } -} - -void DomainMapper_Impl::appendTextContent( - const uno::Reference< text::XTextContent >& xContent, - const uno::Sequence< beans::PropertyValue >& xPropertyValues - ) -{ - SAL_WARN_IF(m_aTextAppendStack.empty(), "writerfilter.dmapper", "no text append stack"); - if (m_aTextAppendStack.empty()) - return; - 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() || !hasTableManager() || getTableManager().isIgnore()) - return; - - try - { - if (m_aTextAppendStack.top().xInsertPosition.is()) - xTextAppendAndConvert->insertTextContentWithProperties( xContent, xPropertyValues, m_aTextAppendStack.top().xInsertPosition ); - else - xTextAppendAndConvert->appendTextContent( xContent, xPropertyValues ); - } - catch(const lang::IllegalArgumentException&) - { - } - catch(const uno::Exception&) - { - } -} - -void DomainMapper_Impl::appendOLE( const OUString& rStreamName, const std::shared_ptr<OLEHandler>& pOLEHandler ) -{ - try - { - uno::Reference< text::XTextContent > xOLE( m_xTextFactory->createInstance("com.sun.star.text.TextEmbeddedObject"), uno::UNO_QUERY_THROW ); - uno::Reference< beans::XPropertySet > xOLEProperties(xOLE, uno::UNO_QUERY_THROW); - - OUString aCLSID = pOLEHandler->getCLSID(m_xComponentContext); - if (aCLSID.isEmpty()) - xOLEProperties->setPropertyValue(getPropertyName( PROP_STREAM_NAME ), - uno::makeAny( rStreamName )); - else - xOLEProperties->setPropertyValue("CLSID", uno::makeAny(aCLSID)); - - OUString aDrawAspect = pOLEHandler->GetDrawAspect(); - if(!aDrawAspect.isEmpty()) - xOLEProperties->setPropertyValue("DrawAspect", uno::makeAny(aDrawAspect)); - - awt::Size aSize = pOLEHandler->getSize(); - if( !aSize.Width ) - aSize.Width = 1000; - if( !aSize.Height ) - aSize.Height = 1000; - xOLEProperties->setPropertyValue(getPropertyName( PROP_WIDTH ), - uno::makeAny(aSize.Width)); - xOLEProperties->setPropertyValue(getPropertyName( PROP_HEIGHT ), - uno::makeAny(aSize.Height)); - - OUString aVisAreaWidth = pOLEHandler->GetVisAreaWidth(); - if(!aVisAreaWidth.isEmpty()) - xOLEProperties->setPropertyValue("VisibleAreaWidth", uno::makeAny(aVisAreaWidth)); - - OUString aVisAreaHeight = pOLEHandler->GetVisAreaHeight(); - if(!aVisAreaHeight.isEmpty()) - xOLEProperties->setPropertyValue("VisibleAreaHeight", uno::makeAny(aVisAreaHeight)); - - uno::Reference< graphic::XGraphic > xGraphic = pOLEHandler->getReplacement(); - xOLEProperties->setPropertyValue(getPropertyName( PROP_GRAPHIC ), - uno::makeAny(xGraphic)); - uno::Reference<beans::XPropertySet> xReplacementProperties(pOLEHandler->getShape(), uno::UNO_QUERY); - if (xReplacementProperties.is()) - { - table::BorderLine2 aBorderProps; - xReplacementProperties->getPropertyValue("LineColor") >>= aBorderProps.Color; - xReplacementProperties->getPropertyValue("LineWidth") >>= aBorderProps.LineWidth; - xReplacementProperties->getPropertyValue("LineStyle") >>= aBorderProps.LineStyle; - - if (aBorderProps.LineStyle) // Set line props only if LineStyle is set - { - xOLEProperties->setPropertyValue("RightBorder", uno::Any(aBorderProps)); - xOLEProperties->setPropertyValue("TopBorder", uno::Any(aBorderProps)); - xOLEProperties->setPropertyValue("LeftBorder", uno::Any(aBorderProps)); - xOLEProperties->setPropertyValue("BottomBorder", uno::Any(aBorderProps)); - } - OUString pProperties[] = { - "AnchorType", - "Surround", - "SurroundContour", - "HoriOrient", - "HoriOrientPosition", - "VertOrient", - "VertOrientPosition", - "VertOrientRelation", - "HoriOrientRelation", - "LeftMargin", - "RightMargin", - "TopMargin", - "BottomMargin" - }; - for (const OUString& s : pProperties) - { - const uno::Any aVal = xReplacementProperties->getPropertyValue(s); - xOLEProperties->setPropertyValue(s, aVal); - } - - if (xReplacementProperties->getPropertyValue("FillStyle").get<css::drawing::FillStyle>() - != css::drawing::FillStyle::FillStyle_NONE) // Apply fill props if style is set - { - xOLEProperties->setPropertyValue( - "FillStyle", xReplacementProperties->getPropertyValue("FillStyle")); - xOLEProperties->setPropertyValue( - "FillColor", xReplacementProperties->getPropertyValue("FillColor")); - xOLEProperties->setPropertyValue( - "FillColor2", xReplacementProperties->getPropertyValue("FillColor2")); - } - } - else - // mimic the treatment of graphics here... it seems anchoring as character - // gives a better ( visually ) result - xOLEProperties->setPropertyValue(getPropertyName( PROP_ANCHOR_TYPE ), uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) ); - // remove ( if valid ) associated shape ( used for graphic replacement ) - SAL_WARN_IF(m_aAnchoredStack.empty(), "writerfilter.dmapper", "no anchor stack"); - if (!m_aAnchoredStack.empty()) - m_aAnchoredStack.top( ).bToRemove = true; - RemoveLastParagraph(); - SAL_WARN_IF(m_aTextAppendStack.empty(), "writerfilter.dmapper", "no text stack"); - if (!m_aTextAppendStack.empty()) - m_aTextAppendStack.pop(); - - appendTextContent( xOLE, uno::Sequence< beans::PropertyValue >() ); - - if (!aCLSID.isEmpty()) - pOLEHandler->importStream(m_xComponentContext, GetTextDocument(), xOLE); - - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "in creation of OLE object" ); - } - -} - -void DomainMapper_Impl::appendStarMath( const Value& val ) -{ - uno::Reference< embed::XEmbeddedObject > formula; - val.getAny() >>= formula; - if( !formula.is() ) - return; - - try - { - uno::Reference< text::XTextContent > xStarMath( m_xTextFactory->createInstance("com.sun.star.text.TextEmbeddedObject"), uno::UNO_QUERY_THROW ); - uno::Reference< beans::XPropertySet > xStarMathProperties(xStarMath, uno::UNO_QUERY_THROW); - - xStarMathProperties->setPropertyValue(getPropertyName( PROP_EMBEDDED_OBJECT ), - val.getAny()); - // tdf#66405: set zero margins for embedded object - xStarMathProperties->setPropertyValue(getPropertyName( PROP_LEFT_MARGIN ), - uno::makeAny(sal_Int32(0))); - xStarMathProperties->setPropertyValue(getPropertyName( PROP_RIGHT_MARGIN ), - uno::makeAny(sal_Int32(0))); - xStarMathProperties->setPropertyValue(getPropertyName( PROP_TOP_MARGIN ), - uno::makeAny(sal_Int32(0))); - xStarMathProperties->setPropertyValue(getPropertyName( PROP_BOTTOM_MARGIN ), - uno::makeAny(sal_Int32(0))); - - uno::Reference< uno::XInterface > xInterface( formula->getComponent(), uno::UNO_QUERY ); - // set zero margins for object's component - uno::Reference< beans::XPropertySet > xComponentProperties( xInterface, uno::UNO_QUERY_THROW ); - xComponentProperties->setPropertyValue(getPropertyName( PROP_LEFT_MARGIN ), - uno::makeAny(sal_Int32(0))); - xComponentProperties->setPropertyValue(getPropertyName( PROP_RIGHT_MARGIN ), - uno::makeAny(sal_Int32(0))); - xComponentProperties->setPropertyValue(getPropertyName( PROP_TOP_MARGIN ), - uno::makeAny(sal_Int32(0))); - xComponentProperties->setPropertyValue(getPropertyName( PROP_BOTTOM_MARGIN ), - uno::makeAny(sal_Int32(0))); - Size size( 1000, 1000 ); - if( oox::FormulaImportBase* formulaimport = dynamic_cast< oox::FormulaImportBase* >( xInterface.get())) - size = formulaimport->getFormulaSize(); - xStarMathProperties->setPropertyValue(getPropertyName( PROP_WIDTH ), - uno::makeAny( sal_Int32(size.Width()))); - xStarMathProperties->setPropertyValue(getPropertyName( PROP_HEIGHT ), - uno::makeAny( sal_Int32(size.Height()))); - xStarMathProperties->setPropertyValue(getPropertyName(PROP_ANCHOR_TYPE), - uno::makeAny(text::TextContentAnchorType_AS_CHARACTER)); - // mimic the treatment of graphics here... it seems anchoring as character - // gives a better ( visually ) result - appendTextContent(xStarMath, uno::Sequence<beans::PropertyValue>()); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "in creation of StarMath object" ); - } -} - -void DomainMapper_Impl::adjustLastPara(sal_Int8 nAlign) -{ - PropertyMapPtr pLastPara = GetTopContextOfType(dmapper::CONTEXT_PARAGRAPH); - pLastPara->Insert(PROP_PARA_ADJUST, uno::makeAny(nAlign), true); -} - -uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter( - uno::Reference< text::XTextRange > const & xBefore ) -{ - uno::Reference< beans::XPropertySet > xRet; - if (m_aTextAppendStack.empty()) - return 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 ); - if (m_aTextAppendStack.top().xInsertPosition.is()) - xCursor->gotoRange( m_aTextAppendStack.top().xInsertPosition, true ); - else - xCursor->gotoEnd( true ); - //the paragraph after this new section is already inserted - xCursor->goLeft(1, true); - css::uno::Reference<css::text::XTextRange> xTextRange(xCursor, css::uno::UNO_QUERY_THROW); - - if (css::uno::Reference<css::text::XDocumentIndexesSupplier> xIndexSupplier{ - GetTextDocument(), css::uno::UNO_QUERY }) - { - css::uno::Reference<css::text::XTextRangeCompare> xCompare( - xTextAppend, css::uno::UNO_QUERY); - const auto xIndexAccess = xIndexSupplier->getDocumentIndexes(); - for (sal_Int32 i = xIndexAccess->getCount(); i > 0; --i) - { - if (css::uno::Reference<css::text::XDocumentIndex> xIndex{ - xIndexAccess->getByIndex(i - 1), css::uno::UNO_QUERY }) - { - const auto xIndexTextRange = xIndex->getAnchor(); - if (xCompare->compareRegionStarts(xTextRange, xIndexTextRange) == 0 - && xCompare->compareRegionEnds(xTextRange, xIndexTextRange) == 0) - { - // The boundaries coincide with an index: trying to attach a section - // to the range will insert the section inside the index. goRight will - // extend the range outside of the index, so that created section will - // be around it. Alternatively we could return index section itself - // instead : xRet.set(xIndex, uno::UNO_QUERY) - to set its properties, - // like columns/fill. - xCursor->goRight(1, true); - break; - } - } - } - } - - uno::Reference< text::XTextContent > xSection( m_xTextFactory->createInstance("com.sun.star.text.TextSection"), uno::UNO_QUERY_THROW ); - xSection->attach( xTextRange ); - xRet.set(xSection, uno::UNO_QUERY ); - } - catch(const uno::Exception&) - { - } - - } - - return xRet; -} - -void DomainMapper_Impl::appendGlossaryEntry() -{ - appendTextSectionAfter(m_xGlossaryEntryStart); -} - -void DomainMapper_Impl::PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType) -{ - m_bSaveParaHadField = m_bParaHadField; - m_aHeaderFooterStack.push(HeaderFooterContext(m_bTextInserted, m_nTableDepth)); - m_bTextInserted = false; - m_nTableDepth = 0; - - const PropertyIds ePropIsOn = bHeader? PROP_HEADER_IS_ON: PROP_FOOTER_IS_ON; - const PropertyIds ePropShared = bHeader? PROP_HEADER_IS_SHARED: PROP_FOOTER_IS_SHARED; - const PropertyIds ePropTextLeft = bHeader? PROP_HEADER_TEXT_LEFT: PROP_FOOTER_TEXT_LEFT; - const PropertyIds ePropText = bHeader? PROP_HEADER_TEXT: PROP_FOOTER_TEXT; - - m_bDiscardHeaderFooter = true; - m_eInHeaderFooterImport - = bHeader ? HeaderFooterImportState::header : HeaderFooterImportState::footer; - - //get the section context - PropertyMapPtr pContext = DomainMapper_Impl::GetTopContextOfType(CONTEXT_SECTION); - //ask for the header/footer name of the given type - SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() ); - if(!pSectionContext) - return; - - // clear the "Link To Previous" flag so that the header/footer - // content is not copied from the previous section - pSectionContext->ClearHeaderFooterLinkToPrevious(bHeader, eType); - - if (!m_bIsNewDoc) - { - return; // TODO sw cannot Undo insert header/footer without crashing - } - - uno::Reference< beans::XPropertySet > xPageStyle = - pSectionContext->GetPageStyle( - *this, - eType == SectionPropertyMap::PAGE_FIRST ); - if (!xPageStyle.is()) - return; - try - { - bool bLeft = eType == SectionPropertyMap::PAGE_LEFT; - bool bFirst = eType == SectionPropertyMap::PAGE_FIRST; - if ((!bLeft && !GetSettingsTable()->GetEvenAndOddHeaders()) || (GetSettingsTable()->GetEvenAndOddHeaders())) - { - //switch on header/footer use - xPageStyle->setPropertyValue( - getPropertyName(ePropIsOn), - uno::makeAny(true)); - - // If the 'Different Even & Odd Pages' flag is turned on - do not ignore it - // Even if the 'Even' header/footer is blank - the flag should be imported (so it would look in LO like in Word) - if (!bFirst && GetSettingsTable()->GetEvenAndOddHeaders()) - xPageStyle->setPropertyValue(getPropertyName(ePropShared), uno::makeAny(false)); - - //set the interface - uno::Reference< text::XText > xText; - xPageStyle->getPropertyValue(getPropertyName(bLeft? ePropTextLeft: ePropText)) >>= xText; - - m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >(xText, uno::UNO_QUERY_THROW), - m_bIsNewDoc - ? uno::Reference<text::XTextCursor>() - : xText->createTextCursorByRange(xText->getStart()))); - m_bDiscardHeaderFooter = false; // set only on success! - } - } - catch( const uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION("writerfilter.dmapper"); - } -} - -void DomainMapper_Impl::PushPageHeader(SectionPropertyMap::PageType eType) -{ - PushPageHeaderFooter(/* bHeader = */ true, eType); -} - -void DomainMapper_Impl::PushPageFooter(SectionPropertyMap::PageType eType) -{ - PushPageHeaderFooter(/* bHeader = */ false, eType); -} - -void DomainMapper_Impl::PopPageHeaderFooter() -{ - //header and footer always have an empty paragraph at the end - //this has to be removed - RemoveLastParagraph( ); - - if (!m_aTextAppendStack.empty()) - { - if (!m_bDiscardHeaderFooter) - { - m_aTextAppendStack.pop(); - } - m_bDiscardHeaderFooter = false; - } - m_eInHeaderFooterImport = HeaderFooterImportState::none; - - if (!m_aHeaderFooterStack.empty()) - { - m_bTextInserted = m_aHeaderFooterStack.top().getTextInserted(); - m_nTableDepth = m_aHeaderFooterStack.top().getTableDepth(); - m_aHeaderFooterStack.pop(); - } - - m_bParaHadField = m_bSaveParaHadField; -} - -void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote ) -{ - SAL_WARN_IF(m_bInFootOrEndnote, "writerfilter.dmapper", "PushFootOrEndnote() is called from another foot or endnote"); - m_bInFootOrEndnote = true; - m_bInFootnote = bIsFootnote; - m_bCheckFirstFootnoteTab = true; - m_bSaveFirstParagraphInCell = m_bFirstParagraphInCell; - try - { - // Redlines outside the footnote should not affect footnote content - m_aRedlines.push(std::vector< RedlineParamsPtr >()); - - // IMHO character styles from footnote labels should be ignored in the edit view of Writer. - // This adds a hack on top of the following hack to save the style name in the context. - PropertyMapPtr pTopContext = GetTopContext(); - OUString sFootnoteCharStyleName; - std::optional< PropertyMap::Property > aProp = pTopContext->getProperty(PROP_CHAR_STYLE_NAME); - if (aProp) - aProp->second >>= sFootnoteCharStyleName; - - // Remove style reference, if any. This reference did appear here as a side effect of tdf#43017 - // Seems it is not required by LO, but causes side effects during editing. So remove it - // for footnotes/endnotes to restore original LO behavior here. - pTopContext->Erase(PROP_CHAR_STYLE_NAME); - - uno::Reference< text::XText > xFootnoteText; - if (GetTextFactory().is()) - xFootnoteText.set( GetTextFactory()->createInstance( - bIsFootnote ? - OUString( "com.sun.star.text.Footnote" ) : OUString( "com.sun.star.text.Endnote" )), - uno::UNO_QUERY_THROW ); - uno::Reference< text::XFootnote > xFootnote( xFootnoteText, uno::UNO_QUERY_THROW ); - pTopContext->SetFootnote(xFootnote, sFootnoteCharStyleName); - uno::Sequence< beans::PropertyValue > aFontProperties = pTopContext->GetPropertyValues(); - appendTextContent( uno::Reference< text::XTextContent >( xFootnoteText, uno::UNO_QUERY_THROW ), aFontProperties ); - m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xFootnoteText, uno::UNO_QUERY_THROW ), - xFootnoteText->createTextCursorByRange(xFootnoteText->getStart()))); - - // Redlines for the footnote anchor in the main text content - std::vector< RedlineParamsPtr > aFootnoteRedline = std::move(m_aRedlines.top()); - m_aRedlines.pop(); - CheckRedline( xFootnote->getAnchor( ) ); - m_aRedlines.push( aFootnoteRedline ); - - // Try scanning for custom footnote labels - if (!sFootnoteCharStyleName.isEmpty()) - StartCustomFootnote(pTopContext); - else - EndCustomFootnote(); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION("writerfilter.dmapper", "PushFootOrEndnote"); - } -} - -void DomainMapper_Impl::CreateRedline(uno::Reference<text::XTextRange> const& xRange, - const RedlineParamsPtr& pRedline) -{ - if ( !pRedline ) - return; - - try - { - OUString sType; - switch ( pRedline->m_nToken & 0xffff ) - { - case XML_mod: - sType = getPropertyName( PROP_FORMAT ); - break; - case XML_moveTo: - case XML_ins: - sType = getPropertyName( PROP_INSERT ); - break; - case XML_moveFrom: - m_pParaMarkerRedlineMoveFrom = pRedline.get(); - [[fallthrough]]; - case XML_del: - sType = getPropertyName( PROP_DELETE ); - break; - case XML_ParagraphFormat: - sType = getPropertyName( PROP_PARAGRAPH_FORMAT ); - break; - default: - throw lang::IllegalArgumentException("illegal redline token type", nullptr, 0); - } - beans::PropertyValues aRedlineProperties( 3 ); - beans::PropertyValue * pRedlineProperties = aRedlineProperties.getArray( ); - pRedlineProperties[0].Name = getPropertyName( PROP_REDLINE_AUTHOR ); - pRedlineProperties[0].Value <<= pRedline->m_sAuthor; - pRedlineProperties[1].Name = getPropertyName( PROP_REDLINE_DATE_TIME ); - pRedlineProperties[1].Value <<= ConversionHelper::ConvertDateStringToDateTime( pRedline->m_sDate ); - pRedlineProperties[2].Name = getPropertyName( PROP_REDLINE_REVERT_PROPERTIES ); - pRedlineProperties[2].Value <<= pRedline->m_aRevertProperties; - if (!m_bIsActualParagraphFramed) - { - uno::Reference < text::XRedline > xRedline( xRange, uno::UNO_QUERY_THROW ); - xRedline->makeRedline( sType, aRedlineProperties ); - } - // store frame and (possible floating) table redline data for restoring them after frame conversion - enum StoredRedlines eType; - if (m_bIsActualParagraphFramed || (hasTableManager() && getTableManager().isInTable())) - eType = StoredRedlines::FRAME; - else if (IsInFootOrEndnote()) - eType = IsInFootnote() ? StoredRedlines::FOOTNOTE : StoredRedlines::ENDNOTE; - else - eType = StoredRedlines::NONE; - - if (eType != StoredRedlines::NONE) - { - m_aStoredRedlines[eType].push_back( uno::makeAny(xRange) ); - m_aStoredRedlines[eType].push_back( uno::makeAny(sType) ); - m_aStoredRedlines[eType].push_back( uno::makeAny(aRedlineProperties) ); - } - } - catch( const uno::Exception & ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "in makeRedline" ); - } -} - -void DomainMapper_Impl::CheckParaMarkerRedline( uno::Reference< text::XTextRange > const& xRange ) -{ - if ( m_pParaMarkerRedline ) - { - CreateRedline( xRange, m_pParaMarkerRedline ); - if ( m_pParaMarkerRedline ) - { - m_pParaMarkerRedline.clear(); - m_currentRedline.clear(); - } - } - else if ( m_pParaMarkerRedlineMoveFrom ) - { - // terminating moveFrom redline removes also the paragraph mark - m_pParaMarkerRedlineMoveFrom->m_nToken = XML_del; - CreateRedline( xRange, m_pParaMarkerRedlineMoveFrom ); - } - if ( m_pParaMarkerRedlineMoveFrom ) - { - m_pParaMarkerRedlineMoveFrom.clear(); - } -} - -void DomainMapper_Impl::CheckRedline( uno::Reference< text::XTextRange > const& xRange ) -{ - // Writer core "officially" does not like overlapping redlines, and its UNO interface is stupid enough - // to not prevent that. However, in practice in fact everything appears to work fine (except for the debug warnings - // about redline table corruption, which may possibly be harmless in reality). So leave this as it is, since this - // is a better representation of how the changes happened. If this will ever become a problem, overlapping redlines - // will need to be merged into one, just like doing the changes in the UI does, which will lose some information - // (and so if that happens, it may be better to fix Writer). - // Create the redlines here from lowest (formats) to highest (inserts/removals) priority, since the last one is - // what Writer presents graphically, so this will show deletes as deleted text and not as just formatted text being there. - bool bUsedRange = m_aRedlines.top().size() > 0 || (GetTopContextOfType(CONTEXT_CHARACTER) && - GetTopContextOfType(CONTEXT_CHARACTER)->Redlines().size() > 0); - - // only export ParagraphFormat, when there is no other redline in the same text portion to avoid missing redline compression, - // but always export the first ParagraphFormat redline in a paragraph to keep the paragraph style change data for rejection - if( (!bUsedRange || !m_bParaChanged) && GetTopContextOfType(CONTEXT_PARAGRAPH) ) - { - std::vector<RedlineParamsPtr>& avRedLines = GetTopContextOfType(CONTEXT_PARAGRAPH)->Redlines(); - for( const auto& rRedline : avRedLines ) - CreateRedline( xRange, rRedline ); - } - if( GetTopContextOfType(CONTEXT_CHARACTER) ) - { - std::vector<RedlineParamsPtr>& avRedLines = GetTopContextOfType(CONTEXT_CHARACTER)->Redlines(); - for( const auto& rRedline : avRedLines ) - CreateRedline( xRange, rRedline ); - } - for (const auto& rRedline : m_aRedlines.top() ) - CreateRedline( xRange, rRedline ); -} - -void DomainMapper_Impl::StartParaMarkerChange( ) -{ - m_bIsParaMarkerChange = true; -} - -void DomainMapper_Impl::EndParaMarkerChange( ) -{ - m_bIsParaMarkerChange = false; - m_previousRedline = m_currentRedline; - m_currentRedline.clear(); -} - -void DomainMapper_Impl::StartCustomFootnote(const PropertyMapPtr pContext) -{ - if (pContext == m_pFootnoteContext) - return; - - assert(pContext->GetFootnote().is()); - m_bHasFootnoteStyle = true; - m_bCheckFootnoteStyle = !pContext->GetFootnoteStyle().isEmpty(); - m_pFootnoteContext = pContext; -} - -void DomainMapper_Impl::EndCustomFootnote() -{ - m_bHasFootnoteStyle = false; - m_bCheckFootnoteStyle = false; -} - -void DomainMapper_Impl::PushAnnotation() -{ - try - { - m_bIsInComments = true; - if (!GetTextFactory().is()) - return; - m_xAnnotationField.set( GetTextFactory()->createInstance( "com.sun.star.text.TextField.Annotation" ), - uno::UNO_QUERY_THROW ); - uno::Reference< text::XText > xAnnotationText; - m_xAnnotationField->getPropertyValue("TextRange") >>= xAnnotationText; - m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xAnnotationText, uno::UNO_QUERY_THROW ), - m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : xAnnotationText->createTextCursorByRange(xAnnotationText->getStart()))); - } - catch( const uno::Exception&) - { - DBG_UNHANDLED_EXCEPTION("writerfilter.dmapper"); - } -} - -static void lcl_CopyRedlines( - uno::Reference< text::XText > const& xSrc, - std::deque<css::uno::Any>& rRedlines, - std::vector<sal_Int32>& redPos, - std::vector<sal_Int32>& redLen, - sal_Int32& redIdx) -{ - redIdx = -1; - for( size_t i = 0; i < rRedlines.size(); i+=3) - { - uno::Reference< text::XTextRange > xRange; - rRedlines[i] >>= xRange; - - // is this a redline of the temporary footnote? - uno::Reference<text::XTextCursor> xRangeCursor; - try - { - xRangeCursor = xSrc->createTextCursorByRange( xRange ); - } - catch( const uno::Exception& ) - { - } - if (xRangeCursor.is()) - { - redIdx = i; - sal_Int32 nLen = xRange->getString().getLength(); - redLen.push_back(nLen); - xRangeCursor->gotoRange(xSrc->getStart(), true); - redPos.push_back(xRangeCursor->getString().getLength() - nLen); - } - else - { - // we have already found all redlines of the footnote, - // skip checking the redlines of the other footnotes - if (redIdx > -1) - break; - // failed createTextCursorByRange(), for example, table inside the frame - redLen.push_back(-1); - redPos.push_back(-1); - } - } -} - -static void lcl_PasteRedlines( - uno::Reference< text::XText > const& xDest, - std::deque<css::uno::Any>& rRedlines, - std::vector<sal_Int32>& redPos, - std::vector<sal_Int32>& redLen, - sal_Int32& redIdx) -{ - // create redlines in the copied footnote - for( size_t i = 0; redIdx > -1 && i <= sal::static_int_cast<size_t>(redIdx); i+=3) - { - OUString sType; - beans::PropertyValues aRedlineProperties( 3 ); - // skip failed createTextCursorByRange() - if (redPos[i/3] == -1) - continue; - rRedlines[i+1] >>= sType; - rRedlines[i+2] >>= aRedlineProperties; - uno::Reference< text::XTextCursor > xCrsr = xDest->getText()->createTextCursor(); - xCrsr->goRight(redPos[i/3], false); - xCrsr->goRight(redLen[i/3], true); - uno::Reference < text::XRedline > xRedline( xCrsr, uno::UNO_QUERY_THROW ); - xRedline->makeRedline( sType, aRedlineProperties ); - } -} - -void DomainMapper_Impl::PopFootOrEndnote() -{ - // content of the footnotes were inserted after the first footnote in temporary footnotes, - // restore the content of the actual footnote by copying its content from the first - // (remaining) temporary footnote and remove the temporary footnote. - // FIXME: add footnote IDs to handle possible differences in footnote serialization - uno::Reference< text::XFootnotesSupplier> xFootnotesSupplier( GetTextDocument(), uno::UNO_QUERY ); - uno::Reference< text::XEndnotesSupplier> xEndnotesSupplier( GetTextDocument(), uno::UNO_QUERY ); - if ( IsInFootOrEndnote() && ( ( IsInFootnote() && GetFootnoteCount() > -1 && xFootnotesSupplier.is() ) || - ( !IsInFootnote() && GetEndnoteCount() > -1 && xEndnotesSupplier.is() ) ) ) - { - uno::Reference< text::XFootnote > xFootnoteFirst, xFootnoteLast; - auto xFootnotes = xFootnotesSupplier->getFootnotes(); - auto xEndnotes = xEndnotesSupplier->getEndnotes(); - if (IsInFootnote()) - xFootnotes->getByIndex(xFootnotes->getCount()-1) >>= xFootnoteLast; - else - xEndnotes->getByIndex(xEndnotes->getCount()-1) >>= xFootnoteLast; - if ( ( ( IsInFootnote() && xFootnotes->getCount() > 1 ) || - ( !IsInFootnote() && xEndnotes->getCount() > 1 ) ) && - xFootnoteLast->getLabel().isEmpty() ) - { - // copy content of the first remaining temporary footnote - if ( IsInFootnote() ) - xFootnotes->getByIndex(1) >>= xFootnoteFirst; - else - xEndnotes->getByIndex(1) >>= xFootnoteFirst; - uno::Reference< text::XText > xSrc( xFootnoteFirst, uno::UNO_QUERY_THROW ); - uno::Reference< text::XText > xDest( xFootnoteLast, uno::UNO_QUERY_THROW ); - uno::Reference< text::XTextCopy > xTxt, xTxt2; - xTxt.set( xSrc, uno::UNO_QUERY_THROW ); - xTxt2.set( xDest, uno::UNO_QUERY_THROW ); - xTxt2->copyText( xTxt ); - - // copy its redlines - std::vector<sal_Int32> redPos, redLen; - sal_Int32 redIdx; - enum StoredRedlines eType = IsInFootnote() ? StoredRedlines::FOOTNOTE : StoredRedlines::ENDNOTE; - lcl_CopyRedlines(xSrc, m_aStoredRedlines[eType], redPos, redLen, redIdx); - lcl_PasteRedlines(xDest, m_aStoredRedlines[eType], redPos, redLen, redIdx); - - // remove processed redlines - for( size_t i = 0; redIdx > -1 && i <= sal::static_int_cast<size_t>(redIdx) + 2; i++) - m_aStoredRedlines[eType].pop_front(); - - // remove temporary footnote - xFootnoteFirst->getAnchor()->setString(""); - } - } - - if (!IsRTFImport()) - RemoveLastParagraph(); - - // In case the foot or endnote did not contain a tab. - m_bIgnoreNextTab = false; - - if (!m_aTextAppendStack.empty()) - m_aTextAppendStack.pop(); - - if (m_aRedlines.size() == 1) - { - SAL_WARN("writerfilter.dmapper", "PopFootOrEndnote() is called without PushFootOrEndnote()?"); - return; - } - m_aRedlines.pop(); - m_eSkipFootnoteState = SkipFootnoteSeparator::OFF; - m_bInFootOrEndnote = false; - m_pFootnoteContext = nullptr; - m_bFirstParagraphInCell = m_bSaveFirstParagraphInCell; -} - -void DomainMapper_Impl::PopAnnotation() -{ - RemoveLastParagraph(); - - m_bIsInComments = false; - m_aTextAppendStack.pop(); - - try - { - // See if the annotation will be a single position or a range. - if (m_nAnnotationId == -1 || !m_aAnnotationPositions[m_nAnnotationId].m_xStart.is() || !m_aAnnotationPositions[m_nAnnotationId].m_xEnd.is()) - { - uno::Sequence< beans::PropertyValue > aEmptyProperties; - uno::Reference< text::XTextContent > xContent( m_xAnnotationField, uno::UNO_QUERY_THROW ); - appendTextContent( xContent, aEmptyProperties ); - CheckRedline( xContent->getAnchor( ) ); - } - else - { - AnnotationPosition& aAnnotationPosition = m_aAnnotationPositions[m_nAnnotationId]; - // Create a range that points to the annotation start/end. - uno::Reference<text::XText> const xText = aAnnotationPosition.m_xStart->getText(); - uno::Reference<text::XTextCursor> const xCursor = xText->createTextCursorByRange(aAnnotationPosition.m_xStart); - - bool bMarker = false; - uno::Reference<text::XTextRangeCompare> xTextRangeCompare(xText, uno::UNO_QUERY); - if (xTextRangeCompare->compareRegionStarts(aAnnotationPosition.m_xStart, aAnnotationPosition.m_xEnd) == 0) - { - // Insert a marker so that comment around an anchored image is not collapsed during - // insertion. - xText->insertString(xCursor, "x", false); - bMarker = true; - } - - xCursor->gotoRange(aAnnotationPosition.m_xEnd, true); - uno::Reference<text::XTextRange> const xTextRange(xCursor, uno::UNO_QUERY_THROW); - - // Attach the annotation to the range. - uno::Reference<text::XTextAppend> const xTextAppend = m_aTextAppendStack.top().xTextAppend; - xTextAppend->insertTextContent(xTextRange, uno::Reference<text::XTextContent>(m_xAnnotationField, uno::UNO_QUERY_THROW), !xCursor->isCollapsed()); - - if (bMarker) - { - // Remove the marker. - xCursor->goLeft(1, true); - xCursor->setString(OUString()); - } - } - m_aAnnotationPositions.erase( m_nAnnotationId ); - } - catch (uno::Exception const&) - { - TOOLS_WARN_EXCEPTION("writerfilter.dmapper", "Cannot insert annotation field"); - } - - m_xAnnotationField.clear(); - m_nAnnotationId = -1; -} - -void DomainMapper_Impl::PushPendingShape( const uno::Reference< drawing::XShape > & xShape ) -{ - m_aPendingShapes.push_back(xShape); -} - -uno::Reference<drawing::XShape> DomainMapper_Impl::PopPendingShape() -{ - uno::Reference<drawing::XShape> xRet; - if (!m_aPendingShapes.empty()) - { - xRet = m_aPendingShapes.front(); - m_aPendingShapes.pop_front(); - } - return xRet; -} - -void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape > & xShape ) -{ - // Append these early, so the context and the table manager stack will be - // in sync, even if the text append stack is empty. - appendTableManager(); - appendTableHandler(); - getTableManager().startLevel(); - - if (m_aTextAppendStack.empty()) - return; - uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend; - - try - { - uno::Reference< lang::XServiceInfo > xSInfo( xShape, uno::UNO_QUERY_THROW ); - if (xSInfo->supportsService("com.sun.star.drawing.GroupShape")) - { - // Textboxes in shapes do not support styles, so check saved style information and apply properties directly to the child shapes. - const uno::Reference<drawing::XShapes> xShapes(xShape, uno::UNO_QUERY); - const sal_uInt32 nShapeCount = xShapes.is() ? xShapes->getCount() : 0; - for ( sal_uInt32 i = 0; i < nShapeCount; ++i ) - { - try - { - uno::Reference<beans::XPropertySet> xSyncedPropertySet(xShapes->getByIndex(i), uno::UNO_QUERY_THROW); - comphelper::SequenceAsHashMap aGrabBag( xSyncedPropertySet->getPropertyValue("CharInteropGrabBag") ); - - // only VML import has checked for style. Don't apply default parastyle properties to other imported shapes - // - except for fontsize - to maintain compatibility with previous versions of LibreOffice. - const bool bOnlyApplyCharHeight = !aGrabBag["mso-pStyle"].hasValue(); - - OUString sStyleName; - aGrabBag["mso-pStyle"] >>= sStyleName; - StyleSheetEntryPtr pEntry = GetStyleSheetTable()->FindStyleSheetByISTD( sStyleName ); - if ( !pEntry ) - { - // Use default style even in ambiguous cases (where multiple styles were defined) since MOST styles inherit - // MOST of their properties from the default style. In the ambiguous case, we have to accept some kind of compromise - // and the default paragraph style ought to be the safest one... (compared to DocDefaults or program defaults) - pEntry = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( GetDefaultParaStyleName() ); - } - if ( pEntry ) - { - // The Ids here come from oox/source/vml/vmltextbox.cxx. - // It probably could safely expand to all Ids that shapes support. - const PropertyIds eIds[] = { - PROP_CHAR_HEIGHT, - PROP_CHAR_FONT_NAME, - PROP_CHAR_WEIGHT, - PROP_CHAR_CHAR_KERNING, - PROP_CHAR_COLOR, - PROP_PARA_ADJUST - }; - const uno::Reference<beans::XPropertyState> xSyncedPropertyState(xSyncedPropertySet, uno::UNO_QUERY_THROW); - for ( const auto& eId : eIds ) - { - try - { - if ( bOnlyApplyCharHeight && eId != PROP_CHAR_HEIGHT ) - continue; - - const OUString sPropName = getPropertyName(eId); - if ( beans::PropertyState_DEFAULT_VALUE == xSyncedPropertyState->getPropertyState(sPropName) ) - { - const uno::Any aProp = GetPropertyFromStyleSheet(eId, pEntry, /*bDocDefaults=*/true, /*bPara=*/true); - if ( aProp.hasValue() ) - xSyncedPropertySet->setPropertyValue( sPropName, aProp ); - } - } - catch (const uno::Exception&) - { - TOOLS_WARN_EXCEPTION( "writerfilter.dmapper", "PushShapeContext() text stylesheet property exception" ); - } - } - } - } - catch (const uno::Exception&) - { - TOOLS_WARN_EXCEPTION( "writerfilter.dmapper", "PushShapeContext()" ); - } - } - - // A GroupShape doesn't implement text::XTextRange, but appending - // an empty reference to the stacks still makes sense, because this - // way bToRemove can be set, and we won't end up with duplicated - // shapes for OLE objects. - m_aTextAppendStack.push(TextAppendContext(uno::Reference<text::XTextAppend>(xShape, uno::UNO_QUERY), uno::Reference<text::XTextCursor>())); - uno::Reference<text::XTextContent> xTxtContent(xShape, uno::UNO_QUERY); - m_aAnchoredStack.push(AnchoredContext(xTxtContent)); - } - else if (xSInfo->supportsService("com.sun.star.drawing.OLE2Shape")) - { - // OLE2Shape from oox should be converted to a TextEmbeddedObject for sw. - m_aTextAppendStack.push(TextAppendContext(uno::Reference<text::XTextAppend>(xShape, uno::UNO_QUERY), uno::Reference<text::XTextCursor>())); - uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY); - m_aAnchoredStack.push(AnchoredContext(xTextContent)); - uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY); - - m_xEmbedded.set(m_xTextFactory->createInstance("com.sun.star.text.TextEmbeddedObject"), uno::UNO_QUERY_THROW); - uno::Reference<beans::XPropertySet> xEmbeddedProperties(m_xEmbedded, uno::UNO_QUERY_THROW); - xEmbeddedProperties->setPropertyValue(getPropertyName(PROP_EMBEDDED_OBJECT), xShapePropertySet->getPropertyValue(getPropertyName(PROP_EMBEDDED_OBJECT))); - xEmbeddedProperties->setPropertyValue(getPropertyName(PROP_ANCHOR_TYPE), uno::makeAny(text::TextContentAnchorType_AS_CHARACTER)); - // So that the original bitmap-only shape will be replaced by the embedded object. - m_aAnchoredStack.top().bToRemove = true; - m_aTextAppendStack.pop(); - appendTextContent(m_xEmbedded, uno::Sequence<beans::PropertyValue>()); - } - else - { - uno::Reference< text::XTextRange > xShapeText( xShape, uno::UNO_QUERY_THROW); - // Add the shape to the text append stack - m_aTextAppendStack.push( TextAppendContext(uno::Reference< text::XTextAppend >( xShape, uno::UNO_QUERY_THROW ), - m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xShapeText->getStart() ))); - - // Add the shape to the anchored objects stack - uno::Reference< text::XTextContent > xTxtContent( xShape, uno::UNO_QUERY_THROW ); - m_aAnchoredStack.push( AnchoredContext(xTxtContent) ); - - uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW ); -#ifdef DBG_UTIL - TagLogger::getInstance().unoPropertySet(xProps); -#endif - text::TextContentAnchorType nAnchorType(text::TextContentAnchorType_AT_PARAGRAPH); - xProps->getPropertyValue(getPropertyName( PROP_ANCHOR_TYPE )) >>= nAnchorType; - bool checkZOrderStatus = false; - if (xSInfo->supportsService("com.sun.star.text.TextFrame")) - { - SetIsTextFrameInserted(true); - // Extract the special "btLr text frame" mode, requested by oox, if needed. - // Extract vml ZOrder from FrameInteropGrabBag - uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY); - uno::Sequence<beans::PropertyValue> aGrabBag; - xShapePropertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag; - - for (const auto& rProp : std::as_const(aGrabBag)) - { - if (rProp.Name == "VML-Z-ORDER") - { - GraphicZOrderHelper* pZOrderHelper = m_rDMapper.graphicZOrderHelper(); - sal_Int32 zOrder(0); - rProp.Value >>= zOrder; - xShapePropertySet->setPropertyValue( "ZOrder", uno::makeAny(pZOrderHelper->findZOrder(zOrder))); - pZOrderHelper->addItem(xShapePropertySet, zOrder); - xShapePropertySet->setPropertyValue(getPropertyName( PROP_OPAQUE ), uno::makeAny( zOrder >= 0 ) ); - checkZOrderStatus = true; - } - else if ( rProp.Name == "TxbxHasLink" ) - { - //Chaining of textboxes will happen in ~DomainMapper_Impl - //i.e when all the textboxes are read and all its attributes - //have been set ( basically the Name/LinkedDisplayName ) - //which is set in Graphic Import. - m_vTextFramesForChaining.push_back(xShape); - } - } - - uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY_THROW); - uno::Reference<text::XTextRange> xTextRange(xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW); - xTextAppend->insertTextContent(xTextRange, xTextContent, false); - - uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY); - // we need to re-set this value to xTextContent, then only values are preserved. - xPropertySet->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aGrabBag)); - } - else if (nAnchorType == text::TextContentAnchorType_AS_CHARACTER) - { - // Fix spacing for as-character objects. If the paragraph has CT_Spacing_after set, - // it needs to be set on the object too, as that's what object placement code uses. - PropertyMapPtr paragraphContext = GetTopContextOfType( CONTEXT_PARAGRAPH ); - std::optional<PropertyMap::Property> aPropMargin = paragraphContext->getProperty(PROP_PARA_BOTTOM_MARGIN); - if(aPropMargin) - xProps->setPropertyValue( getPropertyName( PROP_BOTTOM_MARGIN ), aPropMargin->second ); - } - else - { - uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY); - uno::Sequence<beans::PropertyValue> aGrabBag; - xShapePropertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag; - for (const auto& rProp : std::as_const(aGrabBag)) - { - if (rProp.Name == "VML-Z-ORDER") - { - GraphicZOrderHelper* pZOrderHelper = m_rDMapper.graphicZOrderHelper(); - sal_Int32 zOrder(0); - rProp.Value >>= zOrder; - xShapePropertySet->setPropertyValue( "ZOrder", uno::makeAny(pZOrderHelper->findZOrder(zOrder))); - pZOrderHelper->addItem(xShapePropertySet, zOrder); - xShapePropertySet->setPropertyValue(getPropertyName( PROP_OPAQUE ), uno::makeAny( zOrder >= 0 ) ); - checkZOrderStatus = true; - } - else if ( rProp.Name == "TxbxHasLink" ) - { - //Chaining of textboxes will happen in ~DomainMapper_Impl - //i.e when all the textboxes are read and all its attributes - //have been set ( basically the Name/LinkedDisplayName ) - //which is set in Graphic Import. - m_vTextFramesForChaining.push_back(xShape); - } - } - - if(IsSdtEndBefore()) - { - uno::Reference< beans::XPropertySetInfo > xPropSetInfo; - if(xShapePropertySet.is()) - { - xPropSetInfo = xShapePropertySet->getPropertySetInfo(); - if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("InteropGrabBag")) - { - uno::Sequence<beans::PropertyValue> aShapeGrabBag( comphelper::InitPropertySequence({ - { "SdtEndBefore", uno::Any(true) } - })); - xShapePropertySet->setPropertyValue("InteropGrabBag",uno::makeAny(aShapeGrabBag)); - } - } - } - } - if (!IsInHeaderFooter() && !checkZOrderStatus) - xProps->setPropertyValue( - getPropertyName( PROP_OPAQUE ), - uno::makeAny( true ) ); - } - m_bParaChanged = true; - getTableManager().setIsInShape(true); - } - catch ( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION("writerfilter.dmapper", "Exception when adding shape"); - } -} -/* - * Updating chart height and width after reading the actual values from wp:extent -*/ -void DomainMapper_Impl::UpdateEmbeddedShapeProps(const uno::Reference< drawing::XShape > & xShape) -{ - if (!xShape.is()) - return; - - uno::Reference<beans::XPropertySet> xEmbeddedProperties(m_xEmbedded, uno::UNO_QUERY_THROW); - awt::Size aSize = xShape->getSize( ); - xEmbeddedProperties->setPropertyValue(getPropertyName(PROP_WIDTH), uno::makeAny(sal_Int32(aSize.Width))); - xEmbeddedProperties->setPropertyValue(getPropertyName(PROP_HEIGHT), uno::makeAny(sal_Int32(aSize.Height))); -} - - -void DomainMapper_Impl::PopShapeContext() -{ - if (hasTableManager()) - { - getTableManager().endLevel(); - popTableManager(); - } - if ( m_aAnchoredStack.empty() ) - return; - - // For OLE object replacement shape, the text append context was already removed - // or the OLE object couldn't be inserted. - if ( !m_aAnchoredStack.top().bToRemove ) - { - RemoveLastParagraph(); - if (!m_aTextAppendStack.empty()) - m_aTextAppendStack.pop(); - } - - uno::Reference< text::XTextContent > xObj = m_aAnchoredStack.top( ).xTextContent; - try - { - appendTextContent( xObj, uno::Sequence< beans::PropertyValue >() ); - } - catch ( const uno::RuntimeException& ) - { - // this is normal: the shape is already attached - } - - const uno::Reference<drawing::XShape> xShape( xObj, uno::UNO_QUERY_THROW ); - // Remove the shape if required (most likely replacement shape for OLE object) - // or anchored to a discarded header or footer - if ( m_aAnchoredStack.top().bToRemove || m_bDiscardHeaderFooter ) - { - try - { - uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(m_xTextDocument, uno::UNO_QUERY_THROW); - uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage(); - if ( xDrawPage.is() ) - xDrawPage->remove( xShape ); - } - catch( const uno::Exception& ) - { - } - } - - // Relative width calculations deferred until section's margins are defined. - // Being cautious: only deferring undefined/minimum-width shapes in order to avoid causing potential regressions - css::awt::Size aShapeSize; - try - { - aShapeSize = xShape->getSize(); - } - catch (const css::uno::RuntimeException& e) - { - // May happen e.g. when text frame has no frame format - // See sw/qa/extras/ooxmlimport/data/n779627.docx - SAL_WARN("writerfilter.dmapper", "getSize failed. " << e.Message); - } - if( aShapeSize.Width <= 2 ) - { - const uno::Reference<beans::XPropertySet> xShapePropertySet( xShape, uno::UNO_QUERY ); - SectionPropertyMap* pSectionContext = GetSectionContext(); - if ( pSectionContext && (!hasTableManager() || !getTableManager().isInTable()) && - xShapePropertySet->getPropertySetInfo()->hasPropertyByName(getPropertyName(PROP_RELATIVE_WIDTH)) ) - { - pSectionContext->addRelativeWidthShape(xShape); - } - } - - m_aAnchoredStack.pop(); -} - -bool DomainMapper_Impl::IsSdtEndBefore() -{ - bool bIsSdtEndBefore = false; - PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_CHARACTER); - if(pContext) - { - const uno::Sequence< beans::PropertyValue > currentCharProps = pContext->GetPropertyValues(); - for (const auto& rCurrentCharProp : currentCharProps) - { - if (rCurrentCharProp.Name == "CharInteropGrabBag") - { - uno::Sequence<beans::PropertyValue> aCharGrabBag; - rCurrentCharProp.Value >>= aCharGrabBag; - for (const auto& rProp : std::as_const(aCharGrabBag)) - { - if(rProp.Name == "SdtEndBefore") - { - rProp.Value >>= bIsSdtEndBefore; - } - } - } - } - } - return bIsSdtEndBefore; -} - -bool DomainMapper_Impl::IsDiscardHeaderFooter() const -{ - return m_bDiscardHeaderFooter; -} - -// called from TableManager::closeCell() -void DomainMapper_Impl::ClearPreviousParagraph() -{ - // in table cells, set bottom auto margin of last paragraph to 0, except in paragraphs with numbering - if ((m_nTableDepth == (m_nTableCellDepth + 1)) - && m_xPreviousParagraph.is() - && hasTableManager() && getTableManager().isCellLastParaAfterAutospacing()) - { - uno::Reference<container::XNamed> xPreviousNumberingRules(m_xPreviousParagraph->getPropertyValue("NumberingRules"), uno::UNO_QUERY); - if ( !xPreviousNumberingRules.is() || xPreviousNumberingRules->getName().isEmpty() ) - m_xPreviousParagraph->setPropertyValue("ParaBottomMargin", uno::makeAny(static_cast<sal_Int32>(0))); - } - - m_xPreviousParagraph.clear(); - - // next table paragraph will be first paragraph in a cell - m_bFirstParagraphInCell = true; -} - -void DomainMapper_Impl::HandleAltChunk(const OUString& rStreamName) -{ - try - { - // Create the import filter. - uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory( - comphelper::getProcessServiceFactory()); - uno::Reference<uno::XInterface> xDocxFilter - = xMultiServiceFactory->createInstance("com.sun.star.comp.Writer.WriterFilter"); - - // Set the target document. - uno::Reference<document::XImporter> xImporter(xDocxFilter, uno::UNO_QUERY); - xImporter->setTargetDocument(m_xTextDocument); - - // Set the import parameters. - uno::Reference<embed::XHierarchicalStorageAccess> xStorageAccess(m_xDocumentStorage, - uno::UNO_QUERY); - if (!xStorageAccess.is()) - { - return; - } - // Turn the ZIP stream into a seekable one, as the importer only works with such streams. - uno::Reference<io::XStream> xStream = xStorageAccess->openStreamElementByHierarchicalName( - rStreamName, embed::ElementModes::READ); - std::unique_ptr<SvStream> pStream = utl::UcbStreamHelper::CreateStream(xStream, true); - SvMemoryStream aMemory; - aMemory.WriteStream(*pStream); - uno::Reference<io::XStream> xInputStream = new utl::OStreamWrapper(aMemory); - // Not handling AltChunk during paste for now. - uno::Reference<text::XTextRange> xInsertTextRange = GetCurrentXText()->getEnd(); - uno::Reference<text::XTextRange> xSectionStartingRange; - SectionPropertyMap* pSectionContext = GetSectionContext(); - if (pSectionContext) - { - xSectionStartingRange = pSectionContext->GetStartingRange(); - } - uno::Sequence<beans::PropertyValue> aDescriptor(comphelper::InitPropertySequence({ - { "InputStream", uno::Any(xInputStream) }, - { "InsertMode", uno::Any(true) }, - { "TextInsertModeRange", uno::Any(xInsertTextRange) }, - { "AltChunkMode", uno::Any(true) }, - { "AltChunkStartingRange", uno::Any(xSectionStartingRange) }, - })); - - // Do the actual import. - uno::Reference<document::XFilter> xFilter(xDocxFilter, uno::UNO_QUERY); - xFilter->filter(aDescriptor); - } - catch (const uno::Exception& rException) - { - SAL_WARN("writerfilter", "DomainMapper_Impl::HandleAltChunk: failed to handle alt chunk: " - << rException.Message); - } -} - -static sal_Int16 lcl_ParseNumberingType( const OUString& rCommand ) -{ - sal_Int16 nRet = style::NumberingType::PAGE_DESCRIPTOR; - - // The command looks like: " PAGE \* Arabic " - // tdf#132185: but may as well be "PAGE \* Arabic" - OUString sNumber; - constexpr OUStringLiteral rSeparator(u"\\* "); - if (sal_Int32 nStartIndex = rCommand.indexOf(rSeparator); nStartIndex >= 0) - { - nStartIndex += rSeparator.getLength(); - sNumber = rCommand.getToken(0, ' ', nStartIndex); - } - - if( !sNumber.isEmpty() ) - { - //todo: might make sense to hash this list, too - struct NumberingPairs - { - const 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(const NumberingPairs& rNumberingPair : aNumberingPairs) - { - if( /*sCommand*/sNumber.equalsAscii(rNumberingPair.cWordName )) - { - nRet = rNumberingPair.nType; - break; - } - } - - } - return nRet; -} - - -static OUString lcl_ParseFormat( const OUString& rCommand ) -{ - // The command looks like: " DATE \@"dd MMMM yyyy" or "09/02/2014" - // Remove whitespace permitted by standard between \@ and " - OUString command; - sal_Int32 delimPos = rCommand.indexOf("\\@"); - if (delimPos != -1) - { - sal_Int32 wsChars = rCommand.indexOf('\"') - delimPos - 2; - command = rCommand.replaceAt(delimPos+2, wsChars, ""); - } - else - command = rCommand; - - return msfilter::util::findQuotedText(command, "\\@\"", '\"'); -} -/*------------------------------------------------------------------------- -extract a parameter (with or without quotes) between the command and the following backslash - -----------------------------------------------------------------------*/ -static OUString lcl_ExtractToken(OUString const& rCommand, - sal_Int32 & rIndex, bool & rHaveToken, bool & rIsSwitch) -{ - rHaveToken = false; - rIsSwitch = false; - - OUStringBuffer token; - bool bQuoted(false); - for (; rIndex < rCommand.getLength(); ++rIndex) - { - sal_Unicode const currentChar(rCommand[rIndex]); - switch (currentChar) - { - case '\\': - { - if (rIndex == rCommand.getLength() - 1) - { - SAL_INFO("writerfilter.dmapper", "field: trailing escape"); - ++rIndex; - return OUString(); - } - sal_Unicode const nextChar(rCommand[rIndex+1]); - if (bQuoted || '\\' == nextChar) - { - ++rIndex; // read 2 chars - token.append(nextChar); - } - else // field switch (case insensitive) - { - rHaveToken = true; - if (token.isEmpty()) - { - rIsSwitch = true; - rIndex += 2; // read 2 chars - return rCommand.copy(rIndex - 2, 2).toAsciiUpperCase(); - } - else - { // leave rIndex, read it again next time - return token.makeStringAndClear(); - } - } - } - break; - case '\"': - if (bQuoted || !token.isEmpty()) - { - rHaveToken = true; - if (bQuoted) - { - ++rIndex; - } - return token.makeStringAndClear(); - } - else - { - bQuoted = true; - } - break; - case ' ': - if (bQuoted) - { - token.append(' '); - } - else - { - if (!token.isEmpty()) - { - rHaveToken = true; - ++rIndex; - return token.makeStringAndClear(); - } - } - break; - case '=': - if (token.isEmpty()) - { - rHaveToken = true; - ++rIndex; - return "FORMULA"; - } - else - token.append('='); - break; - default: - token.append(currentChar); - break; - } - } - assert(rIndex == rCommand.getLength()); - if (bQuoted) - { - // MS Word allows this, so just emit a debug message - SAL_INFO("writerfilter.dmapper", - "field argument with unterminated quote"); - } - rHaveToken = !token.isEmpty(); - return token.makeStringAndClear(); -} - -std::tuple<OUString, std::vector<OUString>, std::vector<OUString> > splitFieldCommand(const OUString& rCommand) -{ - OUString sType; - std::vector<OUString> arguments; - std::vector<OUString> switches; - sal_Int32 nStartIndex(0); - // tdf#54584: Field may be prepended by a backslash - // This is not an escapement, but already escaped literal "\" - // MS Word allows this, so just skip it - if ((rCommand.getLength() >= nStartIndex + 2) && - (rCommand[nStartIndex] == L'\\') && - (rCommand[nStartIndex + 1] != L'\\') && - (rCommand[nStartIndex + 1] != L' ')) - { - ++nStartIndex; - } - - do - { - bool bHaveToken; - bool bIsSwitch; - OUString const token = - lcl_ExtractToken(rCommand, nStartIndex, bHaveToken, bIsSwitch); - assert(nStartIndex <= rCommand.getLength()); - if (bHaveToken) - { - if (sType.isEmpty()) - { - sType = token.toAsciiUpperCase(); - } - else if (bIsSwitch || !switches.empty()) - { - switches.push_back(token); - } - else - { - arguments.push_back(token); - } - } - } while (nStartIndex < rCommand.getLength()); - - return std::make_tuple(sType, arguments, switches); -} - -static OUString lcl_ExtractVariableAndHint( const OUString& rCommand, 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' - if (nIndex == -1) - return OUString(); - while(rCommand[nIndex] == ' ') - ++nIndex; - OUString sShortCommand( rCommand.copy( nIndex ) ); //cut off the " ASK " - - sShortCommand = sShortCommand.getToken(0, '\\'); - nIndex = 0; - OUString sRet = sShortCommand.getToken( 0, ' ', nIndex); - if( nIndex > 0) - rHint = sShortCommand.copy( nIndex ); - if( rHint.isEmpty() ) - rHint = sRet; - return sRet; -} - - -static bool lcl_FindInCommand( - const OUString& rCommand, - sal_Unicode cSwitch, - OUString& rValue ) -{ - bool bRet = false; - OUString sSearch = "\\" + OUStringChar( 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() ; - if( nEndIndex - nIndex > 3 ) - rValue = rCommand.copy( nIndex + 3, nEndIndex - nIndex - 3); - } - return bRet; -} - - -void DomainMapper_Impl::GetCurrentLocale(lang::Locale& rLocale) -{ - PropertyMapPtr pTopContext = GetTopContext(); - std::optional<PropertyMap::Property> pLocale = pTopContext->getProperty(PROP_CHAR_LOCALE); - if( pLocale ) - pLocale->second >>= rLocale; - else - { - PropertyMapPtr pParaContext = GetTopContextOfType(CONTEXT_PARAGRAPH); - pLocale = pParaContext->getProperty(PROP_CHAR_LOCALE); - if( pLocale ) - { - pLocale->second >>= rLocale; - } - } -} - -/*------------------------------------------------------------------------- - extract the number format from the command and apply the resulting number - format to the XPropertySet - -----------------------------------------------------------------------*/ -void DomainMapper_Impl::SetNumberFormat( const OUString& rCommand, - uno::Reference< beans::XPropertySet > const& xPropertySet, - bool const bDetectFormat) -{ - OUString sFormatString = lcl_ParseFormat( rCommand ); - // find \h - hijri/luna calendar todo: what about saka/era calendar? - bool bHijri = 0 < rCommand.indexOf("\\h "); - lang::Locale aUSLocale; - aUSLocale.Language = "en"; - aUSLocale.Country = "US"; - - //determine current locale - todo: is it necessary to initialize this locale? - lang::Locale aCurrentLocale = aUSLocale; - GetCurrentLocale( aCurrentLocale ); - OUString sFormat = ConversionHelper::ConvertMSFormatStringToSO( sFormatString, aCurrentLocale, bHijri); - //get the number formatter and convert the string to a format value - try - { - sal_Int32 nKey = 0; - uno::Reference< util::XNumberFormatsSupplier > xNumberSupplier( m_xTextDocument, uno::UNO_QUERY_THROW ); - if( bDetectFormat ) - { - uno::Reference< util::XNumberFormatter> xFormatter(util::NumberFormatter::create(m_xComponentContext), uno::UNO_QUERY_THROW); - xFormatter->attachNumberFormatsSupplier( xNumberSupplier ); - nKey = xFormatter->detectNumberFormat( 0, rCommand ); - } - else - { - nKey = xNumberSupplier->getNumberFormats()->addNewConverted( sFormat, aUSLocale, aCurrentLocale ); - } - xPropertySet->setPropertyValue( - getPropertyName(PROP_NUMBER_FORMAT), - uno::makeAny( nKey )); - } - catch(const uno::Exception&) - { - } -} - -static uno::Any lcl_getGrabBagValue( const uno::Sequence<beans::PropertyValue>& grabBag, OUString const & name ) -{ - auto pProp = std::find_if(grabBag.begin(), grabBag.end(), - [&name](const beans::PropertyValue& rProp) { return rProp.Name == name; }); - if (pProp != grabBag.end()) - return pProp->Value; - return uno::Any(); -} - -//Link the text frames. -void DomainMapper_Impl::ChainTextFrames() -{ - //can't link textboxes if there are not even two of them... - if( 2 > m_vTextFramesForChaining.size() ) - return ; - - struct TextFramesForChaining { - css::uno::Reference< css::drawing::XShape > xShape; - sal_Int32 nId; - sal_Int32 nSeq; - OUString s_mso_next_textbox; - bool bShapeNameSet; - TextFramesForChaining(): nId(0), nSeq(0), bShapeNameSet(false) {} - } ; - typedef std::map <OUString, TextFramesForChaining> ChainMap; - - try - { - ChainMap aTextFramesForChainingHelper; - OUString sChainNextName("ChainNextName"); - - //learn about ALL of the textboxes and their chaining values first - because frames are processed in no specific order. - for( const auto& rTextFrame : m_vTextFramesForChaining ) - { - uno::Reference<text::XTextContent> xTextContent(rTextFrame, uno::UNO_QUERY_THROW); - uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY); - uno::Reference<beans::XPropertySetInfo> xPropertySetInfo; - if( xPropertySet.is() ) - xPropertySetInfo = xPropertySet->getPropertySetInfo(); - uno::Sequence<beans::PropertyValue> aGrabBag; - uno::Reference<lang::XServiceInfo> xServiceInfo(xPropertySet, uno::UNO_QUERY); - - TextFramesForChaining aChainStruct; - OUString sShapeName; - OUString sLinkChainName; - - //The chaining name and the shape name CAN be different in .docx. - //MUST use LinkDisplayName/ChainName as the shape name for establishing links. - if ( xServiceInfo->supportsService("com.sun.star.text.TextFrame") ) - { - xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag; - xPropertySet->getPropertyValue("LinkDisplayName") >>= sShapeName; - } - else - { - xPropertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag; - xPropertySet->getPropertyValue("ChainName") >>= sShapeName; - } - - lcl_getGrabBagValue( aGrabBag, "Txbx-Id") >>= aChainStruct.nId; - lcl_getGrabBagValue( aGrabBag, "Txbx-Seq") >>= aChainStruct.nSeq; - lcl_getGrabBagValue( aGrabBag, "LinkChainName") >>= sLinkChainName; - lcl_getGrabBagValue( aGrabBag, "mso-next-textbox") >>= aChainStruct.s_mso_next_textbox; - - //Sometimes the shape names have not been imported. If not, we may have a fallback name. - //Set name later, only if required for linking. - if( sShapeName.isEmpty() ) - aChainStruct.bShapeNameSet = false; - else - { - aChainStruct.bShapeNameSet = true; - sLinkChainName = sShapeName; - } - - if( !sLinkChainName.isEmpty() ) - { - aChainStruct.xShape = rTextFrame; - aTextFramesForChainingHelper[sLinkChainName] = aChainStruct; - } - } - - //if mso-next-textbox tags are provided, create those vml-style links first. Afterwards we will make dml-style id/seq links. - for (auto& msoItem : aTextFramesForChainingHelper) - { - //if no mso-next-textbox, we are done. - //if it points to itself, we are done. - if( !msoItem.second.s_mso_next_textbox.isEmpty() - && msoItem.second.s_mso_next_textbox != msoItem.first ) - { - ChainMap::iterator nextFinder=aTextFramesForChainingHelper.find(msoItem.second.s_mso_next_textbox); - if( nextFinder != aTextFramesForChainingHelper.end() ) - { - //if the frames have no name yet, then set them. LinkDisplayName / ChainName are read-only. - if( !msoItem.second.bShapeNameSet ) - { - uno::Reference< container::XNamed > xNamed( msoItem.second.xShape, uno::UNO_QUERY ); - if ( xNamed.is() ) - { - xNamed->setName( msoItem.first ); - msoItem.second.bShapeNameSet = true; - } - } - if( !nextFinder->second.bShapeNameSet ) - { - uno::Reference< container::XNamed > xNamed( nextFinder->second.xShape, uno::UNO_QUERY ); - if ( xNamed.is() ) - { - xNamed->setName( nextFinder->first ); - nextFinder->second.bShapeNameSet = true; - } - } - - uno::Reference<text::XTextContent> xTextContent(msoItem.second.xShape, uno::UNO_QUERY_THROW); - uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY); - - //The reverse chaining happens automatically, so only one direction needs to be set - xPropertySet->setPropertyValue(sChainNextName, uno::makeAny(nextFinder->first)); - - //the last item in an mso-next-textbox chain is indistinguishable from id/seq items. Now that it is handled, remove it. - if( nextFinder->second.s_mso_next_textbox.isEmpty() ) - aTextFramesForChainingHelper.erase(nextFinder->first); - } - } - } - - //TODO: Perhaps allow reverse sequences when mso-layout-flow-alt = "bottom-to-top" - const sal_Int32 nDirection = 1; - - //Finally - go through and attach the chains based on matching ID and incremented sequence number (dml-style). - for (const auto& rOuter : aTextFramesForChainingHelper) - { - if( rOuter.second.s_mso_next_textbox.isEmpty() ) //non-empty ones already handled earlier - so skipping them now. - { - for (const auto& rInner : aTextFramesForChainingHelper) - { - if ( rInner.second.nId == rOuter.second.nId ) - { - if ( rInner.second.nSeq == ( rOuter.second.nSeq + nDirection ) ) - { - uno::Reference<text::XTextContent> xTextContent(rOuter.second.xShape, uno::UNO_QUERY_THROW); - uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY); - - //The reverse chaining happens automatically, so only one direction needs to be set - xPropertySet->setPropertyValue(sChainNextName, uno::makeAny(rInner.first)); - break ; //there cannot be more than one next frame - } - } - } - } - } - m_vTextFramesForChaining.clear(); //clear the vector - } - catch (const uno::Exception&) - { - DBG_UNHANDLED_EXCEPTION("writerfilter.dmapper"); - } -} - -uno::Reference<beans::XPropertySet> DomainMapper_Impl::FindOrCreateFieldMaster(const char* pFieldMasterService, const OUString& rFieldMasterName) -{ - // query master, create if not available - uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY_THROW ); - uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters(); - uno::Reference< beans::XPropertySet > xMaster; - OUString sFieldMasterService( OUString::createFromAscii(pFieldMasterService) ); - OUStringBuffer aFieldMasterName; - OUString sDatabaseDataSourceName = GetSettingsTable()->GetCurrentDatabaseDataSource(); - bool bIsMergeField = sFieldMasterService.endsWith("Database"); - aFieldMasterName.appendAscii( pFieldMasterService ); - aFieldMasterName.append('.'); - if ( bIsMergeField && !sDatabaseDataSourceName.isEmpty() ) - { - aFieldMasterName.append(sDatabaseDataSourceName); - aFieldMasterName.append('.'); - } - aFieldMasterName.append(rFieldMasterName); - OUString sFieldMasterName = aFieldMasterName.makeStringAndClear(); - if(xFieldMasterAccess->hasByName(sFieldMasterName)) - { - //get the master - xMaster.set(xFieldMasterAccess->getByName(sFieldMasterName), uno::UNO_QUERY_THROW); - } - else if( m_xTextFactory.is() ) - { - //create the master - xMaster.set( m_xTextFactory->createInstance(sFieldMasterService), uno::UNO_QUERY_THROW); - if ( !bIsMergeField || sDatabaseDataSourceName.isEmpty() ) - { - //set the master's name - xMaster->setPropertyValue( - getPropertyName(PROP_NAME), - uno::makeAny(rFieldMasterName)); - } else { - // set database data, based on the "databasename.tablename" of sDatabaseDataSourceName - xMaster->setPropertyValue( - getPropertyName(PROP_DATABASE_NAME), - uno::makeAny(sDatabaseDataSourceName.copy(0, sDatabaseDataSourceName.indexOf('.')))); - xMaster->setPropertyValue( - getPropertyName(PROP_COMMAND_TYPE), - uno::makeAny(sal_Int32(0))); - xMaster->setPropertyValue( - getPropertyName(PROP_DATATABLE_NAME), - uno::makeAny(sDatabaseDataSourceName.copy(sDatabaseDataSourceName.indexOf('.') + 1))); - xMaster->setPropertyValue( - getPropertyName(PROP_DATACOLUMN_NAME), - uno::makeAny(rFieldMasterName)); - } - } - return xMaster; -} - -void DomainMapper_Impl::PushFieldContext() -{ - m_bParaHadField = true; - if(m_bDiscardHeaderFooter) - return; -#ifdef DBG_UTIL - TagLogger::getInstance().element("pushFieldContext"); -#endif - - uno::Reference<text::XTextCursor> xCrsr; - if (!m_aTextAppendStack.empty()) - { - uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend; - if (xTextAppend.is()) - xCrsr = xTextAppend->createTextCursorByRange( - m_aTextAppendStack.top().xInsertPosition.is() - ? m_aTextAppendStack.top().xInsertPosition - : xTextAppend->getEnd()); - } - - uno::Reference< text::XTextRange > xStart; - if (xCrsr.is()) - xStart = xCrsr->getStart(); - m_aFieldStack.push_back(new FieldContext(xStart)); -} -/*------------------------------------------------------------------------- -//the current field context waits for the completion of the command - -----------------------------------------------------------------------*/ -bool DomainMapper_Impl::IsOpenFieldCommand() const -{ - return !m_aFieldStack.empty() && !m_aFieldStack.back()->IsCommandCompleted(); -} -/*------------------------------------------------------------------------- -//the current field context waits for the completion of the command - -----------------------------------------------------------------------*/ -bool DomainMapper_Impl::IsOpenField() const -{ - return !m_aFieldStack.empty(); -} - -// Mark top field context as containing a fixed field -void DomainMapper_Impl::SetFieldLocked() -{ - if (IsOpenField()) - m_aFieldStack.back()->SetFieldLocked(); -} - -HeaderFooterContext::HeaderFooterContext(bool bTextInserted, sal_Int32 nTableDepth) - : m_bTextInserted(bTextInserted) - , m_nTableDepth(nTableDepth) -{ -} - -bool HeaderFooterContext::getTextInserted() const -{ - return m_bTextInserted; -} - -sal_Int32 HeaderFooterContext::getTableDepth() const { return m_nTableDepth; } - -FieldContext::FieldContext(uno::Reference< text::XTextRange > const& xStart) - : m_bFieldCommandCompleted(false) - , m_xStartRange( xStart ) - , m_bFieldLocked( false ) -{ - m_pProperties = new PropertyMap(); -} - - -FieldContext::~FieldContext() -{ -} - -void FieldContext::SetTextField(uno::Reference<text::XTextField> const& xTextField) -{ -#ifndef NDEBUG - if (xTextField.is()) - { - uno::Reference<lang::XServiceInfo> const xServiceInfo(xTextField, uno::UNO_QUERY); - assert(xServiceInfo.is()); - // those must be set by SetFormField() - assert(!xServiceInfo->supportsService("com.sun.star.text.Fieldmark") - && !xServiceInfo->supportsService("com.sun.star.text.FormFieldmark")); - } -#endif - m_xTextField = xTextField; -} - -void FieldContext::AppendCommand(std::u16string_view rPart) -{ - m_sCommand += rPart; -} - -::std::vector<OUString> FieldContext::GetCommandParts() const -{ - ::std::vector<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.isEmpty()) - continue; - - if (sToken[0] == '"') - { - bInStringNext = true; - sToken = sToken.copy(1); - } - if (sToken.endsWith("\"")) - { - bInStringNext = false; - sToken = sToken.copy(0, sToken.getLength() - 1); - } - - if (bInString) - { - sPart += " " + sToken; - if (!bInStringNext) - { - 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(OUString const & rPartOfCommand) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("appendFieldCommand"); - TagLogger::getInstance().chars(rPartOfCommand); - TagLogger::getInstance().endElement(); -#endif - - FieldContextPtr pContext = m_aFieldStack.back(); - OSL_ENSURE( pContext, "no field context available"); - if( pContext ) - { - pContext->AppendCommand( rPartOfCommand ); - } -} - - -typedef std::multimap < sal_Int32, OUString > TOCStyleMap; - - -static ww::eField GetWW8FieldId(OUString const& rType) -{ - std::unordered_map<OUString, ww::eField> mapID - { - {"ADDRESSBLOCK", ww::eADDRESSBLOCK}, - {"ADVANCE", ww::eADVANCE}, - {"ASK", ww::eASK}, - {"AUTONUM", ww::eAUTONUM}, - {"AUTONUMLGL", ww::eAUTONUMLGL}, - {"AUTONUMOUT", ww::eAUTONUMOUT}, - {"AUTOTEXT", ww::eAUTOTEXT}, - {"AUTOTEXTLIST", ww::eAUTOTEXTLIST}, - {"AUTHOR", ww::eAUTHOR}, - {"BARCODE", ww::eBARCODE}, - {"BIDIOUTLINE", ww::eBIDIOUTLINE}, - {"DATE", ww::eDATE}, - {"COMMENTS", ww::eCOMMENTS}, - {"COMPARE", ww::eCOMPARE}, - {"CONTROL", ww::eCONTROL}, - {"CREATEDATE", ww::eCREATEDATE}, - {"DATABASE", ww::eDATABASE}, - {"DDEAUTOREF", ww::eDDEAUTOREF}, - {"DDEREF", ww::eDDEREF}, - {"DOCPROPERTY", ww::eDOCPROPERTY}, - {"DOCVARIABLE", ww::eDOCVARIABLE}, - {"EDITTIME", ww::eEDITTIME}, - {"EMBED", ww::eEMBED}, - {"EQ", ww::eEQ}, - {"FILLIN", ww::eFILLIN}, - {"FILENAME", ww::eFILENAME}, - {"FILESIZE", ww::eFILESIZE}, - {"FOOTREF", ww::eFOOTREF}, -// {"FORMULA", ww::}, - {"FORMCHECKBOX", ww::eFORMCHECKBOX}, - {"FORMDROPDOWN", ww::eFORMDROPDOWN}, - {"FORMTEXT", ww::eFORMTEXT}, - {"GLOSSREF", ww::eGLOSSREF}, - {"GOTOBUTTON", ww::eGOTOBUTTON}, - {"GREETINGLINE", ww::eGREETINGLINE}, - {"HTMLCONTROL", ww::eHTMLCONTROL}, - {"HYPERLINK", ww::eHYPERLINK}, - {"IF", ww::eIF}, - {"INFO", ww::eINFO}, - {"INCLUDEPICTURE", ww::eINCLUDEPICTURE}, - {"INCLUDETEXT", ww::eINCLUDETEXT}, - {"INCLUDETIFF", ww::eINCLUDETIFF}, - {"KEYWORDS", ww::eKEYWORDS}, - {"LASTSAVEDBY", ww::eLASTSAVEDBY}, - {"LINK", ww::eLINK}, - {"LISTNUM", ww::eLISTNUM}, - {"MACRO", ww::eMACRO}, - {"MACROBUTTON", ww::eMACROBUTTON}, - {"MERGEDATA", ww::eMERGEDATA}, - {"MERGEFIELD", ww::eMERGEFIELD}, - {"MERGEINC", ww::eMERGEINC}, - {"MERGEREC", ww::eMERGEREC}, - {"MERGESEQ", ww::eMERGESEQ}, - {"NEXT", ww::eNEXT}, - {"NEXTIF", ww::eNEXTIF}, - {"NOTEREF", ww::eNOTEREF}, - {"PAGE", ww::ePAGE}, - {"PAGEREF", ww::ePAGEREF}, - {"PLUGIN", ww::ePLUGIN}, - {"PRINT", ww::ePRINT}, - {"PRINTDATE", ww::ePRINTDATE}, - {"PRIVATE", ww::ePRIVATE}, - {"QUOTE", ww::eQUOTE}, - {"RD", ww::eRD}, - {"REF", ww::eREF}, - {"REVNUM", ww::eREVNUM}, - {"SAVEDATE", ww::eSAVEDATE}, - {"SECTION", ww::eSECTION}, - {"SECTIONPAGES", ww::eSECTIONPAGES}, - {"SEQ", ww::eSEQ}, - {"SET", ww::eSET}, - {"SKIPIF", ww::eSKIPIF}, - {"STYLEREF", ww::eSTYLEREF}, - {"SUBSCRIBER", ww::eSUBSCRIBER}, - {"SUBJECT", ww::eSUBJECT}, - {"SYMBOL", ww::eSYMBOL}, - {"TA", ww::eTA}, - {"TEMPLATE", ww::eTEMPLATE}, - {"TIME", ww::eTIME}, - {"TITLE", ww::eTITLE}, - {"TOA", ww::eTOA}, - {"USERINITIALS", ww::eUSERINITIALS}, - {"USERADDRESS", ww::eUSERADDRESS}, - {"USERNAME", ww::eUSERNAME}, - - {"TOC", ww::eTOC}, - {"TC", ww::eTC}, - {"NUMCHARS", ww::eNUMCHARS}, - {"NUMWORDS", ww::eNUMWORDS}, - {"NUMPAGES", ww::eNUMPAGES}, - {"INDEX", ww::eINDEX}, - {"XE", ww::eXE}, - {"BIBLIOGRAPHY", ww::eBIBLIOGRAPHY}, - {"CITATION", ww::eCITATION}, - }; - auto const it = mapID.find(rType); - return (it == mapID.end()) ? ww::eNONE : it->second; -} - -static const FieldConversionMap_t & lcl_GetFieldConversion() -{ - static const FieldConversionMap_t aFieldConversionMap - { -// {"ADDRESSBLOCK", {"", FIELD_ADDRESSBLOCK }}, -// {"ADVANCE", {"", FIELD_ADVANCE }}, - {"ASK", {"SetExpression", FIELD_ASK }}, - {"AUTONUM", {"SetExpression", FIELD_AUTONUM }}, - {"AUTONUMLGL", {"SetExpression", FIELD_AUTONUMLGL }}, - {"AUTONUMOUT", {"SetExpression", FIELD_AUTONUMOUT }}, - {"AUTHOR", {"DocInfo.CreateAuthor", FIELD_AUTHOR }}, - {"DATE", {"DateTime", FIELD_DATE }}, - {"COMMENTS", {"DocInfo.Description", FIELD_COMMENTS }}, - {"CREATEDATE", {"DocInfo.CreateDateTime", FIELD_CREATEDATE }}, - {"DOCPROPERTY", {"", FIELD_DOCPROPERTY }}, - {"DOCVARIABLE", {"User", FIELD_DOCVARIABLE }}, - {"EDITTIME", {"DocInfo.EditTime", FIELD_EDITTIME }}, - {"EQ", {"", FIELD_EQ }}, - {"FILLIN", {"Input", FIELD_FILLIN }}, - {"FILENAME", {"FileName", FIELD_FILENAME }}, -// {"FILESIZE", {"", FIELD_FILESIZE }}, - {"FORMULA", {"TableFormula", FIELD_FORMULA }}, - {"FORMCHECKBOX", {"", FIELD_FORMCHECKBOX }}, - {"FORMDROPDOWN", {"DropDown", FIELD_FORMDROPDOWN }}, - {"FORMTEXT", {"Input", FIELD_FORMTEXT }}, - {"GOTOBUTTON", {"", FIELD_GOTOBUTTON }}, - {"HYPERLINK", {"", FIELD_HYPERLINK }}, - {"IF", {"ConditionalText", FIELD_IF }}, -// {"INFO", {"", FIELD_INFO }}, - {"INCLUDEPICTURE", {"", FIELD_INCLUDEPICTURE}}, - {"KEYWORDS", {"DocInfo.KeyWords", FIELD_KEYWORDS }}, - {"LASTSAVEDBY", {"DocInfo.ChangeAuthor", FIELD_LASTSAVEDBY }}, - {"MACROBUTTON", {"Macro", FIELD_MACROBUTTON }}, - {"MERGEFIELD", {"Database", FIELD_MERGEFIELD }}, - {"MERGEREC", {"DatabaseNumberOfSet", FIELD_MERGEREC }}, -// {"MERGESEQ", {"", FIELD_MERGESEQ }}, - {"NEXT", {"DatabaseNextSet", FIELD_NEXT }}, - {"NEXTIF", {"DatabaseNextSet", FIELD_NEXTIF }}, - {"PAGE", {"PageNumber", FIELD_PAGE }}, - {"PAGEREF", {"GetReference", FIELD_PAGEREF }}, - {"REF", {"GetReference", FIELD_REF }}, - {"REVNUM", {"DocInfo.Revision", FIELD_REVNUM }}, - {"SAVEDATE", {"DocInfo.Change", FIELD_SAVEDATE }}, -// {"SECTION", {"", FIELD_SECTION }}, -// {"SECTIONPAGES", {"", FIELD_SECTIONPAGES }}, - {"SEQ", {"SetExpression", FIELD_SEQ }}, - {"SET", {"SetExpression", FIELD_SET }}, -// {"SKIPIF", {"", FIELD_SKIPIF }}, -// {"STYLEREF", {"", FIELD_STYLEREF }}, - {"SUBJECT", {"DocInfo.Subject", FIELD_SUBJECT }}, - {"SYMBOL", {"", FIELD_SYMBOL }}, - {"TEMPLATE", {"TemplateName", FIELD_TEMPLATE }}, - {"TIME", {"DateTime", FIELD_TIME }}, - {"TITLE", {"DocInfo.Title", FIELD_TITLE }}, - {"USERINITIALS", {"Author", FIELD_USERINITIALS }}, -// {"USERADDRESS", {"", FIELD_USERADDRESS }}, - {"USERNAME", {"Author", FIELD_USERNAME }}, - - - {"TOC", {"com.sun.star.text.ContentIndex", FIELD_TOC }}, - {"TC", {"com.sun.star.text.ContentIndexMark", FIELD_TC }}, - {"NUMCHARS", {"CharacterCount", FIELD_NUMCHARS }}, - {"NUMWORDS", {"WordCount", FIELD_NUMWORDS }}, - {"NUMPAGES", {"PageCount", FIELD_NUMPAGES }}, - {"INDEX", {"com.sun.star.text.DocumentIndex", FIELD_INDEX }}, - {"XE", {"com.sun.star.text.DocumentIndexMark", FIELD_XE }}, - {"BIBLIOGRAPHY",{"com.sun.star.text.Bibliography", FIELD_BIBLIOGRAPHY }}, - {"CITATION", {"com.sun.star.text.TextField.Bibliography",FIELD_CITATION }}, - }; - - return aFieldConversionMap; -} - -static const FieldConversionMap_t & lcl_GetEnhancedFieldConversion() -{ - static const FieldConversionMap_t aEnhancedFieldConversionMap = - { - {"FORMCHECKBOX", {"FormFieldmark", FIELD_FORMCHECKBOX}}, - {"FORMDROPDOWN", {"FormFieldmark", FIELD_FORMDROPDOWN}}, - {"FORMTEXT", {"Fieldmark", FIELD_FORMTEXT}}, - }; - - return aEnhancedFieldConversionMap; -} - -void DomainMapper_Impl::handleFieldSet - (const FieldContextPtr& pContext, - uno::Reference< uno::XInterface > const & xFieldInterface, - uno::Reference< beans::XPropertySet > const& xFieldProperties) -{ - OUString sVariable, sHint; - - sVariable = lcl_ExtractVariableAndHint(pContext->GetCommand(), sHint); - - // remove surrounding "" if exists - if(sHint.getLength() >= 2) - { - OUString sTmp = sHint.trim(); - if (sTmp.startsWith("\"") && sTmp.endsWith("\"")) - { - sHint = sTmp.copy(1, sTmp.getLength() - 2); - } - } - - // determine field master name - uno::Reference< beans::XPropertySet > xMaster = - FindOrCreateFieldMaster - ("com.sun.star.text.FieldMaster.SetExpression", sVariable ); - - // a set field is a string - xMaster->setPropertyValue(getPropertyName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING)); - - // attach the master to the field - uno::Reference< text::XDependentTextField > xDependentField - ( xFieldInterface, uno::UNO_QUERY_THROW ); - xDependentField->attachTextFieldMaster( xMaster ); - - xFieldProperties->setPropertyValue(getPropertyName(PROP_HINT), uno::makeAny( sHint )); - xFieldProperties->setPropertyValue(getPropertyName(PROP_CONTENT), uno::makeAny( sHint )); - xFieldProperties->setPropertyValue(getPropertyName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING)); - - // Mimic MS Word behavior (hide the SET) - xFieldProperties->setPropertyValue(getPropertyName(PROP_IS_VISIBLE), uno::makeAny(false)); -} - -void DomainMapper_Impl::handleFieldAsk - (const FieldContextPtr& pContext, - uno::Reference< uno::XInterface > & xFieldInterface, - uno::Reference< beans::XPropertySet > const& xFieldProperties) -{ - //doesn the command contain a variable name? - OUString sVariable, sHint; - - sVariable = lcl_ExtractVariableAndHint( pContext->GetCommand(), - sHint ); - if(!sVariable.isEmpty()) - { - // determine field master name - uno::Reference< beans::XPropertySet > xMaster = - FindOrCreateFieldMaster - ("com.sun.star.text.FieldMaster.SetExpression", sVariable ); - // An ASK field is always a string of characters - xMaster->setPropertyValue(getPropertyName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING)); - - // 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( - getPropertyName(PROP_IS_INPUT), uno::makeAny( true )); - // set the prompt - xFieldProperties->setPropertyValue( - getPropertyName(PROP_HINT), - uno::makeAny( sHint )); - xFieldProperties->setPropertyValue(getPropertyName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING)); - // The ASK has no field value to display - xFieldProperties->setPropertyValue(getPropertyName(PROP_IS_VISIBLE), uno::makeAny(false)); - } - else - { - //don't insert the field - //todo: maybe import a 'normal' input field here? - xFieldInterface = nullptr; - } -} - -/** - * Converts a Microsoft Word field formula into LibreOffice syntax - * @param input The Microsoft Word field formula, with no leading '=' sign - * @return An equivalent LibreOffice field formula - */ -OUString DomainMapper_Impl::convertFieldFormula(const OUString& input) { - - OUString listSeparator = m_pSettingsTable->GetListSeparator(); - - /* Replace logical condition functions with LO equivalent operators */ - OUString changed = input.replaceAll(" <> ", " NEQ "); - changed = changed.replaceAll(" <= ", " LEQ "); - changed = changed.replaceAll(" >= ", " GEQ "); - changed = changed.replaceAll(" = " , " EQ "); - changed = changed.replaceAll(" < " , " L "); - changed = changed.replaceAll(" > " , " G "); - - changed = changed.replaceAll("<>", " NEQ "); - changed = changed.replaceAll("<=", " LEQ "); - changed = changed.replaceAll(">=", " GEQ "); - changed = changed.replaceAll("=" , " EQ "); - changed = changed.replaceAll("<" , " L "); - changed = changed.replaceAll(">" , " G "); - - /* Replace function calls with infix keywords for AND(), OR(), and ROUND(). Nothing needs to be - * done for NOT(). This simple regex will work properly with most common cases. However, it may - * not work correctly when the arguments are nested subcalls to other functions, like - * ROUND(MIN(1,2),MAX(3,4)). See TDF#134765. */ - icu::ErrorCode status; - icu::UnicodeString usInput(changed.getStr()); - const uint32_t rMatcherFlags = UREGEX_CASE_INSENSITIVE; - OUString regex = "\\b(AND|OR|ROUND)\\s*\\(\\s*([^" + listSeparator + "]+)\\s*" + listSeparator + "\\s*([^)]+)\\s*\\)"; - icu::UnicodeString usRegex(regex.getStr()); - icu::RegexMatcher rmatch1(usRegex, usInput, rMatcherFlags, status); - usInput = rmatch1.replaceAll(icu::UnicodeString("(($2) $1 ($3))"), status); - - /* Assumes any remaining list separators separate arguments to functions that accept lists - * (SUM, MIN, MAX, MEAN, etc.) */ - usInput.findAndReplace(icu::UnicodeString(listSeparator.getStr()), "|"); - - /* Surround single cell references with angle brackets. - * If there is ever added a function name that ends with a digit, this regex will need to be revisited. */ - icu::RegexMatcher rmatch2("\\b([A-Z]{1,3}[0-9]+)\\b(?![(])", usInput, rMatcherFlags, status); - usInput = rmatch2.replaceAll(icu::UnicodeString("<$1>"), status); - - /* Cell references must be upper case - * TODO: convert reference to other tables, e.g. SUM(Table1 A1:B2), where "Table1" is a bookmark of the table, - * TODO: also column range A:A */ - icu::RegexMatcher rmatch3("(<[a-z]{1,3}[0-9]+>|\\b(above|below|left|right)\\b)", usInput, rMatcherFlags, status); - icu::UnicodeString replacedCellRefs; - while (rmatch3.find(status) && status.isSuccess()) { - rmatch3.appendReplacement(replacedCellRefs, rmatch3.group(status).toUpper(), status); - } - rmatch3.appendTail(replacedCellRefs); - - /* Fix up cell ranges */ - icu::RegexMatcher rmatch4("<([A-Z]{1,3}[0-9]+)>:<([A-Z]{1,3}[0-9]+)>", replacedCellRefs, rMatcherFlags, status); - usInput = rmatch4.replaceAll(icu::UnicodeString("<$1:$2>"), status); - - /* Fix up user defined names */ - icu::RegexMatcher rmatch5("\\bDEFINED\\s*\\(<([A-Z]+[0-9]+)>\\)", usInput, rMatcherFlags, status); - usInput = rmatch5.replaceAll(icu::UnicodeString("DEFINED($1)"), status); - - /* Prepare replace of ABOVE/BELOW/LEFT/RIGHT by adding spaces around them */ - icu::RegexMatcher rmatch6("\\b(ABOVE|BELOW|LEFT|RIGHT)\\b", usInput, rMatcherFlags, status); - usInput = rmatch6.replaceAll(icu::UnicodeString(" $1 "), status); - - return OUString(usInput.getTerminatedBuffer()); -} - -void DomainMapper_Impl::handleFieldFormula - (const FieldContextPtr& pContext, - uno::Reference< beans::XPropertySet > const& xFieldProperties) -{ - OUString command = pContext->GetCommand().trim(); - - // Remove number formatting from \# to end of command - // TODO: handle custom number formatting - sal_Int32 delimPos = command.indexOf("\\#"); - if (delimPos != -1) - { - command = command.replaceAt(delimPos, command.getLength() - delimPos, "").trim(); - } - - // command must contains = and at least another char - if (command.getLength() < 2) - return; - - // we don't copy the = symbol from the command - OUString formula = convertFieldFormula(command.copy(1)); - - xFieldProperties->setPropertyValue(getPropertyName(PROP_CONTENT), uno::makeAny(formula)); - xFieldProperties->setPropertyValue(getPropertyName(PROP_NUMBER_FORMAT), uno::makeAny(sal_Int32(0))); - xFieldProperties->setPropertyValue("IsShowFormula", uno::makeAny(false)); - - // grab-bag the original and converted formula - if (hasTableManager()) - { - TablePropertyMapPtr pPropMap(new TablePropertyMap()); - pPropMap->Insert(PROP_CELL_FORMULA, uno::makeAny(command.copy(1)), true, CELL_GRAB_BAG); - pPropMap->Insert(PROP_CELL_FORMULA_CONVERTED, uno::makeAny(formula), true, CELL_GRAB_BAG); - getTableManager().cellProps(pPropMap); - } -} - -void DomainMapper_Impl::handleRubyEQField( const FieldContextPtr& pContext) -{ - const OUString & rCommand(pContext->GetCommand()); - sal_Int32 nIndex = 0, nEnd = 0; - RubyInfo aInfo ; - nIndex = rCommand.indexOf("\\* jc" ); - if (nIndex != -1) - { - nIndex += 5; - sal_uInt32 nJc = rCommand.getToken(0, ' ',nIndex).toInt32(); - const sal_Int32 aRubyAlignValues[] = - { - NS_ooxml::LN_Value_ST_RubyAlign_center, - NS_ooxml::LN_Value_ST_RubyAlign_distributeLetter, - NS_ooxml::LN_Value_ST_RubyAlign_distributeSpace, - NS_ooxml::LN_Value_ST_RubyAlign_left, - NS_ooxml::LN_Value_ST_RubyAlign_right, - NS_ooxml::LN_Value_ST_RubyAlign_rightVertical, - }; - aInfo.nRubyAlign = aRubyAlignValues[(nJc<SAL_N_ELEMENTS(aRubyAlignValues))?nJc:0]; - } - - // we don't parse or use the font field in rCommand - - nIndex = rCommand.indexOf("\\* hps" ); - if (nIndex != -1) - { - nIndex += 6; - aInfo.nHps = rCommand.getToken(0, ' ',nIndex).toInt32(); - } - - nIndex = rCommand.indexOf("\\o"); - if (nIndex == -1) - return; - nIndex = rCommand.indexOf('(', nIndex); - if (nIndex == -1) - return; - nEnd = rCommand.lastIndexOf(')'); - if (nEnd == -1) - return; - if (nEnd <= nIndex) - return; - - OUString sRubyParts = rCommand.copy(nIndex+1,nEnd-nIndex-1); - nIndex = 0; - OUString sPart1 = sRubyParts.getToken(0, ',', nIndex); - OUString sPart2 = sRubyParts.getToken(0, ',', nIndex); - if ((nIndex = sPart1.indexOf('(')) != -1 && (nEnd = sPart1.lastIndexOf(')'))!=-1 && nEnd > nIndex) - { - aInfo.sRubyText = sPart1.copy(nIndex+1,nEnd-nIndex-1); - } - - PropertyMapPtr pRubyContext(new PropertyMap()); - pRubyContext->InsertProps(GetTopContext()); - if (aInfo.nHps > 0) - { - double fVal = double(aInfo.nHps) / 2.; - uno::Any aVal = uno::makeAny( fVal ); - - pRubyContext->Insert(PROP_CHAR_HEIGHT, aVal); - pRubyContext->Insert(PROP_CHAR_HEIGHT_ASIAN, aVal); - } - PropertyValueVector_t aProps = comphelper::sequenceToContainer< PropertyValueVector_t >(pRubyContext->GetPropertyValues()); - aInfo.sRubyStyle = m_rDMapper.getOrCreateCharStyle(aProps, /*bAlwaysCreate=*/false); - PropertyMapPtr pCharContext(new PropertyMap()); - if (m_pLastCharacterContext) - pCharContext->InsertProps(m_pLastCharacterContext); - pCharContext->InsertProps(pContext->getProperties()); - pCharContext->Insert(PROP_RUBY_TEXT, uno::makeAny( aInfo.sRubyText ) ); - pCharContext->Insert(PROP_RUBY_ADJUST, uno::makeAny(static_cast<sal_Int16>(ConversionHelper::convertRubyAlign(aInfo.nRubyAlign)))); - if ( aInfo.nRubyAlign == NS_ooxml::LN_Value_ST_RubyAlign_rightVertical ) - pCharContext->Insert(PROP_RUBY_POSITION, uno::makeAny(css::text::RubyPosition::INTER_CHARACTER)); - pCharContext->Insert(PROP_RUBY_STYLE, uno::makeAny(aInfo.sRubyStyle)); - appendTextPortion(sPart2, pCharContext); - -} - -void DomainMapper_Impl::handleAutoNum - (const FieldContextPtr& pContext, - uno::Reference< uno::XInterface > const & xFieldInterface, - uno::Reference< beans::XPropertySet > const& xFieldProperties) -{ - //create a sequence field master "AutoNr" - uno::Reference< beans::XPropertySet > xMaster = - FindOrCreateFieldMaster - ("com.sun.star.text.FieldMaster.SetExpression", - "AutoNr"); - - xMaster->setPropertyValue( getPropertyName(PROP_SUB_TYPE), - uno::makeAny(text::SetVariableType::SEQUENCE)); - - //apply the numbering type - xFieldProperties->setPropertyValue( - getPropertyName(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 - (std::u16string_view rFirstParam, - uno::Reference< beans::XPropertySet > const& xFieldProperties, - FieldId eFieldId ) -{ - if ( eFieldId != FIELD_USERINITIALS ) - xFieldProperties->setPropertyValue - ( getPropertyName(PROP_FULL_NAME), uno::makeAny( true )); - - if (!rFirstParam.empty()) - { - xFieldProperties->setPropertyValue( - getPropertyName( PROP_IS_FIXED ), - uno::makeAny( true )); - //PROP_CURRENT_PRESENTATION is set later anyway - } -} - - void DomainMapper_Impl::handleDocProperty - (const FieldContextPtr& pContext, - OUString const& rFirstParam, - uno::Reference< uno::XInterface > & xFieldInterface) -{ - //some docproperties should be imported as document statistic fields, some as DocInfo fields - //others should be user fields - if (rFirstParam.isEmpty()) - return; - - constexpr sal_uInt8 SET_ARABIC = 0x01; - constexpr sal_uInt8 SET_DATE = 0x04; - struct DocPropertyMap - { - const char* pDocPropertyName; - const 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, - }; - uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(m_xTextDocument, uno::UNO_QUERY); - uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties(); - uno::Reference<beans::XPropertySet> xUserDefinedProps(xDocumentProperties->getUserDefinedProperties(), uno::UNO_QUERY_THROW); - uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xUserDefinedProps->getPropertySetInfo(); - //search for a field mapping - OUString sFieldServiceName; - size_t nMap = 0; - for( ; nMap < SAL_N_ELEMENTS(aDocProperties); ++nMap ) - { - if ((rFirstParam.equalsAscii(aDocProperties[nMap].pDocPropertyName)) && (!xPropertySetInfo->hasPropertyByName(rFirstParam))) - { - sFieldServiceName = - OUString::createFromAscii - (aDocProperties[nMap].pServiceName); - break; - } - } - OUString sServiceName("com.sun.star.text.TextField."); - bool bIsCustomField = false; - if(sFieldServiceName.isEmpty()) - { - //create a custom property field - sServiceName += "DocInfo.Custom"; - bIsCustomField = true; - } - else - { - sServiceName += sFieldServiceName; - } - if (m_xTextFactory.is()) - xFieldInterface = m_xTextFactory->createInstance(sServiceName); - uno::Reference<beans::XPropertySet> xFieldProperties( xFieldInterface, uno::UNO_QUERY_THROW); - if( bIsCustomField ) - { - xFieldProperties->setPropertyValue( - getPropertyName(PROP_NAME), uno::makeAny(rFirstParam)); - pContext->SetCustomField( xFieldProperties ); - } - else - { - if(0 != (aDocProperties[nMap].nFlags & SET_ARABIC)) - xFieldProperties->setPropertyValue( - getPropertyName(PROP_NUMBERING_TYPE), - uno::makeAny( style::NumberingType::ARABIC )); - else if(0 != (aDocProperties[nMap].nFlags & SET_DATE)) - { - xFieldProperties->setPropertyValue( - getPropertyName(PROP_IS_DATE), - uno::makeAny( true )); - SetNumberFormat( pContext->GetCommand(), xFieldProperties ); - } - } -} - -static uno::Sequence< beans::PropertyValues > lcl_createTOXLevelHyperlinks( bool bHyperlinks, const OUString& sChapterNoSeparator, - const uno::Sequence< beans::PropertyValues >& aLevel ) -{ - //create a copy of the level and add two new entries - hyperlink start and end - bool bChapterNoSeparator = !sChapterNoSeparator.isEmpty(); - 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 = getPropertyName( PROP_TOKEN_TYPE ); - aHyperlink[0].Value <<= getPropertyName( PROP_TOKEN_HYPERLINK_START ); - pNewLevel[0] = aHyperlink; - aHyperlink[0].Value <<= getPropertyName( PROP_TOKEN_HYPERLINK_END ); - pNewLevel[aNewLevel.getLength() -1] = aHyperlink; - } - if( bChapterNoSeparator ) - { - beans::PropertyValues aChapterNo(2); - aChapterNo[0].Name = getPropertyName( PROP_TOKEN_TYPE ); - aChapterNo[0].Value <<= getPropertyName( PROP_TOKEN_CHAPTER_INFO ); - aChapterNo[1].Name = getPropertyName( 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 = getPropertyName( PROP_TOKEN_TYPE ); - aChapterSeparator[0].Value <<= getPropertyName( PROP_TOKEN_TEXT ); - aChapterSeparator[1].Name = getPropertyName( PROP_TEXT ); - aChapterSeparator[1].Value <<= sChapterNoSeparator; - pNewLevel[aNewLevel.getLength() - (bHyperlinks ? 3 : 1)] = aChapterSeparator; - } - //copy the 'old' entries except the last (page no) - std::copy(aLevel.begin(), std::prev(aLevel.end()), std::next(aNewLevel.begin())); - //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]; - - return aNewLevel; -} - -/// Returns title of the TOC placed in paragraph(s) before TOC field inside STD-frame -OUString DomainMapper_Impl::extractTocTitle() -{ - if (!m_xSdtEntryStart.is()) - return OUString(); - - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if(!xTextAppend.is()) - return OUString(); - - // try-catch was added in the same way as inside appendTextSectionAfter() - try - { - uno::Reference<text::XParagraphCursor> xCursor(xTextAppend->createTextCursorByRange(m_xSdtEntryStart), uno::UNO_QUERY_THROW); - if (!xCursor.is()) - return OUString(); - - //the cursor has been moved to the end of the paragraph because of the appendTextPortion() calls - xCursor->gotoStartOfParagraph( false ); - if (m_aTextAppendStack.top().xInsertPosition.is()) - xCursor->gotoRange( m_aTextAppendStack.top().xInsertPosition, true ); - else - xCursor->gotoEnd( true ); - - // the paragraph after this new section might have been already inserted - OUString sResult = xCursor->getString(); - if (sResult.endsWith(SAL_NEWLINE_STRING)) - sResult = sResult.copy(0, sResult.getLength() - SAL_N_ELEMENTS(SAL_NEWLINE_STRING) + 1); - - return sResult; - } - catch(const uno::Exception&) - { - } - - return OUString(); -} - -css::uno::Reference<css::beans::XPropertySet> -DomainMapper_Impl::StartIndexSectionChecked(const OUString& sServiceName) -{ - if (m_bParaChanged) - { - finishParagraph(GetTopContextOfType(CONTEXT_PARAGRAPH), false); // resets m_bParaChanged - PopProperties(CONTEXT_PARAGRAPH); - PushProperties(CONTEXT_PARAGRAPH); - SetIsFirstRun(true); - // The first paragraph of the index that is continuation of just finished one needs to be - // removed when finished (unless more content will arrive, which will set m_bParaChanged) - m_bRemoveThisParagraph = true; - } - const auto& xTextAppend = GetTopTextAppend(); - const auto xTextRange = xTextAppend->getEnd(); - const auto xRet = createSectionForRange(xTextRange, xTextRange, sServiceName, false); - if (!m_aTextAppendStack.top().xInsertPosition) - { - try - { - m_bStartedTOC = true; - uno::Reference<text::XTextCursor> xTOCTextCursor - = xTextRange->getText()->createTextCursor(); - assert(xTOCTextCursor.is()); - xTOCTextCursor->gotoEnd(false); - m_aTextAppendStack.push(TextAppendContext(xTextAppend, xTOCTextCursor)); - } - catch (const uno::Exception&) - { - TOOLS_WARN_EXCEPTION("writerfilter.dmapper", - "DomainMapper_Impl::StartIndexSectionChecked:"); - } - } - return xRet; -} - -void DomainMapper_Impl::handleToc - (const FieldContextPtr& pContext, - const OUString & sTOCServiceName) -{ - OUString sValue; - if (IsInHeaderFooter()) - m_bStartTOCHeaderFooter = true; - bool bTableOfFigures = false; - bool bHyperlinks = false; - bool bFromOutline = false; - bool bFromEntries = false; - bool bHideTabLeaderPageNumbers = false ; - bool bIsTabEntry = false ; - bool bNewLine = false ; - bool bParagraphOutlineLevel = false; - - sal_Int16 nMaxLevel = 10; - OUString sTemplate; - OUString sChapterNoSeparator; - OUString sFigureSequence; - uno::Reference< beans::XPropertySet > xTOC; - OUString aBookmarkName; - -// \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 )) - { - aBookmarkName = sValue.trim().replaceAll("\"",""); - } - 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; - sFigureSequence = sValue.trim(); - sFigureSequence = sFigureSequence.replaceAll("\"", "").replaceAll("'",""); - } -// \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, such 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; - if (sValue.isEmpty()) - nMaxLevel = WW_OUTLINE_MAX; - else - { - sal_Int32 nIndex = 0; - sValue.getToken( 0, '-', nIndex ); - nMaxLevel = static_cast<sal_Int16>(nIndex != -1 ? sValue.copy(nIndex).toInt32() : 0); - } - } -// \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 - if( lcl_FindInCommand( pContext->GetCommand(), 't', sValue )) - { - OUString sToken = sValue.getToken(1, '"'); - sTemplate = sToken.isEmpty() ? sValue : sToken; - } -// \u Builds a table of contents by using the applied paragraph outline level - if( lcl_FindInCommand( pContext->GetCommand(), 'u', sValue )) - { - bFromOutline = true; - bParagraphOutlineLevel = 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 )) - { - bIsTabEntry = true ; - } -// \x Preserve newline characters within table entries - if( lcl_FindInCommand( pContext->GetCommand(), 'x', sValue )) - { - bNewLine = true ; - } -// \z Hides page numbers within the table of contents when shown in Web Layout View - if( lcl_FindInCommand( pContext->GetCommand(), 'z', sValue )) - { - bHideTabLeaderPageNumbers = true ; - } - - //if there's no option then it should be created from outline - if( !bFromOutline && !bFromEntries && sTemplate.isEmpty() ) - bFromOutline = true; - - const OUString aTocTitle = extractTocTitle(); - - if (m_xTextFactory.is() && ! m_aTextAppendStack.empty()) - { - const auto& xTextAppend = GetTopTextAppend(); - if (aTocTitle.isEmpty() || bTableOfFigures) - { - // reset marker of the TOC title - m_xSdtEntryStart.clear(); - - // Create section before setting m_bStartTOC: finishing paragraph - // inside StartIndexSectionChecked could do the wrong thing otherwise - xTOC = StartIndexSectionChecked(bTableOfFigures ? "com.sun.star.text.IllustrationsIndex" - : sTOCServiceName); - - const auto xTextCursor = xTextAppend->getText()->createTextCursor(); - if (xTextCursor) - xTextCursor->gotoEnd(false); - xTOCMarkerCursor = xTextCursor; - } - else - { - // create TOC section - css::uno::Reference<css::text::XTextRange> xTextRangeEndOfTocHeader = GetTopTextAppend()->getEnd(); - xTOC = createSectionForRange(m_xSdtEntryStart, xTextRangeEndOfTocHeader, sTOCServiceName, false); - - // init [xTOCMarkerCursor] - uno::Reference< text::XText > xText = xTextAppend->getText(); - uno::Reference< text::XTextCursor > xCrsr = xText->createTextCursor(); - xTOCMarkerCursor = xCrsr; - - // create header of the TOC with the TOC title inside - createSectionForRange(m_xSdtEntryStart, xTextRangeEndOfTocHeader, "com.sun.star.text.IndexHeaderSection", true); - } - } - - m_bStartTOC = true; - - if (xTOC.is()) - xTOC->setPropertyValue(getPropertyName( PROP_TITLE ), uno::makeAny(aTocTitle)); - - if (!aBookmarkName.isEmpty()) - xTOC->setPropertyValue(getPropertyName(PROP_TOC_BOOKMARK), uno::makeAny(aBookmarkName)); - if( !bTableOfFigures && xTOC.is() ) - { - xTOC->setPropertyValue( getPropertyName( PROP_LEVEL ), uno::makeAny( nMaxLevel ) ); - xTOC->setPropertyValue( getPropertyName( PROP_CREATE_FROM_OUTLINE ), uno::makeAny( bFromOutline )); - xTOC->setPropertyValue( getPropertyName( PROP_CREATE_FROM_MARKS ), uno::makeAny( bFromEntries )); - xTOC->setPropertyValue( getPropertyName( PROP_HIDE_TAB_LEADER_AND_PAGE_NUMBERS ), uno::makeAny( bHideTabLeaderPageNumbers )); - xTOC->setPropertyValue( getPropertyName( PROP_TAB_IN_TOC ), uno::makeAny( bIsTabEntry )); - xTOC->setPropertyValue( getPropertyName( PROP_TOC_NEW_LINE ), uno::makeAny( bNewLine )); - xTOC->setPropertyValue( getPropertyName( PROP_TOC_PARAGRAPH_OUTLINE_LEVEL ), uno::makeAny( bParagraphOutlineLevel )); - if( !sTemplate.isEmpty() ) - { - //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) - { - OUString sStyleName = sTemplate.getToken( 0, ',', nPosition ); - //empty tokens should be skipped - while( sStyleName.isEmpty() && nPosition > 0 ) - sStyleName = sTemplate.getToken( 0, ',', nPosition ); - nLevel = sTemplate.getToken( 0, ',', nPosition ).toInt32(); - if( !nLevel ) - nLevel = 1; - if( !sStyleName.isEmpty() ) - aMap.emplace(nLevel, sStyleName); - } - uno::Reference< container::XIndexReplace> xParaStyles; - xTOC->getPropertyValue(getPropertyName(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< 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(getPropertyName(PROP_CREATE_FROM_LEVEL_PARAGRAPH_STYLES), uno::makeAny( true )); - - } - if(bHyperlinks || !sChapterNoSeparator.isEmpty()) - { - uno::Reference< container::XIndexReplace> xLevelFormats; - xTOC->getPropertyValue(getPropertyName(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; - - uno::Sequence< beans::PropertyValues > aNewLevel = lcl_createTOXLevelHyperlinks( - bHyperlinks, sChapterNoSeparator, - aLevel ); - xLevelFormats->replaceByIndex( nLevel, uno::makeAny( aNewLevel ) ); - } - } - } - else if (bTableOfFigures && xTOC.is()) - { - if (!sFigureSequence.isEmpty()) - xTOC->setPropertyValue(getPropertyName(PROP_LABEL_CATEGORY), - uno::makeAny(sFigureSequence)); - - if ( bHyperlinks ) - { - uno::Reference< container::XIndexReplace> xLevelFormats; - xTOC->getPropertyValue(getPropertyName(PROP_LEVEL_FORMAT)) >>= xLevelFormats; - uno::Sequence< beans::PropertyValues > aLevel; - xLevelFormats->getByIndex( 1 ) >>= aLevel; - - uno::Sequence< beans::PropertyValues > aNewLevel = lcl_createTOXLevelHyperlinks( - bHyperlinks, sChapterNoSeparator, - aLevel ); - xLevelFormats->replaceByIndex( 1, uno::makeAny( aNewLevel ) ); - } - } - pContext->SetTOC( xTOC ); - m_bParaHadField = false; -} - -uno::Reference<beans::XPropertySet> DomainMapper_Impl::createSectionForRange( - uno::Reference< css::text::XTextRange > xStart, - uno::Reference< css::text::XTextRange > xEnd, - const OUString & sObjectType, - bool stepLeft) -{ - if (!xStart.is()) - return uno::Reference<beans::XPropertySet>(); - if (!xEnd.is()) - return uno::Reference<beans::XPropertySet>(); - - uno::Reference< beans::XPropertySet > xRet; - if (m_aTextAppendStack.empty()) - return xRet; - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if(xTextAppend.is()) - { - try - { - uno::Reference< text::XParagraphCursor > xCursor( - xTextAppend->createTextCursorByRange( xStart ), uno::UNO_QUERY_THROW); - //the cursor has been moved to the end of the paragraph because of the appendTextPortion() calls - xCursor->gotoStartOfParagraph( false ); - xCursor->gotoRange( xEnd, true ); - //the paragraph after this new section is already inserted - if (stepLeft) - xCursor->goLeft(1, true); - uno::Reference< text::XTextContent > xSection( m_xTextFactory->createInstance(sObjectType), uno::UNO_QUERY_THROW ); - xSection->attach( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW) ); - xRet.set(xSection, uno::UNO_QUERY ); - } - catch(const uno::Exception&) - { - } - } - - return xRet; -} - -void DomainMapper_Impl::handleBibliography - (const FieldContextPtr& pContext, - const OUString & sTOCServiceName) -{ - if (m_aTextAppendStack.empty()) - { - // tdf#130214: a workaround to avoid crash on import errors - SAL_WARN("writerfilter.dmapper", "no text append stack"); - return; - } - // Create section before setting m_bStartTOC and m_bStartBibliography: finishing paragraph - // inside StartIndexSectionChecked could do the wrong thing otherwise - const auto xTOC = StartIndexSectionChecked(sTOCServiceName); - m_bStartTOC = true; - m_bStartBibliography = true; - - if (xTOC.is()) - xTOC->setPropertyValue(getPropertyName( PROP_TITLE ), uno::makeAny(OUString())); - - pContext->SetTOC( xTOC ); - m_bParaHadField = false; - - uno::Reference< text::XTextContent > xToInsert( xTOC, uno::UNO_QUERY ); - appendTextContent(xToInsert, uno::Sequence< beans::PropertyValue >() ); -} - -void DomainMapper_Impl::handleIndex - (const FieldContextPtr& pContext, - const OUString & sTOCServiceName) -{ - // Create section before setting m_bStartTOC and m_bStartIndex: finishing paragraph - // inside StartIndexSectionChecked could do the wrong thing otherwise - const auto xTOC = StartIndexSectionChecked(sTOCServiceName); - - m_bStartTOC = true; - m_bStartIndex = true; - OUString sValue; - OUString sIndexEntryType = "I"; // Default value for field flag '\f' is 'I'. - - if (xTOC.is()) - { - xTOC->setPropertyValue(getPropertyName( PROP_TITLE ), uno::makeAny(OUString())); - - if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue )) - { - xTOC->setPropertyValue("IsCommaSeparated", uno::makeAny(true)); - } - if( lcl_FindInCommand( pContext->GetCommand(), 'h', sValue )) - { - xTOC->setPropertyValue("UseAlphabeticalSeparators", uno::makeAny(true)); - } - if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue )) - { - if(!sValue.isEmpty()) - sIndexEntryType = sValue ; - xTOC->setPropertyValue(getPropertyName( PROP_INDEX_ENTRY_TYPE ), uno::makeAny(sIndexEntryType)); - } - } - pContext->SetTOC( xTOC ); - m_bParaHadField = false; - - uno::Reference< text::XTextContent > xToInsert( xTOC, uno::UNO_QUERY ); - appendTextContent(xToInsert, uno::Sequence< beans::PropertyValue >() ); - - if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue )) - { - sValue = sValue.replaceAll("\"", ""); - uno::Reference<text::XTextColumns> xTextColumns; - xTOC->getPropertyValue(getPropertyName( PROP_TEXT_COLUMNS )) >>= xTextColumns; - if (xTextColumns.is()) - { - xTextColumns->setColumnCount( sValue.toInt32() ); - xTOC->setPropertyValue( getPropertyName( PROP_TEXT_COLUMNS ), uno::makeAny( xTextColumns ) ); - } - } -} - -static auto InsertFieldmark(std::stack<TextAppendContext> & rTextAppendStack, - uno::Reference<text::XFormField> const& xFormField, - uno::Reference<text::XTextRange> const& xStartRange, - std::optional<FieldId> const oFieldId) -> void -{ - uno::Reference<text::XTextContent> const xTextContent(xFormField, uno::UNO_QUERY_THROW); - uno::Reference<text::XTextAppend> const& xTextAppend(rTextAppendStack.top().xTextAppend); - uno::Reference<text::XTextCursor> const xCursor = - xTextAppend->createTextCursorByRange(xStartRange); - if (rTextAppendStack.top().xInsertPosition.is()) - { - uno::Reference<text::XTextRangeCompare> const xCompare( - rTextAppendStack.top().xTextAppend, - uno::UNO_QUERY); - if (xCompare->compareRegionStarts(xStartRange, rTextAppendStack.top().xInsertPosition) < 0) - { - SAL_WARN("writerfilter.dmapper", "invalid field mark positions"); - assert(false); - } - xCursor->gotoRange(rTextAppendStack.top().xInsertPosition, true); - } - else - { - xCursor->gotoEnd(true); - } - xTextAppend->insertTextContent(xCursor, xTextContent, true); - if (oFieldId - && (oFieldId == FIELD_FORMCHECKBOX || oFieldId == FIELD_FORMDROPDOWN)) - { - return; // only a single CH_TXT_ATR_FORMELEMENT! - } - // problem: the fieldmark must be inserted in CloseFieldCommand(), because - // attach() takes 2 positions, not 3! - // FAIL: AppendTextNode() ignores the content index! - // plan B: insert a spurious paragraph break now and join - // it in PopFieldContext()! - xCursor->gotoRange(xTextContent->getAnchor()->getEnd(), false); - xCursor->goLeft(1, false); // skip CH_TXT_ATR_FIELDEND - xTextAppend->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK, false); - xCursor->goLeft(1, false); // back to previous paragraph - rTextAppendStack.push(TextAppendContext(xTextAppend, xCursor)); -} - -static auto PopFieldmark(std::stack<TextAppendContext> & rTextAppendStack, - uno::Reference<text::XTextCursor> const& xCursor, - std::optional<FieldId> const oFieldId) -> void -{ - if (oFieldId - && (oFieldId == FIELD_FORMCHECKBOX || oFieldId == FIELD_FORMDROPDOWN)) - { - return; // only a single CH_TXT_ATR_FORMELEMENT! - } - xCursor->gotoRange(rTextAppendStack.top().xInsertPosition, false); - xCursor->goRight(1, true); - xCursor->setString(OUString()); // undo SplitNode from CloseFieldCommand() - // note: paragraph properties will be overwritten - // by finishParagraph() anyway so ignore here - rTextAppendStack.pop(); -} - -void DomainMapper_Impl::CloseFieldCommand() -{ - if(m_bDiscardHeaderFooter) - return; -#ifdef DBG_UTIL - TagLogger::getInstance().element("closeFieldCommand"); -#endif - - FieldContextPtr pContext; - if(!m_aFieldStack.empty()) - pContext = m_aFieldStack.back(); - OSL_ENSURE( pContext, "no field context available"); - if( !pContext ) - return; - - m_bSetUserFieldContent = false; - m_bSetCitation = false; - m_bSetDateValue = false; - const FieldConversionMap_t& aFieldConversionMap = lcl_GetFieldConversion(); - - try - { - uno::Reference< uno::XInterface > xFieldInterface; - - const auto& [sType, vArguments, vSwitches]{ splitFieldCommand(pContext->GetCommand()) }; - (void)vSwitches; - OUString const sFirstParam(vArguments.empty() ? OUString() : vArguments.front()); - - // apply font size to the form control - if (!m_aTextAppendStack.empty() && m_pLastCharacterContext && ( m_pLastCharacterContext->isSet(PROP_CHAR_HEIGHT) || m_pLastCharacterContext->isSet(PROP_CHAR_FONT_NAME ))) - { - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if (xTextAppend.is()) - { - uno::Reference< text::XTextCursor > xCrsr = xTextAppend->getText()->createTextCursor(); - if (xCrsr.is()) - { - xCrsr->gotoEnd(false); - uno::Reference< beans::XPropertySet > xProp( xCrsr, uno::UNO_QUERY ); - if (m_pLastCharacterContext->isSet(PROP_CHAR_HEIGHT)) - { - xProp->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), m_pLastCharacterContext->getProperty(PROP_CHAR_HEIGHT)->second); - if (m_pLastCharacterContext->isSet(PROP_CHAR_HEIGHT_COMPLEX)) - xProp->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT_COMPLEX), m_pLastCharacterContext->getProperty(PROP_CHAR_HEIGHT_COMPLEX)->second); - } - if (m_pLastCharacterContext->isSet(PROP_CHAR_FONT_NAME)) - xProp->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), m_pLastCharacterContext->getProperty(PROP_CHAR_FONT_NAME)->second); - } - } - } - - FieldConversionMap_t::const_iterator const aIt = aFieldConversionMap.find(sType); - if (aIt != aFieldConversionMap.end() - && (!m_bForceGenericFields - // these need to convert ffData to properties... - || (aIt->second.eFieldId == FIELD_FORMCHECKBOX) - || (aIt->second.eFieldId == FIELD_FORMDROPDOWN) - || (aIt->second.eFieldId == FIELD_FORMTEXT))) - { - pContext->SetFieldId(aIt->second.eFieldId); - bool bCreateEnhancedField = false; - uno::Reference< beans::XPropertySet > xFieldProperties; - bool bCreateField = true; - switch (aIt->second.eFieldId) - { - case FIELD_HYPERLINK: - case FIELD_DOCPROPERTY: - case FIELD_TOC: - case FIELD_INDEX: - case FIELD_XE: - case FIELD_BIBLIOGRAPHY: - case FIELD_CITATION: - case FIELD_TC: - case FIELD_EQ: - case FIELD_INCLUDEPICTURE: - case FIELD_SYMBOL: - case FIELD_GOTOBUTTON: - 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: - { - FieldContextPtr pOuter = GetParentFieldContext(m_aFieldStack); - if (pOuter) - { - if (!IsFieldNestingAllowed(pOuter, m_aFieldStack.back())) - { - // Parent field can't host this child field: don't create a child field - // in this case. - bCreateField = false; - } - } - break; - } - } - if (m_bStartTOC && (aIt->second.eFieldId == FIELD_PAGEREF) ) - { - bCreateField = false; - } - - if( bCreateField || bCreateEnhancedField ) - { - //add the service prefix - OUString sServiceName("com.sun.star.text."); - if ( bCreateEnhancedField ) - { - const FieldConversionMap_t& aEnhancedFieldConversionMap = lcl_GetEnhancedFieldConversion(); - FieldConversionMap_t::const_iterator aEnhancedIt = - aEnhancedFieldConversionMap.find(sType); - if ( aEnhancedIt != aEnhancedFieldConversionMap.end()) - sServiceName += OUString::createFromAscii(aEnhancedIt->second.cFieldServiceName ); - } - else - { - sServiceName += "TextField." + OUString::createFromAscii(aIt->second.cFieldServiceName ); - } - -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("fieldService"); - TagLogger::getInstance().chars(sServiceName); - TagLogger::getInstance().endElement(); -#endif - - if (m_xTextFactory.is()) - { - xFieldInterface = m_xTextFactory->createInstance(sServiceName); - xFieldProperties.set( xFieldInterface, uno::UNO_QUERY_THROW); - } - } - switch( aIt->second.eFieldId ) - { - case FIELD_ADDRESSBLOCK: break; - case FIELD_ADVANCE : break; - case FIELD_ASK : - handleFieldAsk(pContext, xFieldInterface, xFieldProperties); - break; - case FIELD_AUTONUM : - case FIELD_AUTONUMLGL : - case FIELD_AUTONUMOUT : - handleAutoNum(pContext, xFieldInterface, xFieldProperties); - break; - case FIELD_AUTHOR : - case FIELD_USERNAME : - case FIELD_USERINITIALS : - handleAuthor(sFirstParam, - xFieldProperties, - aIt->second.eFieldId); - break; - case FIELD_DATE: - if (xFieldProperties.is()) - { - // Get field fixed property from the context handler - if (pContext->IsFieldLocked()) - { - xFieldProperties->setPropertyValue( - getPropertyName(PROP_IS_FIXED), - uno::makeAny( true )); - m_bSetDateValue = true; - } - else - xFieldProperties->setPropertyValue( - getPropertyName(PROP_IS_FIXED), - uno::makeAny( false )); - - xFieldProperties->setPropertyValue( - getPropertyName(PROP_IS_DATE), - uno::makeAny( true )); - SetNumberFormat( pContext->GetCommand(), xFieldProperties ); - } - break; - case FIELD_COMMENTS : - { - // 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 won't 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( - getPropertyName( PROP_IS_FIXED ), uno::makeAny( false )); - //PROP_CURRENT_PRESENTATION is set later anyway - } - break; - case FIELD_CREATEDATE : - { - xFieldProperties->setPropertyValue( - getPropertyName( PROP_IS_DATE ), uno::makeAny( true )); - SetNumberFormat( pContext->GetCommand(), xFieldProperties ); - } - break; - case FIELD_DOCPROPERTY : - handleDocProperty(pContext, sFirstParam, - xFieldInterface); - break; - case FIELD_DOCVARIABLE : - { - if (bCreateField) - { - //create a user field and type - uno::Reference<beans::XPropertySet> xMaster = FindOrCreateFieldMaster( - "com.sun.star.text.FieldMaster.User", sFirstParam); - 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_EQ: - { - OUString aCommand = pContext->GetCommand().trim(); - - msfilter::util::EquationResult aResult(msfilter::util::ParseCombinedChars(aCommand)); - if (!aResult.sType.isEmpty() && m_xTextFactory.is()) - { - xFieldInterface = m_xTextFactory->createInstance("com.sun.star.text.TextField." + aResult.sType); - xFieldProperties = - uno::Reference< beans::XPropertySet >( xFieldInterface, - uno::UNO_QUERY_THROW); - xFieldProperties->setPropertyValue(getPropertyName(PROP_CONTENT), uno::makeAny(aResult.sResult)); - } - else - { - //merge Read_SubF_Ruby into filter/.../util.cxx and reuse that ? - sal_Int32 nSpaceIndex = aCommand.indexOf(' '); - if(nSpaceIndex > 0) - aCommand = aCommand.copy(nSpaceIndex).trim(); - if (aCommand.startsWith("\\s")) - { - aCommand = aCommand.copy(2); - if (aCommand.startsWith("\\do")) - { - aCommand = aCommand.copy(3); - sal_Int32 nStartIndex = aCommand.indexOf('('); - sal_Int32 nEndIndex = aCommand.indexOf(')'); - if (nStartIndex > 0 && nEndIndex > 0) - { - // nDown is the requested "lower by" value in points. - sal_Int32 nDown = aCommand.copy(0, nStartIndex).toInt32(); - OUString aContent = aCommand.copy(nStartIndex + 1, nEndIndex - nStartIndex - 1); - PropertyMapPtr pCharContext = GetTopContext(); - // dHeight is the font size of the current style. - double dHeight = 0; - if ((GetPropertyFromParaStyleSheet(PROP_CHAR_HEIGHT) >>= dHeight) && dHeight != 0) - // Character escapement should be given in negative percents for subscripts. - pCharContext->Insert(PROP_CHAR_ESCAPEMENT, uno::makeAny( sal_Int16(- 100 * nDown / dHeight) ) ); - appendTextPortion(aContent, pCharContext); - } - } - } - else if (aCommand.startsWith("\\* jc")) - { - handleRubyEQField(pContext); - } - } - } - break; - case FIELD_FILLIN : - if (xFieldProperties.is()) - xFieldProperties->setPropertyValue( - getPropertyName(PROP_HINT), uno::makeAny( pContext->GetCommand().getToken(1, '\"'))); - break; - case FIELD_FILENAME: - { - sal_Int32 nNumberingTypeIndex = pContext->GetCommand().indexOf("\\p"); - if (xFieldProperties.is()) - xFieldProperties->setPropertyValue( - getPropertyName(PROP_FILE_FORMAT), - uno::makeAny( nNumberingTypeIndex > 0 ? text::FilenameDisplayFormat::FULL : text::FilenameDisplayFormat::NAME_AND_EXT )); - } - break; - case FIELD_FILESIZE : break; - case FIELD_FORMULA : - if (bCreateField) - { - handleFieldFormula(pContext, xFieldProperties); - } - break; - case FIELD_FORMCHECKBOX : - case FIELD_FORMDROPDOWN : - case FIELD_FORMTEXT : - { - if (bCreateEnhancedField) - { - 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().isEmpty() ) - xNamed->setName( pFFDataHandler->getName() ); - pContext->SetFormField( xFormField ); - } - InsertFieldmark(m_aTextAppendStack, - xFormField, pContext->GetStartRange(), - pContext->GetFieldId()); - } - else - { - if ( aIt->second.eFieldId == FIELD_FORMDROPDOWN ) - lcl_handleDropdownField( xFieldProperties, pContext->getFFDataHandler() ); - else - lcl_handleTextField( xFieldProperties, pContext->getFFDataHandler() ); - } - } - break; - case FIELD_GOTOBUTTON : break; - case FIELD_HYPERLINK: - { - ::std::vector<OUString> aParts = pContext->GetCommandParts(); - - // Syntax is either: - // HYPERLINK "" \l "link" - // or - // HYPERLINK \l "link" - // Make sure "HYPERLINK" doesn't end up as part of link in the second case. - if (!aParts.empty() && aParts[0] == "HYPERLINK") - aParts.erase(aParts.begin()); - - ::std::vector<OUString>::const_iterator aItEnd = aParts.end(); - ::std::vector<OUString>::const_iterator aPartIt = aParts.begin(); - - OUString sURL; - OUString sTarget; - - while (aPartIt != aItEnd) - { - if ( *aPartIt == "\\l" ) - { - ++aPartIt; - - if (aPartIt == aItEnd) - break; - - sURL += "#" + *aPartIt; - } - else if (*aPartIt == "\\m" || *aPartIt == "\\n" || *aPartIt == "\\h") - { - } - else if ( *aPartIt == "\\o" || *aPartIt == "\\t" ) - { - ++aPartIt; - - if (aPartIt == aItEnd) - break; - - sTarget = *aPartIt; - } - else - { - sURL = *aPartIt; - } - - ++aPartIt; - } - - if (!sURL.isEmpty()) - { - if (sURL.startsWith("file:///")) - { - // file:///absolute\\path\\to\\file => invalid file URI (Writer cannot open) - // convert all double backslashes to slashes: - sURL = sURL.replaceAll("\\\\", "/"); - - // file:///absolute\path\to\file => invalid file URI (Writer cannot open) - // convert all backslashes to slashes: - sURL = sURL.replace('\\', '/'); - } - // Try to make absolute any relative URLs, except - // for relative same-document URLs that only contain - // a fragment part: - else if (!sURL.startsWith("#")) { - try { - sURL = rtl::Uri::convertRelToAbs( - m_aBaseUrl, sURL); - } catch (rtl::MalformedUriException & e) { - SAL_WARN( - "writerfilter.dmapper", - "MalformedUriException " - << e.getMessage()); - } - } - pContext->SetHyperlinkURL(sURL); - } - - if (!sTarget.isEmpty()) - pContext->SetHyperlinkTarget(sTarget); - } - break; - case FIELD_IF : break; - case FIELD_INFO : break; - case FIELD_INCLUDEPICTURE: break; - case FIELD_KEYWORDS : - { - if (!sFirstParam.isEmpty()) - { - xFieldProperties->setPropertyValue( - getPropertyName( 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 "); - OUString sMacro = pContext->GetCommand().getToken( 0, ' ', nIndex); - if (xFieldProperties.is()) - xFieldProperties->setPropertyValue( - getPropertyName(PROP_MACRO_NAME), uno::makeAny( sMacro )); - - //extract quick help text - if(xFieldProperties.is() && pContext->GetCommand().getLength() > nIndex + 1) - { - xFieldProperties->setPropertyValue( - getPropertyName(PROP_HINT), - uno::makeAny( pContext->GetCommand().copy( nIndex ))); - } - } - break; - case FIELD_MERGEFIELD : - { - //todo: create a database field and fieldmaster pointing to a column, only - //create a user field and type - uno::Reference< beans::XPropertySet > xMaster = - FindOrCreateFieldMaster("com.sun.star.text.FieldMaster.Database", sFirstParam); - -// xFieldProperties->setPropertyValue( -// "FieldCode", -// uno::makeAny( pContext->GetCommand().copy( nIndex + 1 ))); - uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW ); - xDependentField->attachTextFieldMaster( xMaster ); - } - break; - case FIELD_MERGEREC : break; - case FIELD_MERGESEQ : break; - case FIELD_NEXT : break; - case FIELD_NEXTIF : break; - case FIELD_PAGE : - if (xFieldProperties.is()) - { - xFieldProperties->setPropertyValue( - getPropertyName(PROP_NUMBERING_TYPE), - uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) )); - xFieldProperties->setPropertyValue( - getPropertyName(PROP_SUB_TYPE), - uno::makeAny( text::PageNumberType_CURRENT )); - } - - break; - case FIELD_PAGEREF: - case FIELD_REF: - if (xFieldProperties.is() && !m_bStartTOC) - { - bool bPageRef = aIt->second.eFieldId == FIELD_PAGEREF; - - // Do we need a GetReference (default) or a GetExpression field? - uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY ); - uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters(); - - if (!xFieldMasterAccess->hasByName( - "com.sun.star.text.FieldMaster.SetExpression." - + sFirstParam)) - { - xFieldProperties->setPropertyValue( - getPropertyName(PROP_REFERENCE_FIELD_SOURCE), - uno::makeAny( sal_Int16(text::ReferenceFieldSource::BOOKMARK)) ); - xFieldProperties->setPropertyValue( - getPropertyName(PROP_SOURCE_NAME), - uno::makeAny(sFirstParam) ); - sal_Int16 nFieldPart = (bPageRef ? text::ReferenceFieldPart::PAGE : text::ReferenceFieldPart::TEXT); - OUString sValue; - if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue )) - { - //above-below - nFieldPart = text::ReferenceFieldPart::UP_DOWN; - } - else if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue )) - { - //number - nFieldPart = text::ReferenceFieldPart::NUMBER; - } - else if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue )) - { - //number-no-context - nFieldPart = text::ReferenceFieldPart::NUMBER_NO_CONTEXT; - } - else if( lcl_FindInCommand( pContext->GetCommand(), 'w', sValue )) - { - //number-full-context - nFieldPart = text::ReferenceFieldPart::NUMBER_FULL_CONTEXT; - } - xFieldProperties->setPropertyValue( - getPropertyName( PROP_REFERENCE_FIELD_PART ), uno::makeAny( nFieldPart )); - } - else if( m_xTextFactory.is() ) - { - xFieldInterface = m_xTextFactory->createInstance("com.sun.star.text.TextField.GetExpression"); - xFieldProperties.set(xFieldInterface, uno::UNO_QUERY); - xFieldProperties->setPropertyValue( - getPropertyName(PROP_CONTENT), - uno::makeAny(sFirstParam)); - xFieldProperties->setPropertyValue(getPropertyName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING)); - } - } - break; - case FIELD_REVNUM : break; - case FIELD_SAVEDATE : - SetNumberFormat( pContext->GetCommand(), xFieldProperties ); - break; - case FIELD_SECTION : break; - case FIELD_SECTIONPAGES : break; - case FIELD_SEQ : - { - // command looks like: " SEQ Table \* ARABIC " - OUString sCmd(pContext->GetCommand()); - // find the sequence name, e.g. "SEQ" - OUString sSeqName = msfilter::util::findQuotedText(sCmd, "SEQ ", '\\'); - sSeqName = sSeqName.trim(); - - // create a sequence field master using the sequence name - uno::Reference< beans::XPropertySet > xMaster = FindOrCreateFieldMaster( - "com.sun.star.text.FieldMaster.SetExpression", - sSeqName); - - xMaster->setPropertyValue( - getPropertyName(PROP_SUB_TYPE), - uno::makeAny(text::SetVariableType::SEQUENCE)); - - // apply the numbering type - xFieldProperties->setPropertyValue( - getPropertyName(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 ); - - OUString sFormula = sSeqName + "+1"; - OUString sValue; - if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue )) - { - sFormula = sSeqName; - } - else if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue )) - { - sFormula = sValue; - } - // TODO \s isn't handled, but the spec isn't easy to understand without - // an example for this one. - xFieldProperties->setPropertyValue( - getPropertyName(PROP_CONTENT), - uno::makeAny(sFormula)); - - // Take care of the numeric formatting definition, default is Arabic - sal_Int16 nNumberingType = lcl_ParseNumberingType(pContext->GetCommand()); - if (nNumberingType == style::NumberingType::PAGE_DESCRIPTOR) - nNumberingType = style::NumberingType::ARABIC; - xFieldProperties->setPropertyValue( - getPropertyName(PROP_NUMBERING_TYPE), - uno::makeAny(nNumberingType)); - } - break; - case FIELD_SET : - handleFieldSet(pContext, xFieldInterface, xFieldProperties); - break; - case FIELD_SKIPIF : break; - case FIELD_STYLEREF : break; - case FIELD_SUBJECT : - { - if (!sFirstParam.isEmpty()) - { - xFieldProperties->setPropertyValue( - getPropertyName( PROP_IS_FIXED ), uno::makeAny( true )); - //PROP_CURRENT_PRESENTATION is set later anyway - } - } - break; - case FIELD_SYMBOL: - { - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - OUString sSymbol( sal_Unicode( sFirstParam.startsWithIgnoreAsciiCase("0x") ? sFirstParam.copy(2).toUInt32(16) : sFirstParam.toUInt32() ) ); - OUString sFont; - bool bHasFont = lcl_FindInCommand( pContext->GetCommand(), 'f', sFont); - if ( bHasFont ) - { - sFont = sFont.trim(); - if (sFont.startsWith("\"")) - sFont = sFont.copy(1); - if (sFont.endsWith("\"")) - sFont = sFont.copy(0,sFont.getLength()-1); - } - - - - if (xTextAppend.is()) - { - uno::Reference< text::XText > xText = xTextAppend->getText(); - uno::Reference< text::XTextCursor > xCrsr = xText->createTextCursor(); - if (xCrsr.is()) - { - xCrsr->gotoEnd(false); - xText->insertString(xCrsr, sSymbol, true); - uno::Reference< beans::XPropertySet > xProp( xCrsr, uno::UNO_QUERY ); - xProp->setPropertyValue(getPropertyName(PROP_CHAR_FONT_CHAR_SET), uno::makeAny(awt::CharSet::SYMBOL)); - if(bHasFont) - { - uno::Any aVal = uno::makeAny( sFont ); - xProp->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), aVal); - xProp->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_ASIAN), aVal); - xProp->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME_COMPLEX), aVal); - - } - } - } - } - break; - case FIELD_TEMPLATE: break; - case FIELD_TIME : - { - if (pContext->IsFieldLocked()) - { - xFieldProperties->setPropertyValue( - getPropertyName(PROP_IS_FIXED), - uno::makeAny( true )); - m_bSetDateValue = true; - } - SetNumberFormat( pContext->GetCommand(), xFieldProperties ); - } - break; - case FIELD_TITLE : - { - if (!sFirstParam.isEmpty()) - { - xFieldProperties->setPropertyValue( - getPropertyName( 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_INDEX: - handleIndex(pContext, - OUString::createFromAscii(aIt->second.cFieldServiceName)); - break; - case FIELD_BIBLIOGRAPHY: - handleBibliography(pContext, - OUString::createFromAscii(aIt->second.cFieldServiceName)); - break; - case FIELD_TOC: - handleToc(pContext, - OUString::createFromAscii(aIt->second.cFieldServiceName)); - break; - case FIELD_XE: - { - if( !m_xTextFactory.is() ) - break; - - uno::Reference< beans::XPropertySet > xTC( - m_xTextFactory->createInstance( - OUString::createFromAscii(aIt->second.cFieldServiceName)), - uno::UNO_QUERY_THROW); - if (!sFirstParam.isEmpty()) - { - xTC->setPropertyValue("PrimaryKey", - uno::makeAny(sFirstParam)); - } - uno::Reference< text::XTextContent > xToInsert( xTC, uno::UNO_QUERY ); - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - if (xTextAppend.is()) - { - uno::Reference< text::XText > xText = xTextAppend->getText(); - uno::Reference< text::XTextCursor > xCrsr = xText->createTextCursor(); - if (xCrsr.is()) - { - xCrsr->gotoEnd(false); - xText->insertTextContent(uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ), xToInsert, false); - } - } - } - break; - case FIELD_CITATION: - { - if( !m_xTextFactory.is() ) - break; - - xFieldInterface = m_xTextFactory->createInstance( - OUString::createFromAscii(aIt->second.cFieldServiceName)); - uno::Reference< beans::XPropertySet > xTC(xFieldInterface, - uno::UNO_QUERY_THROW); - OUString sCmd(pContext->GetCommand());//sCmd is the entire instrText including the index e.g. CITATION Kra06 \l 1033 - if( !sCmd.isEmpty()){ - uno::Sequence<beans::PropertyValue> aValues( comphelper::InitPropertySequence({ - { "Identifier", uno::Any(sCmd) } - })); - xTC->setPropertyValue("Fields", uno::makeAny(aValues)); - } - uno::Reference< text::XTextContent > xToInsert( xTC, uno::UNO_QUERY ); - - uno::Sequence<beans::PropertyValue> aValues - = m_aFieldStack.back()->getProperties()->GetPropertyValues(); - appendTextContent(xToInsert, aValues); - m_bSetCitation = true; - } - break; - - case FIELD_TC : - { - if( !m_xTextFactory.is() ) - break; - - uno::Reference< beans::XPropertySet > xTC( - m_xTextFactory->createInstance( - OUString::createFromAscii(aIt->second.cFieldServiceName)), - uno::UNO_QUERY_THROW); - if (!sFirstParam.isEmpty()) - { - xTC->setPropertyValue(getPropertyName(PROP_ALTERNATIVE_TEXT), - uno::makeAny(sFirstParam)); - } - 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.isEmpty() && nLevel >= 0 && nLevel <= 10 ) - xTC->setPropertyValue(getPropertyName(PROP_LEVEL), uno::makeAny( static_cast<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: - if (xFieldProperties.is()) - xFieldProperties->setPropertyValue( - getPropertyName(PROP_NUMBERING_TYPE), - uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) )); - break; - } - - if (!bCreateEnhancedField) - { - pContext->SetTextField( uno::Reference<text::XTextField>(xFieldInterface, uno::UNO_QUERY) ); - } - } - else - { - /* Unsupported fields will be handled here for docx file. - * To handle unsupported fields used fieldmark API. - */ - OUString aCode( pContext->GetCommand().trim() ); - // Don't waste resources on wrapping shapes inside a fieldmark. - if (sType != "SHAPE" && m_xTextFactory.is() && !m_aTextAppendStack.empty()) - { - xFieldInterface = m_xTextFactory->createInstance("com.sun.star.text.Fieldmark"); - - uno::Reference<text::XFormField> const xFormField(xFieldInterface, uno::UNO_QUERY); - InsertFieldmark(m_aTextAppendStack, xFormField, pContext->GetStartRange(), - pContext->GetFieldId()); - xFormField->setFieldType(ODF_UNHANDLED); - ++m_nStartGenericField; - pContext->SetFormField( xFormField ); - uno::Reference<container::XNameContainer> const xNameCont(xFormField->getParameters()); - // note: setting the code to empty string is *required* in - // m_bForceGenericFields mode, or the export will write - // the ODF_UNHANDLED string! - assert(!m_bForceGenericFields || aCode.isEmpty()); - xNameCont->insertByName(ODF_CODE_PARAM, uno::makeAny(aCode)); - ww::eField const id(GetWW8FieldId(sType)); - if (id != ww::eNONE) - { // tdf#129247 tdf#134264 set WW8 id for WW8 export - xNameCont->insertByName(ODF_ID_PARAM, uno::makeAny(OUString::number(id))); - } - } - else - m_bParaHadField = false; - } - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter.dmapper", "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.back(); - OSL_ENSURE( pContext, "no field context available"); - if( pContext ) - { - bRet = pContext->GetTextField().is() - || pContext->GetFieldId() == FIELD_FORMDROPDOWN - || pContext->GetFieldId() == FIELD_FILLIN; - } - - if (!bRet) - { - FieldContextPtr pOuter = GetParentFieldContext(m_aFieldStack); - if (pOuter) - { - if (!IsFieldNestingAllowed(pOuter, m_aFieldStack.back())) - { - // If nesting is not allowed, then the result can only be a string. - bRet = true; - } - } - } - return bRet; -} - -void DomainMapper_Impl::AppendFieldResult(std::u16string_view rString) -{ - assert(!m_aFieldStack.empty()); - FieldContextPtr pContext = m_aFieldStack.back(); - SAL_WARN_IF(!pContext, "writerfilter.dmapper", "no field context"); - if (!pContext) - return; - - FieldContextPtr pOuter = GetParentFieldContext(m_aFieldStack); - if (pOuter) - { - if (!IsFieldNestingAllowed(pOuter, pContext)) - { - if (pOuter->IsCommandCompleted()) - { - // Child can't host the field result, forward to parent's result. - pOuter->AppendResult(rString); - } - return; - } - } - - pContext->AppendResult(rString); -} - -// Calculates css::DateTime based on ddddd.sssss since 1900-1-0 -static util::DateTime lcl_dateTimeFromSerial(const double& dSerial) -{ - const sal_uInt32 secondsPerDay = 86400; - const sal_uInt16 secondsPerHour = 3600; - - DateTime d(Date(30, 12, 1899)); - d.AddDays( static_cast<sal_Int32>(dSerial) ); - - double frac = std::modf(dSerial, &o3tl::temporary(double())); - sal_uInt32 seconds = frac * secondsPerDay; - - util::DateTime date; - date.Year = d.GetYear(); - date.Month = d.GetMonth(); - date.Day = d.GetDay(); - date.Hours = seconds / secondsPerHour; - date.Minutes = (seconds % secondsPerHour) / 60; - date.Seconds = seconds % 60; - - return date; -} - -void DomainMapper_Impl::SetFieldResult(OUString const& rResult) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("setFieldResult"); - TagLogger::getInstance().chars(rResult); -#endif - - FieldContextPtr pContext = m_aFieldStack.back(); - OSL_ENSURE( pContext, "no field context available"); - - if (m_aFieldStack.size() > 1) - { - // This is a nested field. See if the parent supports nesting on the Writer side. - FieldContextPtr pParentContext = m_aFieldStack[m_aFieldStack.size() - 2]; - if (pParentContext) - { - std::vector<OUString> aParentParts = pParentContext->GetCommandParts(); - // Conditional text fields don't support nesting in Writer. - if (!aParentParts.empty() && aParentParts[0] == "IF") - { - return; - } - } - } - - if( !pContext ) - return; - - uno::Reference<text::XTextField> xTextField = pContext->GetTextField(); - try - { - 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( - getPropertyName(PROP_CONTENT), - uno::makeAny( rResult )); - } - else if ( m_bSetCitation ) - { - - uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW); - // In case of SetExpression, the field result contains the content of the variable. - uno::Reference<lang::XServiceInfo> xServiceInfo(xTextField, uno::UNO_QUERY); - - bool bIsSetbiblio = xServiceInfo->supportsService("com.sun.star.text.TextField.Bibliography"); - if( bIsSetbiblio ) - { - uno::Any aProperty = xFieldProperties->getPropertyValue("Fields"); - uno::Sequence<beans::PropertyValue> aValues ; - aProperty >>= aValues; - beans::PropertyValue propertyVal; - sal_Int32 nTitleFoundIndex = -1; - for (sal_Int32 i = 0; i < aValues.getLength(); ++i) - { - propertyVal = aValues[i]; - if (propertyVal.Name == "Title") - { - nTitleFoundIndex = i; - break; - } - } - if (nTitleFoundIndex != -1) - { - OUString titleStr; - uno::Any aValue(propertyVal.Value); - aValue >>= titleStr; - titleStr += rResult; - propertyVal.Value <<= titleStr; - aValues[nTitleFoundIndex] = propertyVal; - } - else - { - aValues.realloc(aValues.getLength() + 1); - propertyVal.Name = "Title"; - propertyVal.Value <<= rResult; - aValues[aValues.getLength() - 1] = propertyVal; - } - xFieldProperties->setPropertyValue("Fields", - uno::makeAny(aValues)); - } - } - else if ( m_bSetDateValue ) - { - uno::Reference< util::XNumberFormatsSupplier > xNumberSupplier( m_xTextDocument, uno::UNO_QUERY_THROW ); - - uno::Reference<util::XNumberFormatter> xFormatter(util::NumberFormatter::create(m_xComponentContext), uno::UNO_QUERY_THROW); - xFormatter->attachNumberFormatsSupplier( xNumberSupplier ); - sal_Int32 nKey = 0; - - uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW); - - xFieldProperties->getPropertyValue( "NumberFormat" ) >>= nKey; - xFieldProperties->setPropertyValue( - "DateTimeValue", - uno::makeAny( lcl_dateTimeFromSerial( xFormatter->convertStringToNumber( nKey, rResult ) ) ) ); - } - else - { - uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW); - // In case of SetExpression, and Input fields the field result contains the content of the variable. - uno::Reference<lang::XServiceInfo> xServiceInfo(xTextField, uno::UNO_QUERY); - // there are fields with a content property, which aren't working correctly with - // a generalized try catch of the content, property, so just restrict content - // handling to these explicit services. - const bool bHasContent = xServiceInfo->supportsService("com.sun.star.text.TextField.SetExpression") || - xServiceInfo->supportsService("com.sun.star.text.TextField.Input"); - // If we already have content set, then use the current presentation - OUString sValue; - if (bHasContent) - { - // this will throw for field types without Content - uno::Any aValue(xFieldProperties->getPropertyValue( - getPropertyName(PROP_CONTENT))); - aValue >>= sValue; - } - xFieldProperties->setPropertyValue( - getPropertyName(bHasContent && sValue.isEmpty()? PROP_CONTENT : PROP_CURRENT_PRESENTATION), - uno::makeAny( rResult )); - - if (xServiceInfo->supportsService( - "com.sun.star.text.TextField.DocInfo.CreateDateTime")) - { - // Creation time is const, don't try to update it. - xFieldProperties->setPropertyValue("IsFixed", uno::makeAny(true)); - } - } - } - catch( const beans::UnknownPropertyException& ) - { - //some fields don't have a CurrentPresentation (DateTime) - } - } - } - catch (const uno::Exception&) - { - TOOLS_WARN_EXCEPTION("writerfilter.dmapper", "DomainMapper_Impl::SetFieldResult"); - } -} - -void DomainMapper_Impl::SetFieldFFData(const FFDataHandler::Pointer_t& pFFDataHandler) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("setFieldFFData"); -#endif - - if (!m_aFieldStack.empty()) - { - FieldContextPtr pContext = m_aFieldStack.back(); - if (pContext) - { - pContext->setFFDataHandler(pFFDataHandler); - } - } - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void DomainMapper_Impl::PopFieldContext() -{ - if(m_bDiscardHeaderFooter) - return; -#ifdef DBG_UTIL - TagLogger::getInstance().element("popFieldContext"); -#endif - - if (m_aFieldStack.empty()) - return; - - FieldContextPtr pContext = m_aFieldStack.back(); - OSL_ENSURE( pContext, "no field context available"); - if( pContext ) - { - if( !pContext->IsCommandCompleted() ) - CloseFieldCommand(); - - if (!pContext->GetResult().isEmpty()) - { - uno::Reference< beans::XPropertySet > xFieldProperties = pContext->GetCustomField(); - if(xFieldProperties.is()) - SetNumberFormat( pContext->GetResult(), xFieldProperties, true ); - SetFieldResult( pContext->GetResult() ); - } - - //insert the field, TC or TOC - uno::Reference< text::XTextAppend > xTextAppend; - if (!m_aTextAppendStack.empty()) - xTextAppend = m_aTextAppendStack.top().xTextAppend; - if(xTextAppend.is()) - { - try - { - uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange()); - uno::Reference< text::XTextContent > xToInsert( pContext->GetTOC(), uno::UNO_QUERY ); - if( xToInsert.is() ) - { - if (m_bStartedTOC || m_bStartIndex || m_bStartBibliography) - { - // inside SDT, last empty paragraph is also part of index - if (!m_bParaChanged && !m_xSdtEntryStart) - { - // End of index is the first item on a new paragraph - this paragraph - // should not be part of index - auto xCursor - = xTextAppend->createTextCursorByRange(xTextAppend->getEnd()); - xCursor->gotoEnd(false); - xCursor->goLeft(1, true); - // delete - xCursor->setString(OUString()); - // But a new paragraph should be started after the index instead - xTextAppend->finishParagraph(css::beans::PropertyValues()); - } - m_bStartedTOC = false; - m_aTextAppendStack.pop(); - m_bTextInserted = false; - m_bParaChanged = true; // the paragraph must stay anyway - } - m_bStartTOC = false; - m_bStartIndex = false; - m_bStartBibliography = false; - if (IsInHeaderFooter() && m_bStartTOCHeaderFooter) - m_bStartTOCHeaderFooter = false; - } - else - { - xToInsert.set(pContext->GetTC(), uno::UNO_QUERY); - if( !xToInsert.is() && !m_bStartTOC && !m_bStartIndex && !m_bStartBibliography ) - xToInsert = pContext->GetTextField(); - if( xToInsert.is() && !m_bStartTOC && !m_bStartIndex && !m_bStartBibliography) - { - PropertyMap aMap; - // Character properties of the field show up here the - // last (always empty) run. Inherit character - // properties from there. - // Also merge in the properties from the field context, - // e.g. SdtEndBefore. - if (m_pLastCharacterContext) - aMap.InsertProps(m_pLastCharacterContext); - aMap.InsertProps(m_aFieldStack.back()->getProperties()); - appendTextContent(xToInsert, aMap.GetPropertyValues()); - CheckRedline( xToInsert->getAnchor( ) ); - } - else - { - FormControlHelper::Pointer_t pFormControlHelper(pContext->getFormControlHelper()); - if (pFormControlHelper) - { - uno::Reference< text::XFormField > xFormField( pContext->GetFormField() ); - assert(xCrsr.is()); - if (pFormControlHelper->hasFFDataHandler()) - { - xToInsert.set(xFormField, uno::UNO_QUERY); - if (xFormField.is() && xToInsert.is()) - { - PopFieldmark(m_aTextAppendStack, xCrsr, - pContext->GetFieldId()); - pFormControlHelper->processField( xFormField ); - } - else - { - pFormControlHelper->insertControl(xCrsr); - } - } - else - { - PopFieldmark(m_aTextAppendStack, xCrsr, - pContext->GetFieldId()); - uno::Reference<lang::XComponent>(xFormField, uno::UNO_QUERY_THROW)->dispose(); // presumably invalid? - } - } - else if (!pContext->GetHyperlinkURL().isEmpty() && xCrsr.is()) - { - xCrsr->gotoEnd( true ); - - // Draw components (like comments) need hyperlinks set differently - SvxUnoTextRangeBase* pDrawText = dynamic_cast<SvxUnoTextRangeBase*>(xCrsr.get()); - if ( pDrawText ) - pDrawText->attachField( std::make_unique<SvxURLField>(pContext->GetHyperlinkURL(), xCrsr->getString(), SvxURLFormat::AppDefault) ); - else - { - uno::Reference< beans::XPropertySet > xCrsrProperties( xCrsr, uno::UNO_QUERY_THROW ); - xCrsrProperties->setPropertyValue(getPropertyName(PROP_HYPER_LINK_U_R_L), uno:: - makeAny(pContext->GetHyperlinkURL())); - - if (!pContext->GetHyperlinkTarget().isEmpty()) - xCrsrProperties->setPropertyValue("HyperLinkTarget", uno::makeAny(pContext->GetHyperlinkTarget())); - - if (m_bStartTOC) { - OUString sDisplayName("Index Link"); - xCrsrProperties->setPropertyValue("VisitedCharStyleName",uno::makeAny(sDisplayName)); - xCrsrProperties->setPropertyValue("UnvisitedCharStyleName",uno::makeAny(sDisplayName)); - } - else - { - uno::Any aAny = xCrsrProperties->getPropertyValue("CharStyleName"); - OUString charStyle; - if (css::uno::fromAny(aAny, &charStyle)) - { - if (charStyle.isEmpty()) - { - xCrsrProperties->setPropertyValue("VisitedCharStyleName", uno::makeAny(OUString("Default Style"))); - xCrsrProperties->setPropertyValue("UnvisitedCharStyleName", uno::makeAny(OUString("Default Style"))); - } - else if (charStyle.equalsIgnoreAsciiCase("Internet Link")) - { - xCrsrProperties->setPropertyValue("CharStyleName", uno::makeAny(OUString("Default Style"))); - } - else - { - xCrsrProperties->setPropertyValue("VisitedCharStyleName", aAny); - xCrsrProperties->setPropertyValue("UnvisitedCharStyleName", aAny); - } - } - } - } - } - else if (m_nStartGenericField != 0) - { - --m_nStartGenericField; - PopFieldmark(m_aTextAppendStack, xCrsr, pContext->GetFieldId()); - if(m_bTextInserted) - { - m_bTextInserted = false; - } - } - } - } - } - catch(const lang::IllegalArgumentException&) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "PopFieldContext()" ); - } - catch(const uno::Exception&) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "PopFieldContext()" ); - } - } - - //TOCs have to include all the imported content - } - - std::vector<FieldParagraph> aParagraphsToFinish; - if (pContext) - { - aParagraphsToFinish = pContext->GetParagraphsToFinish(); - } - - //remove the field context - m_aFieldStack.pop_back(); - - // Finish the paragraph(s) now that the field is closed. - for (const auto& rFinish : aParagraphsToFinish) - { - finishParagraph(rFinish.m_pPropertyMap, rFinish.m_bRemove); - } -} - - -void DomainMapper_Impl::SetBookmarkName( const OUString& rBookmarkName ) -{ - BookmarkMap_t::iterator aBookmarkIter = m_aBookmarkMap.find( m_sCurrentBkmkId ); - if( aBookmarkIter != m_aBookmarkMap.end() ) - { - // fields are internal bookmarks: consume redundant "normal" bookmark - if ( IsOpenField() ) - { - FFDataHandler::Pointer_t pFFDataHandler(GetTopFieldContext()->getFFDataHandler()); - if (pFFDataHandler && pFFDataHandler->getName() == rBookmarkName) - { - // HACK: At the END marker, StartOrEndBookmark will START - // a bookmark which will eventually be abandoned, not created. - m_aBookmarkMap.erase(aBookmarkIter); - return; - } - } - - aBookmarkIter->second.m_sBookmarkName = rBookmarkName; - } - else - m_sCurrentBkmkName = rBookmarkName; -} - -// This method was used as-is for DomainMapper_Impl::startOrEndPermissionRange() implementation. -void DomainMapper_Impl::StartOrEndBookmark( const OUString& rId ) -{ - /* - * Add the dummy paragraph to handle section properties - * iff the first element in the section is a table. If the dummy para is not added yet, then add it; - * So bookmark is not attached to the wrong paragraph. - */ - if(hasTableManager() && getTableManager().isInCell() && m_nTableDepth == 0 && GetIsFirstParagraphInSection() - && !GetIsDummyParaAddedForTableInSection() &&!GetIsTextFrameInserted()) - { - AddDummyParaForTableInSection(); - } - - bool bIsAfterDummyPara = GetIsDummyParaAddedForTableInSection() && GetIsFirstParagraphInSection(); - if (m_aTextAppendStack.empty()) - return; - 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() ) - { - if (m_xTextFactory.is()) - { - uno::Reference< text::XTextContent > xBookmark( m_xTextFactory->createInstance( "com.sun.star.text.Bookmark" ), uno::UNO_QUERY_THROW ); - uno::Reference< text::XTextCursor > xCursor; - uno::Reference< text::XText > xText = aBookmarkIter->second.m_xTextRange->getText(); - if( aBookmarkIter->second.m_bIsStartOfText && !bIsAfterDummyPara) - { - xCursor = xText->createTextCursorByRange( xText->getStart() ); - } - else - { - xCursor = xText->createTextCursorByRange( aBookmarkIter->second.m_xTextRange ); - xCursor->goRight( 1, false ); - } - - xCursor->gotoRange( xTextAppend->getEnd(), true ); - // A Paragraph was recently finished, and a new Paragraph has not been started as yet - // then move the bookmark-End to the earlier paragraph - if (IsOutsideAParagraph()) - { - xCursor->goLeft( 1, false ); - } - uno::Reference< container::XNamed > xBkmNamed( xBookmark, uno::UNO_QUERY_THROW ); - assert(!aBookmarkIter->second.m_sBookmarkName.isEmpty()); - //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 ); - m_sCurrentBkmkId.clear(); - } - else - { - //otherwise insert a text range as marker - bool bIsStart = true; - uno::Reference< text::XTextRange > xCurrent; - if (xTextAppend.is()) - { - uno::Reference<text::XTextCursor> const xCursor = - xTextAppend->createTextCursorByRange( - m_aTextAppendStack.top().xInsertPosition.is() - ? m_aTextAppendStack.top().xInsertPosition - : xTextAppend->getEnd() ); - - if (!xCursor) - return; - - if (!bIsAfterDummyPara) - bIsStart = !xCursor->goLeft(1, false); - xCurrent = xCursor->getStart(); - } - m_sCurrentBkmkId = rId; - m_aBookmarkMap.emplace( rId, BookmarkInsertPosition( bIsStart, m_sCurrentBkmkName, xCurrent ) ); - m_sCurrentBkmkName.clear(); - } - } - catch( const uno::Exception& ) - { - //TODO: What happens to bookmarks where start and end are at different XText objects? - } -} - -void DomainMapper_Impl::setPermissionRangeEd(const OUString& user) -{ - PermMap_t::iterator aPremIter = m_aPermMap.find(m_sCurrentPermId); - if (aPremIter != m_aPermMap.end()) - aPremIter->second.m_Ed = user; - else - m_sCurrentPermEd = user; -} - -void DomainMapper_Impl::setPermissionRangeEdGrp(const OUString& group) -{ - PermMap_t::iterator aPremIter = m_aPermMap.find(m_sCurrentPermId); - if (aPremIter != m_aPermMap.end()) - aPremIter->second.m_EdGrp = group; - else - m_sCurrentPermEdGrp = group; -} - -// This method is based on implementation from DomainMapper_Impl::StartOrEndBookmark() -void DomainMapper_Impl::startOrEndPermissionRange(sal_Int32 permissinId) -{ - /* - * Add the dummy paragraph to handle section properties - * if the first element in the section is a table. If the dummy para is not added yet, then add it; - * So permission is not attached to the wrong paragraph. - */ - if (getTableManager().isInCell() && m_nTableDepth == 0 && GetIsFirstParagraphInSection() - && !GetIsDummyParaAddedForTableInSection() && !GetIsTextFrameInserted()) - { - AddDummyParaForTableInSection(); - } - - if (m_aTextAppendStack.empty()) - return; - - const bool bIsAfterDummyPara = GetIsDummyParaAddedForTableInSection() && GetIsFirstParagraphInSection(); - - uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; - PermMap_t::iterator aPermIter = m_aPermMap.find(permissinId); - - //is the bookmark name already registered? - try - { - if (aPermIter == m_aPermMap.end()) - { - //otherwise insert a text range as marker - bool bIsStart = true; - uno::Reference< text::XTextRange > xCurrent; - if (xTextAppend.is()) - { - uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange(xTextAppend->getEnd()); - - if (!bIsAfterDummyPara) - bIsStart = !xCursor->goLeft(1, false); - xCurrent = xCursor->getStart(); - } - - // register the start of the new permission - m_sCurrentPermId = permissinId; - m_aPermMap.emplace(permissinId, PermInsertPosition(bIsStart, permissinId, m_sCurrentPermEd, m_sCurrentPermEdGrp, xCurrent)); - - // clean up - m_sCurrentPermEd.clear(); - m_sCurrentPermEdGrp.clear(); - } - else - { - if (m_xTextFactory.is()) - { - uno::Reference< text::XTextCursor > xCursor; - uno::Reference< text::XText > xText = aPermIter->second.m_xTextRange->getText(); - if (aPermIter->second.m_bIsStartOfText && !bIsAfterDummyPara) - { - xCursor = xText->createTextCursorByRange(xText->getStart()); - } - else - { - xCursor = xText->createTextCursorByRange(aPermIter->second.m_xTextRange); - xCursor->goRight(1, false); - } - - xCursor->gotoRange(xTextAppend->getEnd(), true); - // A Paragraph was recently finished, and a new Paragraph has not been started as yet - // then move the bookmark-End to the earlier paragraph - if (IsOutsideAParagraph()) - { - xCursor->goLeft(1, false); - } - - // create a new bookmark using specific bookmark name pattern for permissions - uno::Reference< text::XTextContent > xPerm(m_xTextFactory->createInstance("com.sun.star.text.Bookmark"), uno::UNO_QUERY_THROW); - uno::Reference< container::XNamed > xPermNamed(xPerm, uno::UNO_QUERY_THROW); - xPermNamed->setName(aPermIter->second.createBookmarkName()); - - // add new bookmark - const bool bAbsorb = !xCursor->isCollapsed(); - uno::Reference< text::XTextRange > xCurrent(xCursor, uno::UNO_QUERY_THROW); - xTextAppend->insertTextContent(xCurrent, xPerm, bAbsorb); - } - - // remove processed permission - m_aPermMap.erase(aPermIter); - - // clean up - m_sCurrentPermId = 0; - m_sCurrentPermEd.clear(); - m_sCurrentPermEdGrp.clear(); - } - } - catch (const uno::Exception&) - { - //TODO: What happens to bookmarks where start and end are at different XText objects? - } -} - -void DomainMapper_Impl::AddAnnotationPosition( - const bool bStart, - const sal_Int32 nAnnotationId) -{ - if (m_aTextAppendStack.empty()) - return; - - // Create a cursor, pointing to the current position. - uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend; - uno::Reference<text::XTextRange> xCurrent; - if (xTextAppend.is()) - { - uno::Reference<text::XTextCursor> xCursor; - if (m_bIsNewDoc) - xCursor = xTextAppend->createTextCursorByRange(xTextAppend->getEnd()); - else - xCursor = m_aTextAppendStack.top().xCursor; - if (xCursor.is()) - xCurrent = xCursor->getStart(); - } - - // And save it, to be used by PopAnnotation() later. - AnnotationPosition& aAnnotationPosition = m_aAnnotationPositions[ nAnnotationId ]; - if (bStart) - { - aAnnotationPosition.m_xStart = xCurrent; - } - else - { - aAnnotationPosition.m_xEnd = xCurrent; - } - m_aAnnotationPositions[ nAnnotationId ] = aAnnotationPosition; -} - -GraphicImportPtr const & DomainMapper_Impl::GetGraphicImport(GraphicImportType eGraphicImportType) -{ - if(!m_pGraphicImport) - m_pGraphicImport = new GraphicImport( m_xComponentContext, m_xTextFactory, m_rDMapper, eGraphicImportType, m_aPositionOffsets, m_aAligns, m_aPositivePercentages ); - return m_pGraphicImport; -} -/*------------------------------------------------------------------------- - reset graphic import if the last import resulted in a shape, not a graphic - -----------------------------------------------------------------------*/ -void DomainMapper_Impl::ResetGraphicImport() -{ - m_pGraphicImport.clear(); -} - - -void DomainMapper_Impl::ImportGraphic(const 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()); - - // In case the SDT starts with the text portion of the graphic, then set the SDT properties here. - bool bHasGrabBag = false; - uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY); - if (xPropertySet.is()) - { - uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo(); - bHasGrabBag = xPropertySetInfo->hasPropertyByName("FrameInteropGrabBag"); - // In case we're outside a paragraph, then the SDT properties are stored in the paragraph grab-bag, not the frame one. - if (!m_pSdtHelper->isInteropGrabBagEmpty() && bHasGrabBag && !m_pSdtHelper->isOutsideAParagraph()) - { - comphelper::SequenceAsHashMap aFrameGrabBag(xPropertySet->getPropertyValue("FrameInteropGrabBag")); - aFrameGrabBag["SdtPr"] <<= m_pSdtHelper->getInteropGrabBagAndClear(); - xPropertySet->setPropertyValue("FrameInteropGrabBag", uno::makeAny(aFrameGrabBag.getAsConstPropertyValueList())); - } - } - - /* Set "SdtEndBefore" property on Drawing. - * It is required in a case when Drawing appears immediately after first run i.e. - * there is no text/space/tab in between two runs. - * In this case "SdtEndBefore" property needs to be set on Drawing. - */ - if(IsSdtEndBefore()) - { - if(xPropertySet.is() && bHasGrabBag) - { - uno::Sequence<beans::PropertyValue> aFrameGrabBag( comphelper::InitPropertySequence({ - { "SdtEndBefore", uno::Any(true) } - })); - xPropertySet->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aFrameGrabBag)); - } - } - - - // Update the shape properties if it is embedded object. - if(m_xEmbedded.is()){ - if (m_pGraphicImport->GetXShapeObject()) - m_pGraphicImport->GetXShapeObject()->setPosition( - m_pGraphicImport->GetGraphicObjectPosition()); - - uno::Reference<drawing::XShape> xShape = m_pGraphicImport->GetXShapeObject(); - UpdateEmbeddedShapeProps(xShape); - if (eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR) - { - uno::Reference<beans::XPropertySet> xEmbeddedProps(m_xEmbedded, uno::UNO_QUERY); - xEmbeddedProps->setPropertyValue("AnchorType", uno::makeAny(text::TextContentAnchorType_AT_CHARACTER)); - uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY); - xEmbeddedProps->setPropertyValue("HoriOrient", xShapeProps->getPropertyValue("HoriOrient")); - xEmbeddedProps->setPropertyValue("HoriOrientPosition", xShapeProps->getPropertyValue("HoriOrientPosition")); - xEmbeddedProps->setPropertyValue("HoriOrientRelation", xShapeProps->getPropertyValue("HoriOrientRelation")); - xEmbeddedProps->setPropertyValue("VertOrient", xShapeProps->getPropertyValue("VertOrient")); - xEmbeddedProps->setPropertyValue("VertOrientPosition", xShapeProps->getPropertyValue("VertOrientPosition")); - xEmbeddedProps->setPropertyValue("VertOrientRelation", xShapeProps->getPropertyValue("VertOrientRelation")); - //tdf123873 fix missing textwrap import - xEmbeddedProps->setPropertyValue("TextWrap", xShapeProps->getPropertyValue("TextWrap")); - } - } - //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 >() ); - - if (eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR && !m_aTextAppendStack.empty()) - { - // Remember this object is anchored to the current paragraph. - AnchoredObjectInfo aInfo; - aInfo.m_xAnchoredObject = xTextContent; - if (m_pGraphicImport) - { - // We still have the graphic import around, remember the original margin, so later - // SectionPropertyMap::HandleIncreasedAnchoredObjectSpacing() can use it. - aInfo.m_nLeftMargin = m_pGraphicImport->GetLeftMarginOrig(); - } - m_aTextAppendStack.top().m_aAnchoredObjects.push_back(aInfo); - } - else if (eGraphicImportType == IMPORT_AS_DETECTED_INLINE) - m_bParaWithInlineObject = true; - } - - // Clear the reference, so in case the embedded object is inside a - // TextFrame, we won't try to resize it (to match the size of the - // TextFrame) here. - m_xEmbedded.clear(); - m_pGraphicImport.clear(); -} - - -void DomainMapper_Impl::SetLineNumbering( sal_Int32 nLnnMod, sal_uInt32 nLnc, sal_Int32 ndxaLnn ) -{ - if( !m_bLineNumberingSet ) - { - 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( getPropertyName( PROP_IS_ON ), aTrue); - xProperties->setPropertyValue( getPropertyName( PROP_COUNT_EMPTY_LINES ), aTrue ); - xProperties->setPropertyValue( getPropertyName( PROP_COUNT_LINES_IN_FRAMES ), uno::makeAny( false ) ); - xProperties->setPropertyValue( getPropertyName( PROP_INTERVAL ), uno::makeAny( static_cast< sal_Int16 >( nLnnMod ))); - xProperties->setPropertyValue( getPropertyName( PROP_DISTANCE ), uno::makeAny( ConversionHelper::convertTwipToMM100(ndxaLnn) )); - xProperties->setPropertyValue( getPropertyName( PROP_NUMBER_POSITION ), uno::makeAny( style::LineNumberPosition::LEFT)); - xProperties->setPropertyValue( getPropertyName( PROP_NUMBERING_TYPE ), uno::makeAny( style::NumberingType::ARABIC)); - xProperties->setPropertyValue( getPropertyName( PROP_RESTART_AT_EACH_PAGE ), uno::makeAny( nLnc == NS_ooxml::LN_Value_ST_LineNumberRestart_newPage )); - } - catch( const uno::Exception& ) - {} - } - m_bLineNumberingSet = true; - uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier( GetTextDocument(), uno::UNO_QUERY_THROW ); - uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies(); - uno::Reference<container::XNameContainer> xStyles; - xStyleFamilies->getByName(getPropertyName( PROP_PARAGRAPH_STYLES )) >>= xStyles; - lcl_linenumberingHeaderFooter( xStyles, "Header", this ); - lcl_linenumberingHeaderFooter( xStyles, "Footer", this ); -} - - -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() - : top(ConversionHelper::convertTwipToMM100( sal_Int32(1440))) - // This is strange, the RTF spec says it's 1800, but it's clearly 1440 in Word - // OOXML seems not to specify a default value - , right(ConversionHelper::convertTwipToMM100( sal_Int32(1440))) - , bottom(top) - , left(right) - , header(ConversionHelper::convertTwipToMM100(sal_Int32(720))) - , footer(header) - , gutter(0) -{ -} - - -void DomainMapper_Impl::RegisterFrameConversion( - uno::Reference< text::XTextRange > const& xFrameStartRange, - uno::Reference< text::XTextRange > const& xFrameEndRange, - const std::vector<beans::PropertyValue>& rFrameProperties - ) -{ - OSL_ENSURE( - m_aFrameProperties.empty() && !m_xFrameStartRange.is() && !m_xFrameEndRange.is(), - "frame properties not removed"); - m_aFrameProperties = rFrameProperties; - m_xFrameStartRange = xFrameStartRange; - m_xFrameEndRange = xFrameEndRange; -} - - -void DomainMapper_Impl::ExecuteFrameConversion() -{ - if( m_xFrameStartRange.is() && m_xFrameEndRange.is() && !m_bDiscardHeaderFooter ) - { - std::vector<sal_Int32> redPos, redLen; - try - { - uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( GetTopTextAppend(), uno::UNO_QUERY_THROW ); - // convert redline ranges to cursor movement and character length - sal_Int32 redIdx; - lcl_CopyRedlines(GetTopTextAppend(), m_aStoredRedlines[StoredRedlines::FRAME], redPos, redLen, redIdx); - - const uno::Reference< text::XTextContent >& xTextContent = xTextAppendAndConvert->convertToTextFrame( - m_xFrameStartRange, - m_xFrameEndRange, - comphelper::containerToSequence(m_aFrameProperties) ); - - uno::Reference< text::XText > xDest( xTextContent, uno::UNO_QUERY_THROW ); - lcl_PasteRedlines(xDest, m_aStoredRedlines[StoredRedlines::FRAME], redPos, redLen, redIdx); - } - catch( const uno::Exception&) - { - DBG_UNHANDLED_EXCEPTION( "writerfilter.dmapper", "Exception caught when converting to frame"); - } - - m_bIsActualParagraphFramed = false; - - if (redPos.size() == m_aStoredRedlines[StoredRedlines::FRAME].size()/3) - { - for( sal_Int32 i = m_aStoredRedlines[StoredRedlines::FRAME].size() - 1; i >= 0; --i) - { - // keep redlines of floating tables to process them in CloseSectionGroup() - if ( redPos[i/3] != -1 ) - { - m_aStoredRedlines[StoredRedlines::FRAME].erase(m_aStoredRedlines[StoredRedlines::FRAME].begin() + i); - } - } - } - else - m_aStoredRedlines[StoredRedlines::FRAME].clear(); - } - m_xFrameStartRange = nullptr; - m_xFrameEndRange = nullptr; - m_aFrameProperties.clear(); -} - -void DomainMapper_Impl::AddNewRedline( sal_uInt32 sprmId ) -{ - RedlineParamsPtr pNew( new RedlineParams ); - pNew->m_nToken = XML_mod; - if ( !m_bIsParaMarkerChange ) - { - // <w:rPrChange> applies to the whole <w:r>, <w:pPrChange> applies to the whole <w:p>, - // so keep those two in CONTEXT_CHARACTERS and CONTEXT_PARAGRAPH, which will take - // care of their scope (i.e. when they should be used and discarded). - // Let's keep the rest the same way they used to be handled (explicitly dropped - // from a global stack by endtrackchange), but quite possibly they should not be handled - // that way either (I don't know). - if( sprmId == NS_ooxml::LN_EG_RPrContent_rPrChange ) - GetTopContextOfType( CONTEXT_CHARACTER )->Redlines().push_back( pNew ); - else if( sprmId == NS_ooxml::LN_CT_PPr_pPrChange ) - GetTopContextOfType( CONTEXT_PARAGRAPH )->Redlines().push_back( pNew ); - else if( sprmId != NS_ooxml::LN_CT_ParaRPr_rPrChange ) - m_aRedlines.top().push_back( pNew ); - } - else - { - m_pParaMarkerRedline = pNew; - } - // Newly read data will go into this redline. - m_currentRedline = pNew; -} - -void DomainMapper_Impl::SetCurrentRedlineIsRead() -{ - m_currentRedline.clear(); -} - -sal_Int32 DomainMapper_Impl::GetCurrentRedlineToken( ) const -{ - assert(m_currentRedline); - return m_currentRedline->m_nToken; -} - -void DomainMapper_Impl::SetCurrentRedlineAuthor( const OUString& sAuthor ) -{ - if (!m_xAnnotationField.is()) - { - if (m_currentRedline) - m_currentRedline->m_sAuthor = sAuthor; - else - SAL_INFO("writerfilter.dmapper", "numberingChange not implemented"); - } - else - m_xAnnotationField->setPropertyValue("Author", uno::makeAny(sAuthor)); -} - -void DomainMapper_Impl::SetCurrentRedlineInitials( const OUString& sInitials ) -{ - if (m_xAnnotationField.is()) - m_xAnnotationField->setPropertyValue("Initials", uno::makeAny(sInitials)); -} - -void DomainMapper_Impl::SetCurrentRedlineDate( const OUString& sDate ) -{ - if (!m_xAnnotationField.is()) - { - if (m_currentRedline) - m_currentRedline->m_sDate = sDate; - else - SAL_INFO("writerfilter.dmapper", "numberingChange not implemented"); - } - else - m_xAnnotationField->setPropertyValue("DateTimeValue", uno::makeAny(ConversionHelper::ConvertDateStringToDateTime(sDate))); -} - -void DomainMapper_Impl::SetCurrentRedlineId( sal_Int32 sId ) -{ - if (m_xAnnotationField.is()) - { - m_nAnnotationId = sId; - } - else - { - // This should be an assert, but somebody had the smart idea to reuse this function also for comments and whatnot, - // and in some cases the id is actually not handled, which may be in fact a bug. - if( !m_currentRedline) - SAL_INFO("writerfilter.dmapper", "no current redline"); - } -} - -void DomainMapper_Impl::SetCurrentRedlineToken( sal_Int32 nToken ) -{ - assert(m_currentRedline); - m_currentRedline->m_nToken = nToken; -} - -void DomainMapper_Impl::SetCurrentRedlineRevertProperties( const uno::Sequence<beans::PropertyValue>& aProperties ) -{ - assert(m_currentRedline); - m_currentRedline->m_aRevertProperties = aProperties; -} - - -// This removes only the last redline stored here, those stored in contexts are automatically removed when -// the context is destroyed. -void DomainMapper_Impl::RemoveTopRedline( ) -{ - if (m_aRedlines.top().empty()) - { - if (GetFootnoteCount() > -1 || GetEndnoteCount() > -1) - return; - SAL_WARN("writerfilter.dmapper", "RemoveTopRedline called with empty stack"); - throw uno::Exception("RemoveTopRedline failed", nullptr); - } - m_aRedlines.top().pop_back( ); - m_currentRedline.clear(); -} - -void DomainMapper_Impl::ApplySettingsTable() -{ - if (!(m_pSettingsTable && m_xTextFactory.is())) - return; - - try - { - uno::Reference< beans::XPropertySet > xTextDefaults(m_xTextFactory->createInstance("com.sun.star.text.Defaults"), uno::UNO_QUERY_THROW ); - sal_Int32 nDefTab = m_pSettingsTable->GetDefaultTabStop(); - xTextDefaults->setPropertyValue( getPropertyName( PROP_TAB_STOP_DISTANCE ), uno::makeAny(nDefTab) ); - if (m_pSettingsTable->GetLinkStyles()) - { - // If linked styles are enabled, set paragraph defaults from Word's default template - xTextDefaults->setPropertyValue(getPropertyName(PROP_PARA_BOTTOM_MARGIN), uno::makeAny(ConversionHelper::convertTwipToMM100(200))); - style::LineSpacing aSpacing; - aSpacing.Mode = style::LineSpacingMode::PROP; - aSpacing.Height = sal_Int16(115); - xTextDefaults->setPropertyValue(getPropertyName(PROP_PARA_LINE_SPACING), uno::makeAny(aSpacing)); - } - - if (m_pSettingsTable->GetZoomFactor() || m_pSettingsTable->GetView()) - { - std::vector<beans::PropertyValue> aViewProps; - if (m_pSettingsTable->GetZoomFactor()) - { - aViewProps.emplace_back("ZoomFactor", -1, uno::makeAny(m_pSettingsTable->GetZoomFactor()), beans::PropertyState_DIRECT_VALUE); - aViewProps.emplace_back("VisibleBottom", -1, uno::makeAny(sal_Int32(0)), beans::PropertyState_DIRECT_VALUE); - aViewProps.emplace_back("ZoomType", -1, - uno::makeAny(m_pSettingsTable->GetZoomType()), - beans::PropertyState_DIRECT_VALUE); - } - uno::Reference<container::XIndexContainer> xBox = document::IndexedPropertyValues::create(m_xComponentContext); - xBox->insertByIndex(sal_Int32(0), uno::makeAny(comphelper::containerToSequence(aViewProps))); - uno::Reference<document::XViewDataSupplier> xViewDataSupplier(m_xTextDocument, uno::UNO_QUERY); - xViewDataSupplier->setViewData(xBox); - } - - uno::Reference< beans::XPropertySet > xSettings(m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY); - - if (m_pSettingsTable->GetDoNotExpandShiftReturn()) - xSettings->setPropertyValue( "DoNotJustifyLinesWithManualBreak", uno::makeAny(true) ); - if (m_pSettingsTable->GetUsePrinterMetrics()) - xSettings->setPropertyValue("PrinterIndependentLayout", uno::makeAny(document::PrinterIndependentLayout::DISABLED)); - if( m_pSettingsTable->GetEmbedTrueTypeFonts()) - xSettings->setPropertyValue( getPropertyName( PROP_EMBED_FONTS ), uno::makeAny(true) ); - if( m_pSettingsTable->GetEmbedSystemFonts()) - xSettings->setPropertyValue( getPropertyName( PROP_EMBED_SYSTEM_FONTS ), uno::makeAny(true) ); - xSettings->setPropertyValue("AddParaTableSpacing", uno::makeAny(m_pSettingsTable->GetDoNotUseHTMLParagraphAutoSpacing())); - if (m_pSettingsTable->GetNoLeading()) - { - xSettings->setPropertyValue("AddExternalLeading", uno::makeAny(!m_pSettingsTable->GetNoLeading())); - } - if( m_pSettingsTable->GetProtectForm() ) - xSettings->setPropertyValue("ProtectForm", uno::makeAny( true )); - if( m_pSettingsTable->GetReadOnly() ) - xSettings->setPropertyValue("LoadReadonly", uno::makeAny( true )); - if (m_pSettingsTable->GetGutterAtTop()) - { - xSettings->setPropertyValue("GutterAtTop", uno::makeAny(true)); - } - } - catch(const uno::Exception&) - { - } -} - -uno::Reference<container::XIndexAccess> DomainMapper_Impl::GetCurrentNumberingRules(sal_Int32* pListLevel) -{ - uno::Reference<container::XIndexAccess> xRet; - try - { - OUString aStyle = GetCurrentParaStyleName(); - if (aStyle.isEmpty()) - return xRet; - const StyleSheetEntryPtr pEntry = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(aStyle); - if (!pEntry) - return xRet; - const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry->pProperties.get()); - if (!pStyleSheetProperties) - return xRet; - sal_Int32 nListId = pStyleSheetProperties->GetListId(); - if (nListId < 0) - return xRet; - if (pListLevel) - *pListLevel = pStyleSheetProperties->GetListLevel(); - - // So we are in a paragraph style and it has numbering. Look up the relevant numbering rules. - auto const pList(GetListTable()->GetList(nListId)); - OUString aListName; - if (pList) - { - aListName = pList->GetStyleName(); - } - uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY_THROW); - uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies(); - uno::Reference<container::XNameAccess> xNumberingStyles; - xStyleFamilies->getByName("NumberingStyles") >>= xNumberingStyles; - uno::Reference<beans::XPropertySet> xStyle(xNumberingStyles->getByName(aListName), uno::UNO_QUERY); - xRet.set(xStyle->getPropertyValue("NumberingRules"), uno::UNO_QUERY); - } - catch (const uno::Exception&) - { - TOOLS_WARN_EXCEPTION("writerfilter.dmapper", "GetCurrentNumberingRules: exception caught"); - } - return xRet; -} - -uno::Reference<beans::XPropertySet> DomainMapper_Impl::GetCurrentNumberingCharStyle() -{ - uno::Reference<beans::XPropertySet> xRet; - try - { - sal_Int32 nListLevel = -1; - uno::Reference<container::XIndexAccess> xLevels; - if ( GetTopContextType() == CONTEXT_PARAGRAPH ) - xLevels = GetCurrentNumberingRules(&nListLevel); - if (!xLevels.is()) - { - if (IsOOXMLImport()) - return xRet; - - PropertyMapPtr pContext = m_pTopContext; - if (IsRTFImport() && !IsOpenField()) - { - // Looking up the paragraph context explicitly (and not just taking - // the top context) is necessary for RTF, where formatting of a run - // and of the paragraph mark is not separated. - // We know that the formatting inside a field won't affect the - // paragraph marker formatting, though. - pContext = GetTopContextOfType(CONTEXT_PARAGRAPH); - if (!pContext) - return xRet; - } - - // In case numbering rules is not found via a style, try the direct formatting instead. - std::optional<PropertyMap::Property> oProp = pContext->getProperty(PROP_NUMBERING_RULES); - if (oProp) - { - xLevels.set(oProp->second, uno::UNO_QUERY); - // Found the rules, then also try to look up our numbering level. - oProp = pContext->getProperty(PROP_NUMBERING_LEVEL); - if (oProp) - oProp->second >>= nListLevel; - else - nListLevel = 0; - } - - if (!xLevels.is()) - return xRet; - } - uno::Sequence<beans::PropertyValue> aProps; - xLevels->getByIndex(nListLevel) >>= aProps; - auto pProp = std::find_if(aProps.begin(), aProps.end(), - [](const beans::PropertyValue& rProp) { return rProp.Name == "CharStyleName"; }); - if (pProp != aProps.end()) - { - OUString aCharStyle; - pProp->Value >>= aCharStyle; - uno::Reference<container::XNameAccess> xCharacterStyles; - uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY); - uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies(); - xStyleFamilies->getByName("CharacterStyles") >>= xCharacterStyles; - xRet.set(xCharacterStyles->getByName(aCharStyle), uno::UNO_QUERY_THROW); - } - } - catch( const uno::Exception& ) - { - } - return xRet; -} - -SectionPropertyMap * DomainMapper_Impl::GetSectionContext() -{ - SectionPropertyMap* pSectionContext = nullptr; - //the section context is not available before the first call of startSectionGroup() - if( !IsAnyTableImport() ) - { - PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_SECTION); - pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() ); - } - - return pSectionContext; -} - -void DomainMapper_Impl::deferCharacterProperty(sal_Int32 id, const css::uno::Any& value) -{ - deferredCharacterProperties[ id ] = value; -} - -void DomainMapper_Impl::processDeferredCharacterProperties() -{ - // Actually process in DomainMapper, so that it's the same source file like normal processing. - if( !deferredCharacterProperties.empty()) - { - m_rDMapper.processDeferredCharacterProperties( deferredCharacterProperties ); - deferredCharacterProperties.clear(); - } -} - -sal_Int32 DomainMapper_Impl::getNumberingProperty(const sal_Int32 nListId, sal_Int32 nNumberingLevel, const OUString& aProp) -{ - sal_Int32 nRet = 0; - if ( nListId < 0 ) - return nRet; - - try - { - if (nNumberingLevel < 0) // It seems it's valid to omit numbering level, and in that case it means zero. - nNumberingLevel = 0; - - auto const pList(GetListTable()->GetList(nListId)); - assert(pList); - const OUString aListName = pList->GetStyleName(); - const uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY_THROW); - const uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies(); - uno::Reference<container::XNameAccess> xNumberingStyles; - xStyleFamilies->getByName("NumberingStyles") >>= xNumberingStyles; - const uno::Reference<beans::XPropertySet> xStyle(xNumberingStyles->getByName(aListName), uno::UNO_QUERY); - const uno::Reference<container::XIndexAccess> xNumberingRules(xStyle->getPropertyValue("NumberingRules"), uno::UNO_QUERY); - if (xNumberingRules.is()) - { - uno::Sequence<beans::PropertyValue> aProps; - xNumberingRules->getByIndex(nNumberingLevel) >>= aProps; - auto pProp = std::find_if(aProps.begin(), aProps.end(), - [&aProp](const beans::PropertyValue& rProp) { return rProp.Name == aProp; }); - if (pProp != aProps.end()) - pProp->Value >>= nRet; - } - } - catch( const uno::Exception& ) - { - // This can happen when the doc contains some hand-crafted invalid list level. - } - - return nRet; -} - -sal_Int32 DomainMapper_Impl::getCurrentNumberingProperty(const OUString& aProp) -{ - sal_Int32 nRet = 0; - - std::optional<PropertyMap::Property> pProp = m_pTopContext->getProperty(PROP_NUMBERING_RULES); - uno::Reference<container::XIndexAccess> xNumberingRules; - if (pProp) - xNumberingRules.set(pProp->second, uno::UNO_QUERY); - pProp = m_pTopContext->getProperty(PROP_NUMBERING_LEVEL); - // Default numbering level is the first one. - sal_Int32 nNumberingLevel = 0; - if (pProp) - pProp->second >>= nNumberingLevel; - if (xNumberingRules.is()) - { - uno::Sequence<beans::PropertyValue> aProps; - xNumberingRules->getByIndex(nNumberingLevel) >>= aProps; - auto pPropVal = std::find_if(aProps.begin(), aProps.end(), - [&aProp](const beans::PropertyValue& rProp) { return rProp.Name == aProp; }); - if (pPropVal != aProps.end()) - pPropVal->Value >>= nRet; - } - - return nRet; -} - - -void DomainMapper_Impl::enableInteropGrabBag(const OUString& aName) -{ - m_aInteropGrabBagName = aName; -} - -void DomainMapper_Impl::disableInteropGrabBag() -{ - m_aInteropGrabBagName.clear(); - m_aInteropGrabBag.clear(); - m_aSubInteropGrabBag.clear(); -} - -bool DomainMapper_Impl::isInteropGrabBagEnabled() const -{ - return !(m_aInteropGrabBagName.isEmpty()); -} - -void DomainMapper_Impl::appendGrabBag(std::vector<beans::PropertyValue>& rInteropGrabBag, const OUString& aKey, const OUString& aValue) -{ - if (m_aInteropGrabBagName.isEmpty()) - return; - beans::PropertyValue aProperty; - aProperty.Name = aKey; - aProperty.Value <<= aValue; - rInteropGrabBag.push_back(aProperty); -} - -void DomainMapper_Impl::appendGrabBag(std::vector<beans::PropertyValue>& rInteropGrabBag, const OUString& aKey, std::vector<beans::PropertyValue>& rValue) -{ - if (m_aInteropGrabBagName.isEmpty()) - return; - beans::PropertyValue aProperty; - aProperty.Name = aKey; - aProperty.Value <<= comphelper::containerToSequence(rValue); - rValue.clear(); - rInteropGrabBag.push_back(aProperty); -} - -void DomainMapper_Impl::substream(Id rName, - ::writerfilter::Reference<Stream>::Pointer_t const& ref) -{ -#ifndef NDEBUG - size_t contextSize(m_aContextStack.size()); - size_t propSize[NUMBER_OF_CONTEXTS]; - for (int i = 0; i < NUMBER_OF_CONTEXTS; ++i) { - propSize[i] = m_aPropertyStacks[i].size(); - } -#endif - - // Save "has footnote" state, which is specific to a section in the body - // text, so state from substreams is not relevant. - bool bHasFtn = m_bHasFtn; - - //finalize any waiting frames before starting alternate streams - CheckUnregisteredFrameConversion(); - ExecuteFrameConversion(); - - appendTableManager(); - // Appending a TableManager resets its TableHandler, so we need to append - // that as well, or tables won't be imported properly in headers/footers. - appendTableHandler(); - getTableManager().startLevel(); - - //import of page header/footer - //Ensure that only one header/footer per section is pushed - - switch( rName ) - { - case NS_ooxml::LN_headerl: - PushPageHeader(SectionPropertyMap::PAGE_LEFT); - break; - case NS_ooxml::LN_headerr: - PushPageHeader(SectionPropertyMap::PAGE_RIGHT); - break; - case NS_ooxml::LN_headerf: - PushPageHeader(SectionPropertyMap::PAGE_FIRST); - break; - case NS_ooxml::LN_footerl: - PushPageFooter(SectionPropertyMap::PAGE_LEFT); - break; - case NS_ooxml::LN_footerr: - PushPageFooter(SectionPropertyMap::PAGE_RIGHT); - break; - case NS_ooxml::LN_footerf: - PushPageFooter(SectionPropertyMap::PAGE_FIRST); - break; - case NS_ooxml::LN_footnote: - case NS_ooxml::LN_endnote: - PushFootOrEndnote( NS_ooxml::LN_footnote == rName ); - break; - case NS_ooxml::LN_annotation : - PushAnnotation(); - break; - } - ref->resolve(m_rDMapper); - - switch( rName ) - { - case NS_ooxml::LN_headerl: - case NS_ooxml::LN_headerr: - case NS_ooxml::LN_headerf: - case NS_ooxml::LN_footerl: - case NS_ooxml::LN_footerr: - case NS_ooxml::LN_footerf: - PopPageHeaderFooter(); - break; - case NS_ooxml::LN_footnote: - case NS_ooxml::LN_endnote: - PopFootOrEndnote(); - break; - case NS_ooxml::LN_annotation : - PopAnnotation(); - break; - } - - getTableManager().endLevel(); - popTableManager(); - m_bHasFtn = bHasFtn; - - switch(rName) - { - case NS_ooxml::LN_footnote: - case NS_ooxml::LN_endnote: - m_pTableHandler->setHadFootOrEndnote(true); - m_bHasFtn = true; - break; - } - - // check that stacks are the same as before substream - assert(m_aContextStack.size() == contextSize); - for (int i = 0; i < NUMBER_OF_CONTEXTS; ++i) { - assert(m_aPropertyStacks[i].size() == propSize[i]); - } -} -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx deleted file mode 100644 index 581d2dba6692..000000000000 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ /dev/null @@ -1,1143 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#pragma once - -#include <com/sun/star/text/XParagraphCursor.hpp> -#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/style/TabStop.hpp> -#include <com/sun/star/container/XNameContainer.hpp> -#include <com/sun/star/embed/XStorage.hpp> -#include <queue> -#include <stack> -#include <string_view> -#include <o3tl/sorted_vector.hxx> -#include <unordered_map> -#include <vector> -#include <optional> - -#include "DomainMapper.hxx" -#include "DomainMapperTableManager.hxx" -#include "DomainMapperTableHandler.hxx" -#include "PropertyMap.hxx" -#include "FontTable.hxx" -#include "NumberingManager.hxx" -#include "StyleSheetTable.hxx" -#include "SettingsTable.hxx" -#include "ThemeTable.hxx" -#include "GraphicImport.hxx" -#include "OLEHandler.hxx" -#include "FFDataHandler.hxx" -#include "SmartTagHandler.hxx" -#include "FormControlHelper.hxx" -#include <map> - -namespace com::sun::star{ - namespace awt{ - struct Size; - } - namespace lang{ - class XMultiServiceFactory; - struct Locale; - } - namespace text - { - class XTextField; - class XFormField; - } - namespace beans{ class XPropertySet;} -} - -namespace writerfilter::dmapper { - -class SdtHelper; - -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 -}; -enum { NUMBER_OF_CONTEXTS = CONTEXT_LIST + 1 }; - -enum BreakType -{ - PAGE_BREAK, - COLUMN_BREAK -}; - -/** - * Two special footnotes are a separator line, and a continuation line. - * In MSOffice, these can contain text as well, but LO doesn't implement this - * rarely used feature, so the separator text needs to be skipped. (tdf#123262) - * Three-way logic is needed because there is no guaranteed on-off event. - * OFF == not in footnote separator - * ON == in footnote separator - * SKIPPING == ON status has been recognized. - */ -enum class SkipFootnoteSeparator -{ - OFF, - ON, - SKIPPING -}; - -// type of stored redlines -enum StoredRedlines -{ - FRAME = 0, - FOOTNOTE, - ENDNOTE, - NONE -}; - -/** - * Storage for state that is relevant outside a header/footer, but not inside it. - * - * In case some state of DomainMapper_Impl should be reset before handling the - * header/footer and should be restored once handling of header/footer is done, - * then you can use this class to do so. - */ -class HeaderFooterContext -{ - bool m_bTextInserted; - sal_Int32 m_nTableDepth; - -public: - explicit HeaderFooterContext(bool bTextInserted, sal_Int32 nTableDepth); - bool getTextInserted() const; - sal_Int32 getTableDepth() const; -}; - -/// Information about a paragraph to be finished after a field end. -struct FieldParagraph -{ - PropertyMapPtr m_pPropertyMap; - bool m_bRemove = false; -}; - -/// field stack element -class FieldContext : public virtual SvRefBase -{ - bool m_bFieldCommandCompleted; - css::uno::Reference<css::text::XTextRange> m_xStartRange; - - OUString m_sCommand; - OUString m_sResult; - std::optional<FieldId> m_eFieldId; - bool m_bFieldLocked; - - css::uno::Reference<css::text::XTextField> m_xTextField; - css::uno::Reference<css::text::XFormField> m_xFormField; - css::uno::Reference<css::beans::XPropertySet> m_xTOC; - css::uno::Reference<css::beans::XPropertySet> m_xTC; // TOX entry - css::uno::Reference<css::beans::XPropertySet> m_xCustomField; - - OUString m_sHyperlinkURL; - /// A frame for the hyperlink when one exists. - OUString m_sHyperlinkTarget; - - FFDataHandler::Pointer_t m_pFFDataHandler; - FormControlHelper::Pointer_t m_pFormControlHelper; - /// (Character) properties of the field itself. - PropertyMapPtr m_pProperties; - - std::vector<FieldParagraph> m_aParagraphsToFinish; - -public: - explicit FieldContext(css::uno::Reference<css::text::XTextRange> const& xStart); - ~FieldContext() override; - - const css::uno::Reference<css::text::XTextRange>& GetStartRange() const { return m_xStartRange; } - - void AppendCommand(std::u16string_view rPart); - const OUString& GetCommand() const {return m_sCommand; } - - void SetFieldId(FieldId eFieldId ) { m_eFieldId = eFieldId; } - std::optional<FieldId> const & GetFieldId() const { return m_eFieldId; } - - void AppendResult(std::u16string_view rResult) { m_sResult += rResult; } - const OUString& GetResult() const { return m_sResult; } - - void SetCommandCompleted() { m_bFieldCommandCompleted = true; } - bool IsCommandCompleted() const { return m_bFieldCommandCompleted; } - - void SetFieldLocked() { m_bFieldLocked = true; } - bool IsFieldLocked() const { return m_bFieldLocked; } - - const css::uno::Reference<css::beans::XPropertySet>& GetCustomField() const { return m_xCustomField; } - void SetCustomField(css::uno::Reference<css::beans::XPropertySet> const& xCustomField) { m_xCustomField = xCustomField; } - const css::uno::Reference<css::text::XTextField>& GetTextField() const { return m_xTextField;} - void SetTextField(css::uno::Reference<css::text::XTextField> const& xTextField); - const css::uno::Reference<css::text::XFormField>& GetFormField() const { return m_xFormField;} - void SetFormField(css::uno::Reference<css::text::XFormField> const& xFormField) { m_xFormField = xFormField;} - - void SetTOC(css::uno::Reference<css::beans::XPropertySet> const& xTOC) { m_xTOC = xTOC; } - const css::uno::Reference<css::beans::XPropertySet>& GetTOC() const { return m_xTOC; } - - void SetTC(css::uno::Reference<css::beans::XPropertySet> const& xTC) { m_xTC = xTC; } - const css::uno::Reference<css::beans::XPropertySet>& GetTC() const { return m_xTC; } - - void SetHyperlinkURL( const OUString& rURL ) { m_sHyperlinkURL = rURL; } - const OUString& GetHyperlinkURL() const { return m_sHyperlinkURL; } - void SetHyperlinkTarget(const OUString& rTarget) { m_sHyperlinkTarget = rTarget; } - const OUString& GetHyperlinkTarget() const { return m_sHyperlinkTarget; } - - void setFFDataHandler(FFDataHandler::Pointer_t pFFDataHandler) { m_pFFDataHandler = pFFDataHandler; } - const FFDataHandler::Pointer_t& getFFDataHandler() const { return m_pFFDataHandler; } - - void setFormControlHelper(FormControlHelper::Pointer_t pFormControlHelper) { m_pFormControlHelper = pFormControlHelper; } - const FormControlHelper::Pointer_t& getFormControlHelper() const { return m_pFormControlHelper; } - const PropertyMapPtr& getProperties() const { return m_pProperties; } - - ::std::vector<OUString> GetCommandParts() const; - - std::vector<FieldParagraph>& GetParagraphsToFinish() { return m_aParagraphsToFinish; } -}; - -struct TextAppendContext -{ - css::uno::Reference<css::text::XTextAppend> xTextAppend; - css::uno::Reference<css::text::XTextRange> xInsertPosition; - css::uno::Reference<css::text::XParagraphCursor> xCursor; - ParagraphPropertiesPtr pLastParagraphProperties; - - /** - * Objects anchored to the current paragraph, may affect the paragraph - * spacing. - */ - std::vector<AnchoredObjectInfo> m_aAnchoredObjects; - - TextAppendContext(const css::uno::Reference<css::text::XTextAppend>& xAppend, const css::uno::Reference<css::text::XTextCursor>& xCur) - : xTextAppend(xAppend) - { - xCursor.set(xCur, css::uno::UNO_QUERY); - xInsertPosition = xCursor; - } -}; - -struct AnchoredContext -{ - css::uno::Reference<css::text::XTextContent> xTextContent; - bool bToRemove; - - explicit AnchoredContext(const css::uno::Reference<css::text::XTextContent>& xContent) - : xTextContent(xContent), bToRemove(false) - { - } -}; - -typedef tools::SvRef<FieldContext> FieldContextPtr; - -/*------------------------------------------------------------------------- - extended tab stop struct - -----------------------------------------------------------------------*/ -struct DeletableTabStop : public css::style::TabStop -{ - bool bDeleted; - explicit DeletableTabStop() - : bDeleted(false) - { - // same defaults as SvxXMLTabStopContext_Impl - FillChar = ' '; - DecimalChar = ','; - } - DeletableTabStop(const css::style::TabStop& rTabStop) - : TabStop(rTabStop), - bDeleted(false) - { - } -}; -/// helper to remember bookmark start position -struct BookmarkInsertPosition -{ - bool m_bIsStartOfText; - OUString m_sBookmarkName; - css::uno::Reference<css::text::XTextRange> m_xTextRange; - BookmarkInsertPosition(bool bIsStartOfText, const OUString& rName, css::uno::Reference<css::text::XTextRange> const& xTextRange): - m_bIsStartOfText( bIsStartOfText ), - m_sBookmarkName( rName ), - m_xTextRange( xTextRange ) - {} -}; - -struct PermInsertPosition -{ - bool m_bIsStartOfText; - sal_Int32 m_Id; - OUString m_Ed; - OUString m_EdGrp; - - css::uno::Reference<css::text::XTextRange> m_xTextRange; - - PermInsertPosition(bool bIsStartOfText, sal_Int32 id, const OUString& ed, const OUString& edGrp, css::uno::Reference<css::text::XTextRange> const& xTextRange) - : m_bIsStartOfText(bIsStartOfText) - , m_Id(id) - , m_Ed(ed) - , m_EdGrp(edGrp) - , m_xTextRange(xTextRange) - {} - - OUString createBookmarkName() const - { - OUString bookmarkName; - - assert((!m_Ed.isEmpty()) || (!m_EdGrp.isEmpty())); - - if (m_Ed.isEmpty()) - { - bookmarkName += "permission-for-group:" + - OUString::number(m_Id) + - ":" + - m_EdGrp; - } - else - { - bookmarkName += "permission-for-user:" + - OUString::number(m_Id) + - ":" + - m_Ed; - } - - //todo: make sure the name is not used already! - return bookmarkName; - } -}; - -/// Stores the start/end positions of an annotation before its insertion. -struct AnnotationPosition -{ - css::uno::Reference<css::text::XTextRange> m_xStart; - css::uno::Reference<css::text::XTextRange> m_xEnd; -}; - -struct RubyInfo -{ - OUString sRubyText; - OUString sRubyStyle; - sal_uInt32 nSprmId; - sal_uInt32 nRubyAlign; - sal_uInt32 nHps; - sal_uInt32 nHpsBaseText; - - RubyInfo(): - nSprmId(0), - nRubyAlign(0), - nHps(0), - nHpsBaseText(0) - { - } -}; - -struct LineNumberSettings -{ - sal_Int32 nDistance; - sal_Int32 nInterval; - bool bRestartAtEachPage; - LineNumberSettings() : - nDistance(-1) - ,nInterval(0) - ,bRestartAtEachPage(true) - {} - -}; - -/// Contains information about a table that will be potentially converted to a floating one at the section end. -struct FloatingTableInfo -{ - css::uno::Reference<css::text::XTextRange> m_xStart; - css::uno::Reference<css::text::XTextRange> m_xEnd; - css::uno::Sequence<css::beans::PropertyValue> m_aFrameProperties; - sal_Int32 m_nTableWidth; - sal_Int32 m_nTableWidthType; - /// Break type of the section that contains this table. - sal_Int32 m_nBreakType = -1; - - FloatingTableInfo(css::uno::Reference<css::text::XTextRange> const& xStart, - css::uno::Reference<css::text::XTextRange> const& xEnd, - const css::uno::Sequence<css::beans::PropertyValue>& aFrameProperties, - sal_Int32 nTableWidth, sal_Int32 nTableWidthType) - : m_xStart(xStart), - m_xEnd(xEnd), - m_aFrameProperties(aFrameProperties), - m_nTableWidth(nTableWidth), - m_nTableWidthType(nTableWidthType) - { - } - css::uno::Any getPropertyValue(std::u16string_view propertyName); -}; - -/// Stores original/in-file-format info about a single anchored object. -struct AnchoredObjectInfo -{ - css::uno::Reference<css::text::XTextContent> m_xAnchoredObject; - sal_Int32 m_nLeftMargin = 0; -}; - -/// Stores info about objects anchored to a given paragraph. -struct AnchoredObjectsInfo -{ - css::uno::Reference<css::text::XTextRange> m_xParagraph; - std::vector<AnchoredObjectInfo> m_aAnchoredObjects; -}; - -struct SymbolData -{ - sal_Unicode cSymbol; - OUString sFont; - SymbolData(): - cSymbol(), - sFont() - { } -}; - -class DomainMapper; -class DomainMapper_Impl final -{ -public: - typedef std::map < OUString, BookmarkInsertPosition > BookmarkMap_t; - typedef std::map < sal_Int32, PermInsertPosition > PermMap_t; - -private: - SourceDocumentType m_eDocumentType; - DomainMapper& m_rDMapper; - OUString m_aBaseUrl; - css::uno::Reference<css::text::XTextDocument> m_xTextDocument; - css::uno::Reference<css::beans::XPropertySet> m_xDocumentSettings; - css::uno::Reference<css::lang::XMultiServiceFactory> m_xTextFactory; - css::uno::Reference<css::uno::XComponentContext> m_xComponentContext; - css::uno::Reference<css::container::XNameContainer> m_xPageStyles1; - // cache next available number, expensive to repeatedly compute - std::optional<int> m_xNextUnusedPageStyleNo; - css::uno::Reference<css::text::XText> m_xBodyText; - css::uno::Reference<css::text::XTextContent> m_xEmbedded; - - std::stack<TextAppendContext> m_aTextAppendStack; - std::stack<AnchoredContext> m_aAnchoredStack; - std::stack<HeaderFooterContext> m_aHeaderFooterStack; - std::deque<FieldContextPtr> m_aFieldStack; - bool m_bForceGenericFields; - bool m_bSetUserFieldContent; - bool m_bSetCitation; - bool m_bSetDateValue; - bool m_bIsFirstSection; - bool m_bIsColumnBreakDeferred; - bool m_bIsPageBreakDeferred; - /// If we want to set "sdt end" on the next character context. - bool m_bSdtEndDeferred; - /// If we want to set "paragraph sdt end" on the next paragraph context. - bool m_bParaSdtEndDeferred; - bool m_bStartTOC; - bool m_bStartTOCHeaderFooter; - /// If we got any text that is the pre-rendered result of the TOC field. - bool m_bStartedTOC; - bool m_bStartIndex; - bool m_bStartBibliography; - unsigned int m_nStartGenericField; - bool m_bTextInserted; - LineNumberSettings m_aLineNumberSettings; - - BookmarkMap_t m_aBookmarkMap; - OUString m_sCurrentBkmkId; - OUString m_sCurrentBkmkName; - - PermMap_t m_aPermMap; - sal_Int32 m_sCurrentPermId; - OUString m_sCurrentPermEd; - OUString m_sCurrentPermEdGrp; - - PageMar m_aPageMargins; - SymbolData m_aSymbolData; - - // TableManagers are stacked: one for each stream to avoid any confusion - std::stack< tools::SvRef< DomainMapperTableManager > > m_aTableManagers; - tools::SvRef<DomainMapperTableHandler> m_pTableHandler; - // List of document lists overrides. They are applied only once on first occurrence in document - o3tl::sorted_vector<sal_Int32> m_aListOverrideApplied; - - //each context needs a stack of currently used attributes - std::stack<PropertyMapPtr> m_aPropertyStacks[NUMBER_OF_CONTEXTS]; - std::stack<ContextType> m_aContextStack; - std::queue<std::optional<sal_Int16>> m_aFrameDirectionQueue; - bool m_bFrameDirectionSet; - FontTablePtr m_pFontTable; - ListsManager::Pointer m_pListTable; - std::deque< css::uno::Reference<css::drawing::XShape> > m_aPendingShapes; - StyleSheetTablePtr m_pStyleSheetTable; - ThemeTablePtr m_pThemeTable; - SettingsTablePtr m_pSettingsTable; - GraphicImportPtr m_pGraphicImport; - - - PropertyMapPtr m_pTopContext; - PropertyMapPtr m_pLastSectionContext; - PropertyMapPtr m_pLastCharacterContext; - - ::std::vector<DeletableTabStop> m_aCurrentTabStops; - OUString m_sCurrentParaStyleName; //highly inaccurate. Overwritten by "overlapping" paragraphs like comments, flys. - OUString m_sDefaultParaStyleName; //caches the ConvertedStyleName of the default paragraph style - bool m_bInDocDefaultsImport; - bool m_bInStyleSheetImport; //in import of fonts, styles, lists or lfos - bool m_bInAnyTableImport; //in import of fonts, styles, lists or lfos - enum class HeaderFooterImportState - { - none, - header, - footer, - } m_eInHeaderFooterImport; - bool m_bDiscardHeaderFooter; - bool m_bInFootOrEndnote; - bool m_bInFootnote; - PropertyMapPtr m_pFootnoteContext; - bool m_bHasFootnoteStyle; - bool m_bCheckFootnoteStyle; - /// Skip paragraphs from the <w:separator/> footnote - SkipFootnoteSeparator m_eSkipFootnoteState; - /// preload footnotes and endnotes - sal_Int32 m_nFootnotes; - sal_Int32 m_nEndnotes; - - bool m_bLineNumberingSet; - bool m_bIsInFootnoteProperties; - - RubyInfo m_aRubyInfo; - //registered frame properties - std::vector<css::beans::PropertyValue> m_aFrameProperties; - css::uno::Reference<css::text::XTextRange> m_xFrameStartRange; - css::uno::Reference<css::text::XTextRange> m_xFrameEndRange; - - // Redline stack - std::stack< std::vector< RedlineParamsPtr > > m_aRedlines; - // The redline currently read, may be also stored by a context instead of m_aRedlines. - RedlineParamsPtr m_currentRedline; - RedlineParamsPtr m_previousRedline; - RedlineParamsPtr m_pParaMarkerRedline; - bool m_bIsParaMarkerChange; - // redline data of the terminating run, if it's a moveFrom deletion - RedlineParamsPtr m_pParaMarkerRedlineMoveFrom; - - /// If the current paragraph has any runs. - bool m_bParaChanged; - bool m_bIsFirstParaInSection; - bool m_bIsFirstParaInSectionAfterRedline; - bool m_bIsFirstParaInShape = false; - bool m_bDummyParaAddedForTableInSection; - bool m_bTextFrameInserted; - bool m_bIsPreviousParagraphFramed; - bool m_bIsLastParaInSection; - bool m_bIsLastSectionGroup; - bool m_bIsInComments; - /// If the current paragraph contains section property definitions. - bool m_bParaSectpr; - bool m_bUsingEnhancedFields; - /// If the current paragraph is inside a structured document element. - bool m_bSdt; - bool m_bIsFirstRun; - bool m_bIsOutsideAParagraph; - /// This is a continuation of already finished paragraph - e.g., first in an index section - bool m_bRemoveThisParagraph = false; - - css::uno::Reference< css::text::XTextCursor > xTOCMarkerCursor; - - //annotation import - css::uno::Reference< css::beans::XPropertySet > m_xAnnotationField; - sal_Int32 m_nAnnotationId; - std::unordered_map< sal_Int32, AnnotationPosition > m_aAnnotationPositions; - - void GetCurrentLocale(css::lang::Locale& rLocale); - void SetNumberFormat(const OUString& rCommand, css::uno::Reference<css::beans::XPropertySet> const& xPropertySet, bool bDetectFormat = false); - /// @throws css::uno::Exception - css::uno::Reference<css::beans::XPropertySet> FindOrCreateFieldMaster(const char* pFieldMasterService, const OUString& rFieldMasterName); - css::uno::Reference<css::beans::XPropertySet> const & GetDocumentSettings(); - - std::map<sal_Int32, css::uno::Any> deferredCharacterProperties; - SmartTagHandler m_aSmartTagHandler; - - css::uno::Reference<css::text::XTextRange> m_xGlossaryEntryStart; - css::uno::Reference<css::text::XTextRange> m_xSdtEntryStart; - -public: - css::uno::Reference<css::text::XTextRange> m_xInsertTextRange; - css::uno::Reference<css::text::XTextRange> m_xAltChunkStartingRange; -private: - bool m_bIsNewDoc; - bool m_bIsAltChunk = false; - bool m_bIsReadGlossaries; -public: - DomainMapper_Impl( - DomainMapper& rDMapper, - css::uno::Reference < css::uno::XComponentContext > const& xContext, - css::uno::Reference< css::lang::XComponent > const& xModel, - SourceDocumentType eDocumentType, - utl::MediaDescriptor const & rMediaDesc); - ~DomainMapper_Impl(); - - SectionPropertyMap* GetLastSectionContext( ) - { - return dynamic_cast< SectionPropertyMap* >( m_pLastSectionContext.get( ) ); - } - - css::uno::Reference<css::container::XNameContainer> const & GetPageStyles(); - OUString GetUnusedPageStyleName(); - css::uno::Reference<css::text::XText> const & GetBodyText(); - const css::uno::Reference<css::lang::XMultiServiceFactory>& GetTextFactory() const - { - return m_xTextFactory; - } - const css::uno::Reference<css::text::XTextDocument>& GetTextDocument() const - { - return m_xTextDocument; - } - void SetDocumentSettingsProperty( const OUString& rPropName, const css::uno::Any& rValue ); - - void CreateRedline(css::uno::Reference<css::text::XTextRange> const& xRange, const RedlineParamsPtr& pRedline); - - void CheckParaMarkerRedline(css::uno::Reference<css::text::XTextRange> const& xRange); - - void CheckRedline(css::uno::Reference<css::text::XTextRange> const& xRange); - - void StartParaMarkerChange( ); - void EndParaMarkerChange( ); - void ChainTextFrames(); - - void RemoveDummyParaForTableInSection(); - void AddDummyParaForTableInSection(); - void RemoveLastParagraph( ); - void SetIsLastParagraphInSection( bool bIsLast ); - bool GetIsLastParagraphInSection() const { return m_bIsLastParaInSection;} - void SetRubySprmId( sal_uInt32 nSprmId) { m_aRubyInfo.nSprmId = nSprmId ; } - void SetRubyText( OUString const &sText, OUString const &sStyle) { - m_aRubyInfo.sRubyText = sText; - m_aRubyInfo.sRubyStyle = sStyle; - } - const RubyInfo & GetRubyInfo() const { return m_aRubyInfo;} - void SetRubyInfo(const RubyInfo & rInfo) { m_aRubyInfo = rInfo;} - - void SetIsLastSectionGroup( bool bIsLast ); - bool GetIsLastSectionGroup() const { return m_bIsLastSectionGroup;} - void SetIsFirstParagraphInSection( bool bIsFirst ); - void SetIsFirstParagraphInSectionAfterRedline( bool bIsFirstAfterRedline ); - bool GetIsFirstParagraphInSection( bool bAfterRedline = false ) const; - void SetIsFirstParagraphInShape(bool bIsFirst); - bool GetIsFirstParagraphInShape() const { return m_bIsFirstParaInShape; } - void SetIsDummyParaAddedForTableInSection( bool bIsAdded ); - bool GetIsDummyParaAddedForTableInSection() const { return m_bDummyParaAddedForTableInSection;} - - /// Track if a textframe has been inserted into this section - void SetIsTextFrameInserted( bool bIsInserted ); - bool GetIsTextFrameInserted() const { return m_bTextFrameInserted;} - - void SetIsPreviousParagraphFramed( bool bIsFramed ) { m_bIsPreviousParagraphFramed = bIsFramed; } - bool GetIsPreviousParagraphFramed() const { return m_bIsPreviousParagraphFramed; } - void SetParaSectpr(bool bParaSectpr); - bool GetParaSectpr() const { return m_bParaSectpr;} - - void SetSymbolChar( sal_Int32 nSymbol) { m_aSymbolData.cSymbol = sal_Unicode(nSymbol); } - void SetSymbolFont( OUString const &rName ) { m_aSymbolData.sFont = rName; } - const SymbolData & GetSymbolData() const { return m_aSymbolData;} - - /// Setter method for m_bSdt. - void SetSdt(bool bSdt); - /// Getter method for m_bSdt. - bool GetSdt() const { return m_bSdt;} - bool GetParaChanged() const { return m_bParaChanged;} - bool GetParaHadField() const { return m_bParaHadField; } - bool GetRemoveThisPara() const { return m_bRemoveThisParagraph; } - - void deferBreak( BreakType deferredBreakType ); - bool isBreakDeferred( BreakType deferredBreakType ); - void clearDeferredBreaks(); - void clearDeferredBreak(BreakType deferredBreakType); - - void setSdtEndDeferred(bool bSdtEndDeferred); - bool isSdtEndDeferred() const; - void setParaSdtEndDeferred(bool bParaSdtEndDeferred); - bool isParaSdtEndDeferred() const; - - void finishParagraph( const PropertyMapPtr& pPropertyMap, const bool bRemove = false, const bool bNoNumbering = false); - void appendTextPortion( const OUString& rString, const PropertyMapPtr& pPropertyMap ); - void appendTextContent(const css::uno::Reference<css::text::XTextContent>&, const css::uno::Sequence<css::beans::PropertyValue>&); - void appendOLE( const OUString& rStreamName, const std::shared_ptr<OLEHandler>& pOleHandler ); - void appendStarMath( const Value& v); - void adjustLastPara(sal_Int8 nAlign); - css::uno::Reference<css::beans::XPropertySet> appendTextSectionAfter(css::uno::Reference<css::text::XTextRange> const & xBefore); - - /// AutoText import: each entry is placed in the separate section - void appendGlossaryEntry(); - /// Remember where entry was started - void setGlossaryEntryStart( css::uno::Reference<css::text::XTextRange> const & xStart ) - { - m_xGlossaryEntryStart = xStart; - } - - // push the new properties onto the stack and make it the 'current' property map - void PushProperties(ContextType eId); - void PushStyleProperties(const PropertyMapPtr& pStyleProperties); - void PushListProperties(const PropertyMapPtr& pListProperties); - void PopProperties(ContextType eId); - - ContextType GetTopContextType() const { return m_aContextStack.top(); } - const PropertyMapPtr& GetTopContext() const - { - return m_pTopContext; - } - PropertyMapPtr GetTopContextOfType(ContextType eId); - - bool HasTopText() const; - css::uno::Reference<css::text::XTextAppend> const & GetTopTextAppend(); - FieldContextPtr const & GetTopFieldContext(); - - bool HasTopAnchoredObjects() const; - - FontTablePtr const & GetFontTable() - { - if(!m_pFontTable) - m_pFontTable = new FontTable(); - return m_pFontTable; - } - StyleSheetTablePtr const & GetStyleSheetTable() - { - if(!m_pStyleSheetTable) - m_pStyleSheetTable = new StyleSheetTable( m_rDMapper, m_xTextDocument, m_bIsNewDoc ); - return m_pStyleSheetTable; - } - OUString GetListStyleName(sal_Int32 nListId); - ListsManager::Pointer const & GetListTable(); - ThemeTablePtr const & GetThemeTable() - { - if(!m_pThemeTable) - m_pThemeTable = new ThemeTable; - return m_pThemeTable; - } - - SettingsTablePtr const & GetSettingsTable() - { - if( !m_pSettingsTable ) - m_pSettingsTable = new SettingsTable(m_rDMapper); - return m_pSettingsTable; - } - - GraphicImportPtr const & GetGraphicImport( GraphicImportType eGraphicImportType ); - void ResetGraphicImport(); - // this method deletes the current m_pGraphicImport after import - void ImportGraphic(const writerfilter::Reference< Properties>::Pointer_t&, GraphicImportType eGraphicImportType ); - - void InitTabStopFromStyle(const css::uno::Sequence<css::style::TabStop>& rInitTabStops); - void IncorporateTabStop( const DeletableTabStop &aTabStop ); - css::uno::Sequence<css::style::TabStop> GetCurrentTabStopAndClear(); - - void SetCurrentParaStyleName(const OUString& sStringValue) {m_sCurrentParaStyleName = sStringValue;} - OUString GetCurrentParaStyleName(); - OUString GetDefaultParaStyleName(); - - // specified style - including inherited properties. Indicate whether paragraph defaults should be checked. - css::uno::Any GetPropertyFromStyleSheet(PropertyIds eId, StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara, bool* bIsDocDefault = nullptr); - // current paragraph style - including inherited properties - css::uno::Any GetPropertyFromParaStyleSheet(PropertyIds eId); - // context's character style - including inherited properties - css::uno::Any GetPropertyFromCharStyleSheet(PropertyIds eId, const PropertyMapPtr& rContext); - // get property first from the given context, or secondly via inheritance from styles/docDefaults - css::uno::Any GetAnyProperty(PropertyIds eId, const PropertyMapPtr& rContext); - void SetDocDefaultsImport( bool bSet ) { m_bInDocDefaultsImport = bSet;} - bool IsDocDefaultsImport()const { return m_bInDocDefaultsImport;} - 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;} - bool IsInShape()const { return m_aAnchoredStack.size() > 0;} - - void PushShapeContext(const css::uno::Reference<css::drawing::XShape>& xShape); - void PopShapeContext(); - void UpdateEmbeddedShapeProps(const css::uno::Reference<css::drawing::XShape>& xShape); - /// Add a pending shape: it's currently inserted into the document, but it should be removed before the import finishes. - void PushPendingShape(const css::uno::Reference<css::drawing::XShape>& xShape); - /// Get the first pending shape, if there are any. - css::uno::Reference<css::drawing::XShape> PopPendingShape(); - - void PushPageHeader(SectionPropertyMap::PageType eType); - void PushPageFooter(SectionPropertyMap::PageType eType); - - void PopPageHeaderFooter(); - bool IsInHeaderFooter() const { return m_eInHeaderFooterImport != HeaderFooterImportState::none; } - - bool IsInTOC() const { return m_bStartTOC; } - - void PushFootOrEndnote( bool bIsFootnote ); - void PopFootOrEndnote(); - bool IsInFootOrEndnote() const { return m_bInFootOrEndnote; } - bool IsInFootnote() const { return m_bInFootnote; } - - void StartCustomFootnote(const PropertyMapPtr pContext); - void EndCustomFootnote(); - bool IsInCustomFootnote() const { return m_bHasFootnoteStyle; } - bool CheckFootnoteStyle() const { return m_bCheckFootnoteStyle; } - void SetHasFootnoteStyle(bool bVal) { m_bHasFootnoteStyle = bVal; } - void SetCheckFootnoteStyle(bool bVal) { m_bCheckFootnoteStyle = bVal; } - - const PropertyMapPtr& GetFootnoteContext() const { return m_pFootnoteContext; } - - SkipFootnoteSeparator GetSkipFootnoteState() const { return m_eSkipFootnoteState; } - void SetSkipFootnoteState(SkipFootnoteSeparator eId) { m_eSkipFootnoteState = eId; } - sal_Int32 GetFootnoteCount() const { return m_nFootnotes; } - void IncrementFootnoteCount() { ++m_nFootnotes; } - sal_Int32 GetEndnoteCount() const { return m_nEndnotes; } - void IncrementEndnoteCount() { ++m_nEndnotes; } - - void PushAnnotation(); - void PopAnnotation(); - - /// A field context starts with a cFieldStart. - void PushFieldContext(); - //the current field context waits for the completion of the command - bool IsOpenFieldCommand() const; - bool IsOpenField() const; - //mark field in current context as locked (fixed) - void SetFieldLocked(); - //collect the pieces of the command - void AppendFieldCommand(OUString const & rPartOfCommand); - void handleRubyEQField( const FieldContextPtr& pContext); - void handleFieldSet - (const FieldContextPtr& pContext, - css::uno::Reference< css::uno::XInterface > const & xFieldInterface, - css::uno::Reference< css::beans::XPropertySet > const& xFieldProperties); - void handleFieldAsk - (const FieldContextPtr& pContext, - css::uno::Reference< css::uno::XInterface > & xFieldInterface, - css::uno::Reference< css::beans::XPropertySet > const& xFieldProperties); - OUString convertFieldFormula(const OUString& input); - void handleFieldFormula - (const FieldContextPtr& pContext, - css::uno::Reference< css::beans::XPropertySet > const& xFieldProperties); - void handleAutoNum - (const FieldContextPtr& pContext, - css::uno::Reference< css::uno::XInterface > const & xFieldInterface, - css::uno::Reference< css::beans::XPropertySet > const& xFieldProperties); - static void handleAuthor - (std::u16string_view rFirstParam, - css::uno::Reference< css::beans::XPropertySet > const& xFieldProperties, - FieldId eFieldId); - void handleDocProperty - (const FieldContextPtr& pContext, - OUString const& rFirstParam, - css::uno::Reference< css::uno::XInterface > & xFieldInterface); - void handleToc - (const FieldContextPtr& pContext, - const OUString & sTOCServiceName); - void handleIndex - (const FieldContextPtr& pContext, - const OUString & sTOCServiceName); - - void handleBibliography - (const FieldContextPtr& pContext, - const OUString & sTOCServiceName); - /// The field command has to be closed (cFieldSep appeared). - void CloseFieldCommand(); - //the _current_ fields require a string type result while TOCs accept richt results - bool IsFieldResultAsString(); - void AppendFieldResult(std::u16string_view rResult); - //apply the result text to the related field - void SetFieldResult(OUString const& rResult); - // set FFData of top field context - void SetFieldFFData( const FFDataHandler::Pointer_t& pFFDataHandler ); - /// The end of field is reached (cFieldEnd appeared) - the command might still be open. - void PopFieldContext(); - - /// Returns title of the TOC placed in paragraph(s) before TOC field inside STD-frame - OUString extractTocTitle(); - css::uno::Reference<css::beans::XPropertySet> createSectionForRange(css::uno::Reference< css::text::XTextRange > xStart, css::uno::Reference< css::text::XTextRange > xEnd, const OUString & sObjectType, bool stepLeft); - - void SetBookmarkName( const OUString& rBookmarkName ); - void StartOrEndBookmark( const OUString& rId ); - - void setPermissionRangeEd(const OUString& user); - void setPermissionRangeEdGrp(const OUString& group); - void startOrEndPermissionRange(sal_Int32 permissinId); - - void AddAnnotationPosition( - const bool bStart, - const sal_Int32 nAnnotationId ); - - bool hasTableManager() const - { - return !m_aTableManagers.empty(); - } - - DomainMapperTableManager& getTableManager() - { - return *m_aTableManagers.top(); - } - - void appendTableManager( ) - { - tools::SvRef<DomainMapperTableManager> pMngr(new DomainMapperTableManager()); - m_aTableManagers.push( pMngr ); - } - - void appendTableHandler( ) - { - if (m_pTableHandler) - m_aTableManagers.top()->setHandler(m_pTableHandler); - } - - void popTableManager( ) - { - if (hasTableManager()) - m_aTableManagers.pop(); - } - - void SetLineNumbering( sal_Int32 nLnnMod, sal_uInt32 nLnc, sal_Int32 ndxaLnn ); - bool IsLineNumberingSet() const {return m_bLineNumberingSet;} - - DeletableTabStop m_aCurrentTabStop; - - /// If we're right after the end of a table. - bool m_bConvertedTable = false; - - bool IsOOXMLImport() const { return m_eDocumentType == SourceDocumentType::OOXML; } - - bool IsRTFImport() const { return m_eDocumentType == SourceDocumentType::RTF; } - - 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;} - - bool IsInComments() const { return m_bIsInComments; }; - - void CheckUnregisteredFrameConversion( ); - - void RegisterFrameConversion(css::uno::Reference<css::text::XTextRange> const& xFrameStartRange, - css::uno::Reference<css::text::XTextRange> const& xFrameEndRange, - const std::vector<css::beans::PropertyValue>& aFrameProperties); - void ExecuteFrameConversion(); - - void AddNewRedline( sal_uInt32 sprmId ); - - sal_Int32 GetCurrentRedlineToken( ) const; - void SetCurrentRedlineAuthor( const OUString& sAuthor ); - void SetCurrentRedlineDate( const OUString& sDate ); - void SetCurrentRedlineId( sal_Int32 nId ); - void SetCurrentRedlineToken( sal_Int32 nToken ); - void SetCurrentRedlineRevertProperties( const css::uno::Sequence<css::beans::PropertyValue>& aProperties ); - void SetCurrentRedlineIsRead(); - void RemoveTopRedline( ); - void SetCurrentRedlineInitials( const OUString& sInitials ); - bool IsFirstRun() const { return m_bIsFirstRun;} - void SetIsFirstRun(bool bval) { m_bIsFirstRun = bval;} - bool IsOutsideAParagraph() const { return m_bIsOutsideAParagraph;} - void SetIsOutsideAParagraph(bool bval) { m_bIsOutsideAParagraph = bval;} - - void ApplySettingsTable(); - - css::uno::Reference<css::text::XTextAppend> GetCurrentXText() { - return m_aTextAppendStack.empty() ? nullptr : m_aTextAppendStack.top().xTextAppend; - } - - void NewFrameDirection() { - m_aFrameDirectionQueue.push(std::nullopt); - m_bFrameDirectionSet = false; - } - void SetFrameDirection(sal_Int16 nDirection) { - if (!m_bFrameDirectionSet) { - assert(!m_aFrameDirectionQueue.empty()); - m_aFrameDirectionQueue.back() = nDirection; - m_bFrameDirectionSet = true; - } - } - std::optional<sal_Int16> PopFrameDirection() { - if (m_aFrameDirectionQueue.empty()) - return {}; - const std::optional<sal_Int16> nDirection = m_aFrameDirectionQueue.front(); - m_aFrameDirectionQueue.pop(); - return nDirection; - } - - SectionPropertyMap * GetSectionContext(); - /// If the current paragraph has a numbering style associated, this method returns its character style (part of the numbering rules) - css::uno::Reference<css::beans::XPropertySet> GetCurrentNumberingCharStyle(); - /// If the current paragraph has a numbering style associated, this method returns its numbering rules - css::uno::Reference<css::container::XIndexAccess> GetCurrentNumberingRules(sal_Int32* pListLevel); - - /** - Used for attributes/sprms which cannot be evaluated immediately (e.g. they depend - on another one that comes in the same CONTEXT_CHARACTER). The property will be processed - again in DomainMapper::processDeferredCharacterProperties(). - */ - void deferCharacterProperty(sal_Int32 id, const css::uno::Any& value); - /** - Processes properties deferred using deferCharacterProperty(). To be called whenever the top - CONTEXT_CHARACTER is going to be used (e.g. by appendText()). - */ - void processDeferredCharacterProperties(); - - sal_Int32 getNumberingProperty(const sal_Int32 nListId, sal_Int32 nListLevel, const OUString& aProp); - /// Get a property of the current numbering style's current level. - sal_Int32 getCurrentNumberingProperty(const OUString& aProp); - - /// If we're importing into a new document, or just pasting to an existing one. - bool IsNewDoc() const { return m_bIsNewDoc;} - - bool IsAltChunk() const { return m_bIsAltChunk;} - - /// If we're importing autotext. - bool IsReadGlossaries() const { return m_bIsReadGlossaries;} - - tools::SvRef<SdtHelper> m_pSdtHelper; - - /// Document background color, applied to every page style. - std::optional<sal_Int32> m_oBackgroundColor; - - /** - * This contains the raw table depth. m_nTableDepth > 0 is the same as - * getTableManager().isInTable(), unless we're in the first paragraph of a - * table, or first paragraph after a table, as the table manager is only - * updated once we ended the paragraph (and know if the para has the - * inTbl SPRM or not). - */ - sal_Int32 m_nTableDepth; - /// Raw table cell depth. - sal_Int32 m_nTableCellDepth; - /// Table cell depth of the last finished paragraph. - sal_Int32 m_nLastTableCellParagraphDepth; - - /// If the current section has footnotes. - bool m_bHasFtn; - /// If the current section has a footnote separator. - bool m_bHasFtnSep; - - /// If the next tab should be ignored, used for footnotes. - bool m_bCheckFirstFootnoteTab; - bool m_bIgnoreNextTab; - /// Pending floating tables: they may be converted to text frames at the section end. - std::vector<FloatingTableInfo> m_aPendingFloatingTables; - - /// Paragraphs with anchored objects in the current section. - std::vector<AnchoredObjectsInfo> m_aAnchoredObjectAnchors; - - /// Append a property to a sub-grabbag if necessary (e.g. 'lineRule', 'auto') - void appendGrabBag(std::vector<css::beans::PropertyValue>& rInteropGrabBag, const OUString& aKey, const OUString& aValue); - void appendGrabBag(std::vector<css::beans::PropertyValue>& rInteropGrabBag, const OUString& aKey, std::vector<css::beans::PropertyValue>& rValue); - - /// Enable, disable and check status of grabbags - void enableInteropGrabBag(const OUString& aName); - void disableInteropGrabBag(); - bool isInteropGrabBagEnabled() const; - - /// Name of m_aInteropGrabBag. - OUString m_aInteropGrabBagName; - - /// A toplevel dmapper grabbag, like 'pPr'. - std::vector<css::beans::PropertyValue> m_aInteropGrabBag; - - /// A sub-grabbag of m_aInteropGrabBag, like 'spacing'. - std::vector<css::beans::PropertyValue> m_aSubInteropGrabBag; - - /// ST_PositionOffset values we received - std::pair<OUString, OUString> m_aPositionOffsets; - /// ST_AlignH/V values we received - std::pair<OUString, OUString> m_aAligns; - /// ST_PositivePercentage values we received - std::queue<OUString> m_aPositivePercentages; - bool isInIndexContext() const { return m_bStartIndex;} - bool isInBibliographyContext() const { return m_bStartBibliography;} - SmartTagHandler& getSmartTagHandler() { return m_aSmartTagHandler; } - - void substream(Id rName, ::writerfilter::Reference<Stream>::Pointer_t const& ref); - - /// If the document needs to split paragraph. - bool m_bIsSplitPara; - - /// Check if "SdtEndBefore" property is set - bool IsSdtEndBefore(); - - bool IsDiscardHeaderFooter() const; - - bool IsForceGenericFields() const { return m_bForceGenericFields; } - - void SetParaAutoBefore(bool bParaAutoBefore) { m_bParaAutoBefore = bParaAutoBefore; } - - /// Forget about the previous paragraph, as it's not inside the same - /// start/end node. - void ClearPreviousParagraph(); - - /// Handle redline text portions in a frame, footnotes and redlines: - /// store their data, and create them after frame creation or footnote/endnote copying - bool m_bIsActualParagraphFramed; - std::deque<css::uno::Any> m_aStoredRedlines[StoredRedlines::NONE]; - - bool IsParaWithInlineObject() const { return m_bParaWithInlineObject; } - - css::uno::Reference< css::embed::XStorage > m_xDocumentStorage; - - /// Handles <w:altChunk>. - void HandleAltChunk(const OUString& rStreamName); - -private: - void PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType); - // Start a new index section; if needed, finish current paragraph - css::uno::Reference<css::beans::XPropertySet> StartIndexSectionChecked(const OUString& sServiceName); - std::vector<css::uno::Reference< css::drawing::XShape > > m_vTextFramesForChaining ; - /// Current paragraph had at least one field in it. - bool m_bParaHadField; - bool m_bSaveParaHadField; - css::uno::Reference<css::beans::XPropertySet> m_xPreviousParagraph; - /// Current paragraph has automatic before spacing. - bool m_bParaAutoBefore; - /// Current paragraph in a table is first paragraph of a cell - bool m_bFirstParagraphInCell; - bool m_bSaveFirstParagraphInCell; - /// Current paragraph had at least one inline object in it. - bool m_bParaWithInlineObject; -}; - -} //namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FFDataHandler.cxx b/writerfilter/source/dmapper/FFDataHandler.cxx deleted file mode 100644 index 507327cf8333..000000000000 --- a/writerfilter/source/dmapper/FFDataHandler.cxx +++ /dev/null @@ -1,190 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "FFDataHandler.hxx" -#include "TagLogger.hxx" - -#include <ooxml/resourceids.hxx> - -namespace writerfilter::dmapper { - -/************************ - * class: FFDataHandler * - ************************/ - -FFDataHandler::FFDataHandler() : -LoggedProperties("FFDataHandler"), -m_nCheckboxHeight(0), -m_bCheckboxAutoHeight(false), -m_nCheckboxChecked(-1), -m_nCheckboxDefault(-1), -m_nTextMaxLength(0) -{ -} - - -FFDataHandler::~FFDataHandler() -{ -} - - -bool FFDataHandler::getCheckboxChecked() const -{ - if (m_nCheckboxChecked != -1) - return m_nCheckboxChecked; - else if (m_nCheckboxDefault != -1) - return m_nCheckboxDefault; - else - return false; -} - - -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_helpText: - { - resolveSprm(r_Sprm); - } - break; - case NS_ooxml::LN_CT_FFData_statusText: - { - resolveSprm(r_Sprm); - } - 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_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_checked: - { - m_nCheckboxChecked = r_Sprm.getValue()->getInt(); - } - break; - case NS_ooxml::LN_CT_FFCheckBox_default: - { - m_nCheckboxDefault = 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_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_sTextType = r_Sprm.getValue()->getString(); - } - 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 DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - break; - } -} - -void FFDataHandler::resolveSprm(Sprm & r_Sprm) -{ - writerfilter::Reference<Properties>::Pointer_t pProperties = r_Sprm.getProps(); - if( pProperties) - pProperties->resolve(*this); -} - -void FFDataHandler::lcl_attribute(Id name, Value & val) -{ - switch (name) - { - case NS_ooxml::LN_CT_FFHelpText_val: - { - m_sHelpText = val.getString(); - } - break; - case NS_ooxml::LN_CT_FFStatusText_val: - { - m_sStatusText = val.getString(); - } - break; - default: -#ifdef DBG_UTIL - TagLogger::getInstance().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 deleted file mode 100644 index 1603d39b0ad0..000000000000 --- a/writerfilter/source/dmapper/FFDataHandler.hxx +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FFDATAHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FFDATAHANDLER_HXX -#include "LoggedResources.hxx" -#include <rtl/ustring.hxx> -#include <vector> -namespace writerfilter::dmapper -{ -class FFDataHandler : public LoggedProperties -{ -public: - // typedefs - typedef ::tools::SvRef<FFDataHandler> Pointer_t; - typedef ::std::vector<OUString> DropDownEntries_t; - - // constructor - FFDataHandler(); - // destructor - virtual ~FFDataHandler() override; - - // member: name - const OUString& getName() const { return m_sName; } - - // member: helpText - const OUString& getHelpText() const { return m_sHelpText; } - - // member: statusText - const OUString& getStatusText() const { return m_sStatusText; } - - const OUString& getEntryMacro() const { return m_sEntryMacro; } - const OUString& getExitMacro() const { return m_sExitMacro; } - - // member: checkboxHeight - sal_uInt32 getCheckboxHeight() const { return m_nCheckboxHeight; } - - // member: checkboxAutoHeight - bool getCheckboxAutoHeight() const { return m_bCheckboxAutoHeight; } - - // member: checkboxChecked or checkboxDefault (if the previous is not set) - bool getCheckboxChecked() const; - - // member: dropDownResult - const OUString& getDropDownResult() const { return m_sDropDownResult; } - - // member: dropDownEntries - const DropDownEntries_t& getDropDownEntries() const { return m_DropDownEntries; } - - // member: textDefault - const OUString& getTextDefault() const { return m_sTextDefault; } - - const OUString& getTextType() const { return m_sTextType; } - const OUString& getTextFormat() const { return m_sTextFormat; } - sal_uInt16 getTextMaxLength() const { return m_nTextMaxLength; } - - // sprm - void resolveSprm(Sprm& r_sprm); - -private: - OUString m_sName; - OUString m_sHelpText; - OUString m_sStatusText; - OUString m_sEntryMacro; - OUString m_sExitMacro; - sal_uInt32 m_nCheckboxHeight; - bool m_bCheckboxAutoHeight; - int m_nCheckboxChecked; - int m_nCheckboxDefault; - OUString m_sDropDownResult; - DropDownEntries_t m_DropDownEntries; - OUString m_sTextDefault; - OUString m_sTextType; - OUString m_sTextFormat; - sal_uInt16 m_nTextMaxLength; - - // sprm - void lcl_sprm(Sprm& r_sprm) override; - - // attribute - void lcl_attribute(Id name, Value& val) override; -}; -} -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FFDATAHANDLER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FieldTypes.hxx b/writerfilter/source/dmapper/FieldTypes.hxx deleted file mode 100644 index 7755c3feb7ca..000000000000 --- a/writerfilter/source/dmapper/FieldTypes.hxx +++ /dev/null @@ -1,306 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FIELDTYPES_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FIELDTYPES_HXX - -namespace writerfilter::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 - ,FIELD_EQ - /* 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 - */ - ,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 supported - */ - ,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 - ,FIELD_PAGEREF - /* REF targetbkm \f \* MERGEFORMAT -> - imports a ShowVariable (bookmarkname)? - \h hyperlink to paragraph - \p relative to para above/below - \f reference number - \d separator number separator - \n paragraph number - \r paragraph number in relative context - \t suppress 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, such 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 contents 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 - /* Document alphabetical index - */ - ,FIELD_INDEX - /* Document alphabetical index marks - */ - ,FIELD_XE - /** - * Bibliography - */ - ,FIELD_BIBLIOGRAPHY - /* Citation - */ - ,FIELD_CITATION -}; - -} -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FIELDTYPES_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FontTable.cxx b/writerfilter/source/dmapper/FontTable.cxx deleted file mode 100644 index 7973a42938ec..000000000000 --- a/writerfilter/source/dmapper/FontTable.cxx +++ /dev/null @@ -1,299 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "FontTable.hxx" -#include <o3tl/deleter.hxx> -#include <ooxml/resourceids.hxx> -#include <vector> -#include <sal/log.hxx> -#include <rtl/tencinfo.h> -#include <vcl/embeddedfontshelper.hxx> -#include <unotools/fontdefs.hxx> - -using namespace com::sun::star; - -namespace writerfilter::dmapper -{ - -struct FontTable_Impl -{ - std::unique_ptr<EmbeddedFontsHelper, o3tl::default_delete<EmbeddedFontsHelper>> xEmbeddedFontHelper; - std::vector< FontEntry::Pointer_t > aFontEntries; - FontEntry::Pointer_t pCurrentEntry; - FontTable_Impl() {} -}; - -FontTable::FontTable() -: LoggedProperties("FontTable") -, LoggedTable("FontTable") -, LoggedStream("FontTable") -, m_pImpl( new FontTable_Impl ) -{ -} - -FontTable::~FontTable() -{ -} - -void FontTable::lcl_attribute(Id Name, Value & val) -{ - SAL_WARN_IF( !m_pImpl->pCurrentEntry, "writerfilter.dmapper", "current entry has to be set here" ); - if(!m_pImpl->pCurrentEntry) - return ; - int nIntValue = val.getInt(); - OUString sValue = val.getString(); - switch(Name) - { - case NS_ooxml::LN_CT_Pitch_val: - if (static_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Pitch_fixed) - ; - else if (static_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Pitch_variable) - ; - else if (static_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Pitch_default) - ; - else - SAL_WARN("writerfilter.dmapper", "FontTable::lcl_attribute: unhandled NS_ooxml::CT_Pitch_val: " << nIntValue); - break; - 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 ); - if( IsStarSymbol( m_pImpl->pCurrentEntry->sFontName )) - m_pImpl->pCurrentEntry->nTextEncoding = RTL_TEXTENCODING_SYMBOL; - } - break; - case NS_ooxml::LN_CT_Charset_characterSet: - { - OString tmp; - sValue.convertToString( &tmp, RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS ); - m_pImpl->pCurrentEntry->nTextEncoding = rtl_getTextEncodingFromMimeCharset( tmp.getStr() ); - // Older LO versions used to write incorrect character set for OpenSymbol, fix. - if( IsStarSymbol( m_pImpl->pCurrentEntry->sFontName )) - m_pImpl->pCurrentEntry->nTextEncoding = RTL_TEXTENCODING_SYMBOL; - break; - } - default: ; - } -} - -void FontTable::lcl_sprm(Sprm& rSprm) -{ - SAL_WARN_IF( !m_pImpl->pCurrentEntry, "writerfilter.dmapper", "current entry has to be set here" ); - if(!m_pImpl->pCurrentEntry) - return ; - sal_uInt32 nSprmId = rSprm.getId(); - - switch(nSprmId) - { - case NS_ooxml::LN_CT_Font_charset: - case NS_ooxml::LN_CT_Font_pitch: - resolveSprm( rSprm ); - break; - case NS_ooxml::LN_CT_Font_embedRegular: - case NS_ooxml::LN_CT_Font_embedBold: - case NS_ooxml::LN_CT_Font_embedItalic: - case NS_ooxml::LN_CT_Font_embedBoldItalic: - { - writerfilter::Reference< Properties >::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - EmbeddedFontHandler handler(*this, m_pImpl->pCurrentEntry->sFontName, - nSprmId == NS_ooxml::LN_CT_Font_embedRegular ? "" - : nSprmId == NS_ooxml::LN_CT_Font_embedBold ? "b" - : nSprmId == NS_ooxml::LN_CT_Font_embedItalic ? "i" - : /*NS_ooxml::LN_CT_Font_embedBoldItalic*/ "bi" ); - pProperties->resolve( handler ); - } - break; - } - case NS_ooxml::LN_CT_Font_altName: - break; - case NS_ooxml::LN_CT_Font_panose1: - break; - case NS_ooxml::LN_CT_Font_family: - break; - case NS_ooxml::LN_CT_Font_sig: - break; - case NS_ooxml::LN_CT_Font_notTrueType: - break; - default: - SAL_WARN("writerfilter.dmapper", "FontTable::lcl_sprm: unhandled token: " << nSprmId); - break; - } -} - -void FontTable::resolveSprm(Sprm & r_Sprm) -{ - writerfilter::Reference<Properties>::Pointer_t pProperties = r_Sprm.getProps(); - if( pProperties ) - pProperties->resolve(*this); -} - -void FontTable::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) -{ - //create a new font entry - SAL_WARN_IF( m_pImpl->pCurrentEntry, "writerfilter.dmapper", "current entry has to be NULL here" ); - m_pImpl->pCurrentEntry = new FontEntry; - ref->resolve(*this); - //append it to the table - m_pImpl->aFontEntries.push_back( m_pImpl->pCurrentEntry ); - m_pImpl->pCurrentEntry.clear(); -} - -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_startShape(uno::Reference<drawing::XShape> const&) -{ -} - -void FontTable::lcl_endShape( ) -{ -} - -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(); -} - -bool FontTable::addEmbeddedFont(const css::uno::Reference<css::io::XInputStream>& stream, - const OUString& fontName, const char* extra, - std::vector<unsigned char> const & key) -{ - if (!m_pImpl->xEmbeddedFontHelper) - m_pImpl->xEmbeddedFontHelper.reset(new EmbeddedFontsHelper); - return m_pImpl->xEmbeddedFontHelper->addEmbeddedFont(stream, fontName, extra, key); -} - -EmbeddedFontHandler::EmbeddedFontHandler(FontTable& rFontTable, const OUString& _fontName, const char* _style ) -: LoggedProperties("EmbeddedFontHandler") -, fontTable( rFontTable ) -, fontName( _fontName ) -, style( _style ) -{ -} - -EmbeddedFontHandler::~EmbeddedFontHandler() -{ - if( !inputStream.is()) - return; - std::vector< unsigned char > key( 32 ); - if( !fontKey.isEmpty()) - { // key for unobfuscating - // 1 3 5 7 10 2 5 7 20 2 5 7 9 1 3 5 - // {62E79491-959F-41E9-B76B-6B32631DEA5C} - static const int pos[ 16 ] = { 35, 33, 31, 29, 27, 25, 22, 20, 17, 15, 12, 10, 7, 5, 3, 1 }; - for( int i = 0; - i < 16; - ++i ) - { - int v1 = fontKey[ pos[ i ]]; - int v2 = fontKey[ pos[ i ] + 1 ]; - assert(( v1 >= '0' && v1 <= '9' ) || ( v1 >= 'A' && v1 <= 'F' )); - assert(( v2 >= '0' && v2 <= '9' ) || ( v2 >= 'A' && v2 <= 'F' )); - int val = ( v1 - ( v1 <= '9' ? '0' : 'A' - 10 )) * 16 + v2 - ( v2 <= '9' ? '0' : 'A' - 10 ); - key[ i ] = val; - key[ i + 16 ] = val; - } - } - fontTable.addEmbeddedFont( inputStream, fontName, style, key ); - inputStream->closeInput(); -} - -void EmbeddedFontHandler::lcl_attribute( Id name, Value& val ) -{ - OUString sValue = val.getString(); - switch( name ) - { - case NS_ooxml::LN_CT_FontRel_fontKey: - fontKey = sValue; - break; - case NS_ooxml::LN_CT_Rel_id: - break; - case NS_ooxml::LN_CT_FontRel_subsetted: - break; // TODO? Let's just ignore this for now and hope - // it doesn't break anything. - case NS_ooxml::LN_inputstream: // the actual font data as stream - val.getAny() >>= inputStream; - break; - default: - break; - } -} - -void EmbeddedFontHandler::lcl_sprm( Sprm& ) -{ -} - - -}//namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FontTable.hxx b/writerfilter/source/dmapper/FontTable.hxx deleted file mode 100644 index 1276eaa8d705..000000000000 --- a/writerfilter/source/dmapper/FontTable.hxx +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FONTTABLE_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FONTTABLE_HXX - -#include <memory> -#include <vector> -#include "LoggedResources.hxx" -#include <com/sun/star/io/XInputStream.hpp> - -namespace writerfilter::dmapper -{ - -struct FontTable_Impl; -struct FontEntry : public virtual SvRefBase -{ - typedef tools::SvRef<FontEntry> Pointer_t; - - OUString sFontName; - sal_Int32 nTextEncoding; - FontEntry() : - nTextEncoding( RTL_TEXTENCODING_DONTKNOW ) - {} -}; - -class FontTable : public LoggedProperties, public LoggedTable - /*,public BinaryObj*/, public LoggedStream -{ - std::unique_ptr<FontTable_Impl> m_pImpl; - - public: - FontTable(); - virtual ~FontTable() override; - - sal_uInt32 size(); - FontEntry::Pointer_t getFontEntry(sal_uInt32 nIndex); - - bool addEmbeddedFont(const css::uno::Reference<css::io::XInputStream>& stream, - const OUString& fontName, const char* extra, - std::vector<unsigned char> const & key); - - private: - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - void resolveSprm(Sprm & r_sprm); - - // Table - virtual void lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) override; - - // Stream - virtual void lcl_startSectionGroup() override; - virtual void lcl_endSectionGroup() override; - virtual void lcl_startParagraphGroup() override; - virtual void lcl_endParagraphGroup() override; - virtual void lcl_startCharacterGroup() override; - virtual void lcl_endCharacterGroup() override; - virtual void lcl_text(const sal_uInt8 * data, size_t len) override; - virtual void lcl_utext(const sal_uInt8 * data, size_t len) override; - virtual void lcl_props(writerfilter::Reference<Properties>::Pointer_t ref) override; - virtual void lcl_table(Id name, - writerfilter::Reference<Table>::Pointer_t ref) override; - virtual void lcl_substream(Id name, - ::writerfilter::Reference<Stream>::Pointer_t ref) override; - virtual void lcl_startShape(css::uno::Reference<css::drawing::XShape> const& xShape) override; - virtual void lcl_endShape( ) override; -}; -typedef tools::SvRef< FontTable > FontTablePtr; - -class EmbeddedFontHandler : public LoggedProperties -{ -public: - EmbeddedFontHandler(FontTable& rFontTable, const OUString& fontName, const char* style); - virtual ~EmbeddedFontHandler() override; -private: - virtual void lcl_attribute( Id name, Value& val ) override; - virtual void lcl_sprm( Sprm& rSprm ) override; - FontTable& fontTable; - OUString fontName; - const char* const style; - OUString fontKey; - css::uno::Reference<css::io::XInputStream> inputStream; -}; - - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FormControlHelper.cxx b/writerfilter/source/dmapper/FormControlHelper.cxx deleted file mode 100644 index f2313bdef0a6..000000000000 --- a/writerfilter/source/dmapper/FormControlHelper.cxx +++ /dev/null @@ -1,375 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#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 "FormControlHelper.hxx" -#include <xmloff/odffields.hxx> -#include <comphelper/sequence.hxx> -#include <tools/diagnose_ex.h> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; - -struct FormControlHelper::FormControlHelper_Impl : public virtual SvRefBase -{ - 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> const & getDrawPage(); - uno::Reference<lang::XMultiServiceFactory> const & getServiceFactory(); - uno::Reference<form::XForm> const & getForm(); - uno::Reference<container::XIndexContainer> getFormComps(); -}; - -uno::Reference<drawing::XDrawPage> const & 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> const & FormControlHelper::FormControlHelper_Impl::getServiceFactory() -{ - if (! rServiceFactory.is()) - rServiceFactory.set(rTextDocument, uno::UNO_QUERY); - - return rServiceFactory; -} - -uno::Reference<form::XForm> const & 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 constexpr OUStringLiteral sDOCXForm = u"DOCX-Standard"; - - OUString sFormName(sDOCXForm); - sal_uInt16 nUnique = 0; - - while (xFormsNamedContainer->hasByName(sFormName)) - { - ++nUnique; - sFormName = sDOCXForm + OUString::number(nUnique); - } - - uno::Reference<uno::XInterface> xForm(getServiceFactory()->createInstance("com.sun.star.form.component.Form")); - if (xForm.is()) - { - uno::Reference<beans::XPropertySet> - xFormProperties(xForm, uno::UNO_QUERY); - uno::Any aAny(sFormName); - xFormProperties->setPropertyValue("Name", aAny); - } - - rForm.set(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> const& xTextDocument, - FFDataHandler::Pointer_t const & pFFData) - : m_pFFData(pFFData), m_pImpl(new FormControlHelper_Impl) -{ - m_pImpl->m_eFieldId = eFieldId; - m_pImpl->rTextDocument = xTextDocument; -} - -FormControlHelper::~FormControlHelper() -{ -} - -bool FormControlHelper::createCheckbox(uno::Reference<text::XTextRange> const& xTextRange, - const 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("com.sun.star.form.component.CheckBox"); - - if (!xInterface.is()) - return false; - - m_pImpl->rFormComponent.set(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 - { - float fCheckBoxHeight = 0.0; - xTextRangeProps->getPropertyValue("CharHeight") >>= fCheckBoxHeight; - nCheckBoxHeight = static_cast<sal_uInt32>(floor(fCheckBoxHeight * 35.3)); - } - catch (beans::UnknownPropertyException &) - { - } - } - - m_pImpl->aSize.Width = nCheckBoxHeight; - m_pImpl->aSize.Height = m_pImpl->aSize.Width; - - if (!m_pFFData->getStatusText().isEmpty()) - { - xPropSet->setPropertyValue("HelpText", uno::Any(m_pFFData->getStatusText())); - } - - xPropSet->setPropertyValue("DefaultState", uno::Any(m_pFFData->getCheckboxChecked())); - - if (!m_pFFData->getHelpText().isEmpty()) - { - xPropSet->setPropertyValue("HelpF1Text", uno::Any(m_pFFData->getHelpText())); - } - - xPropSet->setPropertyValue("Name", uno::Any(rControlName)); - - return true; -} - -void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFormField) -{ - // Set field type first before adding parameters. - if (m_pImpl->m_eFieldId == FIELD_FORMTEXT ) - { - xFormField->setFieldType(ODF_FORMTEXT); - } - else if (m_pImpl->m_eFieldId == FIELD_FORMCHECKBOX ) - { - xFormField->setFieldType(ODF_FORMCHECKBOX); - } - else if (m_pImpl->m_eFieldId == FIELD_FORMDROPDOWN ) - { - xFormField->setFieldType(ODF_FORMDROPDOWN); - } - - uno::Reference<container::XNameContainer> xNameCont = xFormField->getParameters(); - uno::Reference<container::XNamed> xNamed( xFormField, uno::UNO_QUERY ); - if ( !(m_pFFData && xNamed.is() && xNameCont.is()) ) - return; - - OUString sTmp = m_pFFData->getEntryMacro(); - if ( !sTmp.isEmpty() ) - xNameCont->insertByName( "EntryMacro", uno::makeAny(sTmp) ); - sTmp = m_pFFData->getExitMacro(); - if ( !sTmp.isEmpty() ) - xNameCont->insertByName( "ExitMacro", uno::makeAny(sTmp) ); - - sTmp = m_pFFData->getHelpText(); - if ( !sTmp.isEmpty() ) - xNameCont->insertByName( "Help", uno::makeAny(sTmp) ); - - sTmp = m_pFFData->getStatusText(); - if ( !sTmp.isEmpty() ) - xNameCont->insertByName( "Hint", uno::makeAny(sTmp) ); - - if (m_pImpl->m_eFieldId == FIELD_FORMTEXT ) - { - sTmp = m_pFFData->getName(); - try - { - if ( !sTmp.isEmpty() ) - xNamed->setName( sTmp ); - } - catch ( uno::Exception& ) - { - TOOLS_INFO_EXCEPTION("writerfilter", "Set Formfield name failed"); - } - - sTmp = m_pFFData->getTextType(); - if ( !sTmp.isEmpty() ) - xNameCont->insertByName( "Type", uno::makeAny(sTmp) ); - - const sal_uInt16 nMaxLength = m_pFFData->getTextMaxLength(); - if ( nMaxLength ) - { - xNameCont->insertByName( "MaxLength", uno::makeAny(nMaxLength) ); - } - - sTmp = m_pFFData->getTextDefault(); - if ( !sTmp.isEmpty() ) - xNameCont->insertByName( "Content", uno::makeAny(sTmp) ); - - sTmp = m_pFFData->getTextFormat(); - if ( !sTmp.isEmpty() ) - xNameCont->insertByName( "Format", uno::makeAny(sTmp) ); - } - else if (m_pImpl->m_eFieldId == FIELD_FORMCHECKBOX ) - { - uno::Reference<beans::XPropertySet> xPropSet(xFormField, uno::UNO_QUERY); - uno::Any aAny; - aAny <<= m_pFFData->getCheckboxChecked(); - if ( xPropSet.is() ) - xPropSet->setPropertyValue("Checked", aAny); - } - else if (m_pImpl->m_eFieldId == FIELD_FORMDROPDOWN ) - { - const FFDataHandler::DropDownEntries_t& rEntries = m_pFFData->getDropDownEntries(); - if (!rEntries.empty()) - { - if ( xNameCont->hasByName(ODF_FORMDROPDOWN_LISTENTRY) ) - xNameCont->replaceByName(ODF_FORMDROPDOWN_LISTENTRY, uno::makeAny(comphelper::containerToSequence(rEntries))); - else - xNameCont->insertByName(ODF_FORMDROPDOWN_LISTENTRY, uno::makeAny(comphelper::containerToSequence(rEntries))); - - sal_Int32 nResult = m_pFFData->getDropDownResult().toInt32(); - if ( nResult ) - { - if ( xNameCont->hasByName(ODF_FORMDROPDOWN_RESULT) ) - xNameCont->replaceByName(ODF_FORMDROPDOWN_RESULT, uno::makeAny( nResult ) ); - else - xNameCont->insertByName(ODF_FORMDROPDOWN_RESULT, uno::makeAny( nResult ) ); - } - } - } -} - -void FormControlHelper::insertControl(uno::Reference<text::XTextRange> const& xTextRange) -{ - bool bCreated = false; - if ( !m_pFFData ) - return; - uno::Reference<container::XNameContainer> xFormCompsByName(m_pImpl->getForm(), uno::UNO_QUERY); - uno::Reference<container::XIndexContainer> xFormComps(m_pImpl->getFormComps()); - if (! xFormComps.is()) - return; - - sal_Int32 nControl = 0; - bool bDone = false; - OUString sControlName; - - do - { - OUString sTmp = "Control" + OUString::number(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; - - uno::Any aAny(m_pImpl->rFormComponent); - xFormComps->insertByIndex(xFormComps->getCount(), aAny); - - if (! m_pImpl->getServiceFactory().is()) - return; - - uno::Reference<uno::XInterface> xInterface = m_pImpl->getServiceFactory()->createInstance("com.sun.star.drawing.ControlShape"); - - if (! xInterface.is()) - return; - - uno::Reference<drawing::XShape> xShape(xInterface, uno::UNO_QUERY); - - if (! xShape.is()) - return; - - xShape->setSize(m_pImpl->aSize); - - uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY); - - sal_uInt16 nTmp = sal_uInt16(text::TextContentAnchorType_AS_CHARACTER); - xShapeProps->setPropertyValue("AnchorType", uno::makeAny<sal_uInt16>(nTmp)); - - nTmp = text::VertOrientation::CENTER; - xShapeProps->setPropertyValue("VertOrient", uno::makeAny<sal_uInt16>(nTmp)); - - xShapeProps->setPropertyValue("TextRange", uno::Any(xTextRange)); - - 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); -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/FormControlHelper.hxx b/writerfilter/source/dmapper/FormControlHelper.hxx deleted file mode 100644 index f3cb74549226..000000000000 --- a/writerfilter/source/dmapper/FormControlHelper.hxx +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FORMCONTROLHELPER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FORMCONTROLHELPER_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::dmapper -{ -class FormControlHelper : public virtual SvRefBase -{ -public: - typedef tools::SvRef<FormControlHelper> Pointer_t; - FormControlHelper(FieldId eFieldId, - css::uno::Reference<css::text::XTextDocument> const& rTextDocument, - FFDataHandler::Pointer_t const& pFFData); - ~FormControlHelper() override; - - void insertControl(css::uno::Reference<css::text::XTextRange> const& xTextRange); - void processField(css::uno::Reference<css::text::XFormField> const& xFormField); - bool hasFFDataHandler() const { return (m_pFFData != nullptr); } - -private: - FFDataHandler::Pointer_t m_pFFData; - struct FormControlHelper_Impl; - tools::SvRef<FormControlHelper_Impl> m_pImpl; - - bool createCheckbox(css::uno::Reference<css::text::XTextRange> const& xTextRange, - const OUString& rControlName); -}; -} - -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_FORMCONTROLHELPER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/GraphicHelpers.cxx b/writerfilter/source/dmapper/GraphicHelpers.cxx deleted file mode 100644 index d4fc4b9a8c09..000000000000 --- a/writerfilter/source/dmapper/GraphicHelpers.cxx +++ /dev/null @@ -1,348 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "GraphicHelpers.hxx" -#include "TagLogger.hxx" -#include <dmapper/GraphicZOrderHelper.hxx> -#include "PropertyIds.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 <oox/drawingml/drawingmltypes.hxx> -#include <sal/log.hxx> -#include <svx/dialmgr.hxx> -#include <svx/strings.hrc> -#include <tools/diagnose_ex.h> - -#include <iostream> - -namespace writerfilter::dmapper { - -using namespace com::sun::star; - -PositionHandler::PositionHandler( std::pair<OUString, OUString>& rPositionOffsets, std::pair<OUString, OUString>& rAligns ) : -LoggedProperties("PositionHandler"), -m_nOrient(text::VertOrientation::NONE), -m_nRelation(text::RelOrientation::FRAME), -m_nPosition(0), -m_rPositionOffsets(rPositionOffsets), -m_rAligns(rAligns) -{ -} - -PositionHandler::~PositionHandler( ) -{ -} - -void PositionHandler::lcl_attribute( Id aName, Value& rVal ) -{ - sal_Int32 nIntValue = rVal.getInt( ); - switch ( aName ) - { - case NS_ooxml::LN_CT_PosV_relativeFrom: - { - switch ( nIntValue ) - { - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_margin: - m_nRelation = text::RelOrientation::PAGE_PRINT_AREA; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_page: - m_nRelation = text::RelOrientation::PAGE_FRAME; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_topMargin: - m_nRelation = text::RelOrientation::PAGE_PRINT_AREA_TOP; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_bottomMargin: - m_nRelation = text::RelOrientation::PAGE_PRINT_AREA_BOTTOM; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_paragraph: - m_nRelation = text::RelOrientation::FRAME; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_line: - m_nRelation = text::RelOrientation::TEXT_LINE; - break; - - // TODO There are some other unhandled values - default: - SAL_WARN("writerfilter", "unhandled case (" << nIntValue << ") in NS_ooxml::LN_CT_PosV_relativeFrom"); - } - } - break; - - case NS_ooxml::LN_CT_PosH_relativeFrom: - { - switch ( nIntValue ) - { - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_margin: - m_nRelation = text::RelOrientation::PAGE_PRINT_AREA; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_page: - m_nRelation = text::RelOrientation::PAGE_FRAME; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_insideMargin: - m_nRelation = text::RelOrientation::PAGE_FRAME; - m_bPageToggle = true; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_column: - m_nRelation = text::RelOrientation::FRAME; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_character: - m_nRelation = text::RelOrientation::CHAR; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_leftMargin: - m_nRelation = text::RelOrientation::PAGE_LEFT; - break; - - case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_rightMargin: - m_nRelation = text::RelOrientation::PAGE_RIGHT; - break; - - // TODO There are some other unhandled values - default: - SAL_WARN("writerfilter", "unhandled case (" << nIntValue << ") in NS_ooxml::LN_CT_PosH_relativeFrom"); - } - } - break; - default: -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - break; - } -} - -void PositionHandler::lcl_sprm(Sprm& rSprm) -{ - sal_uInt32 nSprmId = rSprm.getId(); - - switch (nSprmId) - { - case NS_ooxml::LN_CT_PosH_posOffset: - m_nPosition = oox::drawingml::convertEmuToHmm(m_rPositionOffsets.first.toInt32()); - m_rPositionOffsets.first.clear(); - break; - case NS_ooxml::LN_CT_PosV_posOffset: - m_nPosition = oox::drawingml::convertEmuToHmm(m_rPositionOffsets.second.toInt32()); - m_rPositionOffsets.second.clear(); - break; - case NS_ooxml::LN_CT_PosH_align: - { - OUString& rAlign = m_rAligns.first; - if (rAlign == "left") - m_nOrient = text::HoriOrientation::LEFT; - else if (rAlign == "right") - m_nOrient = text::HoriOrientation::RIGHT; - else if (rAlign == "center") - m_nOrient = text::HoriOrientation::CENTER; - else if (rAlign == "inside") - m_nOrient = text::HoriOrientation::INSIDE; - else if (rAlign == "outside") - m_nOrient = text::HoriOrientation::OUTSIDE; - rAlign.clear(); - break; - } - case NS_ooxml::LN_CT_PosV_align: - { - OUString& rAlign = m_rAligns.second; - if (rAlign == "top") - m_nOrient = text::VertOrientation::TOP; - else if (rAlign == "bottom") - m_nOrient = text::VertOrientation::BOTTOM; - else if (rAlign == "center") - m_nOrient = text::VertOrientation::CENTER; - else if (rAlign == "inside" && m_nRelation == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM) - m_nOrient = text::VertOrientation::TOP; - else if (rAlign == "outside" && m_nRelation == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM) - m_nOrient = text::VertOrientation::BOTTOM; - rAlign.clear(); - break; - } - } -} - -sal_Int16 PositionHandler::orientation() const -{ - if( m_nRelation == text::RelOrientation::TEXT_LINE ) - { // It appears that to 'line of text' alignment is backwards to other alignments, - // 'top' meaning putting on top of the line instead of having top at the line. - if( m_nOrient == text::VertOrientation::TOP ) - return text::VertOrientation::BOTTOM; - else if( m_nOrient == text::VertOrientation::BOTTOM ) - return text::VertOrientation::TOP; - } - return m_nOrient; -} - -WrapHandler::WrapHandler( ) : -LoggedProperties("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& ) -{ -} - -text::WrapTextMode WrapHandler::getWrapMode( ) const -{ - // The wrap values do not map directly to our wrap mode, - // e.g. none in .docx actually means through in LO. - text::WrapTextMode nMode = text::WrapTextMode_THROUGH; - - switch ( m_nType ) - { - case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_square: - // through and tight are somewhat complicated, approximate - case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_tight: - case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_through: - { - switch ( m_nSide ) - { - case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_left: - nMode = text::WrapTextMode_LEFT; - break; - case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapSide_right: - nMode = text::WrapTextMode_RIGHT; - break; - default: - nMode = text::WrapTextMode_PARALLEL; - } - } - break; - case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_topAndBottom: - nMode = text::WrapTextMode_NONE; - break; - case NS_ooxml::LN_Value_vml_wordprocessingDrawing_ST_WrapType_none: - default: - nMode = text::WrapTextMode_THROUGH; - } - - return nMode; -} - - -void GraphicZOrderHelper::addItem(uno::Reference<beans::XPropertySet> const& props, sal_Int32 const relativeHeight) -{ - items[ relativeHeight ] = props; -} - -// The relativeHeight value in .docx is an arbitrary number, where only the relative ordering matters. -// But in Writer, the z-order is index in 0..(numitems-1) range, so whenever a new item needs to be -// added in the proper z-order, it is necessary to find the proper index. -sal_Int32 GraphicZOrderHelper::findZOrder( sal_Int32 relativeHeight, bool bOldStyle ) -{ - // std::map is iterated sorted by key - auto it = std::find_if(items.cbegin(), items.cend(), - [relativeHeight, bOldStyle](const Items::value_type& rItem) { - // Old-style ordering differs in what should happen when there is already an item with the same z-order: - // we belong under it in case of new-style, but we belong above it in case of old-style. - return bOldStyle ? (rItem.first > relativeHeight) : (rItem.first >= relativeHeight); - } - ); - sal_Int32 itemZOrderOffset(0); // before the item - if( it == items.end()) // we're topmost - { - if( items.empty()) - return 0; - --it; - itemZOrderOffset = 1; // after the topmost - - // Check if this shape has a textbox. If so, the textbox will have its own ZOrder, so - // suggest a larger offset. - bool bTextBox = false; - uno::Reference<beans::XPropertySet> xShape = it->second; - uno::Reference<beans::XPropertySetInfo> xInfo = xShape->getPropertySetInfo(); - if (xInfo->hasPropertyByName("TextBox")) - { - xShape->getPropertyValue("TextBox") >>= bTextBox; - } - if (bTextBox) - { - ++itemZOrderOffset; - } - } - // SwXFrame::getPropertyValue throws uno::RuntimeException - // when its GetFrameFormat() returns nullptr - try { - sal_Int32 itemZOrder(0); - if( it->second->getPropertyValue(getPropertyName( PROP_Z_ORDER )) >>= itemZOrder ) - return itemZOrder + itemZOrderOffset; - } - catch (const uno::RuntimeException&) { - TOOLS_WARN_EXCEPTION("writerfilter", "Exception when getting item z-order"); - } - SAL_WARN( "writerfilter", "findZOrder() didn't find item z-order" ); - return 0; // this should not(?) happen -} - -GraphicNamingHelper::GraphicNamingHelper() - : m_nCounter(0) -{ -} - -OUString GraphicNamingHelper::NameGraphic(const OUString& rTemplate) -{ - OUString aRet = rTemplate; - - if (aRet.isEmpty()) - { - // Empty template: then auto-generate a unique name. - OUString aPrefix(SvxResId(STR_ObjNameSingulGRAF)); - aRet += aPrefix + OUString::number(++m_nCounter); - } - - return aRet; -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/GraphicHelpers.hxx b/writerfilter/source/dmapper/GraphicHelpers.hxx deleted file mode 100644 index 66fd06c06281..000000000000 --- a/writerfilter/source/dmapper/GraphicHelpers.hxx +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_GRAPHICHELPERS_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_GRAPHICHELPERS_HXX - -#include "LoggedResources.hxx" -#include <com/sun/star/text/WrapTextMode.hpp> - -#include <utility> - -namespace writerfilter::dmapper -{ -class PositionHandler : public LoggedProperties -{ -public: - PositionHandler(std::pair<OUString, OUString>& rPositionOffsets, - std::pair<OUString, OUString>& rAligns); - virtual ~PositionHandler() override; - sal_Int16 orientation() const; - sal_Int16 relation() const { return m_nRelation; } - sal_Int32 position() const { return m_nPosition; } - bool GetPageToggle() const { return m_bPageToggle; } - -private: - virtual void lcl_attribute(Id aName, Value& rVal) override; - virtual void lcl_sprm(Sprm& rSprm) override; - sal_Int16 m_nOrient; - sal_Int16 m_nRelation; - sal_Int32 m_nPosition; - std::pair<OUString, OUString>& m_rPositionOffsets; - std::pair<OUString, OUString>& m_rAligns; - bool m_bPageToggle = false; -}; - -class WrapHandler : public LoggedProperties -{ -public: - WrapHandler(); - virtual ~WrapHandler() override; - - css::text::WrapTextMode getWrapMode() const; - -private: - virtual void lcl_attribute(Id aName, Value& rVal) override; - virtual void lcl_sprm(Sprm& rSprm) override; - - sal_Int32 m_nType; - sal_Int32 m_nSide; -}; - -/// Keeps track of the next available unique automatic name. -class GraphicNamingHelper -{ - int m_nCounter; - -public: - GraphicNamingHelper(); - /// Name a graphic based on rTemplate. - OUString NameGraphic(const OUString& rTemplate); -}; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx deleted file mode 100644 index cc81850bfc86..000000000000 --- a/writerfilter/source/dmapper/GraphicImport.cxx +++ /dev/null @@ -1,1632 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#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/drawing/LineStyle.hpp> -#include <com/sun/star/graphic/XGraphic.hpp> -#include <com/sun/star/graphic/GraphicProvider.hpp> -#include <com/sun/star/graphic/XGraphicProvider.hpp> -#include <com/sun/star/io/BufferSizeExceededException.hpp> -#include <com/sun/star/io/XInputStream.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/lang/XServiceInfo.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 <com/sun/star/table/ShadowFormat.hpp> - -#include <svx/svdobj.hxx> -#include <svx/unoapi.hxx> -#include <cppuhelper/implbase.hxx> -#include <rtl/ustrbuf.hxx> -#include <sal/log.hxx> -#include <rtl/math.hxx> -#include <tools/diagnose_ex.h> -#include <comphelper/string.hxx> -#include <comphelper/sequenceashashmap.hxx> -#include <comphelper/sequence.hxx> - -#include <oox/drawingml/drawingmltypes.hxx> - -#include "DomainMapper.hxx" -#include <dmapper/GraphicZOrderHelper.hxx> -#include <ooxml/resourceids.hxx> - -#include "ConversionHelper.hxx" -#include "GraphicHelpers.hxx" -#include "GraphicImport.hxx" -#include "PropertyMap.hxx" -#include "TagLogger.hxx" -#include "WrapPolygonHandler.hxx" -#include "util.hxx" - -#include <comphelper/propertysequence.hxx> - -using namespace css; - -namespace -{ -bool isTopGroupObj(const uno::Reference<drawing::XShape>& xShape) -{ - SdrObject* pObject = GetSdrObjectFromXShape(xShape); - if (!pObject) - return false; - - if (pObject->getParentSdrObjectFromSdrObject()) - return false; - - return pObject->IsGroupObject(); -} -} - -namespace writerfilter::dmapper -{ - -namespace { - -class XInputStreamHelper : public cppu::WeakImplHelper<io::XInputStream> -{ - const sal_uInt8* m_pBuffer; - const sal_Int32 m_nLength; - sal_Int32 m_nPosition; -public: - XInputStreamHelper(const sal_uInt8* buf, size_t len); - - virtual ::sal_Int32 SAL_CALL readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) override; - virtual ::sal_Int32 SAL_CALL readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) override; - virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) override; - virtual ::sal_Int32 SAL_CALL available( ) override; - virtual void SAL_CALL closeInput( ) override; -}; - -} - -XInputStreamHelper::XInputStreamHelper(const sal_uInt8* buf, size_t len) : - m_pBuffer( buf ), - m_nLength( len ), - m_nPosition( 0 ) -{ -} - -sal_Int32 XInputStreamHelper::readBytes( uno::Sequence<sal_Int8>& aData, sal_Int32 nBytesToRead ) -{ - return readSomeBytes( aData, nBytesToRead ); -} - -sal_Int32 XInputStreamHelper::readSomeBytes( uno::Sequence<sal_Int8>& aData, sal_Int32 nMaxBytesToRead ) -{ - sal_Int32 nRet = 0; - if( nMaxBytesToRead > 0 ) - { - if( nMaxBytesToRead > m_nLength - m_nPosition ) - nRet = m_nLength - m_nPosition; - else - nRet = nMaxBytesToRead; - aData.realloc( nRet ); - sal_Int8* pData = aData.getArray(); - if( nRet ) - { - memcpy( pData, m_pBuffer + m_nPosition, nRet ); - m_nPosition += nRet; - } - } - return nRet; -} - - -void XInputStreamHelper::skipBytes( sal_Int32 nBytesToSkip ) -{ - if( nBytesToSkip < 0 || m_nPosition + nBytesToSkip > m_nLength) - throw io::BufferSizeExceededException(); - m_nPosition += nBytesToSkip; -} - - -sal_Int32 XInputStreamHelper::available( ) -{ - return m_nLength - m_nPosition; -} - - -void XInputStreamHelper::closeInput( ) -{ -} - -namespace { - -struct GraphicBorderLine -{ - sal_Int32 nLineWidth; - bool bHasShadow; - - GraphicBorderLine() : - nLineWidth(0) - ,bHasShadow(false) - {} - - bool isEmpty() const - { - return nLineWidth == 0 && !bHasShadow; - } - -}; - -} - -class GraphicImport_Impl -{ -private: - sal_Int32 nXSize; - bool bXSizeValid; - sal_Int32 nYSize; - bool bYSizeValid; - -public: - GraphicImportType eGraphicImportType; - DomainMapper& rDomainMapper; - - sal_Int32 nLeftPosition; - sal_Int32 nTopPosition; - - bool bUseSimplePos; - sal_Int32 zOrder; - - sal_Int16 nHoriOrient; - sal_Int16 nHoriRelation; - bool bPageToggle = false; - sal_Int16 nVertOrient; - sal_Int16 nVertRelation; - text::WrapTextMode nWrap; - bool bLayoutInCell; - bool bCompatForcedLayoutInCell; - bool bAllowOverlap = true; - bool bOpaque; - bool bBehindDoc; - bool bContour; - bool bContourOutside; - WrapPolygon::Pointer_t mpWrapPolygon; - - sal_Int32 nLeftMargin; - sal_Int32 nLeftMarginOrig = 0; - sal_Int32 nRightMargin; - sal_Int32 nTopMargin; - sal_Int32 nBottomMargin; - - bool bShadow; - sal_Int32 nShadowXDistance; - sal_Int32 nShadowYDistance; - sal_Int32 nShadowColor; - sal_Int32 nShadowTransparence; - - sal_Int32 nContrast; - sal_Int32 nBrightness; - - static constexpr sal_Int32 nFillColor = 0xffffffff; - - drawing::ColorMode eColorMode; - - GraphicBorderLine aBorders[4]; - - bool bIsGraphic; - - bool bSizeProtected; - bool bPositionProtected; - bool bHidden; - - sal_Int32 nShapeOptionType; - - OUString sName; - OUString sAlternativeText; - OUString title; - OUString sHyperlinkURL; - std::pair<OUString, OUString>& m_rPositionOffsets; - std::pair<OUString, OUString>& m_rAligns; - std::queue<OUString>& m_rPositivePercentages; - OUString sAnchorId; - comphelper::SequenceAsHashMap m_aInteropGrabBag; - std::optional<sal_Int32> m_oEffectExtentLeft; - std::optional<sal_Int32> m_oEffectExtentTop; - std::optional<sal_Int32> m_oEffectExtentRight; - std::optional<sal_Int32> m_oEffectExtentBottom; - - GraphicImport_Impl(GraphicImportType eImportType, DomainMapper& rDMapper, std::pair<OUString, OUString>& rPositionOffsets, std::pair<OUString, OUString>& rAligns, std::queue<OUString>& rPositivePercentages) : - nXSize(0) - ,bXSizeValid(false) - ,nYSize(0) - ,bYSizeValid(false) - ,eGraphicImportType( eImportType ) - ,rDomainMapper( rDMapper ) - ,nLeftPosition(0) - ,nTopPosition(0) - ,bUseSimplePos(false) - ,zOrder(-1) - ,nHoriOrient( text::HoriOrientation::NONE ) - ,nHoriRelation( text::RelOrientation::FRAME ) - ,nVertOrient( text::VertOrientation::NONE ) - ,nVertRelation( text::RelOrientation::FRAME ) - ,nWrap(text::WrapTextMode_NONE) - ,bLayoutInCell(true) - ,bCompatForcedLayoutInCell(false) - ,bOpaque( !rDMapper.IsInHeaderFooter() ) - ,bBehindDoc(false) - ,bContour(false) - ,bContourOutside(true) - ,nLeftMargin(319) - ,nRightMargin(319) - ,nTopMargin(0) - ,nBottomMargin(0) - ,bShadow(false) - ,nShadowXDistance(0) - ,nShadowYDistance(0) - ,nShadowColor(0) - ,nShadowTransparence(0) - ,nContrast(0) - ,nBrightness(0) - ,eColorMode( drawing::ColorMode_STANDARD ) - ,bIsGraphic(false) - ,bSizeProtected(false) - ,bPositionProtected(false) - ,bHidden(false) - ,nShapeOptionType(0) - ,m_rPositionOffsets(rPositionOffsets) - ,m_rAligns(rAligns) - ,m_rPositivePercentages(rPositivePercentages) - { - if (eGraphicImportType == GraphicImportType::IMPORT_AS_DETECTED_INLINE - && !rDMapper.IsInShape()) - { - zOrder = 0; - } - } - - 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; - } - - void applyMargins(const uno::Reference< beans::XPropertySet >& xGraphicObjectProperties) const - { - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_LEFT_MARGIN ), uno::makeAny(nLeftMargin)); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_RIGHT_MARGIN ), uno::makeAny(nRightMargin)); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_TOP_MARGIN ), uno::makeAny(nTopMargin)); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_BOTTOM_MARGIN ), uno::makeAny(nBottomMargin)); - } - - void applyPosition(const uno::Reference< beans::XPropertySet >& xGraphicObjectProperties) const - { - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_HORI_ORIENT ), - uno::makeAny(nHoriOrient)); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_VERT_ORIENT ), - uno::makeAny(nVertOrient)); - } - - void applyRelativePosition(const uno::Reference< beans::XPropertySet >& xGraphicObjectProperties, bool bRelativeOnly = false) const - { - if (!bRelativeOnly) - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_HORI_ORIENT_POSITION), - uno::makeAny(nLeftPosition)); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_HORI_ORIENT_RELATION ), - uno::makeAny(nHoriRelation)); - xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_PAGE_TOGGLE), - uno::makeAny(bPageToggle)); - if (!bRelativeOnly) - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_VERT_ORIENT_POSITION), - uno::makeAny(nTopPosition)); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_VERT_ORIENT_RELATION ), - uno::makeAny(nVertRelation)); - } - - void applyZOrder(uno::Reference<beans::XPropertySet> const & xGraphicObjectProperties) const - { - if (zOrder >= 0) - { - // tdf#120760 Send objects with behinddoc=true to the back. - sal_Int32 nZOrder = zOrder; - if (bBehindDoc && rDomainMapper.IsInHeaderFooter()) - nZOrder -= SAL_MAX_INT32; - GraphicZOrderHelper* pZOrderHelper = rDomainMapper.graphicZOrderHelper(); - bool bOldStyle = eGraphicImportType == GraphicImportType::IMPORT_AS_DETECTED_INLINE; - xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_Z_ORDER), - uno::makeAny(pZOrderHelper->findZOrder(nZOrder, bOldStyle))); - pZOrderHelper->addItem(xGraphicObjectProperties, nZOrder); - } - } - - void applyName(uno::Reference<beans::XPropertySet> const & xGraphicObjectProperties) const - { - try - { - // Ask the graphic naming helper to find out the name for this - // object: It's around till the end of the import, so it remembers - // what's the first free name. - uno::Reference< container::XNamed > xNamed( xGraphicObjectProperties, uno::UNO_QUERY_THROW ); - xNamed->setName(rDomainMapper.GetGraphicNamingHelper().NameGraphic(sName)); - - if ( sHyperlinkURL.getLength() > 0 ) - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_HYPER_LINK_U_R_L ), - uno::makeAny ( sHyperlinkURL )); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_DESCRIPTION ), - uno::makeAny( sAlternativeText )); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_TITLE ), - uno::makeAny( title )); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION("writerfilter", "failed"); - } - } - - /// Getter for m_aInteropGrabBag, but also merges in the values from other members if they are set. - comphelper::SequenceAsHashMap const & getInteropGrabBag() - { - comphelper::SequenceAsHashMap aEffectExtent; - if (m_oEffectExtentLeft) - aEffectExtent["l"] <<= *m_oEffectExtentLeft; - if (m_oEffectExtentTop) - aEffectExtent["t"] <<= *m_oEffectExtentTop; - if (m_oEffectExtentRight) - aEffectExtent["r"] <<= *m_oEffectExtentRight; - if (m_oEffectExtentBottom) - aEffectExtent["b"] <<= *m_oEffectExtentBottom; - if (!aEffectExtent.empty()) - m_aInteropGrabBag["CT_EffectExtent"] <<= aEffectExtent.getAsConstPropertyValueList(); - return m_aInteropGrabBag; - } -}; - -GraphicImport::GraphicImport(uno::Reference<uno::XComponentContext> const& xComponentContext, - uno::Reference<lang::XMultiServiceFactory> const& xTextFactory, - DomainMapper& rDMapper, - GraphicImportType eImportType, - std::pair<OUString, OUString>& rPositionOffsets, - std::pair<OUString, OUString>& rAligns, - std::queue<OUString>& rPositivePercentages) -: LoggedProperties("GraphicImport") -, LoggedTable("GraphicImport") -, LoggedStream("GraphicImport") -, m_pImpl(new GraphicImport_Impl(eImportType, rDMapper, rPositionOffsets, rAligns, rPositivePercentages)) -, m_xComponentContext(xComponentContext) -, m_xTextFactory(xTextFactory) -{ -} - -GraphicImport::~GraphicImport() -{ -} - -com::sun::star::awt::Point GraphicImport::GetGraphicObjectPosition() const -{ - return (com::sun::star::awt::Point(m_pImpl->nLeftPosition, m_pImpl->nTopPosition)); -} - -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::putPropertyToFrameGrabBag( const OUString& sPropertyName, const uno::Any& aPropertyValue ) -{ - beans::PropertyValue aProperty; - aProperty.Name = sPropertyName; - aProperty.Value = aPropertyValue; - - if (!m_xShape.is()) - return; - - uno::Reference< beans::XPropertySet > xSet(m_xShape, uno::UNO_QUERY_THROW); - - uno::Reference< beans::XPropertySetInfo > xSetInfo(xSet->getPropertySetInfo()); - if (!xSetInfo.is()) - return; - - OUString aGrabBagPropName; - uno::Reference<lang::XServiceInfo> xServiceInfo(m_xShape, uno::UNO_QUERY_THROW); - if (xServiceInfo->supportsService("com.sun.star.text.TextFrame")) - aGrabBagPropName = "FrameInteropGrabBag"; - else - aGrabBagPropName = "InteropGrabBag"; - - if (xSetInfo->hasPropertyByName(aGrabBagPropName)) - { - //Add pProperty to the end of the Sequence for aGrabBagPropName - uno::Sequence<beans::PropertyValue> aTmp; - xSet->getPropertyValue(aGrabBagPropName) >>= aTmp; - std::vector<beans::PropertyValue> aGrabBag(comphelper::sequenceToContainer<std::vector<beans::PropertyValue> >(aTmp)); - aGrabBag.push_back(aProperty); - - xSet->setPropertyValue(aGrabBagPropName, uno::makeAny(comphelper::containerToSequence(aGrabBag))); - } -} - -void GraphicImport::lcl_attribute(Id nName, Value& rValue) -{ - sal_Int32 nIntValue = rValue.getInt(); - switch( nName ) - { - case NS_ooxml::LN_CT_Hyperlink_URL://90682; - m_pImpl->sHyperlinkURL = rValue.getString(); - break; - case NS_ooxml::LN_blip: //the binary graphic data in a shape - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rValue.getProperties(); - if( pProperties ) - { - pProperties->resolve(*this); - } - } - break; - case NS_ooxml::LN_payload : - { - writerfilter::Reference<BinaryObj>::Pointer_t pPictureData = rValue.getBinary(); - if( pPictureData ) - pPictureData->resolve(*this); - } - break; - - //border properties - case NS_ooxml::LN_CT_Border_sz: - m_pImpl->aBorders[BORDER_TOP].nLineWidth = nIntValue; - break; - case NS_ooxml::LN_CT_Border_val: - //graphic borders don't support different line types - break; - case NS_ooxml::LN_CT_Border_space: - break; - case NS_ooxml::LN_CT_Border_shadow: - m_pImpl->aBorders[BORDER_TOP].bHasShadow = nIntValue != 0; - break; - case NS_ooxml::LN_CT_Border_frame: - break; - case NS_ooxml::LN_CT_PositiveSize2D_cx: - case NS_ooxml::LN_CT_PositiveSize2D_cy: - { - sal_Int32 nDim = oox::drawingml::convertEmuToHmm(nIntValue); - // drawingML equivalent of oox::vml::ShapeType::getAbsRectangle(): - // make sure a shape isn't hidden implicitly just because it has - // zero height or width. - if (nDim == 0) - nDim = 1; - - 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: - m_pImpl->m_oEffectExtentLeft = nIntValue; - break; - case NS_ooxml::LN_CT_EffectExtent_t: - m_pImpl->m_oEffectExtentTop = nIntValue; - break; - case NS_ooxml::LN_CT_EffectExtent_r: - m_pImpl->m_oEffectExtentRight = nIntValue; - break; - case NS_ooxml::LN_CT_EffectExtent_b: - m_pImpl->m_oEffectExtentBottom = nIntValue; - 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 = rValue.getString(); - break; - case NS_ooxml::LN_CT_NonVisualDrawingProps_descr:// 90652; - //alternative text - m_pImpl->sAlternativeText = rValue.getString(); - break; - case NS_ooxml::LN_CT_NonVisualDrawingProps_title: - //alternative text - m_pImpl->title = rValue.getString(); - break; - case NS_ooxml::LN_CT_NonVisualDrawingProps_hidden: - m_pImpl->bHidden = (nIntValue == 1); - 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; - { - m_pImpl->nShapeOptionType = nName; - ProcessShapeOptions(rValue); - } - break; - case NS_ooxml::LN_CT_Anchor_simplePos_attr: // 90987; - m_pImpl->bUseSimplePos = nIntValue > 0; - break; - case NS_ooxml::LN_CT_Anchor_relativeHeight: // 90988; - m_pImpl->zOrder = nIntValue; - break; - case NS_ooxml::LN_CT_Anchor_behindDoc: // 90989; - in background - if (nIntValue > 0) - { - m_pImpl->bOpaque = false; - m_pImpl->bBehindDoc = true; - } - break; - case NS_ooxml::LN_CT_Anchor_locked: // 90990; - ignored - break; - case NS_ooxml::LN_CT_Anchor_layoutInCell: // 90991; - ignored - // Starting in MSO 2013, anchors are ALWAYS considered to be laid out in table cell. - m_pImpl->bCompatForcedLayoutInCell = !nIntValue - && m_pImpl->rDomainMapper.GetSettingsTable()->GetWordCompatibilityMode() > 14 - && m_pImpl->rDomainMapper.IsInTable(); - m_pImpl->bLayoutInCell = m_pImpl->bCompatForcedLayoutInCell || nIntValue; - break; - case NS_ooxml::LN_CT_Anchor_hidden: // 90992; - ignored - break; - case NS_ooxml::LN_CT_Anchor_allowOverlap: - m_pImpl->bAllowOverlap = nIntValue != 0; - break; - case NS_ooxml::LN_CT_Anchor_wp14_anchorId: - case NS_ooxml::LN_CT_Inline_wp14_anchorId: - { - OUStringBuffer aBuffer = OUString::number(nIntValue, 16); - OUStringBuffer aString; - comphelper::string::padToLength(aString, 8 - aBuffer.getLength(), '0'); - aString.append(aBuffer.getStr()); - m_pImpl->sAnchorId = aString.makeStringAndClear().toAsciiUpperCase(); - } - 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(rValue.getInt()); - - break; - case NS_ooxml::LN_CT_WrapThrough_wrapText: - m_pImpl->bContour = true; - m_pImpl->bContourOutside = false; - - handleWrapTextValue(rValue.getInt()); - - break; - case NS_ooxml::LN_CT_WrapSquare_wrapText: //90928; - handleWrapTextValue(rValue.getInt()); - break; - case NS_ooxml::LN_shape: - { - uno::Reference< drawing::XShape> xShape; - rValue.getAny( ) >>= xShape; - if ( xShape.is( ) ) - { - // Is it a graphic image - bool bUseShape = true; - try - { - uno::Reference< beans::XPropertySet > xShapeProps - ( xShape, uno::UNO_QUERY_THROW ); - - uno::Reference<graphic::XGraphic> xGraphic; - xShapeProps->getPropertyValue("Graphic") >>= xGraphic; - - sal_Int32 nRotation = 0; - xShapeProps->getPropertyValue("RotateAngle") >>= nRotation; - - css::beans::PropertyValues aGrabBag; - xShapeProps->getPropertyValue("InteropGrabBag") >>= aGrabBag; - // if the shape contains effects in the grab bag, we should not transform it - // in a XTextContent so those effects can be preserved - bool bContainsEffects = std::any_of(aGrabBag.begin(), aGrabBag.end(), [](const auto& rProp) { - return rProp.Name == "EffectProperties" - || rProp.Name == "3DEffectProperties" - || rProp.Name == "ArtisticEffectProperties"; - }); - - xShapeProps->getPropertyValue("Shadow") >>= m_pImpl->bShadow; - if (m_pImpl->bShadow) - { - xShapeProps->getPropertyValue("ShadowXDistance") >>= m_pImpl->nShadowXDistance; - xShapeProps->getPropertyValue("ShadowYDistance") >>= m_pImpl->nShadowYDistance; - xShapeProps->getPropertyValue("ShadowColor") >>= m_pImpl->nShadowColor; - xShapeProps->getPropertyValue("ShadowTransparence") >>= m_pImpl->nShadowTransparence; - } - - xShapeProps->getPropertyValue("GraphicColorMode") >>= m_pImpl->eColorMode; - xShapeProps->getPropertyValue("AdjustLuminance") >>= m_pImpl->nBrightness; - xShapeProps->getPropertyValue("AdjustContrast") >>= m_pImpl->nContrast; - - // fdo#70457: transform XShape into a SwXTextGraphicObject only if there's no rotation - if ( nRotation == 0 && !bContainsEffects ) - m_xGraphicObject = createGraphicObject( xGraphic, xShapeProps ); - - 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("Height", - uno::makeAny( aSize.Height ) ); - xGraphProps->setPropertyValue("Width", - uno::makeAny( aSize.Width ) ); - - text::GraphicCrop aGraphicCrop( 0, 0, 0, 0 ); - uno::Reference< beans::XPropertySet > xSourceGraphProps( xShape, uno::UNO_QUERY ); - uno::Any aAny = xSourceGraphProps->getPropertyValue("GraphicCrop"); - if(aAny >>= aGraphicCrop) { - xGraphProps->setPropertyValue("GraphicCrop", - uno::makeAny( aGraphicCrop ) ); - } - - // We need to drop the shape here somehow - uno::Reference< lang::XComponent > xShapeComponent( xShape, uno::UNO_QUERY ); - xShapeComponent->dispose( ); - } - } - catch( const beans::UnknownPropertyException & ) - { - // 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); - - - xShapeProps->setPropertyValue - (getPropertyName(PROP_ANCHOR_TYPE), - uno::makeAny - (text::TextContentAnchorType_AS_CHARACTER)); - - // In Word, if a shape is anchored inline, that - // excludes being in the background. - xShapeProps->setPropertyValue("Opaque", uno::makeAny(true)); - - uno::Reference<lang::XServiceInfo> xServiceInfo(m_xShape, uno::UNO_QUERY_THROW); - - // TextFrames can't be rotated. But for anything else, - // make sure that setting size doesn't affect rotation, - // that would not match Word's definition of rotation. - bool bKeepRotation = false; - if (!xServiceInfo->supportsService("com.sun.star.text.TextFrame")) - { - bKeepRotation = true; - xShapeProps->setPropertyValue - (getPropertyName(PROP_TEXT_RANGE), - uno::makeAny - (m_pImpl->rDomainMapper.GetCurrentTextRange())); - } - - awt::Size aSize(m_xShape->getSize()); - - if (m_pImpl->isXSizeValid()) - aSize.Width = m_pImpl->getXSize(); - if (m_pImpl->isYSizeValis()) - aSize.Height = m_pImpl->getYSize(); - - Degree100 nRotation; - if (bKeepRotation) - { - // Use internal API, getPropertyValue(RotateAngle) - // would use GetObjectRotation(), which is not what - // we want. - if (SdrObject* pShape = GetSdrObjectFromXShape(m_xShape)) - nRotation = pShape->GetRotateAngle(); - } - m_xShape->setSize(aSize); - if (bKeepRotation) - { - xShapeProps->setPropertyValue("RotateAngle", uno::makeAny(nRotation.get())); - if (nRotation == 0_deg100) - { - // Include effect extent in the margin to bring Writer layout closer - // to Word. But do this for non-rotated shapes only, where effect - // extents map to increased margins as-is. - if (m_pImpl->m_oEffectExtentLeft) - { - m_pImpl->nLeftMargin += oox::drawingml::convertEmuToHmm( - *m_pImpl->m_oEffectExtentLeft); - } - if (m_pImpl->m_oEffectExtentTop) - { - m_pImpl->nTopMargin += oox::drawingml::convertEmuToHmm( - *m_pImpl->m_oEffectExtentTop); - } - if (m_pImpl->m_oEffectExtentRight) - { - m_pImpl->nRightMargin += oox::drawingml::convertEmuToHmm( - *m_pImpl->m_oEffectExtentRight); - } - if (m_pImpl->m_oEffectExtentBottom) - { - m_pImpl->nBottomMargin += oox::drawingml::convertEmuToHmm( - *m_pImpl->m_oEffectExtentBottom); - } - } - } - - m_pImpl->bIsGraphic = true; - - if (!m_pImpl->sAnchorId.isEmpty()) - { - putPropertyToFrameGrabBag("AnchorId", uno::makeAny(m_pImpl->sAnchorId)); - } - } - - if (bUseShape && m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR) - { - // If we are here, this is a drawingML shape. For those, only dmapper (and not oox) knows the anchoring infos (just like for Writer pictures). - // But they aren't Writer pictures, either (which are already handled above). - uno::Reference< beans::XPropertySet > xShapeProps(m_xShape, uno::UNO_QUERY_THROW); - - // This needs to be AT_PARAGRAPH by default and not AT_CHARACTER, otherwise shape will move when the user inserts a new paragraph. - text::TextContentAnchorType eAnchorType = text::TextContentAnchorType_AT_PARAGRAPH; - - if (m_pImpl->bHidden) - { - xShapeProps->setPropertyValue("Visible", uno::makeAny(false)); - xShapeProps->setPropertyValue("Printable", uno::makeAny(false)); - } - - // Avoid setting AnchorType for TextBoxes till SwTextBoxHelper::syncProperty() doesn't handle transition. - bool bTextBox = false; - xShapeProps->getPropertyValue("TextBox") >>= bTextBox; - - // The positioning change caused by LayoutInCell doesn't sync well - // in the text / frame duo. So the compatibility fix only correctly - // positions the frame and not the text currently. - // tdf#135943: Instead of half-fixing and making a complete mess, - // just avoid until layout's repositioning is sync'd to the text frame. - if (m_pImpl->bLayoutInCell && bTextBox) - m_pImpl->bLayoutInCell = !m_pImpl->bCompatForcedLayoutInCell; - - if (m_pImpl->nVertRelation == text::RelOrientation::TEXT_LINE && !bTextBox) - eAnchorType = text::TextContentAnchorType_AT_CHARACTER; - - xShapeProps->setPropertyValue("AnchorType", uno::makeAny(eAnchorType)); - - if (m_pImpl->nVertRelation == text::RelOrientation::TEXT_LINE && bTextBox) - { - // TEXT_LINE to specific to to-char anchoring, we have to-para, so reset - // to default. - m_pImpl->nVertRelation = text::RelOrientation::FRAME; - } - - if (m_pImpl->bLayoutInCell && bTextBox && m_pImpl->rDomainMapper.IsInTable() - && m_pImpl->nHoriRelation == text::RelOrientation::PAGE_FRAME) - m_pImpl->nHoriRelation = text::RelOrientation::FRAME; - if(m_pImpl->rDomainMapper.IsInTable()) - xShapeProps->setPropertyValue(getPropertyName(PROP_FOLLOW_TEXT_FLOW), - uno::makeAny(m_pImpl->bLayoutInCell)); - //only the position orientation is handled in applyPosition() - m_pImpl->applyPosition(xShapeProps); - - uno::Reference<lang::XServiceInfo> xServiceInfo(m_xShape, uno::UNO_QUERY_THROW); - if (xServiceInfo->supportsService("com.sun.star.drawing.GroupShape") || - xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape")) - { - // You would expect that position and rotation are - // independent, but they are not. Till we are not - // there yet to handle all scaling, translation and - // rotation with a single transformation matrix, - // make sure there is no graphic rotation set when we set - // the position. - sal_Int32 nRotation = 0; - if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape")) - { - xShapeProps->getPropertyValue("RotateAngle") >>= nRotation; - } - if (nRotation) - xShapeProps->setPropertyValue("RotateAngle", uno::makeAny(sal_Int32(0))); - - // Position of the groupshape should be set after children have been added. - // Long-term we should get rid of positioning group - // shapes, though. Do it for top-level ones with - // absolute page position as a start. - // fdo#80555: also set position for graphic shapes here - if (!isTopGroupObj(m_xShape) - || m_pImpl->nHoriRelation != text::RelOrientation::PAGE_FRAME - || m_pImpl->nVertRelation != text::RelOrientation::PAGE_FRAME) - m_xShape->setPosition( - awt::Point(m_pImpl->nLeftPosition, m_pImpl->nTopPosition)); - - if (nRotation) - xShapeProps->setPropertyValue("RotateAngle", uno::makeAny(nRotation)); - } - - - m_pImpl->applyRelativePosition(xShapeProps, /*bRelativeOnly=*/true); - - xShapeProps->setPropertyValue("SurroundContour", uno::makeAny(m_pImpl->bContour)); - m_pImpl->applyMargins(xShapeProps); - xShapeProps->setPropertyValue("Opaque", uno::makeAny(m_pImpl->bOpaque)); - xShapeProps->setPropertyValue("Surround", uno::makeAny(static_cast<sal_Int32>(m_pImpl->nWrap))); - m_pImpl->applyZOrder(xShapeProps); - m_pImpl->applyName(xShapeProps); - xShapeProps->setPropertyValue("AllowOverlap", - uno::makeAny(m_pImpl->bAllowOverlap)); - - // Get the grab-bag set by oox, merge with our one and then put it back. - comphelper::SequenceAsHashMap aInteropGrabBag(xShapeProps->getPropertyValue("InteropGrabBag")); - aInteropGrabBag.update(m_pImpl->getInteropGrabBag()); - xShapeProps->setPropertyValue("InteropGrabBag", uno::makeAny(aInteropGrabBag.getAsConstPropertyValueList())); - } - else if (bUseShape && m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_INLINE) - { - uno::Reference< beans::XPropertySet > xShapeProps(m_xShape, uno::UNO_QUERY_THROW); - m_pImpl->applyMargins(xShapeProps); - m_pImpl->applyZOrder(xShapeProps); - comphelper::SequenceAsHashMap aInteropGrabBag(xShapeProps->getPropertyValue("InteropGrabBag")); - aInteropGrabBag.update(m_pImpl->getInteropGrabBag()); - xShapeProps->setPropertyValue("InteropGrabBag", uno::makeAny(aInteropGrabBag.getAsConstPropertyValueList())); - } - } - } - break; - case NS_ooxml::LN_CT_Inline_distT: - m_pImpl->nTopMargin = 0; - break; - case NS_ooxml::LN_CT_Inline_distB: - m_pImpl->nBottomMargin = 0; - break; - case NS_ooxml::LN_CT_Inline_distL: - m_pImpl->nLeftMargin = 0; - break; - case NS_ooxml::LN_CT_Inline_distR: - m_pImpl->nRightMargin = 0; - break; - case NS_ooxml::LN_CT_GraphicalObjectData_uri: - rValue.getString(); - //TODO: does it need to be handled? - break; - case NS_ooxml::LN_CT_SizeRelH_relativeFrom: - { - switch (nIntValue) - { - case NS_ooxml::LN_ST_SizeRelFromH_margin: - if (m_xShape.is()) - { - uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue("RelativeWidthRelation", uno::makeAny(text::RelOrientation::FRAME)); - } - break; - case NS_ooxml::LN_ST_SizeRelFromH_leftMargin: - case NS_ooxml::LN_ST_SizeRelFromH_outsideMargin: - if (m_xShape.is()) - { - // Here we handle the relative size of the width of some shape. - // The size of the shape's width is going to be relative to the size of the left margin. - // E.g.: (left margin = 8 && relative size = 150%) -> width of some shape = 12. - uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue("RelativeWidthRelation", uno::makeAny(text::RelOrientation::PAGE_LEFT)); - } - break; - case NS_ooxml::LN_ST_SizeRelFromH_rightMargin: - case NS_ooxml::LN_ST_SizeRelFromH_insideMargin: - if (m_xShape.is()) - { - // Same as the left margin above. - uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue("RelativeWidthRelation", uno::makeAny(text::RelOrientation::PAGE_RIGHT)); - } - break; - case NS_ooxml::LN_ST_SizeRelFromH_page: - if (m_xShape.is()) - { - uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue("RelativeWidthRelation", uno::makeAny(text::RelOrientation::PAGE_FRAME)); - } - break; - default: - SAL_WARN("writerfilter", "GraphicImport::lcl_attribute: unhandled NS_ooxml::LN_CT_SizeRelH_relativeFrom value: " << nIntValue); - break; - } - } - break; - case NS_ooxml::LN_CT_SizeRelV_relativeFrom: - { - switch (nIntValue) - { - case NS_ooxml::LN_ST_SizeRelFromV_margin: - if (m_xShape.is()) - { - uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue("RelativeHeightRelation", uno::makeAny(text::RelOrientation::FRAME)); - } - break; - case NS_ooxml::LN_ST_SizeRelFromV_page: - if (m_xShape.is()) - { - uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue("RelativeHeightRelation", uno::makeAny(text::RelOrientation::PAGE_FRAME)); - } - break; - case NS_ooxml::LN_ST_SizeRelFromV_topMargin: - if (m_xShape.is()) - { - uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue("RelativeHeightRelation", uno::makeAny(text::RelOrientation::PAGE_PRINT_AREA)); - } - break; - case NS_ooxml::LN_ST_SizeRelFromV_bottomMargin: - if (m_xShape.is()) - { - uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue("RelativeHeightRelation", uno::makeAny(text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)); - } - break; - default: - SAL_WARN("writerfilter", "GraphicImport::lcl_attribute: unhandled NS_ooxml::LN_CT_SizeRelV_relativeFrom value: " << nIntValue); - break; - } - } - break; - default: -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - break; - } -} - -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 const & rValue) -{ - sal_Int32 nIntValue = rValue.getInt(); - switch( m_pImpl->nShapeOptionType ) - { - case NS_ooxml::LN_CT_Anchor_distL: - m_pImpl->nLeftMargin = nIntValue / 360; - m_pImpl->nLeftMarginOrig = m_pImpl->nLeftMargin; - break; - case NS_ooxml::LN_CT_Anchor_distT: - //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins() - m_pImpl->nTopMargin = nIntValue / 360; - break; - case NS_ooxml::LN_CT_Anchor_distR: - //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustLRWrapForWordMargins() - m_pImpl->nRightMargin = nIntValue / 360; - break; - case NS_ooxml::LN_CT_Anchor_distB: - //todo: changes have to be applied depending on the orientation, see SwWW8ImplReader::AdjustULWrapForWordMargins() - m_pImpl->nBottomMargin = nIntValue / 360; - break; - default: - OSL_FAIL( "shape option unsupported?"); - } -} - - -void GraphicImport::lcl_sprm(Sprm& rSprm) -{ - sal_uInt32 nSprmId = rSprm.getId(); - - switch(nSprmId) - { - 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: - case NS_ooxml::LN_dgm_relIds: - case NS_ooxml::LN_lc_lockedCanvas: - case NS_ooxml::LN_c_chart: - case NS_ooxml::LN_wps_wsp: - case NS_ooxml::LN_wpg_wgp: - case NS_ooxml::LN_sizeRelH_sizeRelH: - case NS_ooxml::LN_sizeRelV_sizeRelV: - case NS_ooxml::LN_hlinkClick_hlinkClick: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - pProperties->resolve(*this); - } - - // We'll map these to PARALLEL, save the original wrap type. - if (nSprmId == NS_ooxml::LN_EG_WrapType_wrapTight) - m_pImpl->m_aInteropGrabBag["EG_WrapType"] <<= OUString("wrapTight"); - else if (nSprmId == NS_ooxml::LN_EG_WrapType_wrapThrough) - m_pImpl->m_aInteropGrabBag["EG_WrapType"] <<= OUString("wrapThrough"); - - switch (nSprmId) - { - case NS_ooxml::LN_EG_WrapType_wrapSquare: - case NS_ooxml::LN_EG_WrapType_wrapThrough: - case NS_ooxml::LN_EG_WrapType_wrapTight: - { - // tdf#137850: Word >= 2013 seems to ignore bBehindDoc except for wrapNone, but older versions honour it. - if (m_pImpl->bBehindDoc && m_pImpl->rDomainMapper.GetSettingsTable()->GetWordCompatibilityMode() > 14) - m_pImpl->bOpaque = true; - } - break; - } - - } - break; - case NS_ooxml::LN_CT_WrapTight_wrapPolygon: - case NS_ooxml::LN_CT_WrapThrough_wrapPolygon: - { - WrapPolygonHandler aHandler; - - resolveSprmProps(aHandler, rSprm); - - m_pImpl->mpWrapPolygon = aHandler.getPolygon(); - - // Save the wrap path in case we can't handle it natively: drawinglayer shapes, TextFrames. - m_pImpl->m_aInteropGrabBag["CT_WrapPath"] <<= m_pImpl->mpWrapPolygon->getPointSequenceSequence(); - } - break; - case NS_ooxml::LN_CT_Anchor_positionH: // 90976; - { - // Use a special handler for the positioning - auto pHandler = std::make_shared<PositionHandler>( m_pImpl->m_rPositionOffsets, m_pImpl->m_rAligns ); - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - pProperties->resolve( *pHandler ); - if( !m_pImpl->bUseSimplePos ) - { - m_pImpl->nHoriRelation = pHandler->relation(); - m_pImpl->bPageToggle = pHandler->GetPageToggle(); - m_pImpl->nHoriOrient = pHandler->orientation(); - m_pImpl->nLeftPosition = pHandler->position(); - - // Left adjustments: if horizontally aligned to left of margin, then remove the - // left wrapping. - if (m_pImpl->nHoriOrient == text::HoriOrientation::LEFT) - { - if (m_pImpl->nHoriRelation == text::RelOrientation::PAGE_PRINT_AREA) - { - m_pImpl->nLeftMargin = 0; - } - } - } - } - } - break; - case NS_ooxml::LN_CT_Anchor_positionV: // 90977; - { - // Use a special handler for the positioning - auto pHandler = std::make_shared<PositionHandler>( m_pImpl->m_rPositionOffsets, m_pImpl->m_rAligns); - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - pProperties->resolve( *pHandler ); - if( !m_pImpl->bUseSimplePos ) - { - m_pImpl->nVertRelation = pHandler->relation(); - m_pImpl->nVertOrient = pHandler->orientation(); - m_pImpl->nTopPosition = pHandler->position(); - } - } - } - break; - case NS_ooxml::LN_CT_SizeRelH_pctWidth: - case NS_ooxml::LN_CT_SizeRelV_pctHeight: - if (m_pImpl->m_rPositivePercentages.empty()) - break; - - if (m_xShape.is()) - { - sal_Int16 nPositivePercentage = rtl::math::round(m_pImpl->m_rPositivePercentages.front().toDouble() / oox::drawingml::PER_PERCENT); - - if (nPositivePercentage) - { - uno::Reference<beans::XPropertySet> xPropertySet(m_xShape, uno::UNO_QUERY); - OUString aProperty = nSprmId == NS_ooxml::LN_CT_SizeRelH_pctWidth ? OUString("RelativeWidth") : OUString("RelativeHeight"); - - sal_Int32 nTextPreRotateAngle = 0; - uno::Any aAny; - if (xPropertySet->getPropertySetInfo()->hasPropertyByName( - "CustomShapeGeometry")) - { - aAny = xPropertySet->getPropertyValue("CustomShapeGeometry"); - } - comphelper::SequenceAsHashMap aCustomShapeGeometry(aAny); - auto it = aCustomShapeGeometry.find("TextPreRotateAngle"); - if (it != aCustomShapeGeometry.end()) - { - nTextPreRotateAngle = it->second.get<sal_Int32>(); - } - if (nTextPreRotateAngle == 0) - { - xPropertySet->setPropertyValue(aProperty, - uno::makeAny(nPositivePercentage)); - } - } - } - - // Make sure the token is consumed even if xShape is an empty - // reference. - m_pImpl->m_rPositivePercentages.pop(); - break; - case NS_ooxml::LN_EG_WrapType_wrapNone: // 90944; - doesn't contain attributes - //depending on the behindDoc attribute text wraps through behind or in front of the object - m_pImpl->nWrap = text::WrapTextMode_THROUGH; - - // Wrap though means the margins defined earlier should not be - // respected. - m_pImpl->nLeftMargin = 0; - m_pImpl->nTopMargin = 0; - m_pImpl->nRightMargin = 0; - m_pImpl->nBottomMargin = 0; - break; - case NS_ooxml::LN_EG_WrapType_wrapTopAndBottom: // 90948; - // tdf#137850: Word >= 2013 seems to ignore bBehindDoc except for wrapNone, but older versions honour it. - if (m_pImpl->bBehindDoc && m_pImpl->rDomainMapper.GetSettingsTable()->GetWordCompatibilityMode() > 14) - m_pImpl->bOpaque = true; - m_pImpl->nWrap = text::WrapTextMode_NONE; - break; - case NS_ooxml::LN_CT_GraphicalObject_graphicData:// 90660; - { - m_pImpl->bIsGraphic = true; - - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_NonVisualDrawingProps_a_hlinkClick: // 90689; - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - pProperties->resolve( *this ); - } - break; - default: - SAL_WARN("writerfilter", "GraphicImport::lcl_sprm: unhandled token: " << nSprmId); - break; - } -} - -void GraphicImport::lcl_entry(writerfilter::Reference<Properties>::Pointer_t /*ref*/) -{ -} - -uno::Reference<text::XTextContent> GraphicImport::createGraphicObject(uno::Reference<graphic::XGraphic> const & rxGraphic, - uno::Reference<beans::XPropertySet> const & xShapeProps) -{ - uno::Reference<text::XTextContent> xGraphicObject; - try - { - if (rxGraphic.is()) - { - uno::Reference< beans::XPropertySet > xGraphicObjectProperties( - m_xTextFactory->createInstance("com.sun.star.text.TextGraphicObject"), - uno::UNO_QUERY_THROW); - xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_GRAPHIC), uno::makeAny(rxGraphic)); - xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_ANCHOR_TYPE), - uno::makeAny( m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR ? - text::TextContentAnchorType_AT_CHARACTER : - text::TextContentAnchorType_AS_CHARACTER )); - xGraphicObject.set( xGraphicObjectProperties, uno::UNO_QUERY_THROW ); - - //shapes have only one border - table::BorderLine2 aBorderLine; - GraphicBorderLine& rBorderLine = m_pImpl->aBorders[0]; - if (rBorderLine.isEmpty() && xShapeProps.is() && xShapeProps->getPropertyValue("LineStyle").get<drawing::LineStyle>() != drawing::LineStyle_NONE) - { - // In case we got no border tokens and we have the - // original shape, then use its line properties as the - // border. - aBorderLine.Color = xShapeProps->getPropertyValue("LineColor").get<sal_Int32>(); - aBorderLine.LineWidth = xShapeProps->getPropertyValue("LineWidth").get<sal_Int32>(); - } - else - { - aBorderLine.Color = 0; - aBorderLine.InnerLineWidth = 0; - aBorderLine.OuterLineWidth = static_cast<sal_Int16>(rBorderLine.nLineWidth); - aBorderLine.LineDistance = 0; - } - PropertyIds const aBorderProps[] = - { - PROP_LEFT_BORDER, - PROP_RIGHT_BORDER, - PROP_TOP_BORDER, - PROP_BOTTOM_BORDER - }; - - for(PropertyIds const & rBorderProp : aBorderProps) - xGraphicObjectProperties->setPropertyValue(getPropertyName(rBorderProp), uno::makeAny(aBorderLine)); - - // setting graphic object shadow properties - if (m_pImpl->bShadow) - { - // Shadow width is approximated by average of X and Y - table::ShadowFormat aShadow; - sal_uInt32 nShadowColor = m_pImpl->nShadowColor & 0x00FFFFFF; // The shadow color we get is RGB only. - sal_Int32 nShadowWidth = (abs(m_pImpl->nShadowXDistance) - + abs(m_pImpl->nShadowYDistance)) / 2; - - aShadow.ShadowWidth = nShadowWidth; - sal_uInt8 nShadowTransparence = float(m_pImpl->nShadowTransparence) * 2.55; - nShadowColor |= (nShadowTransparence << 24); // Add transparence to the color. - aShadow.Color = nShadowColor; - // Distances -ve for top and right, +ve for bottom and left - if (m_pImpl->nShadowXDistance > 0) - { - if (m_pImpl->nShadowYDistance > 0) - aShadow.Location = table::ShadowLocation_BOTTOM_RIGHT; - else - aShadow.Location = table::ShadowLocation_TOP_RIGHT; - } - else - { - if (m_pImpl->nShadowYDistance > 0) - aShadow.Location = table::ShadowLocation_BOTTOM_LEFT; - else - aShadow.Location = table::ShadowLocation_TOP_LEFT; - } - - xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_SHADOW_FORMAT), uno::makeAny(aShadow)); - } - - // setting properties for all types - if( m_pImpl->bPositionProtected ) - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_POSITION_PROTECTED ), - uno::makeAny(true)); - if( m_pImpl->bSizeProtected ) - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_SIZE_PROTECTED ), - uno::makeAny(true)); - - sal_Int32 nWidth = - m_pImpl->nLeftPosition; - if (m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR) - { - //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; - } - - m_pImpl->applyPosition(xGraphicObjectProperties); - m_pImpl->applyRelativePosition(xGraphicObjectProperties); - if( !m_pImpl->bOpaque ) - { - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_OPAQUE ), uno::makeAny(m_pImpl->bOpaque)); - } - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_SURROUND ), - uno::makeAny(static_cast<sal_Int32>(m_pImpl->nWrap))); - if( m_pImpl->rDomainMapper.IsInTable()) - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_FOLLOW_TEXT_FLOW ), - uno::makeAny(m_pImpl->bLayoutInCell)); - - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_SURROUND_CONTOUR ), - uno::makeAny(m_pImpl->bContour)); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_CONTOUR_OUTSIDE ), - uno::makeAny(m_pImpl->bContourOutside)); - m_pImpl->applyMargins(xGraphicObjectProperties); - } - - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_ADJUST_CONTRAST ), - uno::makeAny(static_cast<sal_Int16>(m_pImpl->nContrast))); - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_ADJUST_LUMINANCE ), - uno::makeAny(static_cast<sal_Int16>(m_pImpl->nBrightness))); - if(m_pImpl->eColorMode != drawing::ColorMode_STANDARD) - { - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_GRAPHIC_COLOR_MODE ), - uno::makeAny(m_pImpl->eColorMode)); - } - - xGraphicObjectProperties->setPropertyValue(getPropertyName( PROP_BACK_COLOR ), - uno::makeAny( GraphicImport_Impl::nFillColor )); - m_pImpl->applyZOrder(xGraphicObjectProperties); - - //there seems to be no way to detect the original size via _real_ API - uno::Reference< beans::XPropertySet > xGraphicProperties(rxGraphic, uno::UNO_QUERY_THROW); - - if (m_pImpl->mpWrapPolygon) - { - uno::Any aContourPolyPolygon; - awt::Size aGraphicSize; - WrapPolygon::Pointer_t pCorrected; - xGraphicProperties->getPropertyValue(getPropertyName(PROP_SIZE100th_M_M)) >>= aGraphicSize; - if (aGraphicSize.Width && aGraphicSize.Height) - { - pCorrected = m_pImpl->mpWrapPolygon->correctWordWrapPolygon(aGraphicSize); - } - else - { - xGraphicProperties->getPropertyValue(getPropertyName(PROP_SIZE_PIXEL)) >>= aGraphicSize; - if (aGraphicSize.Width && aGraphicSize.Height) - { - pCorrected = m_pImpl->mpWrapPolygon->correctWordWrapPolygonPixel(aGraphicSize); - } - } - - text::GraphicCrop aGraphicCrop; - xShapeProps->getPropertyValue("GraphicCrop") >>= aGraphicCrop; - if (aGraphicCrop.Top != 0 || aGraphicCrop.Bottom != 0 || aGraphicCrop.Left != 0 - || aGraphicCrop.Right != 0) - { - // Word's wrap polygon deals with a canvas which has the size of the already - // cropped graphic, correct our polygon to have the same render result. - pCorrected = pCorrected->correctCrop(aGraphicSize, aGraphicCrop); - } - - if (pCorrected) - { - aContourPolyPolygon <<= pCorrected->getPointSequenceSequence(); - xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_CONTOUR_POLY_POLYGON), - aContourPolyPolygon); - // We should bring it to front, even if wp:anchor's behindDoc="1", - // because otherwise paragraph background (if set) overlaps the graphic - // TODO: if paragraph's background becomes bottommost, then remove this hack - xGraphicObjectProperties->setPropertyValue("Opaque", uno::makeAny(true)); - } - } - - - if(m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_INLINE || m_pImpl->eGraphicImportType == IMPORT_AS_DETECTED_ANCHOR) - { - if( m_pImpl->getXSize() && m_pImpl->getYSize() ) - xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_SIZE), - uno::makeAny( awt::Size( m_pImpl->getXSize(), m_pImpl->getYSize() ))); - m_pImpl->applyMargins(xGraphicObjectProperties); - m_pImpl->applyName(xGraphicObjectProperties); - } - - // Handle horizontal flip. - bool bMirrored = false; - xShapeProps->getPropertyValue("IsMirrored") >>= bMirrored; - if (bMirrored) - { - xGraphicObjectProperties->setPropertyValue("HoriMirroredOnEvenPages", - uno::makeAny(true)); - xGraphicObjectProperties->setPropertyValue("HoriMirroredOnOddPages", - uno::makeAny(true)); - } - } - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION("writerfilter", ""); - } - return xGraphicObject; -} - - -void GraphicImport::data(const sal_uInt8* buf, size_t len) -{ - beans::PropertyValues aMediaProperties( 1 ); - aMediaProperties[0].Name = getPropertyName(PROP_INPUT_STREAM); - - uno::Reference< io::XInputStream > xIStream = new XInputStreamHelper( buf, len ); - aMediaProperties[0].Value <<= xIStream; - - uno::Reference<beans::XPropertySet> xPropertySet; - uno::Reference<graphic::XGraphicProvider> xGraphicProvider(graphic::GraphicProvider::create(m_xComponentContext)); - uno::Reference<graphic::XGraphic> xGraphic = xGraphicProvider->queryGraphic(aMediaProperties); - m_xGraphicObject = createGraphicObject(xGraphic, xPropertySet); -} - - -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_startShape(uno::Reference<drawing::XShape> const&) -{ -} - -void GraphicImport::lcl_endShape( ) -{ -} - -bool GraphicImport::IsGraphic() const -{ - return m_pImpl->bIsGraphic; -} - -sal_Int32 GraphicImport::GetLeftMarginOrig() const -{ - return m_pImpl->nLeftMarginOrig; -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/GraphicImport.hxx b/writerfilter/source/dmapper/GraphicImport.hxx deleted file mode 100644 index 9ea3984db23b..000000000000 --- a/writerfilter/source/dmapper/GraphicImport.hxx +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_GRAPHICIMPORT_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_GRAPHICIMPORT_HXX - -#include <queue> -#include <memory> - -#include "LoggedResources.hxx" - -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/graphic/XGraphic.hpp> - -namespace com::sun::star { - namespace uno - { - class XComponentContext; - } - namespace lang - { - class XMultiServiceFactory; - } - namespace text - { - class XTextContent; - } - namespace drawing - { - class XShape; - } - namespace beans - { - struct PropertyValue; - } -} - -namespace writerfilter::dmapper -{ -class GraphicImport_Impl; -class DomainMapper; - -enum GraphicImportType -{ - IMPORT_AS_DETECTED_INLINE, - IMPORT_AS_DETECTED_ANCHOR -}; - -class GraphicImport : public LoggedProperties, public LoggedTable - ,public BinaryObj, public LoggedStream -{ - std::unique_ptr<GraphicImport_Impl> m_pImpl; - - css::uno::Reference<css::uno::XComponentContext> m_xComponentContext; - css::uno::Reference<css::lang::XMultiServiceFactory> m_xTextFactory; - - css::uno::Reference<css::text::XTextContent> m_xGraphicObject; - - css::uno::Reference<css::drawing::XShape> m_xShape; - void ProcessShapeOptions(Value const & val); - - css::uno::Reference<css::text::XTextContent> - createGraphicObject(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic, - css::uno::Reference<css::beans::XPropertySet> const & xShapeProps); - - void putPropertyToFrameGrabBag( const OUString& sPropertyName, const css::uno::Any& aPropertyValue ); - -public: - explicit GraphicImport( css::uno::Reference<css::uno::XComponentContext> const& xComponentContext, - css::uno::Reference<css::lang::XMultiServiceFactory> const& xTextFactory, - DomainMapper& rDomainMapper, - GraphicImportType eGraphicImportType, - std::pair<OUString, OUString>& rPositionOffsets, - std::pair<OUString, OUString>& rAligns, - std::queue<OUString>& rPositivePercentages); - virtual ~GraphicImport() override; - - // BinaryObj - virtual void data(const sal_uInt8* buffer, size_t len) override; - - css::uno::Reference<css::text::XTextContent> GetGraphicObject(); - const css::uno::Reference<css::drawing::XShape>& GetXShapeObject() const { return m_xShape;} - bool IsGraphic() const; - sal_Int32 GetLeftMarginOrig() const; - - com::sun::star::awt::Point GetGraphicObjectPosition() const; - - private: - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - - // Table - virtual void lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) override; - - // Stream - virtual void lcl_startSectionGroup() override; - virtual void lcl_endSectionGroup() override; - virtual void lcl_startParagraphGroup() override; - virtual void lcl_endParagraphGroup() override; - virtual void lcl_startCharacterGroup() override; - virtual void lcl_endCharacterGroup() override; - virtual void lcl_text(const sal_uInt8 * data, size_t len) override; - virtual void lcl_utext(const sal_uInt8 * data, size_t len) override; - virtual void lcl_props(writerfilter::Reference<Properties>::Pointer_t ref) override; - virtual void lcl_table(Id name, - writerfilter::Reference<Table>::Pointer_t ref) override; - virtual void lcl_substream(Id name, writerfilter::Reference<Stream>::Pointer_t ref) override; - virtual void lcl_startShape(css::uno::Reference<css::drawing::XShape> const& xShape) override; - virtual void lcl_endShape() override; - - void handleWrapTextValue(sal_uInt32 nVal); -}; - -typedef tools::SvRef<GraphicImport> GraphicImportPtr; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/LatentStyleHandler.cxx b/writerfilter/source/dmapper/LatentStyleHandler.cxx deleted file mode 100644 index bc381d21fe3e..000000000000 --- a/writerfilter/source/dmapper/LatentStyleHandler.cxx +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -#include "LatentStyleHandler.hxx" -#include "TagLogger.hxx" -#include <ooxml/resourceids.hxx> - -namespace writerfilter::dmapper -{ -using namespace ::com::sun::star; - -LatentStyleHandler::LatentStyleHandler() - : LoggedProperties("LatentStyleHandler") -{ -} - -LatentStyleHandler::~LatentStyleHandler() = default; - -void LatentStyleHandler::lcl_attribute(Id nId, Value& rVal) -{ - beans::PropertyValue aValue; - bool bFound = true; - switch (nId) - { - case NS_ooxml::LN_CT_LsdException_name: - aValue.Name = "name"; - break; - case NS_ooxml::LN_CT_LsdException_locked: - aValue.Name = "locked"; - break; - case NS_ooxml::LN_CT_LsdException_uiPriority: - aValue.Name = "uiPriority"; - break; - case NS_ooxml::LN_CT_LsdException_semiHidden: - aValue.Name = "semiHidden"; - break; - case NS_ooxml::LN_CT_LsdException_unhideWhenUsed: - aValue.Name = "unhideWhenUsed"; - break; - case NS_ooxml::LN_CT_LsdException_qFormat: - aValue.Name = "qFormat"; - break; - default: - bFound = false; -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - break; - } - if (bFound) - { - aValue.Value <<= rVal.getString(); - m_aAttributes.push_back(aValue); - } -} - -void LatentStyleHandler::lcl_sprm(Sprm& /*rSprm*/) {} - -const std::vector<beans::PropertyValue>& LatentStyleHandler::getAttributes() const -{ - return m_aAttributes; -} - -} // namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/LatentStyleHandler.hxx b/writerfilter/source/dmapper/LatentStyleHandler.hxx deleted file mode 100644 index db46e974f9f7..000000000000 --- a/writerfilter/source/dmapper/LatentStyleHandler.hxx +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_LATENTSTYLEHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_LATENTSTYLEHANDLER_HXX - -#include "LoggedResources.hxx" -#include <vector> -#include <com/sun/star/beans/PropertyValue.hpp> - -namespace writerfilter::dmapper -{ -/// Handler for a latent style (w:lsdException element) -class LatentStyleHandler : public LoggedProperties -{ - std::vector<css::beans::PropertyValue> m_aAttributes; - - // Properties - void lcl_attribute(Id nId, Value& rVal) override; - void lcl_sprm(Sprm& sprm) override; - -public: - LatentStyleHandler(); - ~LatentStyleHandler() override; - - const std::vector<css::beans::PropertyValue>& getAttributes() const; -}; - -} // namespace writerfilter::dmapper - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/LoggedResources.cxx b/writerfilter/source/dmapper/LoggedResources.cxx deleted file mode 100644 index 4a0886e44812..000000000000 --- a/writerfilter/source/dmapper/LoggedResources.cxx +++ /dev/null @@ -1,382 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "LoggedResources.hxx" -#include "TagLogger.hxx" -#include <ooxml/QNameToString.hxx> - -using namespace ::com::sun::star; - -namespace writerfilter -{ -#ifdef DBG_UTIL - -LoggedResourcesHelper::LoggedResourcesHelper(const std::string& sPrefix) - : msPrefix(sPrefix) -{ -} - -LoggedResourcesHelper::~LoggedResourcesHelper() {} - -void LoggedResourcesHelper::startElement(const std::string& sElement) -{ - TagLogger::getInstance().startElement(msPrefix + "." + sElement); -} - -void LoggedResourcesHelper::endElement() { TagLogger::getInstance().endElement(); } - -void LoggedResourcesHelper::chars(std::u16string_view rChars) -{ - TagLogger::getInstance().chars(rChars); -} - -void LoggedResourcesHelper::chars(const std::string& rChars) -{ - TagLogger::getInstance().chars(rChars); -} - -void LoggedResourcesHelper::attribute(const std::string& rName, const std::string& rValue) -{ - TagLogger::getInstance().attribute(rName, rValue); -} - -void LoggedResourcesHelper::attribute(const std::string& rName, sal_uInt32 nValue) -{ - TagLogger::getInstance().attribute(rName, nValue); -} - -#endif - -LoggedStream::LoggedStream( -#ifdef DBG_UTIL - const std::string& sPrefix) - : mHelper(sPrefix) -#else - const std::string&) -#endif -{ -} - -LoggedStream::~LoggedStream() {} - -void LoggedStream::startSectionGroup() -{ -#ifdef DBG_UTIL - mHelper.startElement("section"); -#endif - - lcl_startSectionGroup(); -} - -void LoggedStream::endSectionGroup() -{ - lcl_endSectionGroup(); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::startParagraphGroup() -{ -#ifdef DBG_UTIL - mHelper.startElement("paragraph"); -#endif - - lcl_startParagraphGroup(); -} - -void LoggedStream::endParagraphGroup() -{ - lcl_endParagraphGroup(); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::startCharacterGroup() -{ -#ifdef DBG_UTIL - mHelper.startElement("charactergroup"); -#endif - - lcl_startCharacterGroup(); -} - -void LoggedStream::endCharacterGroup() -{ - lcl_endCharacterGroup(); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::startShape(uno::Reference<drawing::XShape> const& xShape) -{ -#ifdef DBG_UTIL - mHelper.startElement("shape"); -#endif - - lcl_startShape(xShape); -} - -void LoggedStream::endShape() -{ - lcl_endShape(); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::text(const sal_uInt8* data, size_t len) -{ -#ifdef DBG_UTIL - mHelper.startElement("text"); - - OUString sText(reinterpret_cast<const char*>(data), len, RTL_TEXTENCODING_MS_1252); - - mHelper.startElement("data"); - LoggedResourcesHelper::chars(sText); - LoggedResourcesHelper::endElement(); -#endif - - lcl_text(data, len); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::utext(const sal_uInt8* data, size_t len) -{ -#ifdef DBG_UTIL - mHelper.startElement("utext"); - mHelper.startElement("data"); - - OUString sText(reinterpret_cast<const sal_Unicode*>(data), len); - - LoggedResourcesHelper::chars(sText); - - LoggedResourcesHelper::endElement(); -#endif - - lcl_utext(data, len); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::positionOffset(const OUString& rText, bool bVertical) -{ -#ifdef DBG_UTIL - mHelper.startElement("positionOffset"); - LoggedResourcesHelper::attribute("vertical", static_cast<int>(bVertical)); - LoggedResourcesHelper::chars(rText); -#endif - - lcl_positionOffset(rText, bVertical); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::align(const OUString& rText, bool bVertical) -{ -#ifdef DBG_UTIL - mHelper.startElement("align"); - LoggedResourcesHelper::attribute("vertical", static_cast<int>(bVertical)); - LoggedResourcesHelper::chars(rText); -#endif - - lcl_align(rText, bVertical); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::positivePercentage(const OUString& rText) -{ -#ifdef DBG_UTIL - mHelper.startElement("positivePercentage"); - LoggedResourcesHelper::chars(rText); -#endif - - lcl_positivePercentage(rText); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::props(writerfilter::Reference<Properties>::Pointer_t ref) -{ -#ifdef DBG_UTIL - mHelper.startElement("props"); -#endif - - lcl_props(ref); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::table(Id name, writerfilter::Reference<Table>::Pointer_t ref) -{ -#ifdef DBG_UTIL - mHelper.startElement("table"); - LoggedResourcesHelper::attribute("name", QNameToString(name)); -#endif - - lcl_table(name, ref); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::substream(Id name, writerfilter::Reference<Stream>::Pointer_t ref) -{ -#ifdef DBG_UTIL - mHelper.startElement("substream"); - LoggedResourcesHelper::attribute("name", QNameToString(name)); -#endif - - lcl_substream(name, ref); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::info(const std::string& _info) -{ -#ifdef DBG_UTIL - mHelper.startElement("info"); - LoggedResourcesHelper::attribute("text", _info); -#else - (void)_info; -#endif - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::startGlossaryEntry() -{ -#ifdef DBG_UTIL - mHelper.startElement("startGlossaryEntry"); -#endif - - lcl_startGlossaryEntry(); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -void LoggedStream::endGlossaryEntry() -{ -#ifdef DBG_UTIL - mHelper.startElement("endGlossaryEntry"); -#endif - - lcl_endGlossaryEntry(); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -LoggedProperties::LoggedProperties( -#ifdef DBG_UTIL - const std::string& sPrefix) - : mHelper(sPrefix) -#else - const std::string&) -#endif -{ -} - -LoggedProperties::~LoggedProperties() {} - -void LoggedProperties::attribute(Id name, Value& val) -{ -#ifdef DBG_UTIL - mHelper.startElement("attribute"); - LoggedResourcesHelper::attribute("name", QNameToString(name)); - LoggedResourcesHelper::attribute("value", val.toString()); - LoggedResourcesHelper::endElement(); -#endif - - lcl_attribute(name, val); -} - -void LoggedProperties::sprm(Sprm& rSprm) -{ -#ifdef DBG_UTIL - mHelper.startElement("sprm"); - LoggedResourcesHelper::attribute("name", QNameToString(rSprm.getId())); - LoggedResourcesHelper::chars(rSprm.toString()); -#endif - - lcl_sprm(rSprm); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} - -LoggedTable::LoggedTable( -#ifdef DBG_UTIL - const std::string& sPrefix) - : mHelper(sPrefix) -#else - const std::string&) -#endif -{ -} - -LoggedTable::~LoggedTable() {} - -void LoggedTable::entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref) -{ -#ifdef DBG_UTIL - mHelper.startElement("entry"); - LoggedResourcesHelper::attribute("pos", pos); -#else - (void)pos; -#endif - - lcl_entry(ref); - -#ifdef DBG_UTIL - LoggedResourcesHelper::endElement(); -#endif -} -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/LoggedResources.hxx b/writerfilter/source/dmapper/LoggedResources.hxx deleted file mode 100644 index 52ef6a43e9d2..000000000000 --- a/writerfilter/source/dmapper/LoggedResources.hxx +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_LOGGEDRESOURCES_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_LOGGEDRESOURCES_HXX - -#include <sal/config.h> - -#include <string_view> - -#include <dmapper/resourcemodel.hxx> - -namespace writerfilter -{ -#ifdef DBG_UTIL -class LoggedResourcesHelper final -{ -public: - explicit LoggedResourcesHelper(const std::string& sPrefix); - ~LoggedResourcesHelper(); - - void startElement(const std::string& sElement); - static void endElement(); - static void chars(std::u16string_view rChars); - static void chars(const std::string& rChars); - static void attribute(const std::string& rName, const std::string& rValue); - static void attribute(const std::string& rName, sal_uInt32 nValue); - -private: - std::string msPrefix; -}; -#endif - -class LoggedStream : public Stream -{ -public: - explicit LoggedStream(const std::string& sPrefix); - virtual ~LoggedStream() override; - - void startSectionGroup() override; - void endSectionGroup() override; - void startParagraphGroup() override; - void endParagraphGroup() override; - void startCharacterGroup() override; - void endCharacterGroup() override; - void startShape(css::uno::Reference<css::drawing::XShape> const& xShape) override; - void endShape() override; - void text(const sal_uInt8* data, size_t len) override; - void utext(const sal_uInt8* data, size_t len) override; - void positionOffset(const OUString& rText, bool bVertical) override; - void align(const OUString& rText, bool bVertical) override; - void positivePercentage(const OUString& rText) override; - void props(writerfilter::Reference<Properties>::Pointer_t ref) override; - void table(Id name, writerfilter::Reference<Table>::Pointer_t ref) override; - void substream(Id name, writerfilter::Reference<Stream>::Pointer_t ref) override; - void info(const std::string& info) override; - void startGlossaryEntry() override; - void endGlossaryEntry() override; - -protected: - virtual void lcl_startSectionGroup() = 0; - virtual void lcl_endSectionGroup() = 0; - virtual void lcl_startParagraphGroup() = 0; - virtual void lcl_endParagraphGroup() = 0; - virtual void lcl_startCharacterGroup() = 0; - virtual void lcl_endCharacterGroup() = 0; - virtual void lcl_startShape(css::uno::Reference<css::drawing::XShape> const& xShape) = 0; - virtual void lcl_endShape() = 0; - virtual void lcl_text(const sal_uInt8* data, size_t len) = 0; - virtual void lcl_utext(const sal_uInt8* data, size_t len) = 0; - virtual void lcl_positionOffset(const OUString& /*rText*/, bool /*bVertical*/) {} - virtual css::awt::Point getPositionOffset() override { return css::awt::Point(); } - virtual void lcl_align(const OUString& /*rText*/, bool /*bVertical*/) {} - virtual void lcl_positivePercentage(const OUString& /*rText*/) {} - virtual void lcl_props(writerfilter::Reference<Properties>::Pointer_t ref) = 0; - virtual void lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t ref) = 0; - virtual void lcl_substream(Id name, writerfilter::Reference<Stream>::Pointer_t ref) = 0; - virtual void lcl_startGlossaryEntry() {} - virtual void lcl_endGlossaryEntry() {} - -#ifdef DBG_UTIL - LoggedResourcesHelper mHelper; -#endif -}; - -class LoggedProperties : public Properties -{ -public: - explicit LoggedProperties(const std::string& sPrefix); - virtual ~LoggedProperties() override; - - void attribute(Id name, Value& val) override; - void sprm(Sprm& sprm) override; - -protected: - virtual void lcl_attribute(Id name, Value& val) = 0; - virtual void lcl_sprm(Sprm& sprm) = 0; - -#ifdef DBG_UTIL - LoggedResourcesHelper mHelper; -#endif -}; - -class LoggedTable : public Table -{ -public: - explicit LoggedTable(const std::string& sPrefix); - virtual ~LoggedTable() override; - - void entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref) override; - -protected: - virtual void lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) = 0; - -#ifdef DBG_UTIL - LoggedResourcesHelper mHelper; -#endif -}; -} -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_LOGGEDRESOURCES_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/MeasureHandler.cxx b/writerfilter/source/dmapper/MeasureHandler.cxx deleted file mode 100644 index 5eea9a5c613b..000000000000 --- a/writerfilter/source/dmapper/MeasureHandler.cxx +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "MeasureHandler.hxx" -#include "ConversionHelper.hxx" -#include <ooxml/resourceids.hxx> -#include <osl/diagnose.h> -#include <com/sun/star/text/SizeType.hpp> -#include <comphelper/sequence.hxx> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; - - -MeasureHandler::MeasureHandler() : -LoggedProperties("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(); - switch( rName ) - { - case NS_ooxml::LN_CT_TblWidth_type: - { - //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; - - if (!m_aInteropGrabBagName.isEmpty()) - { - beans::PropertyValue aValue; - aValue.Name = "type"; - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_TblWidth_nil: aValue.Value <<= OUString("nil"); break; - case NS_ooxml::LN_Value_ST_TblWidth_pct: aValue.Value <<= OUString("pct"); break; - case NS_ooxml::LN_Value_ST_TblWidth_dxa: aValue.Value <<= OUString("dxa"); break; - case NS_ooxml::LN_Value_ST_TblWidth_auto: aValue.Value <<= OUString("auto"); break; - } - m_aInteropGrabBag.push_back(aValue); - } - } - break; - case NS_ooxml::LN_CT_Height_hRule: - { - OUString sHeightType = rVal.getString(); - if ( sHeightType == "exact" ) - m_nRowHeightSizeType = text::SizeType::FIX; - } - break; - case NS_ooxml::LN_CT_TblWidth_w: - m_nMeasureValue = nIntValue; - if (!m_aInteropGrabBagName.isEmpty()) - { - beans::PropertyValue aValue; - aValue.Name = "w"; - aValue.Value <<= nIntValue; - m_aInteropGrabBag.push_back(aValue); - } - break; - case NS_ooxml::LN_CT_Height_val: // a string value - { - m_nUnit = NS_ooxml::LN_Value_ST_TblWidth_dxa; - OUString sHeight = rVal.getString(); - m_nMeasureValue = sHeight.toInt32(); - } - break; - default: - OSL_FAIL( "unknown attribute"); - } -} - - -void MeasureHandler::lcl_sprm(Sprm &) {} - - -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; -} - -void MeasureHandler::enableInteropGrabBag(const OUString& aName) -{ - m_aInteropGrabBagName = aName; -} - -beans::PropertyValue MeasureHandler::getInteropGrabBag() -{ - beans::PropertyValue aRet; - aRet.Name = m_aInteropGrabBagName; - aRet.Value <<= comphelper::containerToSequence(m_aInteropGrabBag); - return aRet; -} - -} //namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/MeasureHandler.hxx b/writerfilter/source/dmapper/MeasureHandler.hxx deleted file mode 100644 index 3b70987d5345..000000000000 --- a/writerfilter/source/dmapper/MeasureHandler.hxx +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_MEASUREHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_MEASUREHANDLER_HXX - -#include "LoggedResources.hxx" -#include <vector> -#include <com/sun/star/beans/PropertyValue.hpp> - -namespace writerfilter::dmapper -{ -/** Handler for sprms that contain a measure and a unit - - Left indent of tables - - Preferred width of tables - */ -class MeasureHandler : public LoggedProperties -{ - sal_Int32 m_nMeasureValue; - sal_Int32 m_nUnit; - sal_Int16 m_nRowHeightSizeType; //table row height type - - OUString m_aInteropGrabBagName; - std::vector<css::beans::PropertyValue> m_aInteropGrabBag; - - // Properties - virtual void lcl_attribute(Id Name, Value& val) override; - virtual void lcl_sprm(Sprm& sprm) override; - -public: - MeasureHandler(); - virtual ~MeasureHandler() override; - - sal_Int32 getMeasureValue() const; - - sal_Int32 getValue() const { return m_nMeasureValue; } - sal_Int32 getUnit() const { return m_nUnit; } - - sal_Int16 GetRowHeightSizeType() const { return m_nRowHeightSizeType; } - void enableInteropGrabBag(const OUString& aName); - css::beans::PropertyValue getInteropGrabBag(); -}; -typedef tools::SvRef<MeasureHandler> MeasureHandlerPtr; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ModelEventListener.cxx b/writerfilter/source/dmapper/ModelEventListener.cxx deleted file mode 100644 index 8e20f7ad90e5..000000000000 --- a/writerfilter/source/dmapper/ModelEventListener.cxx +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "ModelEventListener.hxx" -#include "PropertyIds.hxx" -#include <rtl/ustring.hxx> -#include <com/sun/star/document/XEventBroadcaster.hpp> -#include <com/sun/star/text/XTextFieldsSupplier.hpp> -#include <com/sun/star/util/XRefreshable.hpp> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/text/ReferenceFieldPart.hpp> -#include <com/sun/star/text/ReferenceFieldSource.hpp> -#include <com/sun/star/frame/XModel.hpp> -#include <com/sun/star/view/XFormLayerAccess.hpp> -#include <tools/diagnose_ex.h> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; - - -ModelEventListener::ModelEventListener(bool bIndexes, bool bControls) - : m_bIndexes(bIndexes), - m_bControls(bControls) -{ -} - - -ModelEventListener::~ModelEventListener() -{ -} - - -void ModelEventListener::notifyEvent( const document::EventObject& rEvent ) -{ - if ( rEvent.EventName == "OnFocus" && m_bIndexes) - { - try - { - //remove listener - uno::Reference<document::XEventBroadcaster>(rEvent.Source, uno::UNO_QUERY_THROW )->removeEventListener( - uno::Reference<document::XEventListener>(this)); - - // If we have PAGEREF fields, update fields as well. - uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(rEvent.Source, uno::UNO_QUERY); - uno::Reference<container::XEnumeration> xEnumeration = xTextFieldsSupplier->getTextFields()->createEnumeration(); - sal_Int32 nIndex = 0; - while(xEnumeration->hasMoreElements()) - { - try - { - uno::Reference<beans::XPropertySet> xPropertySet(xEnumeration->nextElement(), uno::UNO_QUERY); - sal_Int16 nSource = 0; - xPropertySet->getPropertyValue(getPropertyName(PROP_REFERENCE_FIELD_SOURCE)) >>= nSource; - sal_Int16 nPart = 0; - xPropertySet->getPropertyValue(getPropertyName(PROP_REFERENCE_FIELD_PART)) >>= nPart; - if (nSource == text::ReferenceFieldSource::BOOKMARK && nPart == text::ReferenceFieldPart::PAGE) - ++nIndex; - } - catch( const beans::UnknownPropertyException& ) - { - // doesn't even have such a property? ignore - } - } - if (nIndex) - { - uno::Reference<util::XRefreshable> xRefreshable(xTextFieldsSupplier->getTextFields(), uno::UNO_QUERY); - xRefreshable->refresh(); - } - } - catch( const uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "exception while updating indexes"); - } - } - - if ( rEvent.EventName == "OnFocus" && m_bControls) - { - - // Form design mode is enabled by default in Writer, not in Word. - uno::Reference<frame::XModel> xModel(rEvent.Source, uno::UNO_QUERY); - uno::Reference<view::XFormLayerAccess> xFormLayerAccess(xModel->getCurrentController(), uno::UNO_QUERY); - xFormLayerAccess->setFormDesignMode(false); - } -} - - -void ModelEventListener::disposing( const lang::EventObject& rEvent ) -{ - try - { - uno::Reference<document::XEventBroadcaster>(rEvent.Source, uno::UNO_QUERY_THROW )->removeEventListener( - uno::Reference<document::XEventListener>(this)); - } - catch( const uno::Exception& ) - { - } -} - -} //namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ModelEventListener.hxx b/writerfilter/source/dmapper/ModelEventListener.hxx deleted file mode 100644 index 7080674ff27c..000000000000 --- a/writerfilter/source/dmapper/ModelEventListener.hxx +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_MODELEVENTLISTENER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_MODELEVENTLISTENER_HXX - -#include <com/sun/star/document/XEventListener.hpp> -#include <cppuhelper/implbase.hxx> - -namespace writerfilter::dmapper -{ -class ModelEventListener : public cppu::WeakImplHelper<css::document::XEventListener> -{ - bool m_bIndexes; - bool m_bControls; - -public: - ModelEventListener(bool bIndexes, bool bControls); - virtual ~ModelEventListener() override; - - virtual void SAL_CALL notifyEvent(const css::document::EventObject& Event) override; - virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override; -}; -} //namespace writerfilter::dmapper -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx deleted file mode 100644 index 2143f3b2f04c..000000000000 --- a/writerfilter/source/dmapper/NumberingManager.cxx +++ /dev/null @@ -1,1174 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <sal/config.h> - -#include "ConversionHelper.hxx" -#include "NumberingManager.hxx" -#include "StyleSheetTable.hxx" -#include "PropertyIds.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> -#include <com/sun/star/graphic/XGraphic.hpp> -#include <com/sun/star/awt/XBitmap.hpp> - -#include <osl/diagnose.h> -#include <rtl/ustring.hxx> -#include <sal/log.hxx> -#include <tools/diagnose_ex.h> -#include <tools/UnitConversion.hxx> -#include <comphelper/sequence.hxx> -#include <comphelper/propertyvalue.hxx> -#include <comphelper/string.hxx> - -using namespace com::sun::star; - -namespace writerfilter::dmapper { - -//--------------------------------------------------- Utility functions -template <typename T> -static beans::PropertyValue lcl_makePropVal(PropertyIds nNameID, T const & aValue) -{ - return {getPropertyName(nNameID), 0, uno::makeAny(aValue), beans::PropertyState_DIRECT_VALUE}; -} - -static sal_Int32 lcl_findProperty( const uno::Sequence< beans::PropertyValue >& aProps, std::u16string_view sName ) -{ - sal_Int32 i = 0; - sal_Int32 nLen = aProps.getLength( ); - sal_Int32 nPos = -1; - - while ( nPos == -1 && i < nLen ) - { - if ( aProps[i].Name == sName ) - nPos = i; - else - i++; - } - - return nPos; -} - -static void lcl_mergeProperties( const uno::Sequence< beans::PropertyValue >& aSrc, - uno::Sequence< beans::PropertyValue >& aDst ) -{ - for ( const auto& rProp : aSrc ) - { - // Look for the same property in aDst - sal_Int32 nPos = lcl_findProperty( aDst, rProp.Name ); - if ( nPos >= 0 ) - { - // Replace the property value by the one in aSrc - aDst[nPos] = rProp; - } - else - { - // Simply add the new value - aDst.realloc( aDst.getLength( ) + 1 ); - aDst[ aDst.getLength( ) - 1 ] = rProp; - } - } -} - -//-------------------------------------------- ListLevel implementation -void ListLevel::SetValue( Id nId, sal_Int32 nValue ) -{ - switch( nId ) - { - case NS_ooxml::LN_CT_Lvl_start: - m_nIStartAt = nValue; - break; - case NS_ooxml::LN_CT_NumLvl_startOverride: - m_nStartOverride = nValue; - break; - case NS_ooxml::LN_CT_NumFmt_val: - m_nNFC = nValue; - break; - case NS_ooxml::LN_CT_Lvl_isLgl: - break; - case NS_ooxml::LN_CT_Lvl_legacy: - break; - case NS_ooxml::LN_CT_Lvl_suff: - m_nXChFollow = nValue; - break; - case NS_ooxml::LN_CT_TabStop_pos: - if (nValue < 0) - { - SAL_INFO("writerfilter", - "unsupported list tab stop position " << nValue); - } - else - m_nTabstop = nValue; - break; - default: - OSL_FAIL( "this line should never be reached"); - } - m_bHasValues = true; -} - -void ListLevel::SetCustomNumberFormat(const OUString& rValue) { m_aCustomNumberFormat = rValue; } - -bool ListLevel::HasValues() const -{ - return m_bHasValues; -} - -void ListLevel::SetParaStyle( const tools::SvRef< StyleSheetEntry >& pStyle ) -{ - if (!pStyle) - return; - m_pParaStyle = pStyle; - // AFAICT .docx spec does not identify which numberings or paragraph - // styles are actually the ones to be used for outlines (chapter numbering), - // it only kind of says somewhere that they should be named Heading1 to Heading9. - const OUString styleId= pStyle->sConvertedStyleName; - m_outline = ( styleId.getLength() == RTL_CONSTASCII_LENGTH( "Heading 1" ) - && styleId.match( "Heading ", 0 ) - && styleId[ RTL_CONSTASCII_LENGTH( "Heading " ) ] >= '1' - && styleId[ RTL_CONSTASCII_LENGTH( "Heading " ) ] <= '9' ); -} - -uno::Sequence<beans::PropertyValue> ListLevel::GetProperties(bool bDefaults) -{ - uno::Sequence<beans::PropertyValue> aLevelProps = GetLevelProperties(bDefaults); - if (m_pParaStyle) - AddParaProperties( &aLevelProps ); - return aLevelProps; -} - -static bool IgnoreForCharStyle(std::u16string_view aStr, const bool bIsSymbol) -{ - //Names found in PropertyIds.cxx, Lines 56-396 - return (aStr==u"Adjust" || aStr==u"IndentAt" || aStr==u"FirstLineIndent" - || aStr==u"FirstLineOffset" || aStr==u"LeftMargin" - || aStr==u"CharInteropGrabBag" || aStr==u"ParaInteropGrabBag" || - // We need font names when they are different for the bullet and for the text. - // But leave symbols alone, we only want to keep the font style for letters and numbers. - (bIsSymbol && aStr==u"CharFontName") - ); -} -uno::Sequence< beans::PropertyValue > ListLevel::GetCharStyleProperties( ) -{ - PropertyValueVector_t rProperties; - - uno::Sequence< beans::PropertyValue > vPropVals = PropertyMap::GetPropertyValues(); - beans::PropertyValue* aValIter = vPropVals.begin(); - beans::PropertyValue* aEndIter = vPropVals.end(); - const bool bIsSymbol(m_sBulletChar.getLength() <= 1); - for( ; aValIter != aEndIter; ++aValIter ) - if (! IgnoreForCharStyle(aValIter->Name, bIsSymbol)) - rProperties.emplace_back(aValIter->Name, 0, aValIter->Value, beans::PropertyState_DIRECT_VALUE); - - return comphelper::containerToSequence(rProperties); -} - -uno::Sequence<beans::PropertyValue> ListLevel::GetLevelProperties(bool bDefaults) -{ - std::vector<beans::PropertyValue> aNumberingProperties; - - if (m_nIStartAt >= 0) - aNumberingProperties.push_back(lcl_makePropVal<sal_Int16>(PROP_START_WITH, m_nIStartAt) ); - else if (bDefaults) - aNumberingProperties.push_back(lcl_makePropVal<sal_Int16>(PROP_START_WITH, 0)); - - sal_Int16 nNumberFormat = -1; - if (m_nNFC == NS_ooxml::LN_Value_ST_NumberFormat_custom) - { - nNumberFormat = ConversionHelper::ConvertCustomNumberFormat(m_aCustomNumberFormat); - } - else - { - nNumberFormat = ConversionHelper::ConvertNumberingType(m_nNFC); - } - if( m_nNFC >= 0) - { - if (m_xGraphicBitmap.is()) - nNumberFormat = style::NumberingType::BITMAP; - aNumberingProperties.push_back(lcl_makePropVal(PROP_NUMBERING_TYPE, nNumberFormat)); - } - - // todo: this is not the bullet char - if( nNumberFormat == style::NumberingType::CHAR_SPECIAL ) - { - if (!m_sBulletChar.isEmpty()) - { - aNumberingProperties.push_back(lcl_makePropVal(PROP_BULLET_CHAR, m_sBulletChar.copy(0, 1))); - } - else - { - // If w:lvlText's value is null - set bullet char to zero. - aNumberingProperties.push_back(lcl_makePropVal<sal_Unicode>(PROP_BULLET_CHAR, 0)); - } - } - if (m_xGraphicBitmap.is()) - { - aNumberingProperties.push_back(lcl_makePropVal(PROP_GRAPHIC_BITMAP, m_xGraphicBitmap)); - aNumberingProperties.push_back(lcl_makePropVal(PROP_GRAPHIC_SIZE, m_aGraphicSize)); - } - - if (m_nTabstop.has_value()) - aNumberingProperties.push_back(lcl_makePropVal(PROP_LISTTAB_STOP_POSITION, *m_nTabstop)); - else if (bDefaults) - aNumberingProperties.push_back(lcl_makePropVal<sal_Int16>(PROP_LISTTAB_STOP_POSITION, 0)); - - //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 - -// TODO: sRGBXchNums; array of inherited numbers - -// nXChFollow; following character 0 - tab, 1 - space, 2 - nothing - if (bDefaults || m_nXChFollow != SvxNumberFormat::LISTTAB) - aNumberingProperties.push_back(lcl_makePropVal(PROP_LEVEL_FOLLOW, m_nXChFollow)); - - PropertyIds const aReadIds[] = - { - PROP_ADJUST, PROP_INDENT_AT, PROP_FIRST_LINE_INDENT, - PROP_FIRST_LINE_OFFSET, PROP_LEFT_MARGIN - }; - for(PropertyIds const & rReadId : aReadIds) { - std::optional<PropertyMap::Property> aProp = getProperty(rReadId); - if (aProp) - aNumberingProperties.emplace_back( getPropertyName(aProp->first), 0, aProp->second, beans::PropertyState_DIRECT_VALUE ); - else if (rReadId == PROP_FIRST_LINE_INDENT && bDefaults) - // Writer default is -360 twips, Word default seems to be 0. - aNumberingProperties.emplace_back("FirstLineIndent", 0, uno::makeAny(static_cast<sal_Int32>(0)), beans::PropertyState_DIRECT_VALUE); - else if (rReadId == PROP_INDENT_AT && bDefaults) - // Writer default is 720 twips, Word default seems to be 0. - aNumberingProperties.emplace_back("IndentAt", 0, - uno::makeAny(static_cast<sal_Int32>(0)), - beans::PropertyState_DIRECT_VALUE); - } - - std::optional<PropertyMap::Property> aPropFont = getProperty(PROP_CHAR_FONT_NAME); - if(aPropFont && !isOutlineNumbering()) - aNumberingProperties.emplace_back( getPropertyName(PROP_BULLET_FONT_NAME), 0, aPropFont->second, beans::PropertyState_DIRECT_VALUE ); - - return comphelper::containerToSequence(aNumberingProperties); -} - -// Add the properties only if they do not already exist in the sequence. -void ListLevel::AddParaProperties( uno::Sequence< beans::PropertyValue >* props ) -{ - uno::Sequence< beans::PropertyValue >& aProps = *props; - - OUString sFirstLineIndent = getPropertyName( - PROP_FIRST_LINE_INDENT ); - OUString sIndentAt = getPropertyName( - PROP_INDENT_AT ); - - bool hasFirstLineIndent = lcl_findProperty( aProps, sFirstLineIndent ); - bool hasIndentAt = lcl_findProperty( aProps, sIndentAt ); - - if( hasFirstLineIndent && hasIndentAt ) - return; // has them all, nothing to add - - const uno::Sequence< beans::PropertyValue > aParaProps = m_pParaStyle->pProperties->GetPropertyValues( ); - - // ParaFirstLineIndent -> FirstLineIndent - // ParaLeftMargin -> IndentAt - - OUString sParaIndent = getPropertyName( - PROP_PARA_FIRST_LINE_INDENT ); - OUString sParaLeftMargin = getPropertyName( - PROP_PARA_LEFT_MARGIN ); - - for ( const auto& rParaProp : aParaProps ) - { - if ( !hasFirstLineIndent && rParaProp.Name == sParaIndent ) - { - aProps.realloc( aProps.getLength() + 1 ); - aProps[aProps.getLength( ) - 1] = rParaProp; - aProps[aProps.getLength( ) - 1].Name = sFirstLineIndent; - } - else if ( !hasIndentAt && rParaProp.Name == sParaLeftMargin ) - { - aProps.realloc( aProps.getLength() + 1 ); - aProps[aProps.getLength( ) - 1] = rParaProp; - aProps[aProps.getLength( ) - 1].Name = sIndentAt; - } - - } -} - -NumPicBullet::NumPicBullet() - : m_nId(0) -{ -} - -NumPicBullet::~NumPicBullet() -{ -} - -void NumPicBullet::SetId(sal_Int32 nId) -{ - m_nId = nId; -} - -void NumPicBullet::SetShape(uno::Reference<drawing::XShape> const& xShape) -{ - m_xShape = xShape; -} - - -//--------------------------------------- AbstractListDef implementation - -AbstractListDef::AbstractListDef( ) : - m_nId( -1 ) -{ -} - -AbstractListDef::~AbstractListDef( ) -{ -} - -void AbstractListDef::SetValue( sal_uInt32 nSprmId ) -{ - switch( nSprmId ) - { - case NS_ooxml::LN_CT_AbstractNum_tmpl: - 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( sal_uInt16 nLvl ) -{ - if ( nLvl >= m_aLevels.size() ) - m_aLevels.resize( nLvl+1 ); - - ListLevel::Pointer pLevel( new ListLevel ); - m_pCurrentLevel = pLevel; - m_aLevels[nLvl] = pLevel; -} - -uno::Sequence<uno::Sequence<beans::PropertyValue>> AbstractListDef::GetPropertyValues(bool bDefaults) -{ - 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++ ) - { - if (m_aLevels[i]) - aResult[i] = m_aLevels[i]->GetProperties(bDefaults); - } - - return result; -} - -const OUString& AbstractListDef::MapListId(OUString const& rId) -{ - if (!m_oListId) - { - m_oListId = rId; - } - return *m_oListId; -} - -//---------------------------------------------- ListDef implementation - -ListDef::ListDef( ) : AbstractListDef( ) -{ - m_nDefaultParentLevels = WW_OUTLINE_MAX + 1; -} - -ListDef::~ListDef( ) -{ -} - -const OUString & ListDef::GetStyleName(sal_Int32 const nId, - uno::Reference<container::XNameContainer> const& xStyles) -{ - if (xStyles.is()) - { - OUString sStyleName = "WWNum" + OUString::number( nId ); - - while (xStyles->hasByName(sStyleName)) // unique - { - sStyleName += "a"; - } - - m_StyleName = sStyleName; - } - else - { -// fails in rtftok test assert(!m_StyleName.isEmpty()); // must be inited first - } - - return m_StyleName; -} - -uno::Sequence<uno::Sequence<beans::PropertyValue>> ListDef::GetMergedPropertyValues() -{ - if (!m_pAbstractDef) - return uno::Sequence< uno::Sequence< beans::PropertyValue > >(); - - // [1] Call the same method on the abstract list - uno::Sequence<uno::Sequence<beans::PropertyValue>> aAbstract - = m_pAbstractDef->GetPropertyValues(/*bDefaults=*/true); - - // [2] Call the upper class method - uno::Sequence<uno::Sequence<beans::PropertyValue>> aThis - = AbstractListDef::GetPropertyValues(/*bDefaults=*/false); - - // Merge the results of [2] in [1] - sal_Int32 nThisCount = aThis.getLength( ); - sal_Int32 nAbstractCount = aAbstract.getLength( ); - for ( sal_Int32 i = 0; i < nThisCount && i < nAbstractCount; i++ ) - { - uno::Sequence< beans::PropertyValue > level = aThis[i]; - if (level.hasElements() && GetLevel(i)->HasValues()) - { - // If the element contains something, merge it, but ignore stub overrides. - lcl_mergeProperties( level, aAbstract[i] ); - } - } - - return aAbstract; -} - -static uno::Reference< container::XNameContainer > lcl_getUnoNumberingStyles( - uno::Reference<lang::XMultiServiceFactory> const& xFactory) -{ - uno::Reference< container::XNameContainer > xStyles; - - try - { - uno::Reference< style::XStyleFamiliesSupplier > xFamilies( xFactory, uno::UNO_QUERY_THROW ); - uno::Any oFamily = xFamilies->getStyleFamilies( )->getByName("NumberingStyles"); - - oFamily >>= xStyles; - } - catch ( const uno::Exception & ) - { - } - - return xStyles; -} - -void ListDef::CreateNumberingRules( DomainMapper& rDMapper, - uno::Reference<lang::XMultiServiceFactory> const& 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( )) ) - return; - - try - { - // Create the numbering style - uno::Reference< beans::XPropertySet > xStyle ( - xFactory->createInstance("com.sun.star.style.NumberingStyle"), - uno::UNO_QUERY_THROW ); - - OUString sStyleName = GetStyleName(GetId(), xStyles); - - xStyles->insertByName( sStyleName, makeAny( xStyle ) ); - - uno::Any oStyle = xStyles->getByName( sStyleName ); - xStyle.set( oStyle, uno::UNO_QUERY_THROW ); - - // Get the default OOo Numbering style rules - uno::Any aRules = xStyle->getPropertyValue( getPropertyName( PROP_NUMBERING_RULES ) ); - aRules >>= m_xNumRules; - - uno::Sequence<uno::Sequence<beans::PropertyValue>> aProps = GetMergedPropertyValues(); - - sal_Int32 nAbstLevels = m_pAbstractDef ? m_pAbstractDef->Size() : 0; - sal_Int32 nLevel = 0; - while ( nLevel < nAbstLevels ) - { - ListLevel::Pointer pAbsLevel = m_pAbstractDef->GetLevel( nLevel ); - ListLevel::Pointer pLevel = GetLevel( nLevel ); - - // Get the merged level properties - auto aLvlProps = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aProps[nLevel]); - - // Get the char style - auto aAbsCharStyleProps = pAbsLevel - ? pAbsLevel->GetCharStyleProperties() - : uno::Sequence<beans::PropertyValue>(); - if ( pLevel ) - { - uno::Sequence< beans::PropertyValue >& rAbsCharStyleProps = aAbsCharStyleProps; - uno::Sequence< beans::PropertyValue > aCharStyleProps = - pLevel->GetCharStyleProperties( ); - uno::Sequence< beans::PropertyValue >& rCharStyleProps = aCharStyleProps; - lcl_mergeProperties( rAbsCharStyleProps, rCharStyleProps ); - } - - if( aAbsCharStyleProps.hasElements() ) - { - // Change the sequence into a vector - auto aStyleProps = comphelper::sequenceToContainer<PropertyValueVector_t>(aAbsCharStyleProps); - - //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, /*bAlwaysCreate=*/true ); - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_CHAR_STYLE_NAME), sStyle)); - } - - // Get the prefix / suffix / Parent numbering - // and add them to the level properties - OUString sText = pAbsLevel - ? pAbsLevel->GetBulletChar() - : OUString(); - // Inherit <w:lvlText> from the abstract level in case the override would be empty. - if (pLevel && !pLevel->GetBulletChar().isEmpty()) - sText = pLevel->GetBulletChar( ); - - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PREFIX), OUString(""))); - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SUFFIX), OUString(""))); - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_LIST_FORMAT), sText)); - - // Total count of replacement holders is determining amount of required parent numbering to include - // TODO: not sure how "%" symbol is escaped. This is not supported yet - sal_Int16 nParentNum = comphelper::string::getTokenCount(sText, '%'); - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PARENT_NUMBERING), nParentNum)); - - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_POSITION_AND_SPACE_MODE), sal_Int16(text::PositionAndSpaceMode::LABEL_ALIGNMENT))); - - // Replace the numbering rules for the level - m_xNumRules->replaceByIndex(nLevel, uno::makeAny(comphelper::containerToSequence(aLvlProps))); - - // Handle the outline level here - if (pAbsLevel && pAbsLevel->isOutlineNumbering()) - { - uno::Reference< text::XChapterNumberingSupplier > xOutlines ( - xFactory, uno::UNO_QUERY_THROW ); - uno::Reference< container::XIndexReplace > xOutlineRules = - xOutlines->getChapterNumberingRules( ); - - StyleSheetEntryPtr pParaStyle = pAbsLevel->GetParaStyle( ); - aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HEADING_STYLE_NAME), pParaStyle->sConvertedStyleName)); - - xOutlineRules->replaceByIndex(nLevel, uno::makeAny(comphelper::containerToSequence(aLvlProps))); - } - - if (pAbsLevel) - { - // first level without default outline paragraph style - const tools::SvRef< StyleSheetEntry >& aParaStyle = pAbsLevel->GetParaStyle(); - if ( WW_OUTLINE_MAX + 1 == m_nDefaultParentLevels && ( !aParaStyle || - aParaStyle->sConvertedStyleName.getLength() != RTL_CONSTASCII_LENGTH( "Heading 1" ) || - !aParaStyle->sConvertedStyleName.startsWith("Heading ") || - aParaStyle->sConvertedStyleName[ RTL_CONSTASCII_LENGTH( "Heading " ) ] - u'1' != nLevel ) ) - { - m_nDefaultParentLevels = nLevel; - } - } - - nLevel++; - } - - // Create the numbering style for these rules - OUString sNumRulesName = getPropertyName( PROP_NUMBERING_RULES ); - xStyle->setPropertyValue( sNumRulesName, uno::makeAny( m_xNumRules ) ); - } - catch( const lang::IllegalArgumentException& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "" ); - assert( !"Incorrect argument to UNO call" ); - } - catch( const uno::RuntimeException& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "" ); - assert( !"Incorrect argument to UNO call" ); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "" ); - } - -} - -//------------------------------------- NumberingManager implementation - - -ListsManager::ListsManager(DomainMapper& rDMapper, - const uno::Reference<lang::XMultiServiceFactory> & xFactory) - : LoggedProperties("ListsManager") - , LoggedTable("ListsManager") - , m_rDMapper(rDMapper) - , m_xFactory(xFactory) -{ -} - -ListsManager::~ListsManager( ) -{ - DisposeNumPicBullets(); -} - -void ListsManager::DisposeNumPicBullets( ) -{ - uno::Reference<drawing::XShape> xShape; - for (const auto& rNumPicBullet : m_aNumPicBullets) - { - xShape = rNumPicBullet->GetShape(); - if (xShape.is()) - { - uno::Reference<lang::XComponent> xShapeComponent(xShape, uno::UNO_QUERY); - xShapeComponent->dispose(); - } - } -} - -void ListsManager::lcl_attribute( Id nName, Value& rVal ) -{ - ListLevel::Pointer pCurrentLvl; - - if (nName != NS_ooxml::LN_CT_NumPicBullet_numPicBulletId) - { - OSL_ENSURE( m_pCurrentDefinition, "current entry has to be set here"); - if(!m_pCurrentDefinition) - return ; - pCurrentLvl = m_pCurrentDefinition->GetCurrentLevel( ); - } - else - { - SAL_WARN_IF(!m_pCurrentNumPicBullet, "writerfilter", "current entry has to be set here"); - if (!m_pCurrentNumPicBullet) - return; - } - int nIntValue = rVal.getInt(); - - - switch(nName) - { - 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 together with separators 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) - { - //if the BulletChar is a soft-hyphen (0xad) - //replace it with a hard-hyphen (0x2d) - //-> this fixes missing hyphen export in PDF etc. - // see tdf#101626 - pCurrentLvl->SetBulletChar( rVal.getString().replace( 0xad, 0x2d ) ); - } - } - break; - case NS_ooxml::LN_CT_Lvl_start: - case NS_ooxml::LN_CT_Lvl_numFmt: - case NS_ooxml::LN_CT_NumFmt_format: - case NS_ooxml::LN_CT_NumFmt_val: - case NS_ooxml::LN_CT_Lvl_isLgl: - case NS_ooxml::LN_CT_Lvl_legacy: - if ( pCurrentLvl ) - { - if (nName == NS_ooxml::LN_CT_NumFmt_format) - { - pCurrentLvl->SetCustomNumberFormat(rVal.getString()); - } - else - { - pCurrentLvl->SetValue(nName, sal_Int32(nIntValue)); - } - } - break; - case NS_ooxml::LN_CT_Num_numId: - m_pCurrentDefinition->SetId( rVal.getString().toInt32( ) ); - break; - case NS_ooxml::LN_CT_AbstractNum_nsid: - m_pCurrentDefinition->SetId( nIntValue ); - break; - case NS_ooxml::LN_CT_AbstractNum_tmpl: - AbstractListDef::SetValue( nName ); - break; - case NS_ooxml::LN_CT_NumLvl_ilvl: - //add a new level to the level vector and make it the current one - m_pCurrentDefinition->AddLevel(rVal.getString().toUInt32()); - break; - case NS_ooxml::LN_CT_Lvl_ilvl: - m_pCurrentDefinition->AddLevel(rVal.getString().toUInt32()); - 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_start: - case NS_ooxml::LN_CT_Ind_left: - if ( pCurrentLvl ) - pCurrentLvl->Insert( - PROP_INDENT_AT, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) )); - break; - case NS_ooxml::LN_CT_Ind_hanging: - if ( pCurrentLvl ) - pCurrentLvl->Insert( - PROP_FIRST_LINE_INDENT, uno::makeAny( - ConversionHelper::convertTwipToMM100( nIntValue ) )); - break; - case NS_ooxml::LN_CT_Ind_firstLine: - if ( pCurrentLvl ) - pCurrentLvl->Insert( - PROP_FIRST_LINE_INDENT, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) )); - break; - 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 ) - pCurrentLvl->SetValue( nName, - ConversionHelper::convertTwipToMM100( nIntValue ) ); - } - break; - case NS_ooxml::LN_CT_TabStop_val: - { - // TODO Do something of that - } - break; - case NS_ooxml::LN_CT_NumPicBullet_numPicBulletId: - m_pCurrentNumPicBullet->SetId(rVal.getString().toInt32()); - break; - default: - SAL_WARN("writerfilter", "ListsManager::lcl_attribute: unhandled token: " << nName); - } -} - -void ListsManager::lcl_sprm( Sprm& rSprm ) -{ - //fill the attributes of the style sheet - sal_uInt32 nSprmId = rSprm.getId(); - if( !(m_pCurrentDefinition || - nSprmId == NS_ooxml::LN_CT_Numbering_abstractNum || - nSprmId == NS_ooxml::LN_CT_Numbering_num || - (nSprmId == NS_ooxml::LN_CT_NumPicBullet_pict && m_pCurrentNumPicBullet) || - nSprmId == NS_ooxml::LN_CT_Numbering_numPicBullet)) - return; - - static bool bIsStartVisited = false; - 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) - { - //create a new Abstract list entry - OSL_ENSURE( !m_pCurrentDefinition, "current entry has to be NULL here"); - m_pCurrentDefinition = 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) - { - // Create a new list entry - OSL_ENSURE( !m_pCurrentDefinition, "current entry has to be NULL here"); - ListDef::Pointer listDef( new ListDef ); - m_pCurrentDefinition = listDef.get(); - pProperties->resolve( *this ); - //append it to the table - m_aLists.push_back( listDef ); - - m_pCurrentDefinition = AbstractListDef::Pointer(); - } - } - break; - case NS_ooxml::LN_CT_Numbering_numPicBullet: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - { - NumPicBullet::Pointer numPicBullet(new NumPicBullet()); - m_pCurrentNumPicBullet = numPicBullet; - pProperties->resolve(*this); - m_aNumPicBullets.push_back(numPicBullet); - m_pCurrentNumPicBullet = NumPicBullet::Pointer(); - } - } - break; - case NS_ooxml::LN_CT_NumPicBullet_pict: - { - uno::Reference<drawing::XShape> xShape = m_rDMapper.PopPendingShape(); - - m_pCurrentNumPicBullet->SetShape(xShape); - } - break; - case NS_ooxml::LN_CT_Lvl_lvlPicBulletId: - if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel()) - { - uno::Reference<drawing::XShape> xShape; - for (const auto& rNumPicBullet : m_aNumPicBullets) - { - if (rNumPicBullet->GetId() == nIntValue) - { - xShape = rNumPicBullet->GetShape(); - break; - } - } - if (xShape.is()) - { - uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY); - try - { - uno::Any aAny = xPropertySet->getPropertyValue("Graphic"); - if (aAny.has<uno::Reference<graphic::XGraphic>>() && pCurrentLevel) - { - auto xGraphic = aAny.get<uno::Reference<graphic::XGraphic>>(); - if (xGraphic.is()) - { - uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY); - pCurrentLevel->SetGraphicBitmap(xBitmap); - } - } - } - catch (const beans::UnknownPropertyException&) - {} - - // Respect only the aspect ratio of the picture, not its size. - awt::Size aPrefSize = xShape->getSize(); - if ( aPrefSize.Height * aPrefSize.Width != 0 ) - { - // See SwDefBulletConfig::InitFont(), default height is 14. - const int nFontHeight = 14; - // Point -> mm100. - const int nHeight = nFontHeight * 35; - int nWidth = (nHeight * aPrefSize.Width) / aPrefSize.Height; - - awt::Size aSize( convertMm100ToTwip(nWidth), convertMm100ToTwip(nHeight) ); - pCurrentLevel->SetGraphicSize( aSize ); - } - else - { - awt::Size aSize( convertMm100ToTwip(aPrefSize.Width), convertMm100ToTwip(aPrefSize.Height) ); - pCurrentLevel->SetGraphicSize( aSize ); - } - } - } - break; - case NS_ooxml::LN_CT_Num_abstractNumId: - { - sal_Int32 nAbstractNumId = rSprm.getValue()->getInt(); - ListDef* pListDef = dynamic_cast< ListDef* >( m_pCurrentDefinition.get( ) ); - if ( pListDef != nullptr ) - { - // The current def should be a ListDef - pListDef->SetAbstractDefinition( - GetAbstractList( nAbstractNumId ) ); - } - } - break; - case NS_ooxml::LN_CT_AbstractNum_multiLevelType: - break; - case NS_ooxml::LN_CT_AbstractNum_tmpl: - AbstractListDef::SetValue( nSprmId ); - break; - case NS_ooxml::LN_CT_AbstractNum_lvl: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if(pProperties) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_Lvl_start: - if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel()) - pCurrentLevel->SetValue( nSprmId, nIntValue ); - bIsStartVisited = true; - break; - case NS_ooxml::LN_CT_Lvl_numFmt: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - { - pProperties->resolve(*this); - } - if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel()) - { - if( !bIsStartVisited ) - { - pCurrentLevel->SetValue( NS_ooxml::LN_CT_Lvl_start, 0 ); - bIsStartVisited = true; - } - } - } - break; - case NS_ooxml::LN_CT_Lvl_isLgl: - case NS_ooxml::LN_CT_Lvl_legacy: - if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel()) - { - pCurrentLevel->SetValue(nSprmId, nIntValue); - } - break; - case NS_ooxml::LN_CT_Lvl_suff: - { - if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel()) - { - SvxNumberFormat::LabelFollowedBy value = SvxNumberFormat::LISTTAB; - if( rSprm.getValue()->getString() == "tab" ) - value = SvxNumberFormat::LISTTAB; - else if( rSprm.getValue()->getString() == "space" ) - value = SvxNumberFormat::SPACE; - else if( rSprm.getValue()->getString() == "nothing" ) - value = SvxNumberFormat::NOTHING; - else - SAL_WARN( "writerfilter", "Unknown ST_LevelSuffix value " - << rSprm.getValue()->getString()); - pCurrentLevel->SetValue( nSprmId, value ); - } - } - 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) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_NumLvl_lvl: - { - // overwrite level - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if(pProperties) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_Lvl_lvlJc: - { - sal_Int16 nValue = text::HoriOrientation::NONE; - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_Jc_left: - case NS_ooxml::LN_Value_ST_Jc_start: - nValue = text::HoriOrientation::LEFT; - break; - case NS_ooxml::LN_Value_ST_Jc_center: - nValue = text::HoriOrientation::CENTER; - break; - case NS_ooxml::LN_Value_ST_Jc_right: - case NS_ooxml::LN_Value_ST_Jc_end: - nValue = text::HoriOrientation::RIGHT; - break; - } - - if (nValue != text::HoriOrientation::NONE) - { - if (ListLevel::Pointer pLevel = m_pCurrentDefinition->GetCurrentLevel()) - { - pLevel->Insert( - PROP_ADJUST, uno::makeAny( nValue ) ); - } - } - } - 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) - 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) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_Lvl_pStyle: - { - OUString sStyleName = rSprm.getValue( )->getString( ); - if (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_CT_Num_lvlOverride: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_NumLvl_startOverride: - { - if(m_pCurrentDefinition) - { - if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel()) - { - pCurrentLevel->SetValue(NS_ooxml::LN_CT_NumLvl_startOverride, nIntValue); - } - } - } - break; - case NS_ooxml::LN_CT_AbstractNum_numStyleLink: - { - OUString sStyleName = rSprm.getValue( )->getString( ); - m_pCurrentDefinition->SetNumStyleLink(sStyleName); - } - break; - case NS_ooxml::LN_CT_AbstractNum_styleLink: - { - OUString sStyleName = rSprm.getValue()->getString(); - m_pCurrentDefinition->SetStyleLink(sStyleName); - } - 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_ooxml::LN_EG_RPrBase_sz: - case NS_ooxml::LN_EG_RPrBase_lang: - case NS_ooxml::LN_EG_RPrBase_eastAsianLayout: - //no break! - default: - if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel()) - { - m_rDMapper.PushListProperties(pCurrentLevel.get()); - m_rDMapper.sprm( rSprm ); - m_rDMapper.PopListProperties(); - } - } -} - -void ListsManager::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref ) -{ - if( m_rDMapper.IsOOXMLImport() || m_rDMapper.IsRTFImport() ) - { - ref->resolve(*this); - } - else - { - // Create AbstractListDef's - OSL_ENSURE( !m_pCurrentDefinition, "current entry has to be NULL here"); - m_pCurrentDefinition = 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 ) -{ - for (const auto& listDef : m_aAbstractLists) - { - if (listDef->GetId( ) == nId) - { - if (listDef->GetNumStyleLink().getLength() > 0) - { - // If the abstract num has a style linked, check the linked style's number id. - StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( ); - - const StyleSheetEntryPtr pStyleSheetEntry = - pStylesTable->FindStyleSheetByISTD(listDef->GetNumStyleLink() ); - - const StyleSheetPropertyMap* pStyleSheetProperties = - dynamic_cast<const StyleSheetPropertyMap*>(pStyleSheetEntry ? pStyleSheetEntry->pProperties.get() : nullptr); - - if( pStyleSheetProperties && pStyleSheetProperties->GetListId() >= 0 ) - { - ListDef::Pointer pList = GetList( pStyleSheetProperties->GetListId() ); - if ( pList!=nullptr ) - return pList->GetAbstractDefinition(); - } - - // In stylesheet we did not found anything useful. Try to find base abstractnum having this stylelink - for (const auto & baseListDef : m_aAbstractLists) - { - if (baseListDef->GetStyleLink() == listDef->GetNumStyleLink()) - { - return baseListDef; - } - } - } - - // Standalone abstract list - return listDef; - } - } - - return nullptr; -} - -ListDef::Pointer ListsManager::GetList( sal_Int32 nId ) -{ - ListDef::Pointer pList; - - int nLen = m_aLists.size( ); - int i = 0; - while ( !pList && i < nLen ) - { - if ( m_aLists[i]->GetId( ) == nId ) - pList = m_aLists[i]; - i++; - } - - return pList; -} - -void ListsManager::CreateNumberingRules( ) -{ - // Loop over the definitions - for ( const auto& rList : m_aLists ) - { - rList->CreateNumberingRules( m_rDMapper, m_xFactory ); - } - m_rDMapper.GetStyleSheetTable()->ApplyNumberingStyleNameToParaStyles(); -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/NumberingManager.hxx b/writerfilter/source/dmapper/NumberingManager.hxx deleted file mode 100644 index 0a4c3e18f8e6..000000000000 --- a/writerfilter/source/dmapper/NumberingManager.hxx +++ /dev/null @@ -1,259 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_NUMBERINGMANAGER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_NUMBERINGMANAGER_HXX - -#include "PropertyMap.hxx" - -#include "DomainMapper.hxx" -#include "LoggedResources.hxx" -#include "StyleSheetTable.hxx" - -#include <editeng/numitem.hxx> - -#include <com/sun/star/container/XIndexReplace.hpp> -#include <com/sun/star/awt/XBitmap.hpp> - -namespace writerfilter::dmapper { - -class DomainMapper; -class StyleSheetEntry; - - -/** Class representing the numbering level properties. - */ -class ListLevel : public PropertyMap -{ - sal_Int32 m_nIStartAt; //LN_CT_Lvl_start - sal_Int32 m_nStartOverride; - sal_Int32 m_nNFC; //LN_CT_Lvl_numFmt - /// LN_CT_NumFmt_format, in case m_nNFC is custom. - OUString m_aCustomNumberFormat; - sal_Int16 m_nXChFollow; //LN_IXCHFOLLOW - OUString m_sBulletChar; - css::awt::Size m_aGraphicSize; - css::uno::Reference<css::awt::XBitmap> m_xGraphicBitmap; - std::optional<sal_Int32> m_nTabstop; - tools::SvRef< StyleSheetEntry > m_pParaStyle; - bool m_outline; - bool m_bHasValues = false; - -public: - - typedef tools::SvRef< ListLevel > Pointer; - - ListLevel() : - m_nIStartAt(-1) - ,m_nStartOverride(-1) - ,m_nNFC(-1) - ,m_nXChFollow(SvxNumberFormat::LISTTAB) - ,m_outline(false) - {} - - // Setters for the import - void SetValue( Id nId, sal_Int32 nValue ); - void SetCustomNumberFormat(const OUString& rValue); - void SetBulletChar( const OUString& sValue ) { m_sBulletChar = sValue; }; - void SetGraphicSize( const css::awt::Size& aValue ) { m_aGraphicSize = aValue; }; - - void SetGraphicBitmap(css::uno::Reference<css::awt::XBitmap> const& xGraphicBitmap) - { m_xGraphicBitmap = xGraphicBitmap; } - void SetParaStyle( const tools::SvRef< StyleSheetEntry >& pStyle ); - - // Getters - const OUString& GetBulletChar( ) const { return m_sBulletChar; }; - const tools::SvRef< StyleSheetEntry >& GetParaStyle( ) const { return m_pParaStyle; }; - bool isOutlineNumbering() const { return m_outline; } - sal_Int32 GetStartOverride() const { return m_nStartOverride; }; - /// Determines if SetValue() was called at least once. - bool HasValues() const; - - // UNO mapping functions - css::uno::Sequence<css::beans::PropertyValue> GetProperties(bool bDefaults); - - css::uno::Sequence<css::beans::PropertyValue> GetCharStyleProperties(); -private: - - css::uno::Sequence<css::beans::PropertyValue> GetLevelProperties(bool bDefaults); - - void AddParaProperties(css::uno::Sequence<css::beans::PropertyValue>* pProps); -}; - -/// Represents a numbering picture bullet: an id and a graphic. -class NumPicBullet final : public virtual SvRefBase -{ -public: - typedef tools::SvRef<NumPicBullet> Pointer; - NumPicBullet(); - ~NumPicBullet() override; - - void SetId(sal_Int32 nId); - sal_Int32 GetId() const { return m_nId;} - void SetShape(css::uno::Reference<css::drawing::XShape> const& xShape); - const css::uno::Reference<css::drawing::XShape>& GetShape() const { return m_xShape; } -private: - sal_Int32 m_nId; - css::uno::Reference<css::drawing::XShape> m_xShape; -}; - -class AbstractListDef : public virtual SvRefBase -{ -private: - // 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 numbering import - ListLevel::Pointer m_pCurrentLevel; - - // The style name linked to. - OUString m_sNumStyleLink; - - // This abstract numbering is a base definition for this style - OUString m_sStyleLink; - - /// list id to use for all derived numbering definitions - std::optional<OUString> m_oListId; - -public: - typedef tools::SvRef< AbstractListDef > Pointer; - - AbstractListDef( ); - virtual ~AbstractListDef( ) override; - - // Setters using during the import - void SetId( sal_Int32 nId ) { m_nId = nId; }; - static void SetValue( sal_uInt32 nSprmId ); - - // Accessors - sal_Int32 GetId( ) const { return m_nId; }; - - sal_Int16 Size( ) { return sal_Int16( m_aLevels.size( ) ); }; - ListLevel::Pointer GetLevel( sal_uInt16 nLvl ); - void AddLevel( sal_uInt16 nLvl ); - - const ListLevel::Pointer& GetCurrentLevel( ) const { return m_pCurrentLevel; }; - - css::uno::Sequence< css::uno::Sequence<css::beans::PropertyValue> > GetPropertyValues(bool bDefaults); - - void SetNumStyleLink(const OUString& sValue) { m_sNumStyleLink = sValue; }; - const OUString& GetNumStyleLink() const { return m_sNumStyleLink; }; - - void SetStyleLink(const OUString& sValue) { m_sStyleLink = sValue; }; - const OUString& GetStyleLink() const { return m_sStyleLink; }; - - const OUString& MapListId(OUString const& rId); - bool isOutlineNumbering( sal_uInt16 nLvl ) { return GetLevel(nLvl) && GetLevel(nLvl)->isOutlineNumbering(); } -}; - -class ListDef : public AbstractListDef -{ -private: - // Pointer to the abstract numbering - AbstractListDef::Pointer m_pAbstractDef; - - // Cache for the UNO numbering rules - css::uno::Reference< css::container::XIndexReplace > m_xNumRules; - - /// mapped list style name - OUString m_StyleName; - - /// not custom outline parent levels - sal_Int16 m_nDefaultParentLevels; - -public: - typedef tools::SvRef< ListDef > Pointer; - - ListDef( ); - virtual ~ListDef( ) override; - - // Accessors - void SetAbstractDefinition( AbstractListDef::Pointer pAbstract ) { m_pAbstractDef = pAbstract; }; - const AbstractListDef::Pointer& GetAbstractDefinition( ) const { return m_pAbstractDef; }; - - // Mapping functions - const OUString & GetStyleName() const { return m_StyleName; }; - const OUString & GetStyleName(sal_Int32 nId, css::uno::Reference<css::container::XNameContainer> const& xStyles); - - sal_Int16 GetDefaultParentLevels() const { return m_nDefaultParentLevels; }; - - css::uno::Sequence< css::uno::Sequence<css::beans::PropertyValue> > GetMergedPropertyValues(); - - void CreateNumberingRules(DomainMapper& rDMapper, css::uno::Reference<css::lang::XMultiServiceFactory> const& xFactory); - - const css::uno::Reference<css::container::XIndexReplace>& GetNumberingRules() const { return m_xNumRules; } - -}; - -/** This class provides access to the defined numbering styles. - */ -class ListsManager : - public LoggedProperties, - public LoggedTable -{ -private: - - DomainMapper& m_rDMapper; - css::uno::Reference<css::lang::XMultiServiceFactory> m_xFactory; - - // The numbering entries - std::vector< NumPicBullet::Pointer > m_aNumPicBullets; - std::vector< AbstractListDef::Pointer > m_aAbstractLists; - std::vector< ListDef::Pointer > m_aLists; - - - // These members are used for import only - AbstractListDef::Pointer m_pCurrentDefinition; - NumPicBullet::Pointer m_pCurrentNumPicBullet; - - AbstractListDef::Pointer GetAbstractList( sal_Int32 nId ); - - // Properties - virtual void lcl_attribute( Id nName, Value & rVal ) override; - virtual void lcl_sprm(Sprm & sprm) override; - - // Table - virtual void lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) override; - -public: - - ListsManager(DomainMapper& rDMapper, const css::uno::Reference<css::lang::XMultiServiceFactory>& xFactory); - virtual ~ListsManager() override; - - typedef tools::SvRef< ListsManager > Pointer; - - ListDef::Pointer GetList( sal_Int32 nId ); - - // Mapping methods - void CreateNumberingRules( ); - - // Dispose the NumPicBullets - void DisposeNumPicBullets( ); -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/OLEHandler.cxx b/writerfilter/source/dmapper/OLEHandler.cxx deleted file mode 100644 index f7cc322d808a..000000000000 --- a/writerfilter/source/dmapper/OLEHandler.cxx +++ /dev/null @@ -1,331 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "OLEHandler.hxx" -#include "DomainMapper.hxx" -#include "GraphicHelpers.hxx" - -#include <oox/ole/oleobjecthelper.hxx> -#include <ooxml/resourceids.hxx> -#include <rtl/ustring.hxx> -#include <sal/log.hxx> -#include <osl/diagnose.h> -#include <tools/diagnose_ex.h> -#include <unotools/mediadescriptor.hxx> -#include <officecfg/Office/Common.hxx> -#include <com/sun/star/container/XNameAccess.hpp> -#include <com/sun/star/document/XEmbeddedObjectResolver.hpp> -#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp> -#include <com/sun/star/document/XFilter.hpp> -#include <com/sun/star/document/XImporter.hpp> -#include <com/sun/star/drawing/XShape.hpp> -#include <com/sun/star/graphic/XGraphic.hpp> -#include <com/sun/star/io/XOutputStream.hpp> -#include <com/sun/star/lang/XComponent.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/text/XTextDocument.hpp> -#include <com/sun/star/text/WrapTextMode.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; - - -OLEHandler::OLEHandler(DomainMapper& rDomainMapper) : -LoggedProperties("OLEHandler"), - m_nWrapMode(text::WrapTextMode_THROUGHT), - m_rDomainMapper(rDomainMapper) -{ -} - - -OLEHandler::~OLEHandler() -{ -} - - -void OLEHandler::lcl_attribute(Id rName, Value & rVal) -{ - OUString sStringValue = rVal.getString(); - switch( rName ) - { - case NS_ooxml::LN_CT_OLEObject_Type: - break; - case NS_ooxml::LN_CT_OLEObject_ProgID: - m_sProgId = sStringValue; - break; - case NS_ooxml::LN_CT_OLEObject_ShapeID: - break; - case NS_ooxml::LN_CT_OLEObject_DrawAspect: - m_sDrawAspect = sStringValue; - break; - case NS_ooxml::LN_CT_OLEObject_ObjectID: - break; - case NS_ooxml::LN_CT_OLEObject_r_id: - break; - case NS_ooxml::LN_inputstream: - rVal.getAny() >>= m_xInputStream; - break; - case NS_ooxml::LN_CT_Object_dxaOrig: - m_sVisAreaWidth = sStringValue; - break; - case NS_ooxml::LN_CT_Object_dyaOrig: - m_sVisAreaHeight = sStringValue; - break; - case NS_ooxml::LN_shape: - { - uno::Reference< drawing::XShape > xTempShape; - rVal.getAny() >>= xTempShape; - - // Control shape is handled on a different code path - uno::Reference< lang::XServiceInfo > xSInfo( xTempShape, uno::UNO_QUERY_THROW ); - if(xSInfo->supportsService("com.sun.star.drawing.ControlShape")) - { - m_rDomainMapper.hasControls(true); - break; - } - - if( xTempShape.is() ) - { - m_xShape.set( xTempShape ); - - // No need to set the wrapping here as it's either set in oox or will be set later - - // Shapes in the header or footer should be in the background, since the default is WrapTextMode_THROUGH. - if (m_rDomainMapper.IsInHeaderFooter()) - { - try - { - uno::Reference<beans::XPropertySet> xShapeProps(m_xShape, uno::UNO_QUERY); - xShapeProps->setPropertyValue("Opaque", uno::makeAny(false)); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION("writerfilter", "Exception in OLE Handler"); - } - } - } - } - break; - default: - OSL_FAIL( "unknown attribute"); - } -} - -css::awt::Size OLEHandler::getSize() const -{ - if (!m_xShape) - return css::awt::Size(); - return m_xShape->getSize(); -} - -css::uno::Reference<css::graphic::XGraphic> OLEHandler::getReplacement() const -{ - if (!m_xShape) - return nullptr; - uno::Reference<beans::XPropertySet> xShapeProps(m_xShape, uno::UNO_QUERY); - css::uno::Reference<css::graphic::XGraphic> xReplacement; - xShapeProps->getPropertyValue(getPropertyName(PROP_BITMAP)) >>= xReplacement; - return xReplacement; -} - -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 ) - { - pProperties->resolve(*this); - } - } - break; - case NS_ooxml::LN_wrap_wrap: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if ( pProperties ) - { - tools::SvRef<WrapHandler> pHandler( new WrapHandler ); - pProperties->resolve( *pHandler ); - - m_nWrapMode = pHandler->getWrapMode( ); - - try - { - uno::Reference< beans::XPropertySet > xShapeProps( m_xShape, uno::UNO_QUERY_THROW ); - - xShapeProps->setPropertyValue( - getPropertyName( PROP_SURROUND ), - uno::makeAny( static_cast<sal_Int32>(m_nWrapMode) ) ); - - // Through shapes in the header or footer(that spill into the body) should be in the background. - // It is just assumed that all shapes will spill into the body. - if( m_rDomainMapper.IsInHeaderFooter() ) - xShapeProps->setPropertyValue("Opaque", uno::makeAny(m_nWrapMode != text::WrapTextMode_THROUGH)); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION("writerfilter", "Exception in OLE Handler"); - } - } - } - break; - default: - { - OSL_FAIL( "unknown attribute"); - } - } -} - -void OLEHandler::importStream(const uno::Reference<uno::XComponentContext>& xComponentContext, const uno::Reference<text::XTextDocument>& xTextDocument, const uno::Reference<text::XTextContent>& xOLE) -{ - OUString aFilterService; - if (m_sProgId == "Word.Document.12") - aFilterService = "com.sun.star.comp.Writer.WriterFilter"; - else if (m_sProgId == "Excel.Sheet.12") - aFilterService = "com.sun.star.comp.oox.xls.ExcelFilter"; - else if (m_sProgId == "Equation.3") - aFilterService = "com.sun.star.comp.Math.MathTypeFilter"; - else - SAL_WARN("writerfilter", "OLEHandler::importStream: unhandled m_sProgId: " << m_sProgId); - - if (!m_xInputStream.is() || aFilterService.isEmpty()) - return; - - // Create the filter service. - uno::Reference<uno::XInterface> xInterface = xComponentContext->getServiceManager()->createInstanceWithContext(aFilterService, xComponentContext); - - // Set target document. - uno::Reference<document::XImporter> xImporter(xInterface, uno::UNO_QUERY); - uno::Reference<document::XEmbeddedObjectSupplier> xSupplier(xOLE, uno::UNO_QUERY); - uno::Reference<lang::XComponent> xEmbeddedObject = xSupplier->getEmbeddedObject(); - if (!xEmbeddedObject.is()) - return; - xImporter->setTargetDocument( xEmbeddedObject ); - - // Import the input stream. - utl::MediaDescriptor aMediaDescriptor; - aMediaDescriptor["InputStream"] <<= m_xInputStream; - uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY); - xFilter->filter(aMediaDescriptor.getAsConstPropertyValueList()); - - // Now that the data is imported, update the (typically) changed stream name. - uno::Reference<beans::XPropertySet> xPropertySet(xOLE, uno::UNO_QUERY); - ::oox::ole::SaveInteropProperties(xTextDocument, - xPropertySet->getPropertyValue("StreamName").get<OUString>(), &m_aURL, - m_sProgId); -} - -OUString OLEHandler::getCLSID(const uno::Reference<uno::XComponentContext>& xComponentContext) const -{ - OUString aRet; - - // See officecfg/registry/data/org/openoffice/Office/Embedding.xcu. - if (m_sProgId == "Word.Document.12") - { - if (officecfg::Office::Common::Filter::Microsoft::Import::WinWordToWriter::get(xComponentContext)) - aRet = "8BC6B165-B1B2-4EDD-aa47-dae2ee689dd6"; - } - else if (m_sProgId == "Excel.Sheet.12") - { - if (officecfg::Office::Common::Filter::Microsoft::Import::ExcelToCalc::get(xComponentContext)) - aRet = "47BBB4CB-CE4C-4E80-A591-42D9AE74950F"; - } - else if (m_sProgId == "Equation.3") - { - if (officecfg::Office::Common::Filter::Microsoft::Import::MathTypeToMath::get(xComponentContext)) - aRet = "078B7ABA-54FC-457F-8551-6147E776A997"; - } - else - SAL_WARN("writerfilter", "OLEHandler::getCLSID: unhandled m_sProgId: " << m_sProgId); - - return aRet; -} - -OUString const & OLEHandler::GetDrawAspect() const -{ - return m_sDrawAspect; -} - -OUString const & OLEHandler::GetVisAreaWidth() const -{ - return m_sVisAreaWidth; -} - -OUString const & OLEHandler::GetVisAreaHeight() const -{ - return m_sVisAreaHeight; -} - -OUString OLEHandler::copyOLEOStream( - uno::Reference<text::XTextDocument> const& xTextDocument) -{ - 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("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 ); - OUString aURL = "Obj" + OUString::number( 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; - } - } - - ::oox::ole::SaveInteropProperties(xTextDocument, aURL, nullptr, m_sProgId); - - OUString aPersistName( xEmbeddedResolver->resolveEmbeddedObjectURL( aURL ) ); - sRet = aPersistName.copy( strlen("vnd.sun.star.EmbeddedObject:") ); - - } - uno::Reference< lang::XComponent > xComp( xEmbeddedResolver, uno::UNO_QUERY_THROW ); - xComp->dispose(); - m_aURL = aURL; - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "OLEHandler::createOLEObject"); - } - return sRet; -} - -} //namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/OLEHandler.hxx b/writerfilter/source/dmapper/OLEHandler.hxx deleted file mode 100644 index eb04d4782c90..000000000000 --- a/writerfilter/source/dmapper/OLEHandler.hxx +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_OLEHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_OLEHANDLER_HXX - -#include "LoggedResources.hxx" -#include <com/sun/star/awt/Size.hpp> -#include <com/sun/star/drawing/XShape.hpp> -#include <com/sun/star/text/WrapTextMode.hpp> - -namespace com::sun::star{ - namespace graphic{ - class XGraphic; - } - namespace io{ - class XInputStream; - } - namespace text{ - class XTextContent; - class XTextDocument; - } - namespace uno { - class XComponentContext; - } -} -namespace writerfilter::dmapper -{ -class DomainMapper; -/** Handler for OLE objects - */ -class OLEHandler : public LoggedProperties -{ - OUString m_sProgId; - OUString m_sDrawAspect; - OUString m_sVisAreaWidth; - OUString m_sVisAreaHeight; - /// The stream URL right after the import of the raw data. - OUString m_aURL; - - css::text::WrapTextMode m_nWrapMode; - - css::uno::Reference<css::drawing::XShape> m_xShape; - - css::uno::Reference<css::io::XInputStream> m_xInputStream; - DomainMapper& m_rDomainMapper; - - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - -public: - explicit OLEHandler(DomainMapper& rDomainMapper); - virtual ~OLEHandler() override; - - const css::uno::Reference<css::drawing::XShape>& getShape() const { return m_xShape; }; - - bool isOLEObject() const { return m_xInputStream.is(); } - - /// In case of a valid CLSID, import the native data to the previously created empty OLE object. - void importStream(const css::uno::Reference<css::uno::XComponentContext>& xComponentContext, - const css::uno::Reference<css::text::XTextDocument>& xTextDocument, - const css::uno::Reference<css::text::XTextContent>& xOLE); - - /// Get the CLSID of the OLE object, in case we can find one based on m_sProgId. - OUString getCLSID(const css::uno::Reference<css::uno::XComponentContext>& xComponentContext) const; - - OUString const & GetDrawAspect() const; - OUString const & GetVisAreaWidth() const; - OUString const & GetVisAreaHeight() const; - - OUString copyOLEOStream(css::uno::Reference<css::text::XTextDocument> const& xTextDocument); - - css::awt::Size getSize() const; - css::uno::Reference<css::graphic::XGraphic> getReplacement() const; - -}; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PageBordersHandler.cxx b/writerfilter/source/dmapper/PageBordersHandler.cxx deleted file mode 100644 index 89548eb351ee..000000000000 --- a/writerfilter/source/dmapper/PageBordersHandler.cxx +++ /dev/null @@ -1,145 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "BorderHandler.hxx" -#include "PageBordersHandler.hxx" - -#include <ooxml/resourceids.hxx> - -namespace writerfilter::dmapper { - -PgBorder::PgBorder( ) : - m_nDistance( 0 ), - m_ePos( BORDER_RIGHT ), - m_bShadow(false) -{ -} - -PageBordersHandler::PageBordersHandler( ) : -LoggedProperties("PageBordersHandler"), -m_eBorderApply(SectionPropertyMap::BorderApply::ToAllInSection), -m_eOffsetFrom(SectionPropertyMap::BorderOffsetFrom::Text) -{ -} - -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_doc_ST_PageBorderDisplay_allPages: - m_eBorderApply = SectionPropertyMap::BorderApply::ToAllInSection; - break; - case NS_ooxml::LN_Value_doc_ST_PageBorderDisplay_firstPage: - m_eBorderApply = SectionPropertyMap::BorderApply::ToFirstPageInSection; - break; - case NS_ooxml::LN_Value_doc_ST_PageBorderDisplay_notFirstPage: - m_eBorderApply = SectionPropertyMap::BorderApply::ToAllButFirstInSection; - break; - } - } - break; - case NS_ooxml::LN_CT_PageBorders_offsetFrom: - { - switch ( nIntValue ) - { - default: - case NS_ooxml::LN_Value_doc_ST_PageBorderOffset_page: - m_eOffsetFrom = SectionPropertyMap::BorderOffsetFrom::Edge; - break; - case NS_ooxml::LN_Value_doc_ST_PageBorderOffset_text: - m_eOffsetFrom = SectionPropertyMap::BorderOffsetFrom::Text; - 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 ) - { - auto pBorderHandler = std::make_shared<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; - aPgBorder.m_bShadow = pBorderHandler->getShadow(); - if (pBorderHandler->getLineType() != NS_ooxml::LN_Value_ST_Border_none) - { - m_aBorders.push_back( aPgBorder ); - } - } - } - break; - default:; - } -} - -void PageBordersHandler::SetBorders( SectionPropertyMap* pSectContext ) -{ - for (const PgBorder& rBorder : m_aBorders) - { - pSectContext->SetBorder( rBorder.m_ePos, rBorder.m_nDistance, rBorder.m_rLine, rBorder.m_bShadow ); - } - pSectContext->SetBorderApply(m_eBorderApply); - pSectContext->SetBorderOffsetFrom(m_eOffsetFrom); -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PageBordersHandler.hxx b/writerfilter/source/dmapper/PageBordersHandler.hxx deleted file mode 100644 index 4b913c09af1d..000000000000 --- a/writerfilter/source/dmapper/PageBordersHandler.hxx +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PAGEBORDERSHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PAGEBORDERSHANDLER_HXX - -#include "PropertyMap.hxx" - -#include "LoggedResources.hxx" - -#include <com/sun/star/table/BorderLine2.hpp> - -#include <vector> - -namespace writerfilter::dmapper -{ -class PgBorder -{ -public: - css::table::BorderLine2 m_rLine; - sal_Int32 m_nDistance; - BorderPosition m_ePos; - bool m_bShadow; - - PgBorder(); -}; - -class PageBordersHandler : public LoggedProperties -{ -private: - // See implementation of SectionPropertyMap::ApplyBorderToPageStyles - SectionPropertyMap::BorderApply m_eBorderApply; - SectionPropertyMap::BorderOffsetFrom m_eOffsetFrom; - std::vector<PgBorder> m_aBorders; - - // Properties - virtual void lcl_attribute(Id eName, Value& rVal) override; - virtual void lcl_sprm(Sprm& rSprm) override; - -public: - PageBordersHandler(); - virtual ~PageBordersHandler() override; - - void SetBorders(SectionPropertyMap* pSectContext); -}; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx deleted file mode 100644 index 5450c0c0dfc6..000000000000 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ /dev/null @@ -1,380 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include <rtl/ustring.hxx> -#include "PropertyIds.hxx" - -namespace writerfilter::dmapper{ - -OUString getPropertyName( PropertyIds eId ) -{ - OUString sName; - switch(eId) { - case PROP_CHAR_WEIGHT: sName = "CharWeight"; break; - case PROP_CHAR_POSTURE: sName = "CharPosture"; break; - case PROP_CHAR_STRIKEOUT: sName = "CharStrikeout"; break; - case PROP_CHAR_CONTOURED: sName = "CharContoured"; break; - case PROP_CHAR_SHADOWED: sName = "CharShadowed"; break; - case PROP_CHAR_CASE_MAP: sName = "CharCaseMap"; break; - case PROP_CHAR_COLOR: sName = "CharColor"; break; - case PROP_CHAR_RELIEF: sName = "CharRelief"; break; - case PROP_CHAR_UNDERLINE: sName = "CharUnderline"; break; - case PROP_CHAR_UNDERLINE_COLOR: sName = "CharUnderlineColor"; break; - case PROP_CHAR_UNDERLINE_HAS_COLOR: sName = "CharUnderlineHasColor"; break; - case PROP_CHAR_WORD_MODE: sName = "CharWordMode"; break; - case PROP_CHAR_ESCAPEMENT : sName = "CharEscapement"; break; - case PROP_CHAR_ESCAPEMENT_HEIGHT: sName = "CharEscapementHeight"; break; - case PROP_CHAR_HEIGHT: sName = "CharHeight"; break; - case PROP_CHAR_HEIGHT_COMPLEX: sName = "CharHeightComplex"; break; - case PROP_CHAR_LOCALE: sName = "CharLocale"; break; - case PROP_CHAR_LOCALE_ASIAN: sName = "CharLocaleAsian"; break; - case PROP_CHAR_LOCALE_COMPLEX: sName = "CharLocaleComplex"; break; - case PROP_CHAR_WEIGHT_COMPLEX : sName = "CharWeightComplex"; break; - case PROP_CHAR_POSTURE_COMPLEX: sName = "CharPostureComplex"; break; - case PROP_CHAR_CHAR_KERNING: sName = "CharKerning"; break; - case PROP_CHAR_AUTO_KERNING: sName = "CharAutoKerning"; break; - case PROP_CHAR_SCALE_WIDTH: sName = "CharScaleWidth"; break; - case PROP_CHAR_STYLE_NAME: sName = "CharStyleName"; break; - case PROP_CHAR_FONT_NAME: sName = "CharFontName"; break; - case PROP_CHAR_FONT_CHAR_SET: sName = "CharFontCharSet"; break; - case PROP_CHAR_FONT_NAME_ASIAN : sName = "CharFontNameAsian"; break; - case PROP_CHAR_HEIGHT_ASIAN : sName = "CharHeightAsian"; break; - case PROP_CHAR_FONT_NAME_COMPLEX : sName = "CharFontNameComplex"; break; - case PROP_CHAR_HIDDEN : sName = "CharHidden"; break; - case PROP_CHAR_WEIGHT_ASIAN : sName = "CharWeightAsian"; break; - case PROP_CHAR_POSTURE_ASIAN : sName = "CharPostureAsian"; break; - case PROP_CHAR_BACK_COLOR: sName = "CharBackColor"; break; - case PROP_CHAR_EMPHASIS: sName = "CharEmphasis"; break; - case PROP_CHAR_COMBINE_IS_ON: sName = "CharCombineIsOn"; break; - case PROP_CHAR_COMBINE_PREFIX: sName = "CharCombinePrefix"; break; - case PROP_CHAR_COMBINE_SUFFIX: sName = "CharCombineSuffix"; break; - case PROP_CHAR_ROTATION: sName = "CharRotation"; break; - case PROP_CHAR_ROTATION_IS_FIT_TO_LINE: sName = "CharRotationIsFitToLine"; break; - case PROP_CHAR_FLASH: sName = "CharFlash"; break; - case PROP_CHAR_LEFT_BORDER: sName = "CharLeftBorder";break; - case PROP_CHAR_RIGHT_BORDER: sName = "CharRightBorder";break; - case PROP_CHAR_TOP_BORDER: sName = "CharTopBorder";break; - case PROP_CHAR_BOTTOM_BORDER: sName = "CharBottomBorder";break; - case PROP_CHAR_LEFT_BORDER_DISTANCE: sName = "CharLeftBorderDistance"; break; - case PROP_CHAR_RIGHT_BORDER_DISTANCE: sName = "CharRightBorderDistance"; break; - case PROP_CHAR_TOP_BORDER_DISTANCE: sName = "CharTopBorderDistance";break; - case PROP_CHAR_BOTTOM_BORDER_DISTANCE: sName = "CharBottomBorderDistance"; break; - case PROP_CHAR_SHADOW_FORMAT: sName = "CharShadowFormat"; break; - case PROP_CHAR_HIGHLIGHT: sName = "CharHighlight"; break; - case PROP_PARA_STYLE_NAME: sName = "ParaStyleName"; break; - case PROP_PARA_ADJUST: sName = "ParaAdjust"; break; - case PROP_PARA_VERT_ALIGNMENT: sName = "ParaVertAlignment"; break; - case PROP_PARA_LAST_LINE_ADJUST: sName = "ParaLastLineAdjust"; break; - case PROP_PARA_RIGHT_MARGIN : sName = "ParaRightMargin"; break; - case PROP_PARA_LEFT_MARGIN : sName = "ParaLeftMargin"; break; - case PROP_PARA_FIRST_LINE_INDENT: sName = "ParaFirstLineIndent"; break; - case PROP_PARA_KEEP_TOGETHER: sName = "ParaKeepTogether"; break; - case PROP_PARA_TOP_MARGIN: sName = "ParaTopMargin"; break; - case PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING: sName = "ParaTopMarginBeforeAutoSpacing"; break; - case PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING: sName = "ParaBottomMarginAfterAutoSpacing"; break; - case PROP_PARA_CONTEXT_MARGIN: sName = "ParaContextMargin"; break; - case PROP_PARA_BOTTOM_MARGIN: sName = "ParaBottomMargin"; break; - case PROP_PARA_IS_HYPHENATION: sName = "ParaIsHyphenation"; break; - case PROP_PARA_HYPHENATION_NO_CAPS: sName = "ParaHyphenationNoCaps"; break; - case PROP_PARA_LINE_NUMBER_COUNT: sName = "ParaLineNumberCount"; break; - case PROP_PARA_IS_HANGING_PUNCTUATION: sName = "ParaIsHangingPunctuation"; break; - case PROP_PARA_LINE_SPACING: sName = "ParaLineSpacing"; break; - case PROP_PARA_TAB_STOPS: sName = "ParaTabStops"; break; - case PROP_PARA_WIDOWS: sName = "ParaWidows"; break; - case PROP_PARA_ORPHANS: sName = "ParaOrphans"; break; - case PROP_PARA_LINE_NUMBER_START_VALUE: sName = "ParaLineNumberStartValue"; break; - case PROP_NUMBERING_LEVEL: sName = "NumberingLevel"; break; - case PROP_NUMBERING_RULES: sName = "NumberingRules"; break; - case PROP_NUMBERING_TYPE: sName = "NumberingType"; break; - case PROP_START_WITH: sName = "StartWith"; break; - case PROP_ADJUST: sName = "Adjust"; break; - case PROP_PARENT_NUMBERING: sName = "ParentNumbering"; break; - case PROP_RIGHT_MARGIN : sName = "RightMargin"; break; - case PROP_LEFT_MARGIN : sName = "LeftMargin"; break; - case PROP_TOP_MARGIN : sName = "TopMargin"; break; - case PROP_BOTTOM_MARGIN : sName = "BottomMargin"; break; - case PROP_FIRST_LINE_OFFSET: sName = "FirstLineOffset"; break; - case PROP_LEFT_BORDER : sName = "LeftBorder";break; - case PROP_RIGHT_BORDER : sName = "RightBorder";break; - case PROP_TOP_BORDER : sName = "TopBorder";break; - case PROP_BOTTOM_BORDER : sName = "BottomBorder";break; - case PROP_TABLE_BORDER : sName = "TableBorder";break; - case PROP_TABLE_ROW_DELETE : sName = "TableRowDelete"; break; - case PROP_TABLE_ROW_INSERT : sName = "TableRowInsert"; break; - case PROP_TABLE_CELL_DELETE : sName = "TableCellDelete"; break; - case PROP_TABLE_CELL_INSERT : sName = "TableCellInsert"; break; - case PROP_LEFT_BORDER_DISTANCE : sName = "LeftBorderDistance"; break; - case PROP_RIGHT_BORDER_DISTANCE : sName = "RightBorderDistance"; break; - case PROP_TOP_BORDER_DISTANCE : sName = "TopBorderDistance";break; - case PROP_BOTTOM_BORDER_DISTANCE: sName = "BottomBorderDistance"; break; - case PROP_CURRENT_PRESENTATION : sName = "CurrentPresentation"; break; - case PROP_IS_FIXED : sName = "IsFixed"; break; - case PROP_SUB_TYPE : sName = "SubType"; break; - case PROP_FILE_FORMAT : sName = "FileFormat"; break; - case PROP_HYPER_LINK_U_R_L : sName = "HyperLinkURL"; break; - case PROP_NUMBER_FORMAT : sName = "NumberFormat"; break; - case PROP_NAME : sName = "Name"; break; - case PROP_IS_INPUT : sName = "IsInput"; break; - case PROP_HINT : sName = "Hint"; break; - case PROP_FULL_NAME : sName = "FullName"; break; - case PROP_DESCRIPTION : sName = "Description"; break; - case PROP_MACRO_NAME : sName = "MacroName"; break; - case PROP_TITLE : sName = "Title"; break; - case PROP_CONTENT : sName = "Content"; break; - case PROP_INPUT_STREAM : sName = "InputStream"; break; - case PROP_GRAPHIC : sName = "Graphic"; break; - case PROP_ANCHOR_TYPE : sName = "AnchorType"; break; - case PROP_SIZE : sName = "Size"; break; - case PROP_HORI_ORIENT : sName = "HoriOrient"; break; - case PROP_HORI_ORIENT_POSITION : sName = "HoriOrientPosition"; break; - case PROP_HORI_ORIENT_RELATION : sName = "HoriOrientRelation"; break; - case PROP_VERT_ORIENT : sName = "VertOrient"; break; - case PROP_VERT_ORIENT_POSITION : sName = "VertOrientPosition"; break; - case PROP_VERT_ORIENT_RELATION : sName = "VertOrientRelation"; break; - case PROP_SIZE100th_M_M : sName = "Size100thMM"; break; - case PROP_SIZE_PIXEL : sName = "SizePixel"; break; - case PROP_SURROUND : sName = "Surround"; break; - case PROP_SURROUND_CONTOUR : sName = "SurroundContour"; break; - case PROP_ADJUST_CONTRAST : sName = "AdjustContrast"; break; - case PROP_ADJUST_LUMINANCE : sName = "AdjustLuminance"; break; - case PROP_GRAPHIC_COLOR_MODE : sName = "GraphicColorMode"; break; - case PROP_CONTOUR_OUTSIDE : sName = "ContourOutside"; break; - case PROP_CONTOUR_POLY_POLYGON : sName = "ContourPolyPolygon"; break; - case PROP_PAGE_TOGGLE : sName = "PageToggle"; break; - case PROP_BACK_COLOR : sName = "BackColor"; break; - case PROP_BACK_COLOR_TRANSPARENCY: sName = "BackColorTransparency"; break; - case PROP_ALTERNATIVE_TEXT : sName = "AlternativeText"; break; - case PROP_HEADER_TEXT_LEFT : sName = "HeaderTextLeft"; break; - case PROP_HEADER_TEXT : sName = "HeaderText"; break; - case PROP_HEADER_IS_SHARED : sName = "HeaderIsShared"; break; - case PROP_HEADER_IS_ON : sName = "HeaderIsOn"; break; - case PROP_FOOTER_TEXT_LEFT : sName = "FooterTextLeft"; break; - case PROP_FOOTER_TEXT : sName = "FooterText"; break; - case PROP_FOOTER_IS_SHARED : sName = "FooterIsShared"; break; - case PROP_FOOTER_IS_ON : sName = "FooterIsOn"; break; - case PROP_FOOTNOTE_COUNTING : sName = "FootnoteCounting"; break; - case PROP_FOOTNOTE_LINE_ADJUST : sName = "FootnoteLineAdjust"; break; - case PROP_WIDTH : sName = "Width"; break; - case PROP_HEIGHT : sName = "Height"; break; - case PROP_TEXT_COLUMNS : sName = "TextColumns"; break; - case PROP_AUTOMATIC_DISTANCE : sName = "AutomaticDistance"; break; - case PROP_IS_LANDSCAPE : sName = "IsLandscape"; break; - case PROP_FIRST_PAGE : sName = "First Page"; break; - case PROP_PAGE_DESC_NAME : sName = "PageDescName"; break; - case PROP_PAGE_NUMBER_OFFSET: sName = "PageNumberOffset"; break; - case PROP_BREAK_TYPE : sName = "BreakType"; break; - case PROP_FOOTER_IS_DYNAMIC_HEIGHT: sName = "FooterIsDynamicHeight"; break; - case PROP_FOOTER_DYNAMIC_SPACING: sName = "FooterDynamicSpacing"; break; - case PROP_FOOTER_HEIGHT : sName = "FooterHeight"; break; - case PROP_FOOTER_BODY_DISTANCE : sName = "FooterBodyDistance"; break; - case PROP_HEADER_IS_DYNAMIC_HEIGHT: sName = "HeaderIsDynamicHeight"; break; - case PROP_HEADER_DYNAMIC_SPACING: sName = "HeaderDynamicSpacing"; break; - case PROP_HEADER_HEIGHT : sName = "HeaderHeight"; break; - case PROP_HEADER_BODY_DISTANCE : sName = "HeaderBodyDistance"; break; - case PROP_WRITING_MODE : sName = "WritingMode"; break; - case PROP_GRID_MODE : sName = "GridMode"; break; - case PROP_GRID_DISPLAY : sName = "GridDisplay"; break; - case PROP_GRID_PRINT : sName = "GridPrint"; break; - case PROP_GRID_LINES : sName = "GridLines"; break; - case PROP_GRID_BASE_HEIGHT : sName = "GridBaseHeight"; break; - case PROP_GRID_BASE_WIDTH : sName = "GridBaseWidth"; break; - case PROP_GRID_RUBY_HEIGHT : sName = "GridRubyHeight"; break; - case PROP_GRID_STANDARD_MODE : sName = "StandardPageMode"; break; - case PROP_IS_ON : sName = "IsOn"; break; - case PROP_RESTART_AT_EACH_PAGE : sName = "RestartAtEachPage"; break; - case PROP_COUNT_EMPTY_LINES : sName = "CountEmptyLines"; break; - case PROP_COUNT_LINES_IN_FRAMES : sName = "CountLinesInFrames"; break; - case PROP_INTERVAL : sName = "Interval"; break; - case PROP_DISTANCE : sName = "Distance"; break; - case PROP_NUMBER_POSITION : sName = "NumberPosition"; break; - case PROP_LEVEL : sName = "Level"; break; - case PROP_LEVEL_FOLLOW : sName = "LabelFollowedBy"; break; - case PROP_LEVEL_PARAGRAPH_STYLES : sName = "LevelParagraphStyles"; break; - case PROP_LEVEL_FORMAT : sName = "LevelFormat"; break; - case PROP_LIST_FORMAT : sName = "ListFormat"; break; - case PROP_TOKEN_TYPE : sName = "TokenType"; break; - case PROP_TOKEN_HYPERLINK_START : sName = "TokenHyperlinkStart"; break; - case PROP_TOKEN_HYPERLINK_END : sName = "TokenHyperlinkEnd"; break; - case PROP_TOKEN_CHAPTER_INFO : sName = "TokenChapterInfo"; break; - case PROP_CHAPTER_FORMAT : sName = "ChapterFormat"; break; - case PROP_TOKEN_TEXT : sName = "TokenText"; break; - case PROP_TEXT : sName = "Text"; break; - case PROP_CREATE_FROM_OUTLINE : sName = "CreateFromOutline"; break; - case PROP_CREATE_FROM_MARKS : sName = "CreateFromMarks"; break; - case PROP_STANDARD : sName = "Standard"; break; - case PROP_SPLIT : sName = "Split"; break; - case PROP_IS_SPLIT_ALLOWED : sName = "IsSplitAllowed"; break; - case META_PROP_VERTICAL_BORDER : sName = "VerticalBorder"; break; - case META_PROP_HORIZONTAL_BORDER : sName = "HorizontalBorder"; break; - case PROP_HEADER_ROW_COUNT : sName = "HeaderRowCount"; break; - case PROP_SIZE_TYPE : sName = "SizeType"; break; - case PROP_TABLE_COLUMN_SEPARATORS: sName = "TableColumnSeparators"; break; - case META_PROP_TABLE_STYLE_NAME : sName = "TableStyleName"; break; - case PROP_TABLE_REDLINE_PARAMS : sName = "TableRedlineParams"; break; - case PROP_REDLINE_AUTHOR : sName = "RedlineAuthor"; break; - case PROP_REDLINE_DATE_TIME : sName = "RedlineDateTime"; break; - case PROP_REDLINE_TYPE : sName = "RedlineType"; break; - case PROP_REDLINE_REVERT_PROPERTIES: sName = "RedlineRevertProperties"; break; - case PROP_IS_PROTECTED : sName = "IsProtected"; break; - case PROP_SIZE_PROTECTED : sName = "SizeProtected"; break; - case PROP_POSITION_PROTECTED : sName = "PositionProtected"; break; - case PROP_OPAQUE : sName = "Opaque"; break; - case PROP_VERTICAL_MERGE : sName = "VerticalMerge"; break; - case PROP_BULLET_CHAR : sName = "BulletChar"; break; - case PROP_BULLET_FONT_NAME : sName = "BulletFontName"; break; - case PROP_TABS_RELATIVE_TO_INDENT: sName = "TabsRelativeToIndent"; break; - case PROP_PREFIX : sName = "Prefix"; break; - case PROP_SUFFIX : sName = "Suffix"; break; - case PROP_CREATE_FROM_LEVEL_PARAGRAPH_STYLES: sName = "CreateFromLevelParagraphStyles"; break; - case PROP_DROP_CAP_FORMAT : sName = "DropCapFormat"; break; - case PROP_REFERENCE_FIELD_PART : sName = "ReferenceFieldPart"; break; - case PROP_SOURCE_NAME: sName = "SourceName"; break; - case PROP_REFERENCE_FIELD_SOURCE : sName = "ReferenceFieldSource"; break; - case PROP_WIDTH_TYPE : sName = "WidthType"; break; - case PROP_TBL_LOOK : sName = "TblLook"; break; - case PROP_TEXT_RANGE: sName = "TextRange"; break; - case PROP_TEXT_VERTICAL_ADJUST : sName = "TextVerticalAdjust"; break; - case PROP_SERVICE_CHAR_STYLE : sName = "com.sun.star.style.CharacterStyle"; break; - case PROP_SERVICE_PARA_STYLE : sName = "com.sun.star.style.ParagraphStyle"; break; - case PROP_CHARACTER_STYLES : sName = "CharacterStyles"; break; - case PROP_PARAGRAPH_STYLES : sName = "ParagraphStyles"; break; - case PROP_TABLE_BORDER_DISTANCES: sName = "TableBorderDistances"; break; - case META_PROP_CELL_MAR_TOP : sName = "MetaPropCellMarTop"; break; - case META_PROP_CELL_MAR_BOTTOM : sName = "MetaPropCellMarBottom"; break; - case META_PROP_CELL_MAR_LEFT : sName = "MetaPropCellMarLeft"; break; - case META_PROP_CELL_MAR_RIGHT : sName = "MetaPropCellMarRight"; break; - case PROP_START_AT : sName = "StartAt"; break; - case PROP_CHAR_PROP_HEIGHT : sName = "CharPropHeight"; break; - case PROP_CHAR_PROP_HEIGHT_ASIAN : sName = "CharPropHeightAsian"; break; - case PROP_CHAR_PROP_HEIGHT_COMPLEX: sName = "CharPropHeightComplex"; break; - case PROP_FORMAT : sName = "Format"; break; - case PROP_INSERT : sName = "Insert"; break; - case PROP_DELETE : sName = "Delete"; break; - case PROP_PARAGRAPH_FORMAT : sName = "ParagraphFormat"; break; - case PROP_STREAM_NAME: sName = "StreamName"; break; - case PROP_BITMAP : sName = "Bitmap"; break; - case PROP_IS_DATE : sName = "IsDate"; break; - case PROP_TAB_STOP_DISTANCE : sName = "TabStopDistance"; break; - case PROP_INDENT_AT : sName = "IndentAt"; break; - case PROP_FIRST_LINE_INDENT : sName = "FirstLineIndent"; break; - case PROP_NUMBERING_STYLE_NAME : sName = "NumberingStyleName"; break; - case PROP_OUTLINE_LEVEL : sName = "OutlineLevel"; break; - case PROP_LISTTAB_STOP_POSITION : sName = "ListtabStopPosition"; break; - case PROP_POSITION_AND_SPACE_MODE : sName = "PositionAndSpaceMode"; break; - case PROP_PARA_SPLIT: sName = "ParaSplit"; break; - case PROP_HELP: sName = "Help"; break; - case PROP_HEADING_STYLE_NAME: sName = "HeadingStyleName"; break; - case PROP_FRM_DIRECTION: sName = "FRMDirection"; break; - case PROP_EMBEDDED_OBJECT : sName = "EmbeddedObject"; break; - case PROP_IS_VISIBLE: sName = "IsVisible"; break; - case PROP_PAGE_STYLE_LAYOUT: sName = "PageStyleLayout"; break; - case PROP_Z_ORDER: sName = "ZOrder"; break; - case PROP_EMBED_FONTS: sName = "EmbedFonts"; break; - case PROP_EMBED_SYSTEM_FONTS: sName = "EmbedSystemFonts"; break; - case PROP_SHADOW_FORMAT: sName = "ShadowFormat"; break; - case PROP_RELATIVE_WIDTH: sName = "RelativeWidth"; break; - case PROP_IS_WIDTH_RELATIVE: sName = "IsWidthRelative"; break; - case PROP_GRAPHIC_BITMAP: sName = "GraphicBitmap"; break; - case PROP_GRAPHIC_SIZE: sName = "GraphicSize"; break; - case PROP_CHAR_SHADING_VALUE: sName = "CharShadingValue"; break; - case PROP_CHAR_SHADING_MARKER: sName = "CharShadingMarker"; break; - case PROP_LABEL_CATEGORY: sName = "LabelCategory"; break; - case PROP_MIRROR_INDENTS : sName = "MirrorIndents"; break; - case PROP_SURROUND_TEXT_WRAP_SMALL: sName = "SurroundTextWrapSmall"; break; - case PROP_PARA_SHADOW_FORMAT: sName = "ParaShadowFormat"; break; - case PROP_FOOTNOTE_LINE_RELATIVE_WIDTH: sName = "FootnoteLineRelativeWidth"; break; - case PROP_TBL_HEADER: sName = "TblHeader"; break; - case PROP_CHAR_THEME_NAME_ASCII : sName = "CharThemeNameAscii"; break; - case PROP_CHAR_THEME_NAME_CS : sName = "CharThemeNameCs"; break; - case PROP_CHAR_THEME_NAME_H_ANSI : sName = "CharThemeNameHAnsi"; break; - case PROP_CHAR_THEME_NAME_EAST_ASIA : sName = "CharThemeNameEastAsia"; break; - case PROP_CHAR_THEME_FONT_NAME_ASCII : sName = "CharThemeFontNameAscii"; break; - case PROP_CHAR_THEME_FONT_NAME_CS : sName = "CharThemeFontNameCs"; break; - case PROP_CHAR_THEME_FONT_NAME_EAST_ASIA: sName = "CharThemeFontNameEastAsia"; break; - case PROP_CHAR_THEME_COLOR : sName = "CharThemeColor"; break; - case PROP_CHAR_THEME_ORIGINAL_COLOR : sName = "CharThemeOriginalColor"; break; - case PROP_CHAR_THEME_COLOR_SHADE : sName = "CharThemeColorShade"; break; - case PROP_CHAR_THEME_FILL : sName = "CharThemeFill"; break; - case PROP_HORIZONTAL_MERGE: sName = "HorizontalMerge"; break; - case PROP_HIDE_TAB_LEADER_AND_PAGE_NUMBERS : sName = "HideTabLeaderAndPageNumber" ; break ; - case PROP_TAB_IN_TOC : sName = "TabInTOC"; break ; - case PROP_TOC_BOOKMARK: sName = "TOCBookmark"; break; - case PROP_TOC_NEW_LINE: sName = "TOCNewLine"; break; - case PROP_TOC_PARAGRAPH_OUTLINE_LEVEL : sName = "TOCParagraphOutlineLevel"; break; - case PROP_CHAR_THEME_COLOR_TINT : sName = "CharThemeColorTint"; break; - case PROP_CHAR_GLOW_TEXT_EFFECT : sName = "CharGlowTextEffect"; break; - case PROP_CHAR_SHADOW_TEXT_EFFECT : sName = "CharShadowTextEffect"; break; - case PROP_CHAR_REFLECTION_TEXT_EFFECT : sName = "CharReflectionTextEffect"; break; - case PROP_CHAR_TEXTOUTLINE_TEXT_EFFECT : sName = "CharTextOutlineTextEffect"; break; - case PROP_CHAR_TEXTFILL_TEXT_EFFECT : sName = "CharTextFillTextEffect"; break; - case PROP_CHAR_SCENE3D_TEXT_EFFECT : sName = "CharScene3DTextEffect"; break; - case PROP_CHAR_PROPS3D_TEXT_EFFECT : sName = "CharProps3DTextEffect"; break; - case PROP_CHAR_LIGATURES_TEXT_EFFECT : sName = "CharLigaturesTextEffect"; break; - case PROP_CHAR_NUMFORM_TEXT_EFFECT : sName = "CharNumFormTextEffect"; break; - case PROP_CHAR_NUMSPACING_TEXT_EFFECT : sName = "CharNumSpacingTextEffect"; break; - case PROP_CHAR_STYLISTICSETS_TEXT_EFFECT : sName = "CharStylisticSetsTextEffect"; break; - case PROP_CHAR_CNTXTALTS_TEXT_EFFECT : sName = "CharCntxtAltsTextEffect"; break; - case PROP_SDTPR : sName = "SdtPr"; break; - case PROP_INDEX_ENTRY_TYPE : sName = "IndexEntryType"; break; - case PROP_CELL_INTEROP_GRAB_BAG : sName = "CellInteropGrabBag"; break; - case PROP_TABLE_INTEROP_GRAB_BAG : sName = "TableInteropGrabBag"; break; - case PROP_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING : sName = "ApplyParagraphMarkFormatToNumbering"; break; - case PROP_SDT_END_BEFORE: sName = "SdtEndBefore"; break; - case PROP_PARA_SDT_END_BEFORE: sName = "ParaSdtEndBefore"; break; - case META_PROP_TABLE_LOOK: sName = "TableStyleLook"; break; - case PROP_PARA_CNF_STYLE: sName = "ParaCnfStyle"; break; - case PROP_CELL_CNF_STYLE: sName = "CellCnfStyle"; break; - case PROP_ROW_CNF_STYLE: sName = "RowCnfStyle"; break; - case PROP_CELL_HIDE_MARK: sName = "CellHideMark"; break; - case PROP_FOLLOW_TEXT_FLOW: sName = "IsFollowingTextFlow"; break; - case PROP_FILL_STYLE: sName = "FillStyle"; break; - case PROP_FILL_COLOR: sName = "FillColor"; break; - case PROP_SNAP_TO_GRID: sName = "SnapToGrid"; break; - case PROP_GRID_SNAP_TO_CHARS: sName = "GridSnapToChars"; break; - case PROP_RUBY_STYLE: sName = "RubyCharStyleName"; break; - case PROP_RUBY_TEXT: sName = "RubyText"; break; - case PROP_RUBY_ADJUST: sName = "RubyAdjust"; break; - case PROP_RUBY_POSITION: sName = "RubyPosition"; break; - case PROP_DATABASE_NAME: sName = "DataBaseName"; break; - case PROP_COMMAND_TYPE: sName = "DataCommandType"; break; - case PROP_DATATABLE_NAME: sName = "DataTableName"; break; - case PROP_DATACOLUMN_NAME: sName = "DataColumnName"; break; - case PROP_CHAR_TRANSPARENCE: sName = "CharTransparence"; break; - case PROP_CELL_FORMULA: sName = "CellFormula"; break; - case PROP_CELL_FORMULA_CONVERTED: sName = "CellFormulaConverted"; break; - case PROP_GUTTER_MARGIN: - sName = "GutterMargin"; - break; - } - assert(sName.getLength()>0); - return sName; -} - -bool isCharacterProperty( const PropertyIds eId ) -{ - return eId > PROP_CHARACTER_STYLES && eId < PROP_CHARACTER_END; -} - -bool isParagraphProperty( const PropertyIds eId ) -{ - return (eId >= PROP_PARA_ADJUST && eId <= PROP_PARA_WIDOWS) || eId == PROP_FILL_COLOR; -} - -} //namespace writerfilter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx deleted file mode 100644 index 766748116a70..000000000000 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ /dev/null @@ -1,375 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PROPERTYIDS_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PROPERTYIDS_HXX - -#include <rtl/ustring.hxx> - -namespace writerfilter::dmapper{ -// Ensure that Character Properties are placed between PROP_CHARACTER_STYLES and PROP_CHARACTER_END -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_ADJUST - ,PROP_ADJUST_CONTRAST - ,PROP_ADJUST_LUMINANCE - ,PROP_ALTERNATIVE_TEXT - ,PROP_ANCHOR_TYPE - ,PROP_AUTOMATIC_DISTANCE - ,PROP_BACK_COLOR - ,PROP_BACK_COLOR_TRANSPARENCY - ,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_LEFT_BORDER - ,PROP_CHAR_RIGHT_BORDER - ,PROP_CHAR_TOP_BORDER - ,PROP_CHAR_BOTTOM_BORDER - ,PROP_CHAR_LEFT_BORDER_DISTANCE - ,PROP_CHAR_RIGHT_BORDER_DISTANCE - ,PROP_CHAR_TOP_BORDER_DISTANCE - ,PROP_CHAR_BOTTOM_BORDER_DISTANCE - ,PROP_CHAR_EMPHASIS - ,PROP_CHAR_ESCAPEMENT - ,PROP_CHAR_ESCAPEMENT_HEIGHT - ,PROP_CHAR_FLASH - ,PROP_CHAR_FONT_CHAR_SET - ,PROP_CHAR_FONT_NAME - ,PROP_CHAR_FONT_NAME_ASIAN - ,PROP_CHAR_FONT_NAME_COMPLEX - ,PROP_CHAR_HEIGHT - ,PROP_CHAR_HEIGHT_ASIAN - ,PROP_CHAR_HEIGHT_COMPLEX - ,PROP_CHAR_HIDDEN - ,PROP_CHAR_HIGHLIGHT - ,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_SHADOW_FORMAT - ,PROP_CHAR_SHADING_MARKER - ,PROP_CHAR_SHADING_VALUE - ,PROP_CHAR_SHADOWED - ,PROP_CHAR_STRIKEOUT - ,PROP_CHAR_STYLE_NAME - ,PROP_CHAR_TEXTOUTLINE_TEXT_EFFECT - ,PROP_CHAR_TEXTFILL_TEXT_EFFECT - ,PROP_CHAR_THEME_NAME_ASCII - ,PROP_CHAR_THEME_NAME_CS - ,PROP_CHAR_THEME_NAME_H_ANSI - ,PROP_CHAR_THEME_NAME_EAST_ASIA - ,PROP_CHAR_THEME_FONT_NAME_ASCII - ,PROP_CHAR_THEME_FONT_NAME_CS - ,PROP_CHAR_THEME_FONT_NAME_EAST_ASIA - ,PROP_CHAR_THEME_COLOR - ,PROP_CHAR_THEME_ORIGINAL_COLOR - ,PROP_CHAR_THEME_COLOR_SHADE - ,PROP_CHAR_THEME_FILL - ,PROP_CHAR_THEME_COLOR_TINT - ,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_CHAR_GLOW_TEXT_EFFECT - ,PROP_CHAR_SHADOW_TEXT_EFFECT - ,PROP_CHAR_REFLECTION_TEXT_EFFECT - ,PROP_CHAR_SCENE3D_TEXT_EFFECT - ,PROP_CHAR_PROPS3D_TEXT_EFFECT - ,PROP_CHAR_LIGATURES_TEXT_EFFECT - ,PROP_CHAR_NUMFORM_TEXT_EFFECT - ,PROP_CHAR_NUMSPACING_TEXT_EFFECT - ,PROP_CHAR_STYLISTICSETS_TEXT_EFFECT - ,PROP_CHAR_CNTXTALTS_TEXT_EFFECT - ,PROP_CHARACTER_END - ,PROP_CONTENT = PROP_CHARACTER_END - ,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_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_FOOTNOTE_COUNTING - ,PROP_FOOTNOTE_LINE_ADJUST - ,PROP_FORMAT - ,PROP_FULL_NAME - ,PROP_GRAPHIC - ,PROP_GRAPHIC_COLOR_MODE - ,PROP_GRID_BASE_HEIGHT - ,PROP_GRID_BASE_WIDTH - ,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_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_DATE - ,PROP_IS_FIXED - ,PROP_IS_INPUT - ,PROP_IS_LANDSCAPE - ,PROP_IS_ON - ,PROP_IS_SPLIT_ALLOWED - ,PROP_IS_VISIBLE - ,PROP_LABEL_CATEGORY - ,PROP_LEFT_BORDER - ,PROP_LEFT_BORDER_DISTANCE - ,PROP_LEFT_MARGIN - ,PROP_LEVEL - ,PROP_LEVEL_FOLLOW - ,PROP_LEVEL_FORMAT - ,PROP_LEVEL_PARAGRAPH_STYLES - ,PROP_LISTTAB_STOP_POSITION - ,PROP_LIST_FORMAT - ,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_FORMAT - ,PROP_PARAGRAPH_STYLES - ,PROP_PARA_ADJUST - ,PROP_PARA_BOTTOM_MARGIN - ,PROP_PARA_FIRST_LINE_INDENT - ,PROP_PARA_IS_HANGING_PUNCTUATION - ,PROP_PARA_IS_HYPHENATION - ,PROP_PARA_HYPHENATION_NO_CAPS - ,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_VERT_ALIGNMENT - ,PROP_PARA_WIDOWS - ,PROP_PARENT_NUMBERING - ,PROP_POSITION_AND_SPACE_MODE - ,PROP_POSITION_PROTECTED - ,PROP_IS_PROTECTED - ,PROP_PREFIX - ,PROP_REDLINE_AUTHOR - ,PROP_REDLINE_DATE_TIME - ,PROP_REDLINE_TYPE - ,PROP_REDLINE_REVERT_PROPERTIES - ,PROP_REFERENCE_FIELD_PART - ,PROP_REFERENCE_FIELD_SOURCE - ,PROP_RESTART_AT_EACH_PAGE - ,PROP_RIGHT_BORDER - ,PROP_RIGHT_BORDER_DISTANCE - ,PROP_RIGHT_MARGIN - ,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_SPLIT - ,PROP_STANDARD - ,PROP_START_AT - ,PROP_START_WITH - ,PROP_STREAM_NAME - ,PROP_SUB_TYPE - ,PROP_SUFFIX - ,PROP_SURROUND - ,PROP_SURROUND_CONTOUR - ,PROP_TABLE_BORDER - ,PROP_TABLE_BORDER_DISTANCES - ,PROP_TABLE_COLUMN_SEPARATORS - ,PROP_TABLE_REDLINE_PARAMS - ,PROP_TABLE_ROW_DELETE - ,PROP_TABLE_ROW_INSERT - ,PROP_TABLE_CELL_DELETE - ,PROP_TABLE_CELL_INSERT - ,PROP_TABS_RELATIVE_TO_INDENT - ,PROP_TAB_STOP_DISTANCE - ,PROP_TEXT - ,PROP_TEXT_COLUMNS - ,PROP_TEXT_RANGE - ,PROP_TEXT_VERTICAL_ADJUST - ,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_VERTICAL_MERGE - ,PROP_GRID_STANDARD_MODE - ,PROP_VERT_ORIENT - ,PROP_VERT_ORIENT_POSITION - ,PROP_VERT_ORIENT_RELATION - ,PROP_WIDTH - ,PROP_WIDTH_TYPE - ,PROP_TBL_LOOK - ,PROP_WRITING_MODE - ,PROP_FRM_DIRECTION - ,PROP_EMBEDDED_OBJECT - ,PROP_PARA_CONTEXT_MARGIN - ,PROP_PAGE_STYLE_LAYOUT - ,PROP_Z_ORDER - ,PROP_EMBED_FONTS - ,PROP_EMBED_SYSTEM_FONTS - ,PROP_SHADOW_FORMAT - ,PROP_RELATIVE_WIDTH - ,PROP_IS_WIDTH_RELATIVE - ,PROP_GRAPHIC_BITMAP - ,PROP_GRAPHIC_SIZE - ,PROP_MIRROR_INDENTS - ,PROP_SURROUND_TEXT_WRAP_SMALL - ,PROP_PARA_SHADOW_FORMAT - ,PROP_FOOTNOTE_LINE_RELATIVE_WIDTH - ,PROP_PARA_TOP_MARGIN_BEFORE_AUTO_SPACING - ,PROP_PARA_BOTTOM_MARGIN_AFTER_AUTO_SPACING - ,PROP_TBL_HEADER - ,PROP_HORIZONTAL_MERGE - ,PROP_HIDE_TAB_LEADER_AND_PAGE_NUMBERS - ,PROP_TAB_IN_TOC - ,PROP_TOC_BOOKMARK - ,PROP_TOC_NEW_LINE - ,PROP_TOC_PARAGRAPH_OUTLINE_LEVEL - ,PROP_SDTPR - ,PROP_CELL_INTEROP_GRAB_BAG - ,PROP_TABLE_INTEROP_GRAB_BAG - ,PROP_INDEX_ENTRY_TYPE - ,PROP_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING - ,PROP_SDT_END_BEFORE - ,PROP_PARA_SDT_END_BEFORE - ,META_PROP_TABLE_LOOK - ,PROP_PARA_CNF_STYLE - ,PROP_CELL_CNF_STYLE - ,PROP_ROW_CNF_STYLE - ,PROP_CELL_HIDE_MARK - ,PROP_FOLLOW_TEXT_FLOW - ,PROP_FILL_STYLE - ,PROP_FILL_COLOR - ,PROP_SNAP_TO_GRID - ,PROP_GRID_SNAP_TO_CHARS - ,PROP_RUBY_STYLE - ,PROP_RUBY_TEXT - ,PROP_RUBY_ADJUST - ,PROP_RUBY_POSITION - ,PROP_DATABASE_NAME - ,PROP_COMMAND_TYPE - ,PROP_DATATABLE_NAME - ,PROP_DATACOLUMN_NAME - ,PROP_CHAR_TRANSPARENCE - ,PROP_CELL_FORMULA - ,PROP_CELL_FORMULA_CONVERTED - ,PROP_GUTTER_MARGIN - }; - -//Returns the UNO string equivalent to eId. -OUString getPropertyName(PropertyIds eId); - -bool isCharacterProperty(const PropertyIds eId); - -bool isParagraphProperty(const PropertyIds eId); - -} // namespace writerfilter::dmapper -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx deleted file mode 100644 index 50af6463fcf1..000000000000 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ /dev/null @@ -1,2157 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <sal/config.h> - -#include <string_view> - -#include "PropertyMap.hxx" -#include "TagLogger.hxx" -#include <ooxml/resourceids.hxx> -#include "DomainMapper_Impl.hxx" -#include "ConversionHelper.hxx" -#include <editeng/boxitem.hxx> -#include <i18nutil/paper.hxx> -#include <osl/diagnose.h> -#include <rtl/ustring.hxx> -#include <sal/log.hxx> -#include <com/sun/star/beans/PropertyAttribute.hpp> -#include <com/sun/star/beans/PropertyValue.hpp> -#include <com/sun/star/beans/XMultiPropertySet.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/style/PageStyleLayout.hpp> -#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> -#include <com/sun/star/table/ShadowFormat.hpp> -#include <com/sun/star/text/RelOrientation.hpp> -#include <com/sun/star/text/HoriOrientation.hpp> -#include <com/sun/star/text/HorizontalAdjust.hpp> -#include <com/sun/star/text/SizeType.hpp> -#include <com/sun/star/text/VertOrientation.hpp> -#include <com/sun/star/text/WritingMode.hpp> -#include <com/sun/star/text/WritingMode2.hpp> -#include <com/sun/star/text/XRedline.hpp> -#include <com/sun/star/text/XTextColumns.hpp> -#include <com/sun/star/text/XText.hpp> -#include <com/sun/star/text/XTextFrame.hpp> -#include <com/sun/star/text/XTextTablesSupplier.hpp> -#include <com/sun/star/text/TextGridMode.hpp> -#include <com/sun/star/text/XTextCopy.hpp> -#include <com/sun/star/style/VerticalAlignment.hpp> -#include <comphelper/sequence.hxx> -#include <comphelper/propertyvalue.hxx> -#include <tools/diagnose_ex.h> -#include "PropertyMapHelper.hxx" -#include <o3tl/sorted_vector.hxx> - -using namespace com::sun::star; - -namespace writerfilter::dmapper { - -uno::Sequence< beans::PropertyValue > PropertyMap::GetPropertyValues( bool bCharGrabBag ) -{ - using comphelper::makePropertyValue; - - if ( m_aValues.empty() && !m_vMap.empty() ) - { - size_t nCharGrabBag = 0; - size_t nParaGrabBag = 0; - size_t nCellGrabBag = 0; - size_t nRowGrabBag = 0; - - const PropValue* pParaStyleProp = nullptr; - const PropValue* pCharStyleProp = nullptr; - const PropValue* pNumRuleProp = nullptr; - - for ( const auto& rPropPair : m_vMap ) - { - if ( rPropPair.second.getGrabBagType() == CHAR_GRAB_BAG ) - nCharGrabBag++; - else if ( rPropPair.second.getGrabBagType() == PARA_GRAB_BAG ) - nParaGrabBag++; - else if ( rPropPair.second.getGrabBagType() == CELL_GRAB_BAG ) - nCellGrabBag++; - else if ( rPropPair.first == PROP_CELL_INTEROP_GRAB_BAG ) - { - uno::Sequence< beans::PropertyValue > aSeq; - rPropPair.second.getValue() >>= aSeq; - nCellGrabBag += aSeq.getLength(); - } - else if ( rPropPair.second.getGrabBagType() == ROW_GRAB_BAG ) - nRowGrabBag++; - - if ( rPropPair.first == PROP_PARA_STYLE_NAME ) pParaStyleProp = &rPropPair.second; - if ( rPropPair.first == PROP_CHAR_STYLE_NAME ) pCharStyleProp = &rPropPair.second; - if ( rPropPair.first == PROP_NUMBERING_RULES ) pNumRuleProp = &rPropPair.second; - } - - // Style names have to be the first elements within the property sequence - // otherwise they will overwrite 'hard' attributes - if ( pParaStyleProp != nullptr ) - m_aValues.push_back( makePropertyValue( getPropertyName( PROP_PARA_STYLE_NAME ), pParaStyleProp->getValue() ) ); - if ( pCharStyleProp != nullptr ) - m_aValues.push_back( makePropertyValue( getPropertyName( PROP_CHAR_STYLE_NAME ), pCharStyleProp->getValue() ) ); - if ( pNumRuleProp != nullptr ) - m_aValues.push_back( makePropertyValue(getPropertyName( PROP_NUMBERING_RULES ), pNumRuleProp->getValue() ) ); - - // If there are any grab bag properties, we need one slot for them. - uno::Sequence< beans::PropertyValue > aCharGrabBagValues( nCharGrabBag ); - uno::Sequence< beans::PropertyValue > aParaGrabBagValues( nParaGrabBag ); - uno::Sequence< beans::PropertyValue > aCellGrabBagValues( nCellGrabBag ); - uno::Sequence< beans::PropertyValue > aRowGrabBagValues ( nRowGrabBag ); - beans::PropertyValue* pCharGrabBagValues = aCharGrabBagValues.getArray(); - beans::PropertyValue* pParaGrabBagValues = aParaGrabBagValues.getArray(); - beans::PropertyValue* pCellGrabBagValues = aCellGrabBagValues.getArray(); - beans::PropertyValue* pRowGrabBagValues = aRowGrabBagValues.getArray(); - // Record index for the next property to be added in each grab bag. - sal_Int32 nRowGrabBagValue = 0; - sal_Int32 nCellGrabBagValue = 0; - sal_Int32 nParaGrabBagValue = 0; - sal_Int32 nCharGrabBagValue = 0; - - for ( const auto& rPropPair : m_vMap ) - { - if ( rPropPair.first != PROP_PARA_STYLE_NAME && - rPropPair.first != PROP_CHAR_STYLE_NAME && - rPropPair.first != PROP_NUMBERING_RULES ) - { - if ( rPropPair.second.getGrabBagType() == CHAR_GRAB_BAG ) - { - if ( bCharGrabBag ) - { - pCharGrabBagValues[nCharGrabBagValue].Name = getPropertyName( rPropPair.first ); - pCharGrabBagValues[nCharGrabBagValue].Value = rPropPair.second.getValue(); - ++nCharGrabBagValue; - } - } - else if ( rPropPair.second.getGrabBagType() == PARA_GRAB_BAG ) - { - pParaGrabBagValues[nParaGrabBagValue].Name = getPropertyName( rPropPair.first ); - pParaGrabBagValues[nParaGrabBagValue].Value = rPropPair.second.getValue(); - ++nParaGrabBagValue; - } - else if ( rPropPair.second.getGrabBagType() == CELL_GRAB_BAG ) - { - pCellGrabBagValues[nCellGrabBagValue].Name = getPropertyName( rPropPair.first ); - pCellGrabBagValues[nCellGrabBagValue].Value = rPropPair.second.getValue(); - ++nCellGrabBagValue; - } - else if ( rPropPair.second.getGrabBagType() == ROW_GRAB_BAG ) - { - pRowGrabBagValues[nRowGrabBagValue].Name = getPropertyName( rPropPair.first ); - pRowGrabBagValues[nRowGrabBagValue].Value = rPropPair.second.getValue(); - ++nRowGrabBagValue; - } - else if ( rPropPair.first == PROP_CELL_INTEROP_GRAB_BAG ) - { - uno::Sequence< beans::PropertyValue > aSeq; - rPropPair.second.getValue() >>= aSeq; - std::copy(aSeq.begin(), aSeq.end(), pCellGrabBagValues + nCellGrabBagValue); - nCellGrabBagValue += aSeq.getLength(); - } - else - { - m_aValues.push_back( makePropertyValue( getPropertyName( rPropPair.first ), rPropPair.second.getValue() ) ); - } - } - } - - if ( nCharGrabBag && bCharGrabBag ) - m_aValues.push_back( makePropertyValue( "CharInteropGrabBag", uno::makeAny( aCharGrabBagValues ) ) ); - - if ( nParaGrabBag ) - m_aValues.push_back( makePropertyValue( "ParaInteropGrabBag", uno::makeAny( aParaGrabBagValues ) ) ); - - if ( nCellGrabBag ) - m_aValues.push_back( makePropertyValue( "CellInteropGrabBag", uno::makeAny( aCellGrabBagValues ) ) ); - - if ( nRowGrabBag ) - m_aValues.push_back( makePropertyValue( "RowInteropGrabBag", uno::makeAny( aRowGrabBagValues ) ) ); - } - - return comphelper::containerToSequence( m_aValues ); -} - -std::vector< PropertyIds > PropertyMap::GetPropertyIds() -{ - std::vector< PropertyIds > aRet; - for ( const auto& rPropPair : m_vMap ) - aRet.push_back( rPropPair.first ); - return aRet; -} - -#ifdef DBG_UTIL -static void lcl_AnyToTag( const uno::Any& rAny ) -{ - try { - sal_Int32 aInt = 0; - if ( rAny >>= aInt ) - { - TagLogger::getInstance().attribute( "value", rAny ); - } - else - { - TagLogger::getInstance().attribute( "unsignedValue", 0 ); - } - - sal_uInt32 auInt = 0; - rAny >>= auInt; - TagLogger::getInstance().attribute( "unsignedValue", auInt ); - - float aFloat = 0.0f; - if ( rAny >>= aFloat ) - { - TagLogger::getInstance().attribute( "floatValue", rAny ); - } - else - { - TagLogger::getInstance().attribute( "unsignedValue", 0 ); - } - - OUString aStr; - rAny >>= aStr; - TagLogger::getInstance().attribute( "stringValue", aStr ); - } - catch ( ... ) - { - } -} -#endif - -void PropertyMap::Insert( PropertyIds eId, const uno::Any& rAny, bool bOverwrite, GrabBagType i_GrabBagType, bool bDocDefault ) -{ -#ifdef DBG_UTIL - const OUString& rInsert = getPropertyName(eId); - - TagLogger::getInstance().startElement("propertyMap.insert"); - TagLogger::getInstance().attribute("name", rInsert); - lcl_AnyToTag(rAny); - TagLogger::getInstance().endElement(); -#endif - - if ( !bOverwrite ) - m_vMap.insert(std::make_pair(eId, PropValue(rAny, i_GrabBagType, bDocDefault))); - else - m_vMap[eId] = PropValue(rAny, i_GrabBagType); - - Invalidate(); -} - -void PropertyMap::Erase( PropertyIds eId ) -{ - // Safe call to erase, it throws no exceptions, even if eId is not in m_vMap - m_vMap.erase(eId); - - Invalidate(); -} - -std::optional< PropertyMap::Property > PropertyMap::getProperty( PropertyIds eId ) const -{ - std::map< PropertyIds, PropValue >::const_iterator aIter = m_vMap.find( eId ); - if ( aIter == m_vMap.end() ) - return std::optional<Property>(); - else - return std::make_pair( eId, aIter->second.getValue() ); -} - -bool PropertyMap::isSet( PropertyIds eId) const -{ - return m_vMap.find( eId ) != m_vMap.end(); -} - -bool PropertyMap::isDocDefault( PropertyIds eId ) const -{ - std::map< PropertyIds, PropValue >::const_iterator aIter = m_vMap.find( eId ); - if ( aIter == m_vMap.end() ) - return false; - else - return aIter->second.getIsDocDefault(); -} - -#ifdef DBG_UTIL -void PropertyMap::dumpXml() const -{ - TagLogger::getInstance().startElement( "PropertyMap" ); - - for ( const auto& rPropPair : m_vMap ) - { - TagLogger::getInstance().startElement( "property" ); - - TagLogger::getInstance().attribute( "name", getPropertyName( rPropPair.first ) ); - - switch ( rPropPair.first ) - { - case PROP_TABLE_COLUMN_SEPARATORS: - lcl_DumpTableColumnSeparators( rPropPair.second.getValue() ); - break; - default: - { - try - { - sal_Int32 aInt = 0; - rPropPair.second.getValue() >>= aInt; - TagLogger::getInstance().attribute( "value", aInt ); - - sal_uInt32 auInt = 0; - rPropPair.second.getValue() >>= auInt; - TagLogger::getInstance().attribute( "unsignedValue", auInt ); - - float aFloat = 0.0; - rPropPair.second.getValue() >>= aFloat; - TagLogger::getInstance().attribute( "floatValue", aFloat ); - - rPropPair.second.getValue() >>= auInt; - TagLogger::getInstance().attribute( "stringValue", std::u16string_view() ); - } - catch ( ... ) - { - } - } - break; - } - - TagLogger::getInstance().endElement(); - } - - TagLogger::getInstance().endElement(); -} -#endif - -void PropertyMap::InsertProps( const PropertyMapPtr& rMap, const bool bOverwrite ) -{ - if ( !rMap ) - return; - - for ( const auto& rPropPair : rMap->m_vMap ) - { - if ( bOverwrite || !m_vMap.count(rPropPair.first) ) - { - if ( !bOverwrite && !rPropPair.second.getIsDocDefault() ) - m_vMap.insert(std::make_pair(rPropPair.first, PropValue(rPropPair.second.getValue(), rPropPair.second.getGrabBagType(), true))); - else - m_vMap[rPropPair.first] = rPropPair.second; - } - } - - insertTableProperties( rMap.get(), bOverwrite ); - - Invalidate(); -} - -void PropertyMap::insertTableProperties( const PropertyMap*, const bool ) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().element( "PropertyMap.insertTableProperties" ); -#endif -} - -void PropertyMap::printProperties() -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement( "properties" ); - - for ( const auto& rPropPair : m_vMap ) - { - SAL_INFO( "writerfilter", getPropertyName( rPropPair.first ) ); - - table::BorderLine2 aLine; - sal_Int32 nColor; - if ( rPropPair.second.getValue() >>= aLine ) - { - TagLogger::getInstance().startElement( "borderline" ); - TagLogger::getInstance().attribute( "color", aLine.Color ); - TagLogger::getInstance().attribute( "inner", aLine.InnerLineWidth ); - TagLogger::getInstance().attribute( "outer", aLine.OuterLineWidth ); - TagLogger::getInstance().endElement(); - } - else if ( rPropPair.second.getValue() >>= nColor ) - { - TagLogger::getInstance().startElement( "color" ); - TagLogger::getInstance().attribute( "number", nColor ); - TagLogger::getInstance().endElement(); - } - } - - TagLogger::getInstance().endElement(); -#else - (void) this; // avoid loplugin:staticmethods -#endif -} - -SectionPropertyMap::SectionPropertyMap( bool bIsFirstSection ) - : m_bIsFirstSection( bIsFirstSection ) - , m_eBorderApply( BorderApply::ToAllInSection ) - , m_eBorderOffsetFrom( BorderOffsetFrom::Text ) - , m_bTitlePage( false ) - , m_nColumnCount( 0 ) - , m_nColumnDistance( 1249 ) - , m_bSeparatorLineIsOn( false ) - , m_bEvenlySpaced( false ) - , m_nPageNumber( -1 ) - , m_nPageNumberType( -1 ) - , m_nBreakType( -1 ) - , m_nLeftMargin( 2540 ) // page left margin, default 1 inch = 1440 twip -> 2540 1/100 mm - , m_nRightMargin( 2540 ) // page right margin, default 1 inch = 1440 twip -> 2540 1/100 mm - , m_nGutterMargin(0) - , m_nTopMargin( 2540 ) - , m_nBottomMargin( 2540 ) - , m_nHeaderTop( 1270 ) // 720 twip - , m_nHeaderBottom( 1270 ) // 720 twip - , m_nGridType( 0 ) - , m_nGridLinePitch( 1 ) - , m_nDxtCharSpace( 0 ) - , m_bGridSnapToChars( true ) - , m_nLnnMod( 0 ) - , m_nLnc(NS_ooxml::LN_Value_ST_LineNumberRestart_newPage) - , m_ndxaLnn( 0 ) - , m_nLnnMin( 0 ) - , m_bDefaultHeaderLinkToPrevious( true ) - , m_bEvenPageHeaderLinkToPrevious( true ) - , m_bFirstPageHeaderLinkToPrevious( true ) - , m_bDefaultFooterLinkToPrevious( true ) - , m_bEvenPageFooterLinkToPrevious( true ) - , m_bFirstPageFooterLinkToPrevious( true ) -{ -#ifdef DBG_UTIL - static sal_Int32 nNumber = 0; - m_nDebugSectionNumber = nNumber++; -#endif - - for ( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder ) - { - m_nBorderDistances[nBorder] = -1; - m_bBorderShadows[nBorder] = false; - } - // todo: set defaults in ApplyPropertiesToPageStyles - // initialize defaults - PaperInfo aLetter( PAPER_LETTER ); - // page height, 1/100mm - Insert( PROP_HEIGHT, uno::makeAny( static_cast<sal_Int32>(aLetter.getHeight()) ) ); - // page width, 1/100mm - Insert( PROP_WIDTH, uno::makeAny( static_cast<sal_Int32>(aLetter.getWidth()) ) ); - // page left margin, default 0x5a0 (1440) twip -> 2540 1/100 mm - Insert( PROP_LEFT_MARGIN, uno::makeAny( sal_Int32(2540) ) ); - // page right margin, default 0x5a0 (1440) twip -> 2540 1/100 mm - Insert( PROP_RIGHT_MARGIN, uno::makeAny( sal_Int32(2540) ) ); - // page top margin, default 0x5a0 (1440) twip -> 2540 1/100 mm - Insert( PROP_TOP_MARGIN, uno::makeAny( sal_Int32(2540) ) ); - // page bottom margin, default 0x5a0 (1440) twip -> 2540 1/100 mm - Insert( PROP_BOTTOM_MARGIN, uno::makeAny( sal_Int32(2540) ) ); - // page style layout - Insert( PROP_PAGE_STYLE_LAYOUT, uno::makeAny( style::PageStyleLayout_ALL ) ); - uno::Any aFalse( uno::makeAny( false ) ); - Insert( PROP_GRID_DISPLAY, aFalse ); - Insert( PROP_GRID_PRINT, aFalse ); - Insert( PROP_GRID_MODE, uno::makeAny( text::TextGridMode::NONE ) ); - - if ( m_bIsFirstSection ) - { - m_sFirstPageStyleName = getPropertyName( PROP_FIRST_PAGE ); - m_sFollowPageStyleName = getPropertyName( PROP_STANDARD ); - } -} - -uno::Reference< beans::XPropertySet > SectionPropertyMap::GetPageStyle( DomainMapper_Impl& rDM_Impl, - bool bFirst ) -{ - const uno::Reference< container::XNameContainer >& xPageStyles = rDM_Impl.GetPageStyles(); - const uno::Reference < lang::XMultiServiceFactory >& xTextFactory = rDM_Impl.GetTextFactory(); - uno::Reference< beans::XPropertySet > xRet; - try - { - if ( bFirst ) - { - if ( m_sFirstPageStyleName.isEmpty() && xPageStyles.is() ) - { - assert( !rDM_Impl.IsInFootOrEndnote() && "Don't create useless page styles" ); - m_sFirstPageStyleName = rDM_Impl.GetUnusedPageStyleName(); - m_aFirstPageStyle.set( xTextFactory->createInstance( "com.sun.star.style.PageStyle" ), - uno::UNO_QUERY ); - - // Call insertByName() before GetPageStyle(), otherwise the - // first and the follow page style will have the same name, and - // insertByName() will fail. - if ( xPageStyles.is() ) - xPageStyles->insertByName( m_sFirstPageStyleName, uno::makeAny( m_aFirstPageStyle ) ); - - // Ensure that m_aFollowPageStyle has been created - GetPageStyle( rDM_Impl, false ); - // Chain m_aFollowPageStyle to be after m_aFirstPageStyle - m_aFirstPageStyle->setPropertyValue( "FollowStyle", - uno::makeAny( m_sFollowPageStyleName ) ); - } - else if ( !m_aFirstPageStyle.is() && xPageStyles.is() ) - { - xPageStyles->getByName( m_sFirstPageStyleName ) >>= m_aFirstPageStyle; - } - xRet = m_aFirstPageStyle; - } - else - { - if ( m_sFollowPageStyleName.isEmpty() && xPageStyles.is() ) - { - assert( !rDM_Impl.IsInFootOrEndnote() && "Don't create useless page styles" ); - m_sFollowPageStyleName = rDM_Impl.GetUnusedPageStyleName(); - m_aFollowPageStyle.set( xTextFactory->createInstance( "com.sun.star.style.PageStyle" ), - uno::UNO_QUERY ); - xPageStyles->insertByName( m_sFollowPageStyleName, uno::makeAny( m_aFollowPageStyle ) ); - } - else if ( !m_aFollowPageStyle.is() && xPageStyles.is() ) - { - xPageStyles->getByName( m_sFollowPageStyleName ) >>= m_aFollowPageStyle; - } - xRet = m_aFollowPageStyle; - } - - } - catch ( const uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION( "writerfilter" ); - } - - return xRet; -} - -void SectionPropertyMap::SetBorder( BorderPosition ePos, sal_Int32 nLineDistance, const table::BorderLine2& rBorderLine, bool bShadow ) -{ - m_oBorderLines[ePos] = rBorderLine; - m_nBorderDistances[ePos] = nLineDistance; - m_bBorderShadows[ePos] = bShadow; -} - -void SectionPropertyMap::ApplyBorderToPageStyles( DomainMapper_Impl& rDM_Impl, - BorderApply eBorderApply, BorderOffsetFrom eOffsetFrom ) -{ - /* - 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; - // todo: negative spacing (from ww8par6.cxx) - switch ( eBorderApply ) - { - case BorderApply::ToAllInSection: // all styles - if ( !m_sFollowPageStyleName.isEmpty() ) - xFirst = GetPageStyle( rDM_Impl, false ); - if ( !m_sFirstPageStyleName.isEmpty() ) - xSecond = GetPageStyle( rDM_Impl, true ); - break; - case BorderApply::ToFirstPageInSection: // first page - if ( !m_sFirstPageStyleName.isEmpty() ) - xFirst = GetPageStyle( rDM_Impl, true ); - break; - case BorderApply::ToAllButFirstInSection: // left and right - if ( !m_sFollowPageStyleName.isEmpty() ) - xFirst = GetPageStyle( rDM_Impl, false ); - break; - default: - return; - } - - // has to be sorted like enum BorderPosition: l-r-t-b - const PropertyIds aBorderIds[4] = - { - PROP_LEFT_BORDER, - PROP_RIGHT_BORDER, - PROP_TOP_BORDER, - PROP_BOTTOM_BORDER - }; - - const PropertyIds aBorderDistanceIds[4] = - { - PROP_LEFT_BORDER_DISTANCE, - PROP_RIGHT_BORDER_DISTANCE, - PROP_TOP_BORDER_DISTANCE, - PROP_BOTTOM_BORDER_DISTANCE - }; - - const PropertyIds aMarginIds[4] = - { - PROP_LEFT_MARGIN, - PROP_RIGHT_MARGIN, - PROP_TOP_MARGIN, - PROP_BOTTOM_MARGIN - }; - - for ( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder ) - { - if ( m_oBorderLines[nBorder] ) - { - const OUString sBorderName = getPropertyName( aBorderIds[nBorder] ); - if ( xFirst.is() ) - xFirst->setPropertyValue( sBorderName, uno::makeAny( *m_oBorderLines[nBorder] ) ); - if ( xSecond.is() ) - xSecond->setPropertyValue( sBorderName, uno::makeAny( *m_oBorderLines[nBorder] ) ); - } - if ( m_nBorderDistances[nBorder] >= 0 ) - { - sal_uInt32 nLineWidth = 0; - if ( m_oBorderLines[nBorder] ) - nLineWidth = m_oBorderLines[nBorder]->LineWidth; - if ( xFirst.is() ) - SetBorderDistance( xFirst, aMarginIds[nBorder], aBorderDistanceIds[nBorder], - m_nBorderDistances[nBorder], eOffsetFrom, nLineWidth ); - if ( xSecond.is() ) - SetBorderDistance( xSecond, aMarginIds[nBorder], aBorderDistanceIds[nBorder], - m_nBorderDistances[nBorder], eOffsetFrom, nLineWidth ); - } - } - - if ( m_bBorderShadows[BORDER_RIGHT] ) - { - table::ShadowFormat aFormat = getShadowFromBorder( *m_oBorderLines[BORDER_RIGHT] ); - if ( xFirst.is() ) - xFirst->setPropertyValue( getPropertyName( PROP_SHADOW_FORMAT ), uno::makeAny( aFormat ) ); - if ( xSecond.is() ) - xSecond->setPropertyValue( getPropertyName( PROP_SHADOW_FORMAT ), uno::makeAny( aFormat ) ); - } -} - -table::ShadowFormat PropertyMap::getShadowFromBorder( const table::BorderLine2& rBorder ) -{ - // In Word UI, shadow is a boolean property, in OOXML, it's a boolean - // property of each 4 border type, finally in Writer the border is a - // property of the page style, with shadow location, distance and - // color. See SwWW8ImplReader::SetShadow(). - table::ShadowFormat aFormat; - aFormat.Color = sal_Int32(COL_BLACK); - aFormat.Location = table::ShadowLocation_BOTTOM_RIGHT; - aFormat.ShadowWidth = rBorder.LineWidth; - return aFormat; -} - -void SectionPropertyMap::SetBorderDistance( const uno::Reference< beans::XPropertySet >& xStyle, - PropertyIds eMarginId, - PropertyIds eDistId, - sal_Int32 nDistance, - BorderOffsetFrom eOffsetFrom, - sal_uInt32 nLineWidth ) -{ - if (!xStyle.is()) - return; - const OUString sMarginName = getPropertyName( eMarginId ); - const OUString sBorderDistanceName = getPropertyName( eDistId ); - uno::Any aMargin = xStyle->getPropertyValue( sMarginName ); - sal_Int32 nMargin = 0; - aMargin >>= nMargin; - editeng::BorderDistanceFromWord(eOffsetFrom == BorderOffsetFrom::Edge, nMargin, nDistance, - nLineWidth); - - // Change the margins with the border distance - uno::Reference< beans::XMultiPropertySet > xMultiSet( xStyle, uno::UNO_QUERY_THROW ); - uno::Sequence<OUString> aProperties { sMarginName, sBorderDistanceName }; - uno::Sequence<uno::Any> aValues { uno::makeAny( nMargin ), uno::makeAny( nDistance ) }; - xMultiSet->setPropertyValues( aProperties, aValues ); -} - -void SectionPropertyMap::DontBalanceTextColumns() -{ - try - { - if ( m_xColumnContainer.is() ) - m_xColumnContainer->setPropertyValue( "DontBalanceTextColumns", uno::makeAny( true ) ); - } - catch ( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "SectionPropertyMap::DontBalanceTextColumns" ); - } -} - -void SectionPropertyMap::ApplySectionProperties( const uno::Reference< beans::XPropertySet >& xSection, DomainMapper_Impl& /*rDM_Impl*/ ) -{ - try - { - if ( xSection.is() ) - { - std::optional< PropertyMap::Property > pProp = getProperty( PROP_WRITING_MODE ); - if ( pProp ) - xSection->setPropertyValue( "WritingMode", pProp->second ); - } - } - catch ( uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "Exception in SectionPropertyMap::ApplySectionProperties"); - } -} - -void SectionPropertyMap::ApplyProtectionProperties( uno::Reference< beans::XPropertySet >& xSection, DomainMapper_Impl& rDM_Impl ) -{ - try - { - // Word implements section protection differently than LO. - // PROP_IS_PROTECTED only applies if global setting GetProtectForm is enabled. - bool bIsProtected = rDM_Impl.GetSettingsTable()->GetProtectForm(); - if ( bIsProtected ) - { - // If form protection is enabled then section protection is enabled, unless explicitly disabled - if ( isSet(PROP_IS_PROTECTED) ) - getProperty(PROP_IS_PROTECTED)->second >>= bIsProtected; - if ( !xSection.is() ) - xSection = rDM_Impl.appendTextSectionAfter( m_xStartingRange ); - if ( xSection.is() ) - xSection->setPropertyValue( getPropertyName(PROP_IS_PROTECTED), uno::makeAny(bIsProtected) ); - } - } - catch ( uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "ApplyProtectionProperties failed setting PROP_IS_PROTECTED"); - } -} - -uno::Reference< text::XTextColumns > SectionPropertyMap::ApplyColumnProperties( const uno::Reference< beans::XPropertySet >& xColumnContainer, - DomainMapper_Impl& rDM_Impl ) -{ - uno::Reference< text::XTextColumns > xColumns; - assert( m_nColumnCount > 1 && "ApplyColumnProperties called without any columns" ); - try - { - const OUString sTextColumns = getPropertyName( PROP_TEXT_COLUMNS ); - if ( xColumnContainer.is() ) - xColumnContainer->getPropertyValue( sTextColumns ) >>= xColumns; - uno::Reference< beans::XPropertySet > xColumnPropSet( xColumns, uno::UNO_QUERY_THROW ); - if ( !m_bEvenlySpaced && - ( sal_Int32(m_aColWidth.size()) == m_nColumnCount ) && - ( (sal_Int32(m_aColDistance.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 = nColSum ? double( nRefValue ) / double( nColSum ) : 0.0; - uno::Sequence< text::TextColumn > aColumns( m_nColumnCount ); - text::TextColumn* pColumn = aColumns.getArray(); - - nColSum = 0; - for ( sal_Int32 nCol = 0; nCol < m_nColumnCount; ++nCol ) - { - const double fLeft = nCol ? m_aColDistance[nCol - 1] / 2 : 0; - pColumn[nCol].LeftMargin = fLeft; - const double fRight = (nCol == m_nColumnCount - 1) ? 0 : m_aColDistance[nCol] / 2; - pColumn[nCol].RightMargin = fRight; - const double fWidth = m_aColWidth[nCol]; - pColumn[nCol].Width = (fWidth + fLeft + fRight) * fRel; - nColSum += pColumn[nCol].Width; - } - if ( nColSum != nRefValue ) - pColumn[m_nColumnCount - 1].Width += (nRefValue - nColSum); - assert( pColumn[m_nColumnCount - 1].Width >= 0 ); - - xColumns->setColumns( aColumns ); - } - else - { - xColumns->setColumnCount( m_nColumnCount ); - xColumnPropSet->setPropertyValue( getPropertyName( PROP_AUTOMATIC_DISTANCE ), uno::makeAny( m_nColumnDistance ) ); - } - - if ( m_bSeparatorLineIsOn ) - { - xColumnPropSet->setPropertyValue( "SeparatorLineIsOn", uno::makeAny( true ) ); - xColumnPropSet->setPropertyValue( "SeparatorLineVerticalAlignment", uno::makeAny( style::VerticalAlignment_TOP ) ); - xColumnPropSet->setPropertyValue( "SeparatorLineRelativeHeight", uno::makeAny( static_cast<sal_Int8>(100) ) ); - xColumnPropSet->setPropertyValue( "SeparatorLineColor", uno::makeAny( static_cast<sal_Int32>(COL_BLACK) ) ); - // 1 twip -> 2 mm100. - xColumnPropSet->setPropertyValue( "SeparatorLineWidth", uno::makeAny( static_cast<sal_Int32>(2) ) ); - } - xColumnContainer->setPropertyValue( sTextColumns, uno::makeAny( xColumns ) ); - // Set the columns to be unbalanced if that compatibility option is set or this is the last section. - m_xColumnContainer = xColumnContainer; - if ( rDM_Impl.GetSettingsTable()->GetNoColumnBalance() || rDM_Impl.GetIsLastSectionGroup() ) - DontBalanceTextColumns(); - } - catch ( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "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( - getPropertyName( PROP_HEADER_IS_ON ) ) >>= bRet; - else - m_aFollowPageStyle->getPropertyValue( - getPropertyName( 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( getPropertyName( PROP_FOOTER_IS_ON ) ) >>= bRet; - else - m_aFollowPageStyle->getPropertyValue( getPropertyName( PROP_FOOTER_IS_ON ) ) >>= bRet; - } - return bRet; -} - -#define MIN_HEAD_FOOT_HEIGHT 100 // minimum header/footer height - -void SectionPropertyMap::CopyHeaderFooterTextProperty( const uno::Reference< beans::XPropertySet >& xPrevStyle, - const uno::Reference< beans::XPropertySet >& xStyle, - PropertyIds ePropId ) -{ - try { - OUString sName = getPropertyName( ePropId ); - - SAL_INFO( "writerfilter", "Copying " << sName ); - uno::Reference< text::XTextCopy > xTxt; - if ( xStyle.is() ) - xTxt.set( xStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW ); - - uno::Reference< text::XTextCopy > xPrevTxt; - if ( xPrevStyle.is() ) - xPrevTxt.set( xPrevStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW ); - - xTxt->copyText( xPrevTxt ); - } - catch ( const uno::Exception& ) - { - TOOLS_INFO_EXCEPTION( "writerfilter", "An exception occurred in SectionPropertyMap::CopyHeaderFooterTextProperty( )" ); - } -} - -// Copy headers and footers from the previous page style. -void SectionPropertyMap::CopyHeaderFooter( const uno::Reference< beans::XPropertySet >& xPrevStyle, - const uno::Reference< beans::XPropertySet >& xStyle, - bool bOmitRightHeader, - bool bOmitLeftHeader, - bool bOmitRightFooter, - bool bOmitLeftFooter ) -{ - bool bHasPrevHeader = false; - bool bHeaderIsShared = true; - OUString sHeaderIsOn = getPropertyName( PROP_HEADER_IS_ON ); - OUString sHeaderIsShared = getPropertyName( PROP_HEADER_IS_SHARED ); - if ( xPrevStyle.is() ) - { - xPrevStyle->getPropertyValue( sHeaderIsOn ) >>= bHasPrevHeader; - xPrevStyle->getPropertyValue( sHeaderIsShared ) >>= bHeaderIsShared; - } - - if ( bHasPrevHeader ) - { - uno::Reference< beans::XMultiPropertySet > xMultiSet( xStyle, uno::UNO_QUERY_THROW ); - uno::Sequence<OUString> aProperties { sHeaderIsOn, sHeaderIsShared }; - uno::Sequence<uno::Any> aValues { uno::makeAny( true ), uno::makeAny( bHeaderIsShared ) }; - xMultiSet->setPropertyValues( aProperties, aValues ); - if ( !bOmitRightHeader ) - { - CopyHeaderFooterTextProperty( xPrevStyle, xStyle, - PROP_HEADER_TEXT ); - } - if ( !bHeaderIsShared && !bOmitLeftHeader ) - { - CopyHeaderFooterTextProperty( xPrevStyle, xStyle, - PROP_HEADER_TEXT_LEFT ); - } - } - - bool bHasPrevFooter = false; - bool bFooterIsShared = true; - OUString sFooterIsOn = getPropertyName( PROP_FOOTER_IS_ON ); - OUString sFooterIsShared = getPropertyName( PROP_FOOTER_IS_SHARED ); - if ( xPrevStyle.is() ) - { - xPrevStyle->getPropertyValue( sFooterIsOn ) >>= bHasPrevFooter; - xPrevStyle->getPropertyValue( sFooterIsShared ) >>= bFooterIsShared; - } - - if ( !bHasPrevFooter ) - return; - - uno::Reference< beans::XMultiPropertySet > xMultiSet( xStyle, uno::UNO_QUERY_THROW ); - uno::Sequence<OUString> aProperties { sFooterIsOn, sFooterIsShared }; - uno::Sequence<uno::Any> aValues { uno::makeAny( true ), uno::makeAny( bFooterIsShared ) }; - xMultiSet->setPropertyValues( aProperties, aValues ); - if ( !bOmitRightFooter ) - { - CopyHeaderFooterTextProperty( xPrevStyle, xStyle, - PROP_FOOTER_TEXT ); - } - if ( !bFooterIsShared && !bOmitLeftFooter ) - { - CopyHeaderFooterTextProperty( xPrevStyle, xStyle, - PROP_FOOTER_TEXT_LEFT ); - } -} - -// Copy header and footer content from the previous docx section as needed. -// -// Any headers and footers which were not defined in this docx section -// should be "linked" with the corresponding header or footer from the -// previous section. LO does not support linking of header/footer content -// across page styles so we just copy the content from the previous section. -void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl ) -{ - SAL_INFO( "writerfilter", "START>>> SectionPropertyMap::CopyLastHeaderFooter()" ); - SectionPropertyMap* pLastContext = rDM_Impl.GetLastSectionContext(); - if ( pLastContext ) - { - uno::Reference< beans::XPropertySet > xPrevStyle = pLastContext->GetPageStyle( rDM_Impl, - bFirstPage ); - uno::Reference< beans::XPropertySet > xStyle = GetPageStyle( rDM_Impl, - bFirstPage ); - - if ( bFirstPage ) - { - CopyHeaderFooter( xPrevStyle, xStyle, - !m_bFirstPageHeaderLinkToPrevious, true, - !m_bFirstPageFooterLinkToPrevious, true ); - } - else - { - CopyHeaderFooter( xPrevStyle, xStyle, - !m_bDefaultHeaderLinkToPrevious, - !m_bEvenPageHeaderLinkToPrevious, - !m_bDefaultFooterLinkToPrevious, - !m_bEvenPageFooterLinkToPrevious ); - } - } - SAL_INFO( "writerfilter", "END>>> SectionPropertyMap::CopyLastHeaderFooter()" ); -} - -void SectionPropertyMap::PrepareHeaderFooterProperties( bool bFirstPage ) -{ - bool bCopyFirstToFollow = bFirstPage && m_bTitlePage && m_aFollowPageStyle.is(); - - sal_Int32 nTopMargin = m_nTopMargin; - sal_Int32 nHeaderTop = m_nHeaderTop; - if ( HasHeader( bFirstPage ) ) - { - nTopMargin = nHeaderTop; - if ( m_nTopMargin > 0 && m_nTopMargin > nHeaderTop ) - nHeaderTop = m_nTopMargin - nHeaderTop; - else - nHeaderTop = 0; - - // minimum header height 1mm - if ( nHeaderTop < MIN_HEAD_FOOT_HEIGHT ) - nHeaderTop = MIN_HEAD_FOOT_HEIGHT; - } - - - if ( m_nTopMargin >= 0 ) //fixed height header -> see WW8Par6.hxx - { - Insert( PROP_HEADER_IS_DYNAMIC_HEIGHT, uno::makeAny( true ) ); - Insert( PROP_HEADER_DYNAMIC_SPACING, uno::makeAny( true ) ); - Insert( PROP_HEADER_BODY_DISTANCE, uno::makeAny( nHeaderTop - MIN_HEAD_FOOT_HEIGHT ) );// ULSpace.Top() - Insert( PROP_HEADER_HEIGHT, uno::makeAny( nHeaderTop ) ); - - if (bCopyFirstToFollow && HasHeader(/*bFirstPage=*/true)) - { - m_aFollowPageStyle->setPropertyValue("HeaderDynamicSpacing", - getProperty(PROP_HEADER_DYNAMIC_SPACING)->second); - m_aFollowPageStyle->setPropertyValue("HeaderHeight", - getProperty(PROP_HEADER_HEIGHT)->second); - } - } - else - { - //todo: old filter fakes a frame into the header/footer to support overlapping - //current setting is completely wrong! - Insert( PROP_HEADER_HEIGHT, uno::makeAny( nHeaderTop ) ); - Insert( PROP_HEADER_BODY_DISTANCE, uno::makeAny( m_nTopMargin - nHeaderTop ) ); - Insert( PROP_HEADER_IS_DYNAMIC_HEIGHT, uno::makeAny( false ) ); - Insert( PROP_HEADER_DYNAMIC_SPACING, uno::makeAny( false ) ); - } - - sal_Int32 nBottomMargin = m_nBottomMargin; - sal_Int32 nHeaderBottom = m_nHeaderBottom; - if ( HasFooter( bFirstPage ) ) - { - nBottomMargin = nHeaderBottom; - if ( m_nBottomMargin > 0 && m_nBottomMargin > nHeaderBottom ) - nHeaderBottom = m_nBottomMargin - nHeaderBottom; - else - nHeaderBottom = 0; - if ( nHeaderBottom < MIN_HEAD_FOOT_HEIGHT ) - nHeaderBottom = MIN_HEAD_FOOT_HEIGHT; - } - - if ( m_nBottomMargin >= 0 ) //fixed height footer -> see WW8Par6.hxx - { - Insert( PROP_FOOTER_IS_DYNAMIC_HEIGHT, uno::makeAny( true ) ); - Insert( PROP_FOOTER_DYNAMIC_SPACING, uno::makeAny( true ) ); - Insert( PROP_FOOTER_BODY_DISTANCE, uno::makeAny( nHeaderBottom - MIN_HEAD_FOOT_HEIGHT ) ); - Insert( PROP_FOOTER_HEIGHT, uno::makeAny( nHeaderBottom ) ); - - if (bCopyFirstToFollow && HasFooter(/*bFirstPage=*/true)) - { - m_aFollowPageStyle->setPropertyValue("FooterDynamicSpacing", - getProperty(PROP_FOOTER_DYNAMIC_SPACING)->second); - m_aFollowPageStyle->setPropertyValue("FooterHeight", - getProperty(PROP_FOOTER_HEIGHT)->second); - } - } - else - { - //todo: old filter fakes a frame into the header/footer to support overlapping - //current setting is completely wrong! - Insert( PROP_FOOTER_IS_DYNAMIC_HEIGHT, uno::makeAny( false ) ); - Insert( PROP_FOOTER_DYNAMIC_SPACING, uno::makeAny( false ) ); - Insert( PROP_FOOTER_HEIGHT, uno::makeAny( m_nBottomMargin - nHeaderBottom ) ); - Insert( PROP_FOOTER_BODY_DISTANCE, uno::makeAny( nHeaderBottom ) ); - } - - //now set the top/bottom margin for the follow page style - Insert( PROP_TOP_MARGIN, uno::makeAny( std::max<sal_Int32>(nTopMargin, 0) ) ); - Insert( PROP_BOTTOM_MARGIN, uno::makeAny( std::max<sal_Int32>(nBottomMargin, 0) ) ); -} - -static uno::Reference< beans::XPropertySet > lcl_GetRangeProperties( bool bIsFirstSection, - DomainMapper_Impl& rDM_Impl, - const uno::Reference< text::XTextRange >& xStartingRange ) -{ - uno::Reference< beans::XPropertySet > xRangeProperties; - if ( bIsFirstSection && rDM_Impl.GetBodyText().is() ) - { - uno::Reference< container::XEnumerationAccess > xEnumAccess( rDM_Impl.GetBodyText(), uno::UNO_QUERY_THROW ); - uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration(); - xRangeProperties.set( xEnum->nextElement(), uno::UNO_QUERY_THROW ); - if ( rDM_Impl.GetIsDummyParaAddedForTableInSection() && xEnum->hasMoreElements() ) - xRangeProperties.set( xEnum->nextElement(), uno::UNO_QUERY_THROW ); - } - else if ( xStartingRange.is() ) - xRangeProperties.set( xStartingRange, uno::UNO_QUERY_THROW ); - return xRangeProperties; -} - -void SectionPropertyMap::HandleMarginsHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl ) -{ - Insert( PROP_LEFT_MARGIN, uno::makeAny( m_nLeftMargin ) ); - Insert( PROP_RIGHT_MARGIN, uno::makeAny( m_nRightMargin ) ); - Insert(PROP_GUTTER_MARGIN, uno::makeAny(m_nGutterMargin)); - - if ( rDM_Impl.m_oBackgroundColor ) - Insert( PROP_BACK_COLOR, uno::makeAny( *rDM_Impl.m_oBackgroundColor ) ); - - // Check for missing footnote separator only in case there is at least - // one footnote. - if (rDM_Impl.m_bHasFtn && !rDM_Impl.m_bHasFtnSep) - { - // Set footnote line width to zero, document has no footnote separator. - Insert(PROP_FOOTNOTE_LINE_RELATIVE_WIDTH, uno::makeAny(sal_Int32(0))); - } - if ( rDM_Impl.m_bHasFtnSep ) - { - //If default paragraph style is RTL, footnote separator should be right aligned - //and for RTL locales, LTR default paragraph style should present a left aligned footnote separator - try - { - uno::Reference<style::XStyleFamiliesSupplier> xStylesSupplier(rDM_Impl.GetTextDocument(), uno::UNO_QUERY); - if ( xStylesSupplier.is() ) - { - uno::Reference<container::XNameAccess> xStyleFamilies = xStylesSupplier->getStyleFamilies(); - uno::Reference<container::XNameAccess> xParagraphStyles; - if ( xStyleFamilies.is() ) - xStyleFamilies->getByName("ParagraphStyles") >>= xParagraphStyles; - uno::Reference<beans::XPropertySet> xStandard; - if ( xParagraphStyles.is() ) - xParagraphStyles->getByName("Standard") >>= xStandard; - if ( xStandard.is() ) - { - sal_Int16 aWritingMode(0); - xStandard->getPropertyValue( getPropertyName(PROP_WRITING_MODE) ) >>= aWritingMode; - if( aWritingMode == text::WritingMode2::RL_TB ) - Insert( PROP_FOOTNOTE_LINE_ADJUST, uno::makeAny( sal_Int16(text::HorizontalAdjust_RIGHT) ), false ); - else - Insert( PROP_FOOTNOTE_LINE_ADJUST, uno::makeAny( sal_Int16(text::HorizontalAdjust_LEFT) ), false ); - } - } - } - catch ( const uno::Exception& ) {} - } - - /*** 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( bFirstPage, rDM_Impl ); - PrepareHeaderFooterProperties( bFirstPage ); -} - -bool SectionPropertyMap::FloatingTableConversion( const DomainMapper_Impl& rDM_Impl, FloatingTableInfo& rInfo ) -{ - // This is OOXML version of the code deciding if the table needs to be - // in a floating frame. - // For ww8 code, see SwWW8ImplReader::FloatingTableConversion in - // sw/source/filter/ww8/ww8par.cxx - // The two should do the same, so if you make changes here, please check - // that the other is in sync. - - // Note that this is just a list of heuristics till sw core can have a - // table that is floating and can span over multiple pages at the same - // time. - - // If there is an explicit section break right after a table, then there - // will be no wrapping anyway. - if (rDM_Impl.m_bConvertedTable && !rDM_Impl.GetIsLastSectionGroup() && rInfo.m_nBreakType == NS_ooxml::LN_Value_ST_SectionMark_nextPage) - return false; - - sal_Int32 nPageWidth = GetPageWidth(); - sal_Int32 nTextAreaWidth = nPageWidth - GetLeftMargin() - GetRightMargin(); - // Count the layout width of the table. - sal_Int32 nTableWidth = rInfo.m_nTableWidth; - if (rInfo.m_nTableWidthType == text::SizeType::VARIABLE) - { - nTableWidth *= nTextAreaWidth / 100.0; - } - sal_Int32 nLeftMargin = 0; - if ( rInfo.getPropertyValue( u"LeftMargin" ) >>= nLeftMargin ) - nTableWidth += nLeftMargin; - sal_Int32 nRightMargin = 0; - if ( rInfo.getPropertyValue( u"RightMargin" ) >>= nRightMargin ) - nTableWidth += nRightMargin; - - sal_Int16 nHoriOrientRelation = rInfo.getPropertyValue( u"HoriOrientRelation" ).get<sal_Int16>(); - sal_Int16 nVertOrientRelation = rInfo.getPropertyValue( u"VertOrientRelation" ).get<sal_Int16>(); - if ( nHoriOrientRelation == text::RelOrientation::PAGE_FRAME && nVertOrientRelation == text::RelOrientation::PAGE_FRAME ) - { - sal_Int16 nHoriOrient = rInfo.getPropertyValue( u"HoriOrient" ).get<sal_Int16>(); - sal_Int16 nVertOrient = rInfo.getPropertyValue( u"VertOrient" ).get<sal_Int16>(); - if ( nHoriOrient == text::HoriOrientation::NONE && nVertOrient == text::VertOrientation::NONE ) - { - // Anchor position is relative to the page horizontally and vertically as well and is an absolute position. - // The more close we are to the left edge, the less likely there will be any wrapping. - // The more close we are to the bottom, the more likely the table will span over to the next page - // So if we're in the bottom left quarter, don't do any conversion. - sal_Int32 nHoriOrientPosition = rInfo.getPropertyValue( u"HoriOrientPosition" ).get<sal_Int32>(); - sal_Int32 nVertOrientPosition = rInfo.getPropertyValue( u"VertOrientPosition" ).get<sal_Int32>(); - sal_Int32 nPageHeight = getProperty( PROP_HEIGHT )->second.get<sal_Int32>(); - if ( nHoriOrientPosition < (nPageWidth / 2) && nVertOrientPosition >( nPageHeight / 2 ) ) - return false; - } - } - - // It seems Word has a limit here, so that in case the table width is quite - // close to the text area width, then it won't perform a wrapping, even in - // case the content (e.g. an empty paragraph) would fit. The magic constant - // here represents this limit. - const sal_Int32 nMagicNumber = 469; - - // If the table's width is smaller than the text area width, text might - // be next to the table and so it should behave as a floating table. - if ( (nTableWidth + nMagicNumber) < nTextAreaWidth ) - return true; - - // If the position is relative to the edge of the page, then we need to check the whole - // page width to see whether text can fit next to the table. - if ( nHoriOrientRelation == text::RelOrientation::PAGE_FRAME ) - { - // If the table is wide enough so that no text fits next to it, then don't create a fly - // for the table: no wrapping will be performed anyway, but multi-page - // tables will be broken. - if ((nTableWidth + nMagicNumber) < (nPageWidth - std::min(GetLeftMargin(), GetRightMargin()))) - return true; - } - - // If there are columns, always create the fly, otherwise the columns would - // restrict geometry of the table. - if ( ColumnCount() > 1 ) - return true; - - return false; -} - -void SectionPropertyMap::InheritOrFinalizePageStyles( DomainMapper_Impl& rDM_Impl ) -{ - // if no new styles have been created for this section, inherit from the previous section, - // otherwise apply this section's settings to the new style. - // Ensure that FollowPage is inherited first - otherwise GetPageStyle may auto-create a follow when checking FirstPage. - SectionPropertyMap* pLastContext = rDM_Impl.GetLastSectionContext(); - //tdf124637 TODO: identify and skip special sections (like footnotes/endnotes) - if ( pLastContext && m_sFollowPageStyleName.isEmpty() ) - m_sFollowPageStyleName = pLastContext->GetPageStyleName(); - else - { - HandleMarginsHeaderFooter( /*bFirst=*/false, rDM_Impl ); - GetPageStyle( rDM_Impl, /*bFirst=*/false ); - if ( rDM_Impl.IsNewDoc() && m_aFollowPageStyle.is() ) - ApplyProperties_( m_aFollowPageStyle ); - } - - // FirstPageStyle may only be inherited if it will not be used or re-linked to a different follow - if ( !m_bTitlePage && pLastContext && m_sFirstPageStyleName.isEmpty() ) - m_sFirstPageStyleName = pLastContext->GetPageStyleName( /*bFirst=*/true ); - else - { - HandleMarginsHeaderFooter( /*bFirst=*/true, rDM_Impl ); - GetPageStyle( rDM_Impl, /*bFirst=*/true ); - if ( rDM_Impl.IsNewDoc() && m_aFirstPageStyle.is() ) - ApplyProperties_( m_aFirstPageStyle ); - - // Chain m_aFollowPageStyle to be after m_aFirstPageStyle - m_aFirstPageStyle->setPropertyValue( "FollowStyle", uno::makeAny( m_sFollowPageStyleName ) ); - } -} - -void SectionPropertyMap::HandleIncreasedAnchoredObjectSpacing(DomainMapper_Impl& rDM_Impl) -{ - // Ignore Word 2010 and older. - if (rDM_Impl.GetSettingsTable()->GetWordCompatibilityMode() < 15) - return; - - sal_Int32 nPageWidth = GetPageWidth(); - sal_Int32 nTextAreaWidth = nPageWidth - GetLeftMargin() - GetRightMargin(); - - std::vector<AnchoredObjectsInfo>& rAnchoredObjectAnchors = rDM_Impl.m_aAnchoredObjectAnchors; - for (const auto& rAnchor : rAnchoredObjectAnchors) - { - // Ignore this paragraph when there are not enough shapes to trigger the Word bug we - // emulate. - if (rAnchor.m_aAnchoredObjects.size() < 4) - continue; - - // Ignore this paragraph if none of the objects are wrapped in the background. - sal_Int32 nOpaqueCount = 0; - for (const auto& rAnchored : rAnchor.m_aAnchoredObjects) - { - uno::Reference<beans::XPropertySet> xShape(rAnchored.m_xAnchoredObject, uno::UNO_QUERY); - if (!xShape.is()) - { - continue; - } - - bool bOpaque = true; - xShape->getPropertyValue("Opaque") >>= bOpaque; - if (!bOpaque) - { - ++nOpaqueCount; - } - } - if (nOpaqueCount < 1) - { - continue; - } - - // Analyze the anchored objects of this paragraph, now that we know the - // page width. - sal_Int32 nShapesWidth = 0; - for (const auto& rAnchored : rAnchor.m_aAnchoredObjects) - { - uno::Reference<drawing::XShape> xShape(rAnchored.m_xAnchoredObject, uno::UNO_QUERY); - if (!xShape.is()) - continue; - - uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY); - if (!xPropertySet.is()) - continue; - - // Ignore objects with no wrapping. - text::WrapTextMode eWrap = text::WrapTextMode_THROUGH; - xPropertySet->getPropertyValue("Surround") >>= eWrap; - if (eWrap == text::WrapTextMode_THROUGH) - continue; - - // Use the original left margin, in case GraphicImport::lcl_sprm() reduced the doc model - // one to 0. - sal_Int32 nLeftMargin = rAnchored.m_nLeftMargin; - sal_Int32 nRightMargin = 0; - xPropertySet->getPropertyValue("RightMargin") >>= nRightMargin; - nShapesWidth += xShape->getSize().Width + nLeftMargin + nRightMargin; - } - - // Ignore cases when we have enough horizontal space for the shapes. - if (nTextAreaWidth > nShapesWidth) - continue; - - sal_Int32 nHeight = 0; - for (const auto& rAnchored : rAnchor.m_aAnchoredObjects) - { - uno::Reference<drawing::XShape> xShape(rAnchored.m_xAnchoredObject, uno::UNO_QUERY); - if (!xShape.is()) - continue; - - nHeight += xShape->getSize().Height; - } - - uno::Reference<beans::XPropertySet> xParagraph(rAnchor.m_xParagraph, uno::UNO_QUERY); - if (xParagraph.is()) - { - sal_Int32 nTopMargin = 0; - xParagraph->getPropertyValue("ParaTopMargin") >>= nTopMargin; - // Increase top spacing of the paragraph to match Word layout - // behavior. - nTopMargin = std::max(nTopMargin, nHeight); - xParagraph->setPropertyValue("ParaTopMargin", uno::makeAny(nTopMargin)); - } - } - rAnchoredObjectAnchors.clear(); -} - -void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) -{ - SectionPropertyMap* pPrevSection = rDM_Impl.GetLastSectionContext(); - - // The default section type is nextPage. - if ( m_nBreakType == -1 ) - m_nBreakType = NS_ooxml::LN_Value_ST_SectionMark_nextPage; - else if ( m_nBreakType == NS_ooxml::LN_Value_ST_SectionMark_nextColumn ) - { - // Word 2013+ seems to treat a section column break as a page break all the time. - // It always acts like a page break if there are no columns, or a different number of columns. - // Also, if this is the first section, the break type is basically irrelevant - works best as nextPage. - if ( rDM_Impl.GetSettingsTable()->GetWordCompatibilityMode() > 14 - || !pPrevSection - || m_nColumnCount < 2 - || m_nColumnCount != pPrevSection->ColumnCount() - ) - { - m_nBreakType = NS_ooxml::LN_Value_ST_SectionMark_nextPage; - } - } - else if ( m_nBreakType == NS_ooxml::LN_Value_ST_SectionMark_continuous ) - { - // if page orientation differs from previous section, it can't be treated as continuous - if ( pPrevSection ) - { - bool bIsLandscape = false; - std::optional< PropertyMap::Property > pProp = getProperty( PROP_IS_LANDSCAPE ); - if ( pProp ) - pProp->second >>= bIsLandscape; - - bool bPrevIsLandscape = false; - pProp = pPrevSection->getProperty( PROP_IS_LANDSCAPE ); - if ( pProp ) - pProp->second >>= bPrevIsLandscape; - - if ( bIsLandscape != bPrevIsLandscape ) - m_nBreakType = NS_ooxml::LN_Value_ST_SectionMark_nextPage; - } - } - - // Text area width is known at the end of a section: decide if tables should be converted or not. - std::vector<FloatingTableInfo>& rPendingFloatingTables = rDM_Impl.m_aPendingFloatingTables; - uno::Reference<text::XTextAppendAndConvert> xBodyText( rDM_Impl.GetBodyText(), uno::UNO_QUERY ); - for ( FloatingTableInfo & rInfo : rPendingFloatingTables ) - { - rInfo.m_nBreakType = m_nBreakType; - if ( FloatingTableConversion( rDM_Impl, rInfo ) ) - { - std::deque<css::uno::Any> aFramedRedlines = rDM_Impl.m_aStoredRedlines[StoredRedlines::FRAME]; - try - { - // convert redline ranges to cursor movement and character length - std::vector<sal_Int32> redPos, redLen; - std::vector<OUString> redCell; - std::vector<OUString> redTable; - for( size_t i = 0; i < aFramedRedlines.size(); i+=3) - { - uno::Reference<text::XText> xCell; - uno::Reference< text::XTextRange > xRange; - aFramedRedlines[i] >>= xRange; - uno::Reference< beans::XPropertySet > xRangeProperties; - if ( xRange.is() ) - { - OUString sTableName; - OUString sCellName; - xRangeProperties.set( xRange, uno::UNO_QUERY_THROW ); - if (xRangeProperties->getPropertySetInfo()->hasPropertyByName("TextTable")) - { - uno::Any aTable = xRangeProperties->getPropertyValue("TextTable"); - if ( aTable != uno::Any() ) - { - uno::Reference<text::XTextTable> xTable; - aTable >>= xTable; - uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); - xTableProperties->getPropertyValue("TableName") >>= sTableName; - } - if (xRangeProperties->getPropertySetInfo()->hasPropertyByName("Cell")) - { - uno::Any aCell = xRangeProperties->getPropertyValue("Cell"); - if ( aCell != uno::Any() ) - { - aCell >>= xCell; - uno::Reference<beans::XPropertySet> xCellProperties(xCell, uno::UNO_QUERY); - xCellProperties->getPropertyValue("CellName") >>= sCellName; - } - } - } - redTable.push_back(sTableName); - redCell.push_back(sCellName); - bool bOk = false; - if (!sTableName.isEmpty() && !sCellName.isEmpty()) - { - uno::Reference<text::XTextCursor> xRangeCursor = xCell->createTextCursorByRange( xRange ); - if ( xRangeCursor.is() ) - { - bOk = true; - sal_Int32 nLen = xRange->getString().getLength(); - redLen.push_back(nLen); - xRangeCursor->gotoStart(true); - redPos.push_back(xRangeCursor->getString().getLength() - nLen); - } - } - if (!bOk) - { - // missing cell or failed createTextCursorByRange() - redLen.push_back(-1); - redPos.push_back(-1); - } - } - } - - xBodyText->convertToTextFrame(rInfo.m_xStart, rInfo.m_xEnd, - rInfo.m_aFrameProperties); - - uno::Reference<text::XTextTablesSupplier> xTextDocument(rDM_Impl.GetTextDocument(), uno::UNO_QUERY); - uno::Reference<container::XNameAccess> xTables = xTextDocument->getTextTables(); - for( size_t i = 0; i < aFramedRedlines.size(); i+=3) - { - OUString sType; - beans::PropertyValues aRedlineProperties( 3 ); - // skip failed createTextCursorByRange() - if (redPos[i/3] == -1) - continue; - aFramedRedlines[i+1] >>= sType; - aFramedRedlines[i+2] >>= aRedlineProperties; - uno::Reference<text::XTextTable> xTable(xTables->getByName(redTable[i/3]), uno::UNO_QUERY); - uno::Reference<text::XText> xCell(xTable->getCellByName(redCell[i/3]), uno::UNO_QUERY); - uno::Reference<text::XTextCursor> xCrsr = xCell->createTextCursor(); - xCrsr->goRight(redPos[i/3], false); - xCrsr->goRight(redLen[i/3], true); - uno::Reference < text::XRedline > xRedline( xCrsr, uno::UNO_QUERY_THROW ); - xRedline->makeRedline( sType, aRedlineProperties ); - } - } - catch (const uno::Exception&) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "convertToTextFrame() failed"); - } - - aFramedRedlines.clear(); - } - } - rPendingFloatingTables.clear(); - - try - { - HandleIncreasedAnchoredObjectSpacing(rDM_Impl); - } - catch (const uno::Exception&) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "HandleIncreasedAnchoredObjectSpacing() failed"); - } - - if ( m_nLnnMod ) - { - bool bFirst = rDM_Impl.IsLineNumberingSet(); - rDM_Impl.SetLineNumbering( m_nLnnMod, m_nLnc, m_ndxaLnn ); - if ( m_nLnnMin > 0 || (bFirst && m_nLnc == NS_ooxml::LN_Value_ST_LineNumberRestart_newSection) ) - { - //set the starting value at the beginning of the section - try - { - uno::Reference< beans::XPropertySet > xRangeProperties; - if ( m_xStartingRange.is() ) - { - xRangeProperties.set( m_xStartingRange, uno::UNO_QUERY_THROW ); - } - else - { - //set the start value at the beginning of the document - xRangeProperties.set( rDM_Impl.GetTextDocument()->getText()->getStart(), uno::UNO_QUERY_THROW ); - } - // Writer is 1-based, Word is 0-based. - xRangeProperties->setPropertyValue( - getPropertyName(PROP_PARA_LINE_NUMBER_START_VALUE), - uno::makeAny(m_nLnnMin + 1)); - } - catch ( const uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION("writerfilter.dmapper", "Exception in SectionPropertyMap::CloseSectionGroup"); - } - } - } - - if (m_nBreakType == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_continuous) - && !rDM_Impl.IsInComments()) - { - //todo: insert a section or access the already inserted section - uno::Reference< beans::XPropertySet > xSection = - rDM_Impl.appendTextSectionAfter( m_xStartingRange ); - if ( xSection.is() ) - { - if ( m_nColumnCount > 1 ) - ApplyColumnProperties( xSection, rDM_Impl ); - - ApplyProtectionProperties( xSection, rDM_Impl ); - } - - try - { - InheritOrFinalizePageStyles( rDM_Impl ); - ApplySectionProperties( xSection, rDM_Impl ); //depends on InheritOrFinalizePageStyles - OUString aName = m_bTitlePage ? m_sFirstPageStyleName : m_sFollowPageStyleName; - uno::Reference< beans::XPropertySet > xRangeProperties( lcl_GetRangeProperties( m_bIsFirstSection, rDM_Impl, m_xStartingRange ) ); - if ( m_bIsFirstSection && !aName.isEmpty() && xRangeProperties.is() ) - { - xRangeProperties->setPropertyValue( getPropertyName( PROP_PAGE_DESC_NAME ), uno::makeAny( aName ) ); - } - else if ((!m_bFirstPageHeaderLinkToPrevious || - !m_bFirstPageFooterLinkToPrevious || - !m_bDefaultHeaderLinkToPrevious || - !m_bDefaultFooterLinkToPrevious || - !m_bEvenPageHeaderLinkToPrevious || - !m_bEvenPageFooterLinkToPrevious) - && rDM_Impl.GetCurrentXText()) - { // find a node in the section that has a page break and change - // it to apply the page style; see "nightmare scenario" in - // wwSectionManager::InsertSegments() - auto xTextAppend = rDM_Impl.GetCurrentXText(); - uno::Reference<container::XEnumerationAccess> const xCursor( - xTextAppend->createTextCursorByRange( - uno::Reference<text::XTextContent>(xSection, uno::UNO_QUERY_THROW)->getAnchor()), - uno::UNO_QUERY_THROW); - uno::Reference<container::XEnumeration> const xEnum( - xCursor->createEnumeration()); - bool isFound = false; - while (xEnum->hasMoreElements()) - { - uno::Reference<beans::XPropertySet> xElem; - xEnum->nextElement() >>= xElem; - if (xElem->getPropertySetInfo()->hasPropertyByName("BreakType")) - { - style::BreakType bt; - if ((xElem->getPropertyValue("BreakType") >>= bt) - && bt == style::BreakType_PAGE_BEFORE) - { - // tdf#112201: do *not* use m_sFirstPageStyleName here! - xElem->setPropertyValue(getPropertyName(PROP_PAGE_DESC_NAME), - uno::makeAny(m_sFollowPageStyleName)); - isFound = true; - break; - } - } - } - uno::Reference<text::XParagraphCursor> const xPCursor(xCursor, - uno::UNO_QUERY_THROW); - float fCharHeight = 0; - if (!isFound) - { // HACK: try the last paragraph of the previous section - xPCursor->gotoPreviousParagraph(false); - uno::Reference<beans::XPropertySet> const xPSCursor(xCursor, uno::UNO_QUERY_THROW); - style::BreakType bt; - if ((xPSCursor->getPropertyValue("BreakType") >>= bt) - && bt == style::BreakType_PAGE_BEFORE) - { - xPSCursor->setPropertyValue(getPropertyName(PROP_PAGE_DESC_NAME), - uno::makeAny(m_sFollowPageStyleName)); - isFound = true; - } - else - { - xPSCursor->getPropertyValue("CharHeight") >>= fCharHeight; - } - } - if (!isFound && fCharHeight <= 1.0) - { - // If still not found, see if the last paragraph is ~invisible, and work with - // the last-in-practice paragraph. - xPCursor->gotoPreviousParagraph(false); - uno::Reference<beans::XPropertySet> xPropertySet(xCursor, uno::UNO_QUERY_THROW); - OUString aPageDescName; - if ((xPropertySet->getPropertyValue("PageDescName") >>= aPageDescName) - && !aPageDescName.isEmpty()) - { - uno::Reference<beans::XPropertySet> xPageStyle( - rDM_Impl.GetPageStyles()->getByName(aPageDescName), uno::UNO_QUERY); - xPageStyle->setPropertyValue("FollowStyle", - uno::makeAny(m_sFollowPageStyleName)); - } - } - } - } - catch ( const uno::Exception& ) - { - SAL_WARN( "writerfilter", "failed to set PageDescName!" ); - } - } - // If the section is of type "New column" (0x01), then simply insert a column break. - // But only if there actually are columns on the page, otherwise a column break - // seems to be handled like a page break by MSO. - else if (m_nBreakType == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_nextColumn) - && m_nColumnCount > 1 && !rDM_Impl.IsInComments()) - { - try - { - InheritOrFinalizePageStyles( rDM_Impl ); - /*TODO tdf#135343: Just inserting a column break sounds like the right idea, but the implementation is wrong. - * Somehow, the previous column section needs to be extended to cover this new text. - * Currently, it is completely broken, producing a no-column section that starts on a new page. - */ - uno::Reference< beans::XPropertySet > xRangeProperties; - if ( m_xStartingRange.is() ) - { - xRangeProperties.set( m_xStartingRange, uno::UNO_QUERY_THROW ); - } - else - { - //set the start value at the beginning of the document - xRangeProperties.set( rDM_Impl.GetTextDocument()->getText()->getStart(), uno::UNO_QUERY_THROW ); - } - xRangeProperties->setPropertyValue( getPropertyName( PROP_BREAK_TYPE ), uno::makeAny( style::BreakType_COLUMN_BEFORE ) ); - } - catch ( const uno::Exception& ) {} - } - else if (!rDM_Impl.IsInComments()) - { - uno::Reference< beans::XPropertySet > xSection; - ApplyProtectionProperties( xSection, rDM_Impl ); - - //get the properties and create appropriate page styles - uno::Reference< beans::XPropertySet > xFollowPageStyle; - //This part certainly is not needed for footnotes, so don't create unused page styles. - if ( !rDM_Impl.IsInFootOrEndnote() ) - { - xFollowPageStyle.set( GetPageStyle( rDM_Impl, false ) ); - - HandleMarginsHeaderFooter(/*bFirstPage=*/false, rDM_Impl ); - } - - if ( rDM_Impl.GetSettingsTable()->GetMirrorMarginSettings() ) - { - Insert( PROP_PAGE_STYLE_LAYOUT, uno::makeAny( style::PageStyleLayout_MIRRORED ) ); - } - uno::Reference< text::XTextColumns > xColumns; - if ( m_nColumnCount > 1 ) - { - // prefer setting column properties into a section, not a page style if at all possible. - if ( !xSection.is() ) - xSection = rDM_Impl.appendTextSectionAfter( m_xStartingRange ); - if ( xSection.is() ) - ApplyColumnProperties( xSection, rDM_Impl ); - else if ( xFollowPageStyle.is() ) - xColumns = ApplyColumnProperties( xFollowPageStyle, rDM_Impl ); - } - - // these BreakTypes are effectively page-breaks: don't evenly distribute text in columns before a page break; - if ( pPrevSection && pPrevSection->ColumnCount() ) - pPrevSection->DontBalanceTextColumns(); - - //prepare text grid properties - sal_Int32 nHeight = 1; - std::optional< PropertyMap::Property > pProp = getProperty( PROP_HEIGHT ); - if ( pProp ) - pProp->second >>= nHeight; - - sal_Int32 nWidth = 1; - pProp = getProperty( PROP_WIDTH ); - if ( pProp ) - pProp->second >>= nWidth; - - text::WritingMode eWritingMode = text::WritingMode_LR_TB; - pProp = getProperty( PROP_WRITING_MODE ); - if ( pProp ) - pProp->second >>= eWritingMode; - - sal_Int32 nTextAreaHeight = eWritingMode == text::WritingMode_LR_TB ? - nHeight - m_nTopMargin - m_nBottomMargin : - nWidth - m_nLeftMargin - m_nRightMargin; - - sal_Int32 nGridLinePitch = m_nGridLinePitch; - //sep.dyaLinePitch - if ( nGridLinePitch < 1 || nGridLinePitch > 31680 ) - { - SAL_WARN( "writerfilter", "sep.dyaLinePitch outside legal range: " << nGridLinePitch ); - nGridLinePitch = 1; - } - - const sal_Int32 nGridLines = nTextAreaHeight / nGridLinePitch; - if ( nGridLines >= 0 && nGridLines <= SAL_MAX_INT16 ) - Insert( PROP_GRID_LINES, uno::makeAny( sal_Int16(nGridLines) ) ); - - // PROP_GRID_MODE - Insert( PROP_GRID_MODE, uno::makeAny( static_cast<sal_Int16> (m_nGridType) ) ); - if ( m_nGridType == text::TextGridMode::LINES_AND_CHARS ) - { - Insert( PROP_GRID_SNAP_TO_CHARS, uno::makeAny( m_bGridSnapToChars ) ); - } - - sal_Int32 nCharWidth = 423; //240 twip/ 12 pt - const StyleSheetEntryPtr pEntry = rDM_Impl.GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( u"Standard" ); - if ( pEntry ) - { - std::optional< PropertyMap::Property > pPropHeight = pEntry->pProperties->getProperty( PROP_CHAR_HEIGHT_ASIAN ); - if ( pPropHeight ) - { - double fHeight = 0; - if ( pPropHeight->second >>= fHeight ) - nCharWidth = ConversionHelper::convertTwipToMM100( static_cast<tools::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 ); - } - - if ( m_nPageNumberType >= 0 ) - Insert( PROP_NUMBERING_TYPE, uno::makeAny( m_nPageNumberType ) ); - - // #i119558#, force to set document as standard page mode, - // refer to ww8 import process function "SwWW8ImplReader::SetDocumentGrid" - try - { - uno::Reference< beans::XPropertySet > xDocProperties; - xDocProperties.set( rDM_Impl.GetTextDocument(), uno::UNO_QUERY_THROW ); - Insert(PROP_GRID_STANDARD_MODE, uno::makeAny(true)); - xDocProperties->setPropertyValue("DefaultPageMode", uno::makeAny(false)); - } - catch ( const uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION("writerfilter.dmapper", "Exception in SectionPropertyMap::CloseSectionGroup"); - } - - Insert( PROP_GRID_BASE_HEIGHT, uno::makeAny( nGridLinePitch ) ); - Insert( PROP_GRID_BASE_WIDTH, uno::makeAny( nCharWidth ) ); - Insert( PROP_GRID_RUBY_HEIGHT, uno::makeAny( sal_Int32( 0 ) ) ); - - if ( rDM_Impl.IsNewDoc() && xFollowPageStyle.is() ) - ApplyProperties_( xFollowPageStyle ); - - //todo: creating a "First Page" style depends on HasTitlePage and _fFacingPage_ - if ( m_bTitlePage ) - { - CopyLastHeaderFooter( true, rDM_Impl ); - PrepareHeaderFooterProperties( true ); - uno::Reference< beans::XPropertySet > xFirstPageStyle = GetPageStyle( - rDM_Impl, true ); - if ( rDM_Impl.IsNewDoc() ) - ApplyProperties_( xFirstPageStyle ); - - if ( xColumns.is() ) - xFirstPageStyle->setPropertyValue( - getPropertyName( PROP_TEXT_COLUMNS ), uno::makeAny( xColumns ) ); - } - - ApplyBorderToPageStyles( rDM_Impl, m_eBorderApply, m_eBorderOffsetFrom ); - - try - { - //now apply this break at the first paragraph of this section - uno::Reference< beans::XPropertySet > xRangeProperties( lcl_GetRangeProperties( m_bIsFirstSection, rDM_Impl, m_xStartingRange ) ); - - // Handle page breaks with odd/even page numbering. We need to use an extra page style for setting the page style - // to left/right, because if we set it to the normal style, we'd set it to "First Page"/"Default Style", which would - // break them (all default pages would be only left or right). - if ( m_nBreakType == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_evenPage) || m_nBreakType == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_oddPage) ) - { - OUString* pageStyle = m_bTitlePage ? &m_sFirstPageStyleName : &m_sFollowPageStyleName; - OUString evenOddStyleName = rDM_Impl.GetUnusedPageStyleName(); - uno::Reference< beans::XPropertySet > evenOddStyle( - rDM_Impl.GetTextFactory()->createInstance( "com.sun.star.style.PageStyle" ), - uno::UNO_QUERY ); - // Unfortunately using setParent() does not work for page styles, so make a deep copy of the page style. - uno::Reference< beans::XPropertySet > pageProperties( m_bTitlePage ? m_aFirstPageStyle : m_aFollowPageStyle ); - uno::Reference< beans::XPropertySetInfo > pagePropertiesInfo( pageProperties->getPropertySetInfo() ); - const uno::Sequence< beans::Property > propertyList( pagePropertiesInfo->getProperties() ); - // Ignore write-only properties. - static const o3tl::sorted_vector<OUString> aDenylist - = { "FooterBackGraphicURL", "BackGraphicURL", "HeaderBackGraphicURL" }; - for ( const auto& rProperty : propertyList ) - { - if ( (rProperty.Attributes & beans::PropertyAttribute::READONLY) == 0 ) - { - if (aDenylist.find(rProperty.Name) == aDenylist.end()) - evenOddStyle->setPropertyValue( - rProperty.Name, - pageProperties->getPropertyValue(rProperty.Name)); - } - } - evenOddStyle->setPropertyValue( "FollowStyle", uno::makeAny( *pageStyle ) ); - rDM_Impl.GetPageStyles()->insertByName( evenOddStyleName, uno::makeAny( evenOddStyle ) ); - evenOddStyle->setPropertyValue( "HeaderIsOn", uno::makeAny( false ) ); - evenOddStyle->setPropertyValue( "FooterIsOn", uno::makeAny( false ) ); - CopyHeaderFooter( pageProperties, evenOddStyle ); - *pageStyle = evenOddStyleName; // And use it instead of the original one (which is set as follow of this one). - if ( m_nBreakType == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_evenPage) ) - evenOddStyle->setPropertyValue( getPropertyName( PROP_PAGE_STYLE_LAYOUT ), uno::makeAny( style::PageStyleLayout_LEFT ) ); - else if ( m_nBreakType == static_cast<sal_Int32>(NS_ooxml::LN_Value_ST_SectionMark_oddPage) ) - evenOddStyle->setPropertyValue( getPropertyName( PROP_PAGE_STYLE_LAYOUT ), uno::makeAny( style::PageStyleLayout_RIGHT ) ); - } - - if (rDM_Impl.m_xAltChunkStartingRange.is()) - { - xRangeProperties.set(rDM_Impl.m_xAltChunkStartingRange, uno::UNO_QUERY); - } - if (xRangeProperties.is() && (rDM_Impl.IsNewDoc() || rDM_Impl.IsAltChunk())) - { - // Avoid setting page style in case of autotext: so inserting the autotext at the - // end of the document does not introduce an unwanted page break. - // Also avoid setting the page style at the very beginning if it still is the default page style. - const OUString sPageStyle = m_bTitlePage ? m_sFirstPageStyleName : m_sFollowPageStyleName; - if (!rDM_Impl.IsReadGlossaries() - && !rDM_Impl.IsInFootOrEndnote() - && !(m_bIsFirstSection && sPageStyle == getPropertyName( PROP_STANDARD ) && m_nPageNumber < 0) - ) - { - xRangeProperties->setPropertyValue( - getPropertyName( PROP_PAGE_DESC_NAME ), - uno::makeAny(sPageStyle) ); - } - - if (0 <= m_nPageNumber) - { - sal_Int16 nPageNumber = static_cast< sal_Int16 >(m_nPageNumber); - xRangeProperties->setPropertyValue(getPropertyName(PROP_PAGE_NUMBER_OFFSET), - uno::makeAny(nPageNumber)); - } - } - } - catch ( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "SectionPropertyMap::CloseSectionGroup" ); - } - } - - // Now that the margins are known, resize relative width shapes because some shapes in LO do not support percentage-sizes - sal_Int32 nParagraphWidth = GetPageWidth() - m_nLeftMargin - m_nRightMargin; - if ( m_nColumnCount > 1 ) - { - // skip custom-width columns since we don't know what column the shape is in. - if ( !m_aColWidth.empty() ) - nParagraphWidth = 0; - else - nParagraphWidth = (nParagraphWidth - (m_nColumnDistance * (m_nColumnCount - 1))) / m_nColumnCount; - } - if ( nParagraphWidth > 0 ) - { - const OUString sPropRelativeWidth = getPropertyName(PROP_RELATIVE_WIDTH); - for ( const auto& xShape : m_xRelativeWidthShapes ) - { - const uno::Reference<beans::XPropertySet> xShapePropertySet( xShape, uno::UNO_QUERY ); - if ( xShapePropertySet->getPropertySetInfo()->hasPropertyByName(sPropRelativeWidth) ) - { - sal_uInt16 nPercent = 0; - try - { - xShapePropertySet->getPropertyValue(sPropRelativeWidth) >>= nPercent; - } - catch (const css::uno::RuntimeException& e) - { - // May happen e.g. when text frame has no frame format - // See sw/qa/extras/ooxmlimport/data/n779627.docx - SAL_WARN("writerfilter", "Getting relative width failed. " << e.Message); - } - if ( nPercent ) - { - const sal_Int32 nWidth = nParagraphWidth * nPercent / 100; - xShape->setSize( awt::Size( nWidth, xShape->getSize().Height ) ); - } - } - } - } - m_xRelativeWidthShapes.clear(); - - rDM_Impl.SetIsLastSectionGroup( false ); - rDM_Impl.SetIsFirstParagraphInSection( true ); - - if ( !rDM_Impl.IsInFootOrEndnote() && !rDM_Impl.IsInComments() ) - { - rDM_Impl.m_bHasFtn = false; - rDM_Impl.m_bHasFtnSep = false; - } -} - -// Clear the flag that says we should take the header/footer content from -// the previous section. This should be called when we encounter a header -// or footer definition for this section. -void SectionPropertyMap::ClearHeaderFooterLinkToPrevious( bool bHeader, PageType eType ) -{ - if ( bHeader ) - { - switch ( eType ) - { - case PAGE_FIRST: m_bFirstPageHeaderLinkToPrevious = false; break; - case PAGE_LEFT: m_bEvenPageHeaderLinkToPrevious = false; break; - case PAGE_RIGHT: m_bDefaultHeaderLinkToPrevious = false; break; - // no default case as all enumeration values have been covered - } - } - else - { - switch ( eType ) - { - case PAGE_FIRST: m_bFirstPageFooterLinkToPrevious = false; break; - case PAGE_LEFT: m_bEvenPageFooterLinkToPrevious = false; break; - case PAGE_RIGHT: m_bDefaultFooterLinkToPrevious = false; break; - } - } -} - -namespace { - -class NamedPropertyValue -{ -private: - OUString m_aName; - -public: - explicit NamedPropertyValue( const OUString& i_aStr ) - : m_aName( i_aStr ) - { - } - - bool operator() ( beans::PropertyValue const & aVal ) - { - return aVal.Name == m_aName; - } -}; - -} - -void SectionPropertyMap::ApplyProperties_( const uno::Reference< beans::XPropertySet >& xStyle ) -{ - uno::Reference< beans::XMultiPropertySet > const xMultiSet( xStyle, uno::UNO_QUERY ); - - std::vector< OUString > vNames; - std::vector< uno::Any > vValues; - { - // Convert GetPropertyValues() value into something useful - uno::Sequence< beans::PropertyValue > vPropVals = GetPropertyValues(); - - //Temporarily store the items that are in grab bags - uno::Sequence< beans::PropertyValue > vCharVals; - uno::Sequence< beans::PropertyValue > vParaVals; - beans::PropertyValue* pCharGrabBag = std::find_if( vPropVals.begin(), vPropVals.end(), NamedPropertyValue( "CharInteropGrabBag" ) ); - if ( pCharGrabBag != vPropVals.end() ) - (pCharGrabBag->Value) >>= vCharVals; - beans::PropertyValue* pParaGrabBag = std::find_if( vPropVals.begin(), vPropVals.end(), NamedPropertyValue( "ParaInteropGrabBag" ) ); - if ( pParaGrabBag != vPropVals.end() ) - (pParaGrabBag->Value) >>= vParaVals; - - for ( beans::PropertyValue* pIter = vPropVals.begin(); pIter != vPropVals.end(); ++pIter ) - { - if ( pIter != pCharGrabBag && pIter != pParaGrabBag - && pIter->Name != "IsProtected" //section-only property - ) - { - vNames.push_back( pIter->Name ); - vValues.push_back( pIter->Value ); - } - } - for ( const beans::PropertyValue & v : std::as_const(vCharVals) ) - { - vNames.push_back( v.Name ); - vValues.push_back( v.Value ); - } - for ( const beans::PropertyValue & v : std::as_const(vParaVals) ) - { - vNames.push_back( v.Name ); - vValues.push_back( v.Value ); - } - } - if ( xMultiSet.is() ) - { - try - { - xMultiSet->setPropertyValues( comphelper::containerToSequence( vNames ), comphelper::containerToSequence( vValues ) ); - return; - } - catch ( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "SectionPropertyMap::ApplyProperties_" ); - } - } - for ( size_t i = 0; i < vNames.size(); ++i ) - { - try - { - if ( xStyle.is() ) - xStyle->setPropertyValue( vNames[i], vValues[i] ); - } - catch ( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "SectionPropertyMap::ApplyProperties_" ); - } - } -} - -sal_Int32 SectionPropertyMap::GetPageWidth() const -{ - return getProperty( PROP_WIDTH )->second.get<sal_Int32>(); -} - -StyleSheetPropertyMap::StyleSheetPropertyMap() - : mnListLevel( -1 ) - , mnOutlineLevel( -1 ) -{ -} - -ParagraphProperties::ParagraphProperties() - : m_bFrameMode( false ) - , m_nDropCap( NS_ooxml::LN_Value_doc_ST_DropCap_none ) - , m_nLines( 0 ) - , m_w( -1 ) - , m_h( -1 ) - , m_nWrap( text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE ) - , m_hAnchor( -1 ) - , m_vAnchor( -1 ) - , 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_nDropCapLength( 0 ) -{ -} - -bool 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 ); -} - -void ParagraphProperties::ResetFrameProperties() -{ - m_bFrameMode = false; - m_nDropCap = NS_ooxml::LN_Value_doc_ST_DropCap_none; - m_nLines = 0; - m_w = -1; - m_h = -1; - m_nWrap = text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE; - m_hAnchor = -1; - m_vAnchor = -1; - 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_nDropCapLength = 0; -} - -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, const bool bOverwrite ) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement( "TablePropertyMap.insertTableProperties" ); - pMap->dumpXml(); -#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 && (bOverwrite || !m_aValidValues[eTarget].bValid) ) - { - m_aValidValues[eTarget].bValid = true; - m_aValidValues[eTarget].nValue = pSource->m_aValidValues[eTarget].nValue; - } - } - } - -#ifdef DBG_UTIL - dumpXml(); - TagLogger::getInstance().endElement(); -#endif -} - -} // namespace writerfilter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx deleted file mode 100644 index f8c976abd388..000000000000 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ /dev/null @@ -1,609 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PROPERTYMAP_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PROPERTYMAP_HXX - -#include <rtl/ustring.hxx> -#include <tools/ref.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/table/BorderLine2.hpp> -#include <com/sun/star/text/WrapTextMode.hpp> -#include <com/sun/star/uno/Any.h> -#include <com/sun/star/drawing/XShape.hpp> -#include "PropertyIds.hxx" -#include <memory> -#include <optional> -#include <map> -#include <vector> -#include <set> - -namespace com::sun::star { - namespace beans { - struct PropertyValue; - } - namespace container { - class XNameContainer; - } - namespace lang { - class XMultiServiceFactory; - } - namespace text { - class XTextRange; - class XTextColumns; - class XFootnote; - } - namespace table { - struct BorderLine2; - struct ShadowFormat; - } -} - -namespace writerfilter::dmapper { - -class DomainMapper_Impl; -struct FloatingTableInfo; -struct AnchoredObjectInfo; - -enum BorderPosition -{ - BORDER_LEFT, - BORDER_RIGHT, - BORDER_TOP, - BORDER_BOTTOM -}; - -enum GrabBagType -{ - NO_GRAB_BAG, - ROW_GRAB_BAG, - CELL_GRAB_BAG, - PARA_GRAB_BAG, - CHAR_GRAB_BAG -}; - -struct RedlineParams : public virtual SvRefBase -{ - OUString m_sAuthor; - OUString m_sDate; - sal_Int32 m_nToken; - - // This can hold properties of runs that had formatted 'track changes' properties - css::uno::Sequence< css::beans::PropertyValue > m_aRevertProperties; -}; - -typedef tools::SvRef< RedlineParams > RedlineParamsPtr; - -class PropValue -{ -private: - css::uno::Any m_aValue; - GrabBagType m_GrabBagType; - bool m_bIsDocDefault; - -public: - PropValue( const css::uno::Any& rValue, GrabBagType i_GrabBagType, bool bDocDefault ) - : m_aValue( rValue ) - , m_GrabBagType( i_GrabBagType ) - , m_bIsDocDefault( bDocDefault ) - { - } - - PropValue( const css::uno::Any& rValue, GrabBagType i_GrabBagType ) - : m_aValue( rValue ) - , m_GrabBagType( i_GrabBagType ) - , m_bIsDocDefault( false ) - { - } - - PropValue() - : m_aValue() - , m_GrabBagType( NO_GRAB_BAG ) - , m_bIsDocDefault( false ) - { - } - - const css::uno::Any& getValue() const { return m_aValue; } - - GrabBagType getGrabBagType() const { return m_GrabBagType; } - - bool getIsDocDefault() const { return m_bIsDocDefault; } -}; - -class PropertyMap; -typedef tools::SvRef< PropertyMap > PropertyMapPtr; - -class PropertyMap : public virtual SvRefBase -{ -private: - // Cache the property values for the GetPropertyValues() call(s). - std::vector< css::beans::PropertyValue > m_aValues; - - // marks context as footnote context - ::text( ) events contain either the footnote character or can be ignored - // depending on sprmCSymbol - css::uno::Reference< css::text::XFootnote > m_xFootnote; - OUString m_sFootnoteCharStyleName; - std::map< PropertyIds, PropValue > m_vMap; - std::vector< RedlineParamsPtr > m_aRedlines; - -public: - typedef std::pair< PropertyIds, css::uno::Any > Property; - - PropertyMap() {} - - // Sequence: Grab Bags: The CHAR_GRAB_BAG has Name "CharInteropGrabBag" and the PARA_GRAB_BAG has Name "ParaInteropGrabBag" - // the contained properties are their Value. - css::uno::Sequence< css::beans::PropertyValue > GetPropertyValues( bool bCharGrabBag = true ); - - std::vector< PropertyIds > GetPropertyIds(); - - // Add property, optionally overwriting existing attributes - void Insert( PropertyIds eId, const css::uno::Any& rAny, bool bOverwrite = true, GrabBagType i_GrabBagType = NO_GRAB_BAG, bool bDocDefault = false ); - - // Remove a named property from *this, does nothing if the property id has not been set - void Erase( PropertyIds eId); - - // Imports properties from pMap (bOverwrite==false means m_bIsDocDefault=true setting) - void InsertProps( const PropertyMapPtr& rMap, const bool bOverwrite = true ); - - // Returns a copy of the property if it exists, .first is its PropertyIds and .second is its Value (type css::uno::Any) - std::optional< Property > getProperty( PropertyIds eId ) const; - - // Has the property named been set (via Insert)? - bool isSet( PropertyIds eId ) const; - bool isDocDefault( PropertyIds eId ) const; - - const css::uno::Reference< css::text::XFootnote >& GetFootnote() const { return m_xFootnote; } - const OUString& GetFootnoteStyle() const { return m_sFootnoteCharStyleName; } - - void SetFootnote(const css::uno::Reference< css::text::XFootnote >& xFootnote, const OUString& sStyleName) - { - m_xFootnote = xFootnote; - m_sFootnoteCharStyleName = sStyleName; - } - - virtual void insertTableProperties( const PropertyMap*, const bool bOverwrite = true ); - - const std::vector< RedlineParamsPtr >& Redlines() const { return m_aRedlines; } - - std::vector< RedlineParamsPtr >& Redlines() { return m_aRedlines; } - - void printProperties(); - -#ifdef DBG_UTIL - void dumpXml() const; -#endif - - static css::table::ShadowFormat getShadowFromBorder( const css::table::BorderLine2& rBorder ); - -protected: - void Invalidate() - { - if ( m_aValues.size() ) - m_aValues.clear(); - } -}; - -class SectionPropertyMap : public PropertyMap -{ -public: - enum class BorderApply - { - ToAllInSection = 0, - ToFirstPageInSection = 1, - ToAllButFirstInSection = 2 - }; - enum class BorderOffsetFrom - { - Text = 0, - Edge = 1, - }; -private: -#ifdef DBG_UTIL - sal_Int32 m_nDebugSectionNumber; -#endif - - // 'temporarily' the section page settings are imported as page styles - // empty strings mark page settings as not yet imported - - bool m_bIsFirstSection; - css::uno::Reference< css::text::XTextRange > m_xStartingRange; - - OUString m_sFirstPageStyleName; - OUString m_sFollowPageStyleName; - css::uno::Reference< css::beans::XPropertySet > m_aFirstPageStyle; - css::uno::Reference< css::beans::XPropertySet > m_aFollowPageStyle; - - std::optional< css::table::BorderLine2 > m_oBorderLines[4]; - sal_Int32 m_nBorderDistances[4]; - BorderApply m_eBorderApply; - BorderOffsetFrom m_eBorderOffsetFrom; - bool m_bBorderShadows[4]; - - bool m_bTitlePage; - sal_Int16 m_nColumnCount; - sal_Int32 m_nColumnDistance; - css::uno::Reference< css::beans::XPropertySet > m_xColumnContainer; - std::vector< sal_Int32 > m_aColWidth; - std::vector< sal_Int32 > m_aColDistance; - - bool m_bSeparatorLineIsOn; - bool m_bEvenlySpaced; - - sal_Int32 m_nPageNumber; - // Page number type is a value from css::style::NumberingType. - sal_Int16 m_nPageNumberType; - sal_Int32 m_nBreakType; - - sal_Int32 m_nLeftMargin; - sal_Int32 m_nRightMargin; - sal_Int32 m_nGutterMargin; - sal_Int32 m_nTopMargin; - sal_Int32 m_nBottomMargin; - sal_Int32 m_nHeaderTop; - sal_Int32 m_nHeaderBottom; - - sal_Int32 m_nGridType; - sal_Int32 m_nGridLinePitch; - sal_Int32 m_nDxtCharSpace; - bool m_bGridSnapToChars; - - // line numbering - sal_Int32 m_nLnnMod; - sal_uInt32 m_nLnc; - sal_Int32 m_ndxaLnn; - sal_Int32 m_nLnnMin; - - std::vector<css::uno::Reference<css::drawing::XShape>> m_xRelativeWidthShapes; - - // The "Link To Previous" flag indicates whether the header/footer - // content should be taken from the previous section - bool m_bDefaultHeaderLinkToPrevious; - bool m_bEvenPageHeaderLinkToPrevious; - bool m_bFirstPageHeaderLinkToPrevious; - bool m_bDefaultFooterLinkToPrevious; - bool m_bEvenPageFooterLinkToPrevious; - bool m_bFirstPageFooterLinkToPrevious; - - void ApplyProperties_( const css::uno::Reference< css::beans::XPropertySet >& xStyle ); - - void DontBalanceTextColumns(); - - /// Apply section-specific properties: only valid to use after PageStyle has been determined by InheritOrFinalizePageStyles - void ApplySectionProperties( const css::uno::Reference< css::beans::XPropertySet >& xSection, DomainMapper_Impl& rDM_Impl ); - - /// Check if document is protected. If so, ensure a section exists, and apply its protected value. - void ApplyProtectionProperties( css::uno::Reference< css::beans::XPropertySet >& xSection, DomainMapper_Impl& rDM_Impl ); - - css::uno::Reference< css::text::XTextColumns > ApplyColumnProperties( const css::uno::Reference< css::beans::XPropertySet >& xFollowPageStyle, - DomainMapper_Impl& rDM_Impl); - - void CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl ); - - static void CopyHeaderFooter( const css::uno::Reference< css::beans::XPropertySet >& xPrevStyle, - const css::uno::Reference< css::beans::XPropertySet >& xStyle, - bool bOmitRightHeader = false, bool bOmitLeftHeader = false, - bool bOmitRightFooter = false, bool bOmitLeftFooter = false ); - - static void CopyHeaderFooterTextProperty( const css::uno::Reference< css::beans::XPropertySet >& xPrevStyle, - const css::uno::Reference< css::beans::XPropertySet >& xStyle, - PropertyIds ePropId ); - - void PrepareHeaderFooterProperties( bool bFirstPage ); - - bool HasHeader( bool bFirstPage ) const; - bool HasFooter( bool bFirstPage ) const; - - static void SetBorderDistance( const css::uno::Reference< css::beans::XPropertySet >& xStyle, - PropertyIds eMarginId, - PropertyIds eDistId, - sal_Int32 nDistance, - BorderOffsetFrom eOffsetFrom, - sal_uInt32 nLineWidth ); - - // Determines if conversion of a given floating table is wanted or not. - bool FloatingTableConversion( const DomainMapper_Impl& rDM_Impl, FloatingTableInfo& rInfo ); - - /// Increases paragraph spacing according to Word 2013+ needs if necessary. - void HandleIncreasedAnchoredObjectSpacing(DomainMapper_Impl& rDM_Impl); - -public: - enum PageType - { - PAGE_FIRST, - PAGE_LEFT, - PAGE_RIGHT - }; - - explicit SectionPropertyMap( bool bIsFirstSection ); - - bool IsFirstSection() const { return m_bIsFirstSection; } - - void SetStart( const css::uno::Reference< css::text::XTextRange >& xRange ) { m_xStartingRange = xRange; } - - const css::uno::Reference< css::text::XTextRange >& GetStartingRange() const { return m_xStartingRange; } - - css::uno::Reference< css::beans::XPropertySet > GetPageStyle( DomainMapper_Impl& rDM_Impl, bool bFirst ); - - const OUString& GetPageStyleName( bool bFirstPage = false ) - { - return bFirstPage ? m_sFirstPageStyleName : m_sFollowPageStyleName; - } - - // @throws css::beans::UnknownPropertyException - // @throws css::beans::PropertyVetoException - // @throws css::lang::IllegalArgumentException - // @throws css::lang::WrappedTargetException - // @throws css::uno::RuntimeException - void InheritOrFinalizePageStyles( DomainMapper_Impl& rDM_Impl ); - - void SetBorder( BorderPosition ePos, sal_Int32 nLineDistance, const css::table::BorderLine2& rBorderLine, bool bShadow ); - void SetBorderApply( BorderApply nSet ) { m_eBorderApply = nSet; } - void SetBorderOffsetFrom( BorderOffsetFrom nSet ) { m_eBorderOffsetFrom = nSet; } - - void SetColumnCount( sal_Int16 nCount ) { m_nColumnCount = nCount; } - sal_Int16 ColumnCount() const { return m_nColumnCount; } - - 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 SetPageNumber( sal_Int32 nSet ) { m_nPageNumber = nSet; } - void SetPageNumberType( sal_Int32 nSet ) { m_nPageNumberType = nSet; } - void SetBreakType( sal_Int32 nSet ) { m_nBreakType = nSet; } - // GetBreakType returns -1 if the breakType has not yet been identified for the section - sal_Int32 GetBreakType() const { return m_nBreakType; } - - void SetLeftMargin( sal_Int32 nSet ) { m_nLeftMargin = nSet; } - sal_Int32 GetLeftMargin() const { return m_nLeftMargin; } - void SetRightMargin( sal_Int32 nSet ) { m_nRightMargin = nSet; } - sal_Int32 GetRightMargin() const { return m_nRightMargin; } - 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 SetGutterMargin( sal_Int32 nGutterMargin ) { m_nGutterMargin = nGutterMargin; } - sal_Int32 GetPageWidth() const; - - void SetGridType( sal_Int32 nSet ) { m_nGridType = nSet; } - void SetGridLinePitch( sal_Int32 nSet ) { m_nGridLinePitch = nSet; } - void SetGridSnapToChars( bool bSet ) { m_bGridSnapToChars = bSet; } - 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; } - - void addRelativeWidthShape( css::uno::Reference<css::drawing::XShape> xShape ) { m_xRelativeWidthShapes.push_back( xShape ); } - - // determine which style gets the borders - void ApplyBorderToPageStyles( DomainMapper_Impl &rDM_Impl, - BorderApply eBorderApply, BorderOffsetFrom eOffsetFrom ); - - void CloseSectionGroup( DomainMapper_Impl& rDM_Impl ); - // Handling of margins, header and footer for any kind of sections breaks. - void HandleMarginsHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl ); - void ClearHeaderFooterLinkToPrevious( bool bHeader, PageType eType ); -}; - -class ParagraphProperties : public virtual SvRefBase -{ -private: - 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 - css::text::WrapTextMode 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 - sal_Int8 m_nDropCapLength; // number of characters - OUString m_sParaStyleName; - - css::uno::Reference< css::text::XTextRange > m_xStartingRange; // start of a frame - css::uno::Reference< css::text::XTextRange > m_xEndingRange; // end of the frame - sal_Int32 m_nListId = -1; - -public: - ParagraphProperties(); - - ParagraphProperties(ParagraphProperties const &) = default; - ParagraphProperties(ParagraphProperties &&) = default; - ParagraphProperties & operator =(ParagraphProperties const &) = default; - ParagraphProperties & operator =(ParagraphProperties &&) = default; - - // Does not compare the starting/ending range, m_sParaStyleName and m_nDropCapLength - bool operator==( const ParagraphProperties& ); - - sal_Int32 GetListId() const { return m_nListId; } - void SetListId( sal_Int32 nId ) { m_nListId = nId; } - - bool IsFrameMode() const { return m_bFrameMode; } - void SetFrameMode( bool set = true ) { m_bFrameMode = set; } - - sal_Int32 GetDropCap() const { return m_nDropCap; } - void SetDropCap( sal_Int32 nSet ) { m_nDropCap = nSet; } - - sal_Int32 GetLines() const { return m_nLines; } - void SetLines( sal_Int32 nSet ) { m_nLines = nSet; } - - sal_Int32 Getw() const { return m_w; } - void Setw( sal_Int32 nSet ) { m_w = nSet; } - - sal_Int32 Geth() const { return m_h; } - void Seth( sal_Int32 nSet ) { m_h = nSet; } - - css::text::WrapTextMode GetWrap() const { return m_nWrap; } - void SetWrap( css::text::WrapTextMode nSet ) { m_nWrap = nSet; } - - sal_Int32 GethAnchor() const { return m_hAnchor; } - void SethAnchor( sal_Int32 nSet ) { m_hAnchor = nSet; } - - sal_Int32 GetvAnchor() const { return m_vAnchor; } - void SetvAnchor( sal_Int32 nSet ) { m_vAnchor = nSet; } - - sal_Int32 Getx() const { return m_x; } - void Setx( sal_Int32 nSet ) { m_x = nSet; m_bxValid = true; } - bool IsxValid() const { return m_bxValid; } - - sal_Int32 Gety() const { return m_y; } - void Sety( sal_Int32 nSet ) { m_y = nSet; m_byValid = true; } - bool IsyValid() const { return m_byValid; } - - void SethSpace( sal_Int32 nSet ) { m_hSpace = nSet; } - sal_Int32 GethSpace() const { return m_hSpace; } - - sal_Int32 GetvSpace() const { return m_vSpace; } - void SetvSpace( sal_Int32 nSet ) { m_vSpace = nSet; } - - sal_Int32 GethRule() const { return m_hRule; } - void SethRule( sal_Int32 nSet ) { m_hRule = nSet; } - - sal_Int32 GetxAlign() const { return m_xAlign; } - void SetxAlign( sal_Int32 nSet ) { m_xAlign = nSet; } - - sal_Int32 GetyAlign() const { return m_yAlign; } - void SetyAlign( sal_Int32 nSet ) { m_yAlign = nSet; } - - sal_Int8 GetDropCapLength() const { return m_nDropCapLength; } - void SetDropCapLength( sal_Int8 nSet ) { m_nDropCapLength = nSet; } - - const css::uno::Reference< css::text::XTextRange >& GetStartingRange() const { return m_xStartingRange; } - void SetStartingRange( const css::uno::Reference< css::text::XTextRange >& xSet ) { m_xStartingRange = xSet; } - - const css::uno::Reference< css::text::XTextRange >& GetEndingRange() const { return m_xEndingRange; } - void SetEndingRange( const css::uno::Reference< css::text::XTextRange >& xSet ) { m_xEndingRange = xSet; } - - const OUString& GetParaStyleName() const { return m_sParaStyleName; } - void SetParaStyleName( const OUString& rSet ) { m_sParaStyleName = rSet; } - - void ResetFrameProperties(); -}; - -typedef tools::SvRef< ParagraphProperties > ParagraphPropertiesPtr; - -/*------------------------------------------------------------------------- - property map of a stylesheet - -----------------------------------------------------------------------*/ - -#define WW_OUTLINE_MAX sal_Int16( 9 ) -#define WW_OUTLINE_MIN sal_Int16( 0 ) - -class StyleSheetPropertyMap - : public PropertyMap - , public ParagraphProperties -{ -private: - sal_Int16 mnListLevel; - sal_Int16 mnOutlineLevel; - -public: - explicit StyleSheetPropertyMap(); - - 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() {} -}; - -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, - TABLE_WIDTH_TYPE, - 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() {} - - bool getValue( TablePropertyMapTarget eWhich, sal_Int32& nFill ); - void setValue( TablePropertyMapTarget eWhich, sal_Int32 nSet ); - - virtual void insertTableProperties( const PropertyMap*, const bool bOverwrite = true ) override; -}; - -typedef tools::SvRef< TablePropertyMap > TablePropertyMapPtr; - -/// Information about a paragraph to be finished after a table end. -struct TableParagraph -{ - css::uno::Reference<css::text::XTextRange> m_rStartParagraph; - css::uno::Reference<css::text::XTextRange> m_rEndParagraph; - PropertyMapPtr m_pPropertyMap; - css::uno::Reference<css::beans::XPropertySet> m_rPropertySet; - std::set<OUString> m_aParaOverrideApplied; -}; - -typedef std::shared_ptr< std::vector<TableParagraph> > TableParagraphVectorPtr; - -} // namespace writerfilter::dmapper - -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PROPERTYMAP_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyMapHelper.cxx b/writerfilter/source/dmapper/PropertyMapHelper.cxx deleted file mode 100644 index a944dc147aa4..000000000000 --- a/writerfilter/source/dmapper/PropertyMapHelper.cxx +++ /dev/null @@ -1,98 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <com/sun/star/text/TableColumnSeparator.hpp> -#include "TagLogger.hxx" -#include "PropertyMapHelper.hxx" - -namespace writerfilter::dmapper -{ -using namespace ::com::sun::star; - -void lcl_DumpTableColumnSeparators(const uno::Any& rTableColumnSeparators) -{ -#ifdef DBG_UTIL - uno::Sequence<text::TableColumnSeparator> aSeq; - rTableColumnSeparators >>= aSeq; - - TagLogger::getInstance().startElement("property.TableColumnSeparators"); - - sal_uInt32 nLength = aSeq.getLength(); - for (sal_uInt32 n = 0; n < nLength; ++n) - { - TagLogger::getInstance().startElement("separator"); - - TagLogger::getInstance().attribute("position", aSeq[n].Position); - TagLogger::getInstance().attribute("visible", sal_uInt32(aSeq[n].IsVisible)); - - TagLogger::getInstance().endElement(); - } - - TagLogger::getInstance().endElement(); -#else - (void)rTableColumnSeparators; -#endif // DBG_UTIL -} - -#ifdef DBG_UTIL -void lcl_DumpPropertyValues(beans::PropertyValues const& rValues) -{ - TagLogger::getInstance().startElement("propertyValues"); - - for (beans::PropertyValue const& propVal : rValues) - { - TagLogger::getInstance().startElement("propertyValue"); - - TagLogger::getInstance().attribute("name", propVal.Name); - - try - { - sal_Int32 aInt = 0; - propVal.Value >>= aInt; - TagLogger::getInstance().attribute("value", aInt); - } - catch (...) - { - } - - if (propVal.Name == "TableColumnSeparators") - { - lcl_DumpTableColumnSeparators(propVal.Value); - } - - TagLogger::getInstance().endElement(); - } - TagLogger::getInstance().endElement(); -} - -void lcl_DumpPropertyValueSeq(css::uno::Sequence<css::beans::PropertyValues> const& rPropValSeq) -{ - TagLogger::getInstance().startElement("PropertyValueSeq"); - - for (auto const& propVal : rPropValSeq) - { - lcl_DumpPropertyValues(propVal); - } - - TagLogger::getInstance().endElement(); -} -#endif // DBG_UTIL -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyMapHelper.hxx b/writerfilter/source/dmapper/PropertyMapHelper.hxx deleted file mode 100644 index 044ae1b92f35..000000000000 --- a/writerfilter/source/dmapper/PropertyMapHelper.hxx +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PROPERTYMAPHELPER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PROPERTYMAPHELPER_HXX - -#include <com/sun/star/beans/PropertyValues.hpp> - -namespace writerfilter::dmapper -{ -void lcl_DumpTableColumnSeparators(const css::uno::Any& rTableColumnSeparators); -#ifdef DBG_UTIL -void lcl_DumpPropertyValues(css::beans::PropertyValues const& rValues); - -void lcl_DumpPropertyValueSeq(css::uno::Sequence<css::beans::PropertyValues> const& rPropValSeq); -#endif // DBG_UTIL -} - -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_PROPERTYMAPHELPER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx deleted file mode 100644 index dd3b7c755ac6..000000000000 --- a/writerfilter/source/dmapper/SdtHelper.cxx +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "SdtHelper.hxx" -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/drawing/XControlShape.hpp> -#include <com/sun/star/text/VertOrientation.hpp> -#include <editeng/unoprnms.hxx> -#include <vcl/svapp.hxx> -#include <vcl/outdev.hxx> -#include <comphelper/sequence.hxx> -#include <xmloff/odffields.hxx> -#include <com/sun/star/text/XTextField.hpp> -#include "DomainMapper_Impl.hxx" -#include "StyleSheetTable.hxx" -#include <officecfg/Office/Writer.hxx> - -namespace writerfilter::dmapper -{ -using namespace ::com::sun::star; - -/// w:sdt's w:dropDownList doesn't have width, so guess the size based on the longest string. -static awt::Size lcl_getOptimalWidth(const StyleSheetTablePtr& pStyleSheet, - OUString const& rDefault, std::vector<OUString>& rItems) -{ - OUString aLongest = rDefault; - sal_Int32 nHeight = 0; - for (const OUString& rItem : rItems) - if (rItem.getLength() > aLongest.getLength()) - aLongest = rItem; - - MapMode aMap(MapUnit::Map100thMM); - OutputDevice* pOut = Application::GetDefaultDevice(); - pOut->Push(PushFlags::FONT | PushFlags::MAPMODE); - - PropertyMapPtr pDefaultCharProps = pStyleSheet->GetDefaultCharProps(); - vcl::Font aFont(pOut->GetFont()); - std::optional<PropertyMap::Property> aFontName - = pDefaultCharProps->getProperty(PROP_CHAR_FONT_NAME); - if (aFontName) - aFont.SetFamilyName(aFontName->second.get<OUString>()); - std::optional<PropertyMap::Property> aHeight = pDefaultCharProps->getProperty(PROP_CHAR_HEIGHT); - if (aHeight) - { - nHeight = aHeight->second.get<double>() * 35; // points -> mm100 - aFont.SetFontSize(Size(0, nHeight)); - } - pOut->SetFont(aFont); - pOut->SetMapMode(aMap); - sal_Int32 nWidth = pOut->GetTextWidth(aLongest); - - pOut->Pop(); - - // Border: see PDFWriterImpl::drawFieldBorder(), border size is font height / 4, - // so additional width / height needed is height / 2. - sal_Int32 nBorder = nHeight / 2; - - // Width: space for the text + the square having the dropdown arrow. - return { nWidth + nBorder + nHeight, nHeight + nBorder }; -} - -SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl) - : m_rDM_Impl(rDM_Impl) - , m_bInsideDropDownControl(false) - , m_bHasElements(false) - , m_bOutsideAParagraph(false) -{ -} - -SdtHelper::~SdtHelper() = default; - -void SdtHelper::createDropDownControl() -{ - assert(m_bInsideDropDownControl); - - const bool bDropDown - = officecfg::Office::Writer::Filter::Import::DOCX::ImportComboBoxAsDropDown::get(); - const OUString aDefaultText = m_aSdtTexts.makeStringAndClear(); - - if (bDropDown) - { - // create field - uno::Reference<css::text::XTextField> xControlModel( - m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.text.TextField.DropDown"), - uno::UNO_QUERY); - - const auto it = std::find_if( - m_aDropDownItems.begin(), m_aDropDownItems.end(), - [aDefaultText](const OUString& item) -> bool { return !item.compareTo(aDefaultText); }); - - if (m_aDropDownItems.end() == it) - { - m_aDropDownItems.push_back(aDefaultText); - } - - // set properties - uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY); - xPropertySet->setPropertyValue("SelectedItem", uno::makeAny(aDefaultText)); - xPropertySet->setPropertyValue( - "Items", uno::makeAny(comphelper::containerToSequence(m_aDropDownItems))); - - // add it into document - m_rDM_Impl.appendTextContent(xControlModel, uno::Sequence<beans::PropertyValue>()); - - m_bHasElements = true; - } - else - { - // create control - uno::Reference<awt::XControlModel> xControlModel( - m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.form.component.ComboBox"), - uno::UNO_QUERY); - - // set properties - uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY); - xPropertySet->setPropertyValue("DefaultText", uno::makeAny(aDefaultText)); - xPropertySet->setPropertyValue("Dropdown", uno::makeAny(true)); - xPropertySet->setPropertyValue( - "StringItemList", uno::makeAny(comphelper::containerToSequence(m_aDropDownItems))); - - // add it into document - createControlShape( - lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), aDefaultText, m_aDropDownItems), - xControlModel, uno::Sequence<beans::PropertyValue>()); - } - - // clean up - m_aDropDownItems.clear(); - m_bInsideDropDownControl = false; -} - -bool SdtHelper::validateDateFormat() -{ - return !m_sDateFormat.toString().isEmpty() && !m_sLocale.toString().isEmpty(); -} - -void SdtHelper::createDateContentControl() -{ - if (!m_xDateFieldStartRange.is()) - return; - - uno::Reference<text::XTextCursor> xCrsr; - if (m_rDM_Impl.HasTopText()) - { - uno::Reference<text::XTextAppend> xTextAppend = m_rDM_Impl.GetTopTextAppend(); - if (xTextAppend.is()) - { - xCrsr = xTextAppend->createTextCursorByRange(xTextAppend); - } - } - if (!xCrsr.is()) - return; - - try - { - xCrsr->gotoRange(m_xDateFieldStartRange, false); - bool bIsInTable = (m_rDM_Impl.hasTableManager() && m_rDM_Impl.getTableManager().isInTable()) - || (m_rDM_Impl.m_nTableDepth > 0); - if (bIsInTable) - xCrsr->goRight(1, false); - xCrsr->gotoEnd(true); - } - catch (uno::Exception&) - { - OSL_ENSURE(false, "Cannot get the right text range for date field"); - return; - } - - uno::Reference<uno::XInterface> xFieldInterface - = m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.text.Fieldmark"); - uno::Reference<text::XFormField> xFormField(xFieldInterface, uno::UNO_QUERY); - uno::Reference<text::XTextContent> xToInsert(xFormField, uno::UNO_QUERY); - if (!(xFormField.is() && xToInsert.is())) - return; - - xToInsert->attach(uno::Reference<text::XTextRange>(xCrsr, uno::UNO_QUERY_THROW)); - xFormField->setFieldType(ODF_FORMDATE); - uno::Reference<container::XNameContainer> xNameCont = xFormField->getParameters(); - if (xNameCont.is()) - { - OUString sDateFormat = m_sDateFormat.makeStringAndClear(); - // Replace quotation mark used for marking static strings in date format - sDateFormat = sDateFormat.replaceAll("'", "\""); - xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT, uno::makeAny(sDateFormat)); - xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT_LANGUAGE, - uno::makeAny(m_sLocale.makeStringAndClear())); - } - OUString sFullDate = m_sDate.makeStringAndClear(); - if (!sFullDate.isEmpty()) - { - sal_Int32 nTimeSep = sFullDate.indexOf("T"); - if (nTimeSep != -1) - sFullDate = sFullDate.copy(0, nTimeSep); - xNameCont->insertByName(ODF_FORMDATE_CURRENTDATE, uno::makeAny(sFullDate)); - } -} - -void SdtHelper::createControlShape(awt::Size aSize, - uno::Reference<awt::XControlModel> const& xControlModel, - const uno::Sequence<beans::PropertyValue>& rGrabBag) -{ - uno::Reference<drawing::XControlShape> xControlShape( - m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.drawing.ControlShape"), - uno::UNO_QUERY); - xControlShape->setSize(aSize); - xControlShape->setControl(xControlModel); - - uno::Reference<beans::XPropertySet> xPropertySet(xControlShape, uno::UNO_QUERY); - xPropertySet->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::CENTER)); - - if (rGrabBag.hasElements()) - xPropertySet->setPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG, uno::makeAny(rGrabBag)); - - uno::Reference<text::XTextContent> xTextContent(xControlShape, uno::UNO_QUERY); - m_rDM_Impl.appendTextContent(xTextContent, uno::Sequence<beans::PropertyValue>()); - m_bHasElements = true; -} - -void SdtHelper::appendToInteropGrabBag(const beans::PropertyValue& rValue) -{ - m_aGrabBag.push_back(rValue); -} - -uno::Sequence<beans::PropertyValue> SdtHelper::getInteropGrabBagAndClear() -{ - uno::Sequence<beans::PropertyValue> aRet = comphelper::containerToSequence(m_aGrabBag); - m_aGrabBag.clear(); - return aRet; -} - -bool SdtHelper::isInteropGrabBagEmpty() const { return m_aGrabBag.empty(); } - -sal_Int32 SdtHelper::getInteropGrabBagSize() const { return m_aGrabBag.size(); } - -bool SdtHelper::containedInInteropGrabBag(const OUString& rValueName) -{ - return std::any_of( - m_aGrabBag.begin(), m_aGrabBag.end(), - [&rValueName](const beans::PropertyValue& i) { return i.Name == rValueName; }); -} - -} // namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx deleted file mode 100644 index e5decd927ad0..000000000000 --- a/writerfilter/source/dmapper/SdtHelper.hxx +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SDTHELPER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SDTHELPER_HXX - -#include <vector> - -#include <com/sun/star/beans/PropertyValue.hpp> -#include <com/sun/star/text/XTextRange.hpp> - -#include <rtl/ustrbuf.hxx> -#include <tools/ref.hxx> - -namespace com::sun::star::awt -{ -struct Size; -class XControlModel; -} - -namespace writerfilter::dmapper -{ -class DomainMapper_Impl; - -/** - * Helper to create form controls from w:sdt tokens. - * - * w:sdt tokens can't be imported as form fields, as w:sdt supports - * e.g. date picking as well. - */ -class SdtHelper final : public virtual SvRefBase -{ - DomainMapper_Impl& m_rDM_Impl; - - /// Items of the drop-down control. - std::vector<OUString> m_aDropDownItems; - /// Indicator of a drop-down control - bool m_bInsideDropDownControl; - /// Pieces of the default text -- currently used only by the dropdown control. - OUStringBuffer m_aSdtTexts; - /// Date ISO string contained in the w:date element, used by the date control. - OUStringBuffer m_sDate; - /// Date format string as it comes from the ooxml document. - OUStringBuffer m_sDateFormat; - /// Start range of the date field - css::uno::Reference<css::text::XTextRange> m_xDateFieldStartRange; - /// Locale string as it comes from the ooxml document. - OUStringBuffer m_sLocale; - /// Grab bag to store unsupported SDTs, aiming to save them back on export. - std::vector<css::beans::PropertyValue> m_aGrabBag; - - bool m_bHasElements; - /// The last stored SDT element is outside paragraphs. - bool m_bOutsideAParagraph; - - /// Create and append the drawing::XControlShape, containing the various models. - void createControlShape(css::awt::Size aSize, - css::uno::Reference<css::awt::XControlModel> const& xControlModel, - const css::uno::Sequence<css::beans::PropertyValue>& rGrabBag); - -public: - explicit SdtHelper(DomainMapper_Impl& rDM_Impl); - ~SdtHelper() override; - - std::vector<OUString>& getDropDownItems() { return m_aDropDownItems; } - OUStringBuffer& getSdtTexts() { return m_aSdtTexts; } - - OUStringBuffer& getDate() { return m_sDate; } - - OUStringBuffer& getDateFormat() { return m_sDateFormat; } - - void setDateFieldStartRange(const css::uno::Reference<css::text::XTextRange>& xStartRange) - { - m_xDateFieldStartRange = xStartRange; - } - - /// Decides if we have enough information to create a date control. - bool validateDateFormat(); - - OUStringBuffer& getLocale() { return m_sLocale; } - /// If createControlShape() was ever called. - bool hasElements() const { return m_bHasElements; } - - void setOutsideAParagraph(bool bOutsideAParagraph) - { - m_bOutsideAParagraph = bOutsideAParagraph; - } - - bool isOutsideAParagraph() const { return m_bOutsideAParagraph; } - - bool isInsideDropDownControl() const { return m_bInsideDropDownControl; } - void setInsideDropDownControl(bool bInside) { m_bInsideDropDownControl = bInside; } - - /// Create drop-down control from w:sdt's w:dropDownList. - void createDropDownControl(); - /// Create date control from w:sdt's w:date. - void createDateContentControl(); - - void appendToInteropGrabBag(const css::beans::PropertyValue& rValue); - css::uno::Sequence<css::beans::PropertyValue> getInteropGrabBagAndClear(); - bool isInteropGrabBagEmpty() const; - bool containedInInteropGrabBag(const OUString& rValueName); - sal_Int32 getInteropGrabBagSize() const; -}; - -} // namespace writerfilter::dmapper - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SectionColumnHandler.cxx b/writerfilter/source/dmapper/SectionColumnHandler.cxx deleted file mode 100644 index 9fed9c34a68e..000000000000 --- a/writerfilter/source/dmapper/SectionColumnHandler.cxx +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "SectionColumnHandler.hxx" -#include "ConversionHelper.hxx" -#include <ooxml/resourceids.hxx> -#include <osl/diagnose.h> - -namespace writerfilter::dmapper -{ -using namespace ::com::sun::star; - -SectionColumnHandler::SectionColumnHandler() - : LoggedProperties("SectionColumnHandler") - , m_bEqualWidth(false) - , m_nSpace(1270) // 720 twips - , m_nNum(0) - , m_bSep(false) -{ - m_aTempColumn.nWidth = m_aTempColumn.nSpace = 0; -} - -SectionColumnHandler::~SectionColumnHandler() {} - -void SectionColumnHandler::lcl_attribute(Id rName, Value& rVal) -{ - sal_Int32 nIntValue = rVal.getInt(); - switch (rName) - { - case NS_ooxml::LN_CT_Columns_equalWidth: - m_bEqualWidth = (nIntValue != 0); - break; - case NS_ooxml::LN_CT_Columns_space: - m_nSpace = ConversionHelper::convertTwipToMM100(nIntValue); - break; - case NS_ooxml::LN_CT_Columns_num: - m_nNum = nIntValue; - break; - case NS_ooxml::LN_CT_Columns_sep: - m_bSep = (nIntValue != 0); - break; - - case NS_ooxml::LN_CT_Column_w: - m_aTempColumn.nWidth = ConversionHelper::convertTwipToMM100(nIntValue); - break; - case NS_ooxml::LN_CT_Column_space: - m_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: - { - m_aTempColumn.nWidth = m_aTempColumn.nSpace = 0; - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - { - pProperties->resolve(*this); - m_aCols.push_back(m_aTempColumn); - } - } - break; - default: - OSL_FAIL("SectionColumnHandler: unknown sprm"); - } -} -} //namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SectionColumnHandler.hxx b/writerfilter/source/dmapper/SectionColumnHandler.hxx deleted file mode 100644 index 70c9d6d7209f..000000000000 --- a/writerfilter/source/dmapper/SectionColumnHandler.hxx +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SECTIONCOLUMNHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SECTIONCOLUMNHANDLER_HXX - -#include "LoggedResources.hxx" -#include <vector> - -namespace writerfilter::dmapper -{ -struct Column_ -{ - sal_Int32 nWidth; - sal_Int32 nSpace; -}; - - -class SectionColumnHandler : public LoggedProperties -{ - bool m_bEqualWidth; - sal_Int32 m_nSpace; - sal_Int32 m_nNum; - bool m_bSep; - std::vector<Column_> m_aCols; - - Column_ m_aTempColumn; - - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - -public: - SectionColumnHandler(); - virtual ~SectionColumnHandler() override; - - bool IsEqualWidth() const { return m_bEqualWidth; } - sal_Int32 GetSpace() const { return m_nSpace; } - sal_Int32 GetNum() const { return m_nNum; } - bool IsSeparator() const { return m_bSep; } - - const std::vector<Column_>& GetColumns() const { return m_aCols;} - -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx deleted file mode 100644 index 02e0a6f8c4a1..000000000000 --- a/writerfilter/source/dmapper/SettingsTable.cxx +++ /dev/null @@ -1,897 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "SettingsTable.hxx" -#include "TagLogger.hxx" - -#include <vector> - -#include <rtl/ustring.hxx> -#include <sfx2/zoomitem.hxx> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/beans/XPropertyState.hpp> -#include <com/sun/star/container/XNameContainer.hpp> -#include <com/sun/star/style/XStyle.hpp> -#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> -#include <comphelper/propertysequence.hxx> -#include <comphelper/sequence.hxx> -#include <ooxml/resourceids.hxx> -#include "ConversionHelper.hxx" -#include "DomainMapper.hxx" -#include "util.hxx" - -using namespace com::sun::star; - -namespace writerfilter { -namespace -{ -/// Maps OOXML <w:zoom w:val="..."> to SvxZoomType. -sal_Int16 lcl_GetZoomType(Id nType) -{ - switch (nType) - { - case NS_ooxml::LN_Value_doc_ST_Zoom_fullPage: - return sal_Int16(SvxZoomType::WHOLEPAGE); - case NS_ooxml::LN_Value_doc_ST_Zoom_bestFit: - return sal_Int16(SvxZoomType::PAGEWIDTH); - case NS_ooxml::LN_Value_doc_ST_Zoom_textFit: - return sal_Int16(SvxZoomType::OPTIMAL); - } - - return sal_Int16(SvxZoomType::PERCENT); -} -} - -namespace dmapper -{ - namespace { - - /** Document protection restrictions - * - * This element specifies the set of document protection restrictions which have been applied to the contents of a - * WordprocessingML document.These restrictions should be enforced by applications editing this document - * when the enforcement attribute is turned on, and ignored(but persisted) otherwise.Document protection is a - * set of restrictions used to prevent unintentional changes to all or part of a WordprocessingML document. - */ - struct DocumentProtection_Impl - { - /** Document Editing Restrictions - * - * Possible values: - * - NS_ooxml::LN_Value_doc_ST_DocProtect_none - * - NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly - * - NS_ooxml::LN_Value_doc_ST_DocProtect_comments - * - NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges - * - NS_ooxml::LN_Value_doc_ST_DocProtect_forms - */ - sal_Int32 m_nEdit; - bool m_bEnforcement; - bool m_bFormatting; - - /** Provider type - * - * Possible values: - * "rsaAES" - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES - * "rsaFull" - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaFull - */ - sal_Int32 m_nCryptProviderType; - OUString m_sCryptAlgorithmClass; - OUString m_sCryptAlgorithmType; - OUString m_sCryptAlgorithmSid; - sal_Int32 m_CryptSpinCount; - OUString m_sHash; - OUString m_sSalt; - - DocumentProtection_Impl() - : m_nEdit(NS_ooxml::LN_Value_doc_ST_DocProtect_none) // Specifies that no editing restrictions have been applied to the document - , m_bEnforcement(false) - , m_bFormatting(false) - , m_nCryptProviderType(NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES) - , m_sCryptAlgorithmClass("hash") - , m_sCryptAlgorithmType("typeAny") - , m_CryptSpinCount(0) - { - } - - css::uno::Sequence<css::beans::PropertyValue> toSequence() const; - - bool enabled() const - { - return ! isNone(); - } - - bool isNone() const { return m_nEdit == NS_ooxml::LN_Value_doc_ST_DocProtect_none; }; - }; - - } - - css::uno::Sequence<css::beans::PropertyValue> DocumentProtection_Impl::toSequence() const - { - std::vector<beans::PropertyValue> documentProtection; - - if (enabled()) - { - // w:edit - { - beans::PropertyValue aValue; - aValue.Name = "edit"; - - switch (m_nEdit) - { - case NS_ooxml::LN_Value_doc_ST_DocProtect_none: aValue.Value <<= OUString("none"); break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly: aValue.Value <<= OUString("readOnly"); break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_comments: aValue.Value <<= OUString("comments"); break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges: aValue.Value <<= OUString("trackedChanges"); break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_forms: aValue.Value <<= OUString("forms"); break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - } - } - - documentProtection.push_back(aValue); - } - - // w:enforcement - if (m_bEnforcement) - { - beans::PropertyValue aValue; - aValue.Name = "enforcement"; - aValue.Value <<= OUString("1"); - documentProtection.push_back(aValue); - } - - // w:formatting - if (m_bFormatting) - { - beans::PropertyValue aValue; - aValue.Name = "formatting"; - aValue.Value <<= OUString("1"); - documentProtection.push_back(aValue); - } - - // w:cryptProviderType - { - beans::PropertyValue aValue; - aValue.Name = "cryptProviderType"; - if (m_nCryptProviderType == NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES) - aValue.Value <<= OUString("rsaAES"); - else if (m_nCryptProviderType == NS_ooxml::LN_Value_doc_ST_CryptProv_rsaFull) - aValue.Value <<= OUString("rsaFull"); - documentProtection.push_back(aValue); - } - - // w:cryptAlgorithmClass - { - beans::PropertyValue aValue; - aValue.Name = "cryptAlgorithmClass"; - aValue.Value <<= m_sCryptAlgorithmClass; - documentProtection.push_back(aValue); - } - - // w:cryptAlgorithmType - { - beans::PropertyValue aValue; - aValue.Name = "cryptAlgorithmType"; - aValue.Value <<= m_sCryptAlgorithmType; - documentProtection.push_back(aValue); - } - - // w:cryptAlgorithmSid - { - beans::PropertyValue aValue; - aValue.Name = "cryptAlgorithmSid"; - aValue.Value <<= m_sCryptAlgorithmSid; - documentProtection.push_back(aValue); - } - - // w:cryptSpinCount - { - beans::PropertyValue aValue; - aValue.Name = "cryptSpinCount"; - aValue.Value <<= OUString::number(m_CryptSpinCount); - documentProtection.push_back(aValue); - } - - // w:hash - { - beans::PropertyValue aValue; - aValue.Name = "hash"; - aValue.Value <<= m_sHash; - documentProtection.push_back(aValue); - } - - // w:salt - { - beans::PropertyValue aValue; - aValue.Name = "salt"; - aValue.Value <<= m_sSalt; - documentProtection.push_back(aValue); - } - } - - return comphelper::containerToSequence(documentProtection); - } - -struct SettingsTable_Impl -{ - int m_nDefaultTabStop; - - bool m_bRecordChanges; - bool m_bShowInsDelChanges; - bool m_bShowFormattingChanges; - bool m_bShowMarkupChanges; - bool m_bLinkStyles; - sal_Int16 m_nZoomFactor; - sal_Int16 m_nZoomType = 0; - sal_Int32 m_nWordCompatibilityMode; - Id m_nView; - bool m_bEvenAndOddHeaders; - bool m_bUsePrinterMetrics; - bool embedTrueTypeFonts; - bool embedSystemFonts; - bool m_bDoNotUseHTMLParagraphAutoSpacing; - bool m_bNoColumnBalance; - bool m_bAutoHyphenation; - bool m_bNoHyphenateCaps; - sal_Int16 m_nHyphenationZone; - bool m_bWidowControl; - bool m_bLongerSpaceSequence; - bool m_bSplitPgBreakAndParaMark; - bool m_bMirrorMargin; - bool m_bDoNotExpandShiftReturn; - bool m_bProtectForm; - bool m_bRedlineProtection; - OUString m_sRedlineProtectionKey; - bool m_bReadOnly; - bool m_bDisplayBackgroundShape; - bool m_bNoLeading = false; - OUString m_sDecimalSymbol; - OUString m_sListSeparator; - - uno::Sequence<beans::PropertyValue> m_pThemeFontLangProps; - - std::vector<beans::PropertyValue> m_aCompatSettings; - uno::Sequence<beans::PropertyValue> m_pCurrentCompatSetting; - OUString m_sCurrentDatabaseDataSource; - - DocumentProtection_Impl m_DocumentProtection; - bool m_bGutterAtTop = false; - - SettingsTable_Impl() : - m_nDefaultTabStop( 720 ) //default is 1/2 in - , m_bRecordChanges(false) - , m_bShowInsDelChanges(true) - , m_bShowFormattingChanges(false) - , m_bShowMarkupChanges(true) - , m_bLinkStyles(false) - , m_nZoomFactor(0) - , m_nWordCompatibilityMode(-1) - , m_nView(0) - , m_bEvenAndOddHeaders(false) - , m_bUsePrinterMetrics(false) - , embedTrueTypeFonts(false) - , embedSystemFonts(false) - , m_bDoNotUseHTMLParagraphAutoSpacing(false) - , m_bNoColumnBalance(false) - , m_bAutoHyphenation(false) - , m_bNoHyphenateCaps(false) - , m_nHyphenationZone(0) - , m_bWidowControl(false) - , m_bLongerSpaceSequence(false) - , m_bSplitPgBreakAndParaMark(false) - , m_bMirrorMargin(false) - , m_bDoNotExpandShiftReturn(false) - , m_bProtectForm(false) - , m_bRedlineProtection(false) - , m_sRedlineProtectionKey() - , m_bReadOnly(false) - , m_bDisplayBackgroundShape(false) - , m_sDecimalSymbol(".") - , m_sListSeparator(",") - , m_pThemeFontLangProps(3) - , m_pCurrentCompatSetting(3) - {} - -}; - -SettingsTable::SettingsTable(const DomainMapper& rDomainMapper) -: LoggedProperties("SettingsTable") -, LoggedTable("SettingsTable") -, m_pImpl( new SettingsTable_Impl ) -{ - if (rDomainMapper.IsRTFImport()) - { - // HTML paragraph auto-spacing is opt-in for RTF, opt-out for OOXML. - m_pImpl->m_bDoNotUseHTMLParagraphAutoSpacing = true; - // Longer space sequence is opt-in for RTF, and not in OOXML. - m_pImpl->m_bLongerSpaceSequence = true; - } -} - -SettingsTable::~SettingsTable() -{ -} - -void SettingsTable::lcl_attribute(Id nName, Value & val) -{ - int nIntValue = val.getInt(); - OUString sStringValue = val.getString(); - - switch(nName) - { - case NS_ooxml::LN_CT_Zoom_percent: - m_pImpl->m_nZoomFactor = nIntValue; - break; - case NS_ooxml::LN_CT_Zoom_val: - m_pImpl->m_nZoomType = lcl_GetZoomType(nIntValue); - break; - case NS_ooxml::LN_CT_Language_val: - m_pImpl->m_pThemeFontLangProps[0].Name = "val"; - m_pImpl->m_pThemeFontLangProps[0].Value <<= sStringValue; - break; - case NS_ooxml::LN_CT_Language_eastAsia: - m_pImpl->m_pThemeFontLangProps[1].Name = "eastAsia"; - m_pImpl->m_pThemeFontLangProps[1].Value <<= sStringValue; - break; - case NS_ooxml::LN_CT_Language_bidi: - m_pImpl->m_pThemeFontLangProps[2].Name = "bidi"; - m_pImpl->m_pThemeFontLangProps[2].Value <<= sStringValue; - break; - case NS_ooxml::LN_CT_View_val: - m_pImpl->m_nView = nIntValue; - break; - case NS_ooxml::LN_CT_CompatSetting_name: - m_pImpl->m_pCurrentCompatSetting[0].Name = "name"; - m_pImpl->m_pCurrentCompatSetting[0].Value <<= sStringValue; - break; - case NS_ooxml::LN_CT_CompatSetting_uri: - m_pImpl->m_pCurrentCompatSetting[1].Name = "uri"; - m_pImpl->m_pCurrentCompatSetting[1].Value <<= sStringValue; - break; - case NS_ooxml::LN_CT_CompatSetting_val: - m_pImpl->m_pCurrentCompatSetting[2].Name = "val"; - m_pImpl->m_pCurrentCompatSetting[2].Value <<= sStringValue; - break; - case NS_ooxml::LN_CT_DocProtect_edit: // 92037 - m_pImpl->m_DocumentProtection.m_nEdit = nIntValue; - // multiple DocProtect_edits should not exist. If they do, last one wins - m_pImpl->m_bRedlineProtection = false; - m_pImpl->m_bProtectForm = false; - m_pImpl->m_bReadOnly = false; - switch (nIntValue) - { - case NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges: - { - m_pImpl->m_bRedlineProtection = true; - m_pImpl->m_sRedlineProtectionKey = m_pImpl->m_DocumentProtection.m_sHash; - break; - } - case NS_ooxml::LN_Value_doc_ST_DocProtect_forms: - m_pImpl->m_bProtectForm = true; - break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly: - m_pImpl->m_bReadOnly = true; - break; - } - break; - case NS_ooxml::LN_CT_DocProtect_enforcement: // 92039 - m_pImpl->m_DocumentProtection.m_bEnforcement = (nIntValue != 0); - break; - case NS_ooxml::LN_CT_DocProtect_formatting: // 92038 - m_pImpl->m_DocumentProtection.m_bFormatting = (nIntValue != 0); - break; - case NS_ooxml::LN_AG_Password_cryptProviderType: // 92025 - m_pImpl->m_DocumentProtection.m_nCryptProviderType = nIntValue; - break; - case NS_ooxml::LN_AG_Password_cryptAlgorithmClass: // 92026 - if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgClass_hash) // 92023 - m_pImpl->m_DocumentProtection.m_sCryptAlgorithmClass = "hash"; - break; - case NS_ooxml::LN_AG_Password_cryptAlgorithmType: // 92027 - if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgType_typeAny) // 92024 - m_pImpl->m_DocumentProtection.m_sCryptAlgorithmType = "typeAny"; - break; - case NS_ooxml::LN_AG_Password_cryptAlgorithmSid: // 92028 - m_pImpl->m_DocumentProtection.m_sCryptAlgorithmSid = sStringValue; - break; - case NS_ooxml::LN_AG_Password_cryptSpinCount: // 92029 - m_pImpl->m_DocumentProtection.m_CryptSpinCount = nIntValue; - break; - case NS_ooxml::LN_AG_Password_hash: // 92035 - m_pImpl->m_DocumentProtection.m_sHash = sStringValue; - break; - case NS_ooxml::LN_AG_Password_salt: // 92036 - m_pImpl->m_DocumentProtection.m_sSalt = sStringValue; - break; - case NS_ooxml::LN_CT_TrackChangesView_insDel: - m_pImpl->m_bShowInsDelChanges = (nIntValue != 0); - break; - case NS_ooxml::LN_CT_TrackChangesView_formatting: - m_pImpl->m_bShowFormattingChanges = (nIntValue != 0); - break; - case NS_ooxml::LN_CT_TrackChangesView_markup: - m_pImpl->m_bShowMarkupChanges = (nIntValue != 0); - break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - } - } -} - -void SettingsTable::lcl_sprm(Sprm& rSprm) -{ - sal_uInt32 nSprmId = rSprm.getId(); - - Value::Pointer_t pValue = rSprm.getValue(); - sal_Int32 nIntValue = pValue->getInt(); - - 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; - case NS_ooxml::LN_CT_Settings_view: - //PropertySetValues - need to be resolved - { - resolveSprmProps(*this, rSprm); - } - 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_linkStyles: // 92663; - m_pImpl->m_bLinkStyles = nIntValue; - break; - case NS_ooxml::LN_CT_Settings_evenAndOddHeaders: - m_pImpl->m_bEvenAndOddHeaders = nIntValue; - break; - case NS_ooxml::LN_CT_Settings_noPunctuationKerning: // 92526; - break; - case NS_ooxml::LN_CT_Settings_characterSpacingControl: // 92527; - // 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) - break; - case NS_ooxml::LN_CT_Settings_decimalSymbol: // 92562; - m_pImpl->m_sDecimalSymbol = pValue->getString(); - break; - case NS_ooxml::LN_CT_Settings_listSeparator: // 92563; - m_pImpl->m_sListSeparator = pValue->getString(); - 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_revisionView: - resolveSprmProps(*this, rSprm); - break; - case NS_ooxml::LN_CT_Settings_documentProtection: - resolveSprmProps(*this, rSprm); - break; - case NS_ooxml::LN_CT_Compat_usePrinterMetrics: - m_pImpl->m_bUsePrinterMetrics = nIntValue; - break; - case NS_ooxml::LN_CT_Settings_embedTrueTypeFonts: - m_pImpl->embedTrueTypeFonts = nIntValue != 0; - break; - case NS_ooxml::LN_CT_Settings_embedSystemFonts: - m_pImpl->embedSystemFonts = nIntValue != 0; - break; - case NS_ooxml::LN_CT_Compat_doNotUseHTMLParagraphAutoSpacing: - m_pImpl->m_bDoNotUseHTMLParagraphAutoSpacing = nIntValue; - break; - case NS_ooxml::LN_CT_Compat_splitPgBreakAndParaMark: - m_pImpl->m_bSplitPgBreakAndParaMark = nIntValue; - break; - case NS_ooxml::LN_CT_Settings_mirrorMargins: - m_pImpl->m_bMirrorMargin = nIntValue; - break; - case NS_ooxml::LN_CT_Settings_mailMerge: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_MailMerge_query: - { - // try to get the "database.table" name from the query saved previously - OUString sVal = pValue->getString(); - if ( sVal.endsWith("$") && sVal.indexOf(".dbo.") > 0 ) - { - sal_Int32 nSpace = sVal.lastIndexOf(' '); - sal_Int32 nDbo = sVal.lastIndexOf(".dbo."); - if ( nSpace > 0 && nSpace < nDbo - 1 ) - { - m_pImpl->m_sCurrentDatabaseDataSource = OUString::Concat(sVal.subView(nSpace + 1, nDbo - nSpace - 1)) + - sVal.subView(nDbo + 4, sVal.getLength() - nDbo - 5); - } - } - } - break; - case NS_ooxml::LN_CT_Compat_compatSetting: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - { - pProperties->resolve(*this); - - beans::PropertyValue aValue; - aValue.Name = "compatSetting"; - aValue.Value <<= m_pImpl->m_pCurrentCompatSetting; - m_pImpl->m_aCompatSettings.push_back(aValue); - } - } - break; - case NS_ooxml::LN_CT_Compat_noColumnBalance: - m_pImpl->m_bNoColumnBalance = nIntValue; - break; - case NS_ooxml::LN_CT_Settings_autoHyphenation: - m_pImpl->m_bAutoHyphenation = nIntValue; - break; - case NS_ooxml::LN_CT_Settings_doNotHyphenateCaps: - m_pImpl->m_bNoHyphenateCaps = nIntValue; - break; - case NS_ooxml::LN_CT_Settings_widowControl: - m_pImpl->m_bWidowControl = nIntValue; - break; - case NS_ooxml::LN_CT_Settings_longerSpaceSequence: - m_pImpl->m_bLongerSpaceSequence = nIntValue; - break; - case NS_ooxml::LN_CT_Compat_doNotExpandShiftReturn: - m_pImpl->m_bDoNotExpandShiftReturn = true; - break; - case NS_ooxml::LN_CT_Settings_displayBackgroundShape: - m_pImpl->m_bDisplayBackgroundShape = nIntValue; - break; - case NS_ooxml::LN_CT_Compat_noLeading: - m_pImpl->m_bNoLeading = nIntValue != 0; - break; - case NS_ooxml::LN_CT_Settings_gutterAtTop: - m_pImpl->m_bGutterAtTop = nIntValue != 0; - break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - } - } -} - -void SettingsTable::lcl_entry(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 ); -} - -bool SettingsTable::GetLinkStyles() const -{ - return m_pImpl->m_bLinkStyles; -} - -sal_Int16 SettingsTable::GetZoomFactor() const -{ - return m_pImpl->m_nZoomFactor; -} - -sal_Int16 SettingsTable::GetZoomType() const { return m_pImpl->m_nZoomType; } - -Id SettingsTable::GetView() const -{ - return m_pImpl->m_nView; -} - -bool SettingsTable::GetUsePrinterMetrics() const -{ - return m_pImpl->m_bUsePrinterMetrics; -} - -bool SettingsTable::GetEvenAndOddHeaders() const -{ - return m_pImpl->m_bEvenAndOddHeaders; -} - -bool SettingsTable::GetEmbedTrueTypeFonts() const -{ - return m_pImpl->embedTrueTypeFonts; -} - -bool SettingsTable::GetEmbedSystemFonts() const -{ - return m_pImpl->embedSystemFonts; -} - -bool SettingsTable::GetDoNotUseHTMLParagraphAutoSpacing() const -{ - return m_pImpl->m_bDoNotUseHTMLParagraphAutoSpacing; -} - -bool SettingsTable::GetNoColumnBalance() const -{ - return m_pImpl->m_bNoColumnBalance; -} - -bool SettingsTable::GetSplitPgBreakAndParaMark() const -{ - return m_pImpl->m_bSplitPgBreakAndParaMark; -} - -bool SettingsTable::GetMirrorMarginSettings() const -{ - return m_pImpl->m_bMirrorMargin; -} - -bool SettingsTable::GetDisplayBackgroundShape() const -{ - return m_pImpl->m_bDisplayBackgroundShape; -} - -bool SettingsTable::GetDoNotExpandShiftReturn() const -{ - return m_pImpl->m_bDoNotExpandShiftReturn; -} - -bool SettingsTable::GetProtectForm() const -{ - return m_pImpl->m_bProtectForm && m_pImpl->m_DocumentProtection.m_bEnforcement; -} - -bool SettingsTable::GetReadOnly() const -{ - return m_pImpl->m_bReadOnly && m_pImpl->m_DocumentProtection.m_bEnforcement; -} - -bool SettingsTable::GetNoHyphenateCaps() const -{ - return m_pImpl->m_bNoHyphenateCaps; -} - -sal_Int16 SettingsTable::GetHyphenationZone() const -{ - return m_pImpl->m_nHyphenationZone; -} - -const OUString & SettingsTable::GetDecimalSymbol() const -{ - return m_pImpl->m_sDecimalSymbol; -} - -const OUString & SettingsTable::GetListSeparator() const -{ - return m_pImpl->m_sListSeparator; -} - - -uno::Sequence<beans::PropertyValue> const & SettingsTable::GetThemeFontLangProperties() const -{ - return m_pImpl->m_pThemeFontLangProps; -} - -uno::Sequence<beans::PropertyValue> SettingsTable::GetCompatSettings() const -{ - if ( GetWordCompatibilityMode() == -1 ) - { - // the default value for an undefined compatibilityMode is 12 (Word 2007) - uno::Sequence<beans::PropertyValue> aCompatSetting( comphelper::InitPropertySequence({ - { "name", uno::Any(OUString("compatibilityMode")) }, - { "uri", uno::Any(OUString("http://schemas.microsoft.com/office/word")) }, - { "val", uno::Any(OUString("12")) } //12: Use word processing features specified in ECMA-376. This is the default. - })); - - beans::PropertyValue aValue; - aValue.Name = "compatSetting"; - aValue.Value <<= aCompatSetting; - - m_pImpl->m_aCompatSettings.push_back(aValue); - } - - return comphelper::containerToSequence(m_pImpl->m_aCompatSettings); -} - -css::uno::Sequence<css::beans::PropertyValue> SettingsTable::GetDocumentProtectionSettings() const -{ - return m_pImpl->m_DocumentProtection.toSequence(); -} - -const OUString & SettingsTable::GetCurrentDatabaseDataSource() const -{ - return m_pImpl->m_sCurrentDatabaseDataSource; -} - -static bool lcl_isDefault(const uno::Reference<beans::XPropertyState>& xPropertyState, const OUString& rPropertyName) -{ - return xPropertyState->getPropertyState(rPropertyName) == beans::PropertyState_DEFAULT_VALUE; -} - -void SettingsTable::ApplyProperties(uno::Reference<text::XTextDocument> const& xDoc) -{ - uno::Reference< beans::XPropertySet> xDocProps( xDoc, uno::UNO_QUERY ); - - if (GetWordCompatibilityMode() <= 14) - { - uno::Reference<lang::XMultiServiceFactory> xTextFactory(xDoc, uno::UNO_QUERY_THROW); - uno::Reference<beans::XPropertySet> xDocumentSettings(xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY_THROW); - xDocumentSettings->setPropertyValue("MsWordCompMinLineHeightByFly", uno::makeAny(true)); - } - - // Show changes value - if (xDocProps.is()) - { - bool bHideChanges = !m_pImpl->m_bShowInsDelChanges || !m_pImpl->m_bShowMarkupChanges; - xDocProps->setPropertyValue("ShowChanges", uno::makeAny( !bHideChanges || m_pImpl->m_bShowFormattingChanges ) ); - } - - // Record changes value - if (xDocProps.is()) - { - xDocProps->setPropertyValue("RecordChanges", uno::makeAny( m_pImpl->m_bRecordChanges ) ); - // Password protected Record changes - if ( m_pImpl->m_bRecordChanges && m_pImpl->m_bRedlineProtection && m_pImpl->m_DocumentProtection.m_bEnforcement ) - { - // use dummy protection key to forbid disabling of Record changes without a notice - // (extending the recent GrabBag support) TODO support password verification... - css::uno::Sequence<sal_Int8> aDummyKey(1); - aDummyKey[0] = 1; - xDocProps->setPropertyValue("RedlineProtectionKey", uno::makeAny( aDummyKey )); - } - } - - // Auto hyphenation: turns on hyphenation by default, <w:suppressAutoHyphens/> may still disable it at a paragraph level. - // Situation is similar for RTF_WIDOWCTRL, which turns on widow / orphan control by default. - if (!(m_pImpl->m_bAutoHyphenation || m_pImpl->m_bNoHyphenateCaps || m_pImpl->m_bWidowControl)) - return; - - uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xDoc, uno::UNO_QUERY); - if (!xStyleFamiliesSupplier.is()) - return; - - uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies(); - uno::Reference<container::XNameContainer> xParagraphStyles = xStyleFamilies->getByName("ParagraphStyles").get< uno::Reference<container::XNameContainer> >(); - uno::Reference<style::XStyle> xDefault = xParagraphStyles->getByName("Standard").get< uno::Reference<style::XStyle> >(); - uno::Reference<beans::XPropertyState> xPropertyState(xDefault, uno::UNO_QUERY); - if (m_pImpl->m_bAutoHyphenation && lcl_isDefault(xPropertyState, "ParaIsHyphenation")) - { - uno::Reference<beans::XPropertySet> xPropertySet(xDefault, uno::UNO_QUERY); - xPropertySet->setPropertyValue("ParaIsHyphenation", uno::makeAny(true)); - } - if (m_pImpl->m_bNoHyphenateCaps) - { - uno::Reference<beans::XPropertySet> xPropertySet(xDefault, uno::UNO_QUERY); - xPropertySet->setPropertyValue("ParaHyphenationNoCaps", uno::makeAny(true)); - } - if (m_pImpl->m_bWidowControl && lcl_isDefault(xPropertyState, "ParaWidows") && lcl_isDefault(xPropertyState, "ParaOrphans")) - { - uno::Reference<beans::XPropertySet> xPropertySet(xDefault, uno::UNO_QUERY); - uno::Any aAny = uno::makeAny(static_cast<sal_Int8>(2)); - xPropertySet->setPropertyValue("ParaWidows", aAny); - xPropertySet->setPropertyValue("ParaOrphans", aAny); - } -} - -bool SettingsTable::GetCompatSettingValue( std::u16string_view sCompatName ) const -{ - bool bRet = false; - for (const auto& rProp : m_pImpl->m_aCompatSettings) - { - if (rProp.Name == "compatSetting") //always true - { - css::uno::Sequence<css::beans::PropertyValue> aCurrentCompatSettings; - rProp.Value >>= aCurrentCompatSettings; - - OUString sName; - aCurrentCompatSettings[0].Value >>= sName; - if ( sName != sCompatName ) - continue; - - OUString sUri; - aCurrentCompatSettings[1].Value >>= sUri; - if ( sUri != "http://schemas.microsoft.com/office/word" ) - continue; - - OUString sVal; - aCurrentCompatSettings[2].Value >>= sVal; - // if repeated, what happens? Last one wins - bRet = sVal.toBoolean(); - } - } - - return bRet; -} - -//Keep this function in-sync with the one in sw/.../docxattributeoutput.cxx -sal_Int32 SettingsTable::GetWordCompatibilityMode() const -{ - if ( m_pImpl->m_nWordCompatibilityMode != -1 ) - return m_pImpl->m_nWordCompatibilityMode; - - for (const auto& rProp : m_pImpl->m_aCompatSettings) - { - if (rProp.Name == "compatSetting") //always true - { - css::uno::Sequence<css::beans::PropertyValue> aCurrentCompatSettings; - rProp.Value >>= aCurrentCompatSettings; - - OUString sName; - aCurrentCompatSettings[0].Value >>= sName; - if ( sName != "compatibilityMode" ) - continue; - - OUString sUri; - aCurrentCompatSettings[1].Value >>= sUri; - if ( sUri != "http://schemas.microsoft.com/office/word" ) - continue; - - OUString sVal; - aCurrentCompatSettings[2].Value >>= sVal; - const sal_Int32 nValidMode = sVal.toInt32(); - // if repeated, highest mode wins in MS Word. 11 is the first valid mode. - if ( nValidMode > 10 && nValidMode > m_pImpl->m_nWordCompatibilityMode ) - m_pImpl->m_nWordCompatibilityMode = nValidMode; - } - } - - return m_pImpl->m_nWordCompatibilityMode; -} - -bool SettingsTable::GetLongerSpaceSequence() const -{ - return m_pImpl->m_bLongerSpaceSequence; -} - -bool SettingsTable::GetNoLeading() const -{ - return m_pImpl->m_bNoLeading; -} - -bool SettingsTable::GetGutterAtTop() const { return m_pImpl->m_bGutterAtTop; } - -}//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 deleted file mode 100644 index 79defda867df..000000000000 --- a/writerfilter/source/dmapper/SettingsTable.hxx +++ /dev/null @@ -1,112 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SETTINGSTABLE_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SETTINGSTABLE_HXX - -#include "LoggedResources.hxx" -#include <com/sun/star/text/XTextDocument.hpp> -#include <memory> - -namespace com::sun::star::lang -{ -class XMultiServiceFactory; -struct Locale; -} - -namespace writerfilter::dmapper -{ -class DomainMapper; - -struct SettingsTable_Impl; - -class SettingsTable : public LoggedProperties, public LoggedTable -{ - std::unique_ptr<SettingsTable_Impl> m_pImpl; - -public: - SettingsTable(const DomainMapper& rDomainMapper); - virtual ~SettingsTable() override; - - //returns default TabStop in 1/100th mm - int GetDefaultTabStop() const; - - /// Automatically update styles from document template? - bool GetLinkStyles() const; - - /// What's the zoom factor set in percents? - sal_Int16 GetZoomFactor() const; - - /// Gets the type of the zoom. - sal_Int16 GetZoomType() const; - - /// What's the requested view? E.g. "web". - Id GetView() const; - - bool GetEvenAndOddHeaders() const; - - bool GetUsePrinterMetrics() const; - - bool GetEmbedTrueTypeFonts() const; - bool GetEmbedSystemFonts() const; - - bool GetDoNotUseHTMLParagraphAutoSpacing() const; - bool GetSplitPgBreakAndParaMark() const; - bool GetMirrorMarginSettings() const; - bool GetDisplayBackgroundShape() const; - bool GetDoNotExpandShiftReturn() const; - bool GetNoColumnBalance() const; - bool GetProtectForm() const; - bool GetReadOnly() const; - bool GetLongerSpaceSequence() const; - bool GetNoLeading() const; - bool GetNoHyphenateCaps() const; - sal_Int16 GetHyphenationZone() const; - - const OUString& GetDecimalSymbol() const; - const OUString& GetListSeparator() const; - - css::uno::Sequence<css::beans::PropertyValue> const& GetThemeFontLangProperties() const; - - css::uno::Sequence<css::beans::PropertyValue> GetCompatSettings() const; - - css::uno::Sequence<css::beans::PropertyValue> GetDocumentProtectionSettings() const; - - void ApplyProperties(css::uno::Reference<css::text::XTextDocument> const& xDoc); - - bool GetCompatSettingValue(std::u16string_view sCompatName) const; - sal_Int32 GetWordCompatibilityMode() const; - - const OUString& GetCurrentDatabaseDataSource() const; - bool GetGutterAtTop() const; - -private: - // Properties - virtual void lcl_attribute(Id Name, Value& val) override; - virtual void lcl_sprm(Sprm& sprm) override; - - // Table - virtual void lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) override; -}; -typedef tools::SvRef<SettingsTable> SettingsTablePtr; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SmartTagHandler.cxx b/writerfilter/source/dmapper/SmartTagHandler.cxx deleted file mode 100644 index c92fa7c44be5..000000000000 --- a/writerfilter/source/dmapper/SmartTagHandler.cxx +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "SmartTagHandler.hxx" - -#include <com/sun/star/rdf/Literal.hpp> -#include <com/sun/star/rdf/URI.hpp> -#include <com/sun/star/rdf/XDocumentMetadataAccess.hpp> -#include <com/sun/star/text/XTextDocument.hpp> -#include <com/sun/star/text/XTextRange.hpp> - -#include <ooxml/resourceids.hxx> - -#include <sal/log.hxx> - -namespace -{ -OUString lcl_getTypePath(OUString& rType) -{ - OUString aRet; - if (rType.startsWith("urn:bails")) - { - rType = "urn:bails"; - aRet = "tscp/bails.rdf"; - } - return aRet; -} -} - -namespace writerfilter::dmapper -{ -using namespace ::com::sun::star; - -SmartTagHandler::SmartTagHandler(uno::Reference<uno::XComponentContext> xComponentContext, - const uno::Reference<text::XTextDocument>& xTextDocument) - : LoggedProperties("SmartTagHandler") - , m_xComponentContext(std::move(xComponentContext)) - , m_xDocumentMetadataAccess(xTextDocument, uno::UNO_QUERY) -{ -} - -SmartTagHandler::~SmartTagHandler() = default; - -void SmartTagHandler::lcl_attribute(Id nId, Value& rValue) -{ - switch (nId) - { - case NS_ooxml::LN_CT_Attr_name: - m_aAttributes.emplace_back(rValue.getString(), OUString()); - break; - case NS_ooxml::LN_CT_Attr_val: - if (!m_aAttributes.empty()) - m_aAttributes.back().second = rValue.getString(); - break; - default: - SAL_WARN("writerfilter", "SmartTagHandler::lcl_attribute: unhandled attribute " - << nId << " (string value: '" << rValue.getString() - << "')"); - break; - } -} - -void SmartTagHandler::lcl_sprm(Sprm& rSprm) -{ - switch (rSprm.getId()) - { - case NS_ooxml::LN_CT_SmartTagPr_attr: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(*this); - break; - } - } -} - -void SmartTagHandler::setURI(const OUString& rURI) { m_aURI = rURI; } - -void SmartTagHandler::setElement(const OUString& rElement) { m_aElement = rElement; } - -void SmartTagHandler::handle(const uno::Reference<text::XTextRange>& xParagraph) -{ - if (m_aURI.isEmpty() || m_aElement.isEmpty() || m_aAttributes.empty()) - return; - - uno::Reference<rdf::XResource> xSubject(xParagraph, uno::UNO_QUERY); - - for (const std::pair<OUString, OUString>& rAttribute : m_aAttributes) - { - OUString aTypeNS = rAttribute.first; - OUString aMetadataFilePath = lcl_getTypePath(aTypeNS); - if (aMetadataFilePath.isEmpty()) - continue; - - uno::Reference<rdf::XURI> xType = rdf::URI::create(m_xComponentContext, aTypeNS); - uno::Sequence<uno::Reference<rdf::XURI>> aGraphNames - = m_xDocumentMetadataAccess->getMetadataGraphsWithType(xType); - uno::Reference<rdf::XURI> xGraphName; - if (aGraphNames.hasElements()) - xGraphName = aGraphNames[0]; - else - { - uno::Sequence<uno::Reference<rdf::XURI>> xTypes = { xType }; - xGraphName = m_xDocumentMetadataAccess->addMetadataFile(aMetadataFilePath, xTypes); - } - uno::Reference<rdf::XNamedGraph> xGraph - = m_xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName); - uno::Reference<rdf::XURI> xKey = rdf::URI::create(m_xComponentContext, rAttribute.first); - uno::Reference<rdf::XLiteral> xValue - = rdf::Literal::create(m_xComponentContext, rAttribute.second); - xGraph->addStatement(xSubject, xKey, xValue); - } - - m_aURI.clear(); - m_aElement.clear(); - m_aAttributes.clear(); -} - -} // namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/SmartTagHandler.hxx b/writerfilter/source/dmapper/SmartTagHandler.hxx deleted file mode 100644 index ef3dd1243231..000000000000 --- a/writerfilter/source/dmapper/SmartTagHandler.hxx +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SMARTTAGHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_SMARTTAGHANDLER_HXX - -#include <vector> - -#include "LoggedResources.hxx" - -namespace com::sun::star -{ -namespace rdf -{ -class XDocumentMetadataAccess; -} -namespace text -{ -class XTextDocument; -class XTextRange; -} -namespace uno -{ -class XComponentContext; -} -} - -namespace writerfilter::dmapper -{ -/// Handler for smart tags, i.e. <w:smartTag> and below. -class SmartTagHandler : public LoggedProperties -{ - css::uno::Reference<css::uno::XComponentContext> m_xComponentContext; - css::uno::Reference<css::rdf::XDocumentMetadataAccess> m_xDocumentMetadataAccess; - OUString m_aURI; - OUString m_aElement; - std::vector<std::pair<OUString, OUString>> m_aAttributes; - -public: - SmartTagHandler(css::uno::Reference<css::uno::XComponentContext> xComponentContext, - const css::uno::Reference<css::text::XTextDocument>& xTextDocument); - ~SmartTagHandler() override; - - void lcl_attribute(Id nId, Value& rValue) override; - void lcl_sprm(Sprm& rSprm) override; - - void setURI(const OUString& rURI); - void setElement(const OUString& rElement); - - /// Set m_aAttributes as RDF statements on xParagraph. - void handle(const css::uno::Reference<css::text::XTextRange>& xParagraph); -}; - -} // namespace writerfilter::dmapper - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx b/writerfilter/source/dmapper/StyleSheetTable.cxx deleted file mode 100644 index 083288bc16b6..000000000000 --- a/writerfilter/source/dmapper/StyleSheetTable.cxx +++ /dev/null @@ -1,1658 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "StyleSheetTable.hxx" -#include "util.hxx" -#include "ConversionHelper.hxx" -#include "TblStylePrHandler.hxx" -#include "TagLogger.hxx" -#include "BorderHandler.hxx" -#include "LatentStyleHandler.hxx" -#include <ooxml/resourceids.hxx> -#include <vector> -#include <iterator> -#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/container/XIndexReplace.hpp> -#include <com/sun/star/text/XTextDocument.hpp> -#include <com/sun/star/style/NumberingType.hpp> -#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> -#include <com/sun/star/style/XStyle.hpp> -#include <com/sun/star/style/ParagraphAdjust.hpp> -#include <com/sun/star/text/WritingMode.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <map> -#include <osl/diagnose.h> -#include <rtl/ustrbuf.hxx> -#include <sal/log.hxx> -#include <comphelper/string.hxx> -#include <comphelper/sequence.hxx> -#include <tools/diagnose_ex.h> -#include <o3tl/sorted_vector.hxx> - -using namespace ::com::sun::star; - -namespace writerfilter::dmapper -{ - -StyleSheetEntry::StyleSheetEntry() : - sStyleIdentifierD() - ,bIsDefaultStyle(false) - ,bInvalidHeight(false) - ,bHasUPE(false) - ,nStyleTypeCode(STYLE_TYPE_UNKNOWN) - ,sBaseStyleIdentifier() - ,sNextStyleIdentifier() - ,pProperties(new StyleSheetPropertyMap) - ,bAutoRedefine(false) -{ -} - -StyleSheetEntry::~StyleSheetEntry() -{ -} - -TableStyleSheetEntry::TableStyleSheetEntry( StyleSheetEntry const & rEntry ): - StyleSheetEntry( ) -{ - bIsDefaultStyle = rEntry.bIsDefaultStyle; - bInvalidHeight = rEntry.bInvalidHeight; - bHasUPE = rEntry.bHasUPE; - nStyleTypeCode = STYLE_TYPE_TABLE; - sBaseStyleIdentifier = rEntry.sBaseStyleIdentifier; - sNextStyleIdentifier = rEntry.sNextStyleIdentifier; - sStyleName = rEntry.sStyleName; - sStyleIdentifierD = rEntry.sStyleIdentifierD; -} - -TableStyleSheetEntry::~TableStyleSheetEntry( ) -{ -} - -void TableStyleSheetEntry::AddTblStylePr( TblStyleType nType, const PropertyMapPtr& pProps ) -{ - static const int nTypesProps = 4; - static const TblStyleType pTypesToFix[nTypesProps] = - { - TBL_STYLE_FIRSTROW, - TBL_STYLE_LASTROW, - TBL_STYLE_FIRSTCOL, - TBL_STYLE_LASTCOL - }; - - static const PropertyIds pPropsToCheck[nTypesProps] = - { - PROP_BOTTOM_BORDER, - PROP_TOP_BORDER, - PROP_RIGHT_BORDER, - PROP_LEFT_BORDER - }; - - for (int i=0; i < nTypesProps; ++i ) - { - if ( nType == pTypesToFix[i] ) - { - PropertyIds nChecked = pPropsToCheck[i]; - std::optional<PropertyMap::Property> pChecked = pProps->getProperty(nChecked); - - PropertyIds nInsideProp = ( i < 2 ) ? META_PROP_HORIZONTAL_BORDER : META_PROP_VERTICAL_BORDER; - std::optional<PropertyMap::Property> pInside = pProps->getProperty(nInsideProp); - - if ( pChecked && pInside ) - { - // In this case, remove the inside border - pProps->Erase( nInsideProp ); - } - - break; - } - } - - // Append the tblStylePr - m_aStyles[nType] = pProps; -} - -PropertyMapPtr TableStyleSheetEntry::GetProperties( sal_Int32 nMask ) -{ - PropertyMapPtr pProps( new PropertyMap ); - - // And finally get the mask ones - pProps->InsertProps(GetLocalPropertiesFromMask(nMask)); - - return pProps; -} - -beans::PropertyValues StyleSheetEntry::GetInteropGrabBagSeq() const -{ - return comphelper::containerToSequence(m_aInteropGrabBag); -} - -beans::PropertyValue StyleSheetEntry::GetInteropGrabBag() -{ - beans::PropertyValue aRet; - aRet.Name = sStyleIdentifierD; - - beans::PropertyValues aSeq = GetInteropGrabBagSeq(); - aRet.Value <<= aSeq; - return aRet; -} - -void StyleSheetEntry::AppendInteropGrabBag(const beans::PropertyValue& rValue) -{ - m_aInteropGrabBag.push_back(rValue); -} - -PropertyMapPtr StyleSheetEntry::GetMergedInheritedProperties(const StyleSheetTablePtr& pStyleSheetTable) -{ - PropertyMapPtr pRet; - if ( pStyleSheetTable && !sBaseStyleIdentifier.isEmpty() && sBaseStyleIdentifier != sStyleIdentifierD ) - { - const StyleSheetEntryPtr pParentStyleSheet = pStyleSheetTable->FindStyleSheetByISTD(sBaseStyleIdentifier); - if ( pParentStyleSheet ) - pRet = pParentStyleSheet->GetMergedInheritedProperties(pStyleSheetTable); - } - - if ( !pRet ) - pRet = new PropertyMap; - - pRet->InsertProps(pProperties); - - return pRet; -} - -static void lcl_mergeProps( const PropertyMapPtr& pToFill, const 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 != SAL_N_ELEMENTS(pPropsToCheck); i++ ) - { - PropertyIds nId = pPropsToCheck[i]; - std::optional<PropertyMap::Property> pProp = pToAdd->getProperty(nId); - - if ( pProp ) - { - 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; - pToFill->Erase(nInsideProp); - } - } - } - - pToFill->InsertProps(pToAdd); -} - -PropertyMapPtr TableStyleSheetEntry::GetLocalPropertiesFromMask( sal_Int32 nMask ) -{ - // Order from right to left - struct TblStyleTypeAndMask { - sal_Int32 mask; - TblStyleType type; - }; - - static const TblStyleTypeAndMask aOrderedStyleTable[] = - { - { 0x010, TBL_STYLE_BAND2HORZ }, - { 0x020, TBL_STYLE_BAND1HORZ }, - { 0x040, TBL_STYLE_BAND2VERT }, - { 0x080, TBL_STYLE_BAND1VERT }, - { 0x100, TBL_STYLE_LASTCOL }, - { 0x200, TBL_STYLE_FIRSTCOL }, - { 0x400, TBL_STYLE_LASTROW }, - { 0x800, TBL_STYLE_FIRSTROW }, - { 0x001, TBL_STYLE_SWCELL }, - { 0x002, TBL_STYLE_SECELL }, - { 0x004, TBL_STYLE_NWCELL }, - { 0x008, TBL_STYLE_NECELL } - }; - - // Get the properties applying according to the mask - PropertyMapPtr pProps( new PropertyMap( ) ); - for (const TblStyleTypeAndMask & i : aOrderedStyleTable) - { - TblStylePrs::iterator pIt = m_aStyles.find( i.type ); - if ( ( nMask & i.mask ) && ( pIt != m_aStyles.end( ) ) ) - lcl_mergeProps( pProps, pIt->second, i.type ); - } - return pProps; -} - -namespace { - -struct ListCharStylePropertyMap_t -{ - OUString sCharStyleName; - PropertyValueVector_t aPropertyValues; - - ListCharStylePropertyMap_t(const 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; - OUString m_sDefaultParaStyleName; //WW8 name - ListCharStylePropertyVector_t m_aListCharStylePropertyVector; - bool m_bHasImportedDefaultParaProps; - bool m_bIsNewDoc; - - StyleSheetTable_Impl(DomainMapper& rDMapper, uno::Reference< text::XTextDocument> const& xTextDocument, bool bIsNewDoc); - - OUString HasListCharStyle( const PropertyValueVector_t& rCharProperties ); - - /// Appends the given key-value pair to the list of latent style properties of the current entry. - void AppendLatentStyleProperty(const OUString& aName, Value const & rValue); - /// Sets all properties of xStyle back to default. - static void SetPropertiesToDefault(const uno::Reference<style::XStyle>& xStyle); -}; - - -StyleSheetTable_Impl::StyleSheetTable_Impl(DomainMapper& rDMapper, - uno::Reference< text::XTextDocument> const& xTextDocument, - bool const bIsNewDoc) - : - m_rDMapper( rDMapper ), - m_xTextDocument( xTextDocument ), - m_pCurrentEntry(), - m_pDefaultParaProps(new PropertyMap), - m_pDefaultCharProps(new PropertyMap), - m_sDefaultParaStyleName("Normal"), - m_bHasImportedDefaultParaProps(false), - m_bIsNewDoc(bIsNewDoc) -{ - //set font height default to 10pt - uno::Any aVal = uno::makeAny( 10.0 ); - m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT, aVal ); - m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT_ASIAN, aVal ); - m_pDefaultCharProps->Insert( PROP_CHAR_HEIGHT_COMPLEX, aVal ); - - // See SwDoc::RemoveAllFormatLanguageDependencies(), internal filters - // disable kerning by default, do the same here. - m_pDefaultCharProps->Insert(PROP_CHAR_AUTO_KERNING, uno::Any(false)); -} - - -OUString StyleSheetTable_Impl::HasListCharStyle( const PropertyValueVector_t& rPropValues ) -{ - for( const auto& rListVector : m_aListCharStylePropertyVector ) - { - const auto& rPropertyValues = rListVector.aPropertyValues; - //if size is identical - if( rPropertyValues.size() == rPropValues.size() ) - { - bool bBreak = false; - //then search for all contained properties - for( const auto& rPropVal1 : rPropValues) - { - //find the property - auto aListIter = std::find_if(rPropertyValues.begin(), rPropertyValues.end(), - [&rPropVal1](const css::beans::PropertyValue& rPropVal2) { return rPropVal2.Name == rPropVal1.Name; }); - //set break flag if property hasn't been found - bBreak = (aListIter == rPropertyValues.end()) || (aListIter->Value != rPropVal1.Value); - if( bBreak ) - break; - } - if( !bBreak ) - return rListVector.sCharStyleName; - } - } - return OUString(); -} - -void StyleSheetTable_Impl::AppendLatentStyleProperty(const OUString& aName, Value const & rValue) -{ - beans::PropertyValue aValue; - aValue.Name = aName; - aValue.Value <<= rValue.getString(); - m_pCurrentEntry->aLatentStyles.push_back(aValue); -} - -void StyleSheetTable_Impl::SetPropertiesToDefault(const uno::Reference<style::XStyle>& xStyle) -{ - // See if the existing style has any non-default properties. If so, reset them back to default. - uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY); - uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo(); - uno::Sequence<beans::Property> aProperties = xPropertySetInfo->getProperties(); - std::vector<OUString> aPropertyNames; - aPropertyNames.reserve(aProperties.getLength()); - std::transform(aProperties.begin(), aProperties.end(), std::back_inserter(aPropertyNames), - [](const beans::Property& rProp) { return rProp.Name; }); - - uno::Reference<beans::XPropertyState> xPropertyState(xStyle, uno::UNO_QUERY); - uno::Sequence<beans::PropertyState> aStates = xPropertyState->getPropertyStates(comphelper::containerToSequence(aPropertyNames)); - for (sal_Int32 i = 0; i < aStates.getLength(); ++i) - { - if (aStates[i] == beans::PropertyState_DIRECT_VALUE) - { - try - { - xPropertyState->setPropertyToDefault(aPropertyNames[i]); - } - catch(const uno::Exception&) - { - TOOLS_INFO_EXCEPTION("writerfilter", "setPropertyToDefault(" << aPropertyNames[i] << ") failed"); - } - } - } -} - -StyleSheetTable::StyleSheetTable(DomainMapper& rDMapper, - uno::Reference< text::XTextDocument> const& xTextDocument, - bool const bIsNewDoc) -: LoggedProperties("StyleSheetTable") -, LoggedTable("StyleSheetTable") -, m_pImpl( new StyleSheetTable_Impl(rDMapper, xTextDocument, bIsNewDoc) ) -{ -} - - -StyleSheetTable::~StyleSheetTable() -{ -} - -void StyleSheetTable::SetDefaultParaProps(PropertyIds eId, const css::uno::Any& rAny) -{ - m_pImpl->m_pDefaultParaProps->Insert(eId, rAny, /*bOverwrite=*/false, NO_GRAB_BAG, /*bDocDefault=*/true); -} - -PropertyMapPtr const & StyleSheetTable::GetDefaultParaProps() const -{ - return m_pImpl->m_pDefaultParaProps; -} - -PropertyMapPtr const & StyleSheetTable::GetDefaultCharProps() const -{ - return m_pImpl->m_pDefaultCharProps; -} - -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(); - OUString sValue = val.getString(); - - // The default type is paragraph, and it needs to be processed first, - // because the NS_ooxml::LN_CT_Style_type handling may set m_pImpl->m_pCurrentEntry - // to point to a different object. - if( m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_UNKNOWN ) - { - if( Name != NS_ooxml::LN_CT_Style_type ) - m_pImpl->m_pCurrentEntry->nStyleTypeCode = STYLE_TYPE_PARA; - } - switch(Name) - { - case NS_ooxml::LN_CT_Style_type: - { - SAL_WARN_IF( m_pImpl->m_pCurrentEntry->nStyleTypeCode != STYLE_TYPE_UNKNOWN, - "writerfilter", "Style type needs to be processed first" ); - StyleType nType(STYLE_TYPE_UNKNOWN); - switch (nIntValue) - { - case NS_ooxml::LN_Value_ST_StyleType_paragraph: - nType = STYLE_TYPE_PARA; - break; - case NS_ooxml::LN_Value_ST_StyleType_character: - nType = STYLE_TYPE_CHAR; - break; - case NS_ooxml::LN_Value_ST_StyleType_table: - nType = STYLE_TYPE_TABLE; - break; - case NS_ooxml::LN_Value_ST_StyleType_numbering: - nType = STYLE_TYPE_LIST; - break; - default: - SAL_WARN("writerfilter", "unknown LN_CT_Style_type " << nType); - [[fallthrough]]; - case 0: // explicit unknown set by tokenizer - break; - - } - if ( nType == STYLE_TYPE_TABLE ) - { - StyleSheetEntryPtr pEntry = m_pImpl->m_pCurrentEntry; - tools::SvRef<TableStyleSheetEntry> pTableEntry( new TableStyleSheetEntry( *pEntry ) ); - m_pImpl->m_pCurrentEntry = pTableEntry.get(); - } - else - m_pImpl->m_pCurrentEntry->nStyleTypeCode = nType; - } - break; - case NS_ooxml::LN_CT_Style_default: - m_pImpl->m_pCurrentEntry->bIsDefaultStyle = (nIntValue != 0); - - if (m_pImpl->m_pCurrentEntry->nStyleTypeCode != STYLE_TYPE_UNKNOWN) - { - // "If this attribute is specified by multiple styles, then the last instance shall be used." - if ( m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_PARA && !m_pImpl->m_pCurrentEntry->sStyleIdentifierD.isEmpty() ) - m_pImpl->m_sDefaultParaStyleName = m_pImpl->m_pCurrentEntry->sStyleIdentifierD; - - beans::PropertyValue aValue; - aValue.Name = "default"; - aValue.Value <<= m_pImpl->m_pCurrentEntry->bIsDefaultStyle; - m_pImpl->m_pCurrentEntry->AppendInteropGrabBag(aValue); - } - break; - case NS_ooxml::LN_CT_Style_customStyle: - if (m_pImpl->m_pCurrentEntry->nStyleTypeCode != STYLE_TYPE_UNKNOWN) - { - beans::PropertyValue aValue; - aValue.Name = "customStyle"; - aValue.Value <<= (nIntValue != 0); - m_pImpl->m_pCurrentEntry->AppendInteropGrabBag(aValue); - } - break; - case NS_ooxml::LN_CT_Style_styleId: - m_pImpl->m_pCurrentEntry->sStyleIdentifierD = sValue; - if(m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE) - { - TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get()); - beans::PropertyValue aValue; - aValue.Name = "styleId"; - aValue.Value <<= sValue; - pTableEntry->AppendInteropGrabBag(aValue); - } - break; - case NS_ooxml::LN_CT_TblWidth_w: - break; - case NS_ooxml::LN_CT_TblWidth_type: - break; - case NS_ooxml::LN_CT_LatentStyles_defQFormat: - m_pImpl->AppendLatentStyleProperty("defQFormat", val); - break; - case NS_ooxml::LN_CT_LatentStyles_defUnhideWhenUsed: - m_pImpl->AppendLatentStyleProperty("defUnhideWhenUsed", val); - break; - case NS_ooxml::LN_CT_LatentStyles_defSemiHidden: - m_pImpl->AppendLatentStyleProperty("defSemiHidden", val); - break; - case NS_ooxml::LN_CT_LatentStyles_count: - m_pImpl->AppendLatentStyleProperty("count", val); - break; - case NS_ooxml::LN_CT_LatentStyles_defUIPriority: - m_pImpl->AppendLatentStyleProperty("defUIPriority", val); - break; - case NS_ooxml::LN_CT_LatentStyles_defLockedState: - m_pImpl->AppendLatentStyleProperty("defLockedState", val); - break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().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 ? pValue->getInt() : 0; - OUString sStringValue = pValue ? pValue->getString() : OUString(); - - switch(nSprmId) - { - case NS_ooxml::LN_CT_Style_name: - //this is only a UI name! - m_pImpl->m_pCurrentEntry->sStyleName = sStringValue; - if(m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE) - { - TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get()); - beans::PropertyValue aValue; - aValue.Name = "name"; - aValue.Value <<= sStringValue; - pTableEntry->AppendInteropGrabBag(aValue); - } - break; - case NS_ooxml::LN_CT_Style_basedOn: - m_pImpl->m_pCurrentEntry->sBaseStyleIdentifier = sStringValue; - if(m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE) - { - TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get()); - beans::PropertyValue aValue; - aValue.Name = "basedOn"; - aValue.Value <<= sStringValue; - pTableEntry->AppendInteropGrabBag(aValue); - } - 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_hidden: - case NS_ooxml::LN_CT_Style_personal: - case NS_ooxml::LN_CT_Style_personalCompose: - case NS_ooxml::LN_CT_Style_personalReply: - break; - case NS_ooxml::LN_CT_Style_autoRedefine: - m_pImpl->m_pCurrentEntry->bAutoRedefine = nIntValue; - break; - case NS_ooxml::LN_CT_Style_tcPr: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties && m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE) - { - auto pTblStylePrHandler = std::make_shared<TblStylePrHandler>(m_pImpl->m_rDMapper); - pProperties->resolve(*pTblStylePrHandler); - StyleSheetEntry* pEntry = m_pImpl->m_pCurrentEntry.get(); - TableStyleSheetEntry& rTableEntry = dynamic_cast<TableStyleSheetEntry&>(*pEntry); - rTableEntry.AppendInteropGrabBag(pTblStylePrHandler->getInteropGrabBag("tcPr")); - - // This is a <w:tcPr> directly under <w:style>, so it affects the whole table. - rTableEntry.pProperties->InsertProps(pTblStylePrHandler->getProperties()); - } - } - break; - case NS_ooxml::LN_CT_Style_trPr: - break; - case NS_ooxml::LN_CT_Style_rsid: - case NS_ooxml::LN_CT_Style_qFormat: - case NS_ooxml::LN_CT_Style_semiHidden: - case NS_ooxml::LN_CT_Style_unhideWhenUsed: - case NS_ooxml::LN_CT_Style_uiPriority: - case NS_ooxml::LN_CT_Style_link: - case NS_ooxml::LN_CT_Style_locked: - if (m_pImpl->m_pCurrentEntry->nStyleTypeCode != STYLE_TYPE_UNKNOWN) - { - StyleSheetEntryPtr pEntry = m_pImpl->m_pCurrentEntry; - beans::PropertyValue aValue; - switch (nSprmId) - { - case NS_ooxml::LN_CT_Style_rsid: - { - // We want the rsid as a hex string, but always with the length of 8. - OUStringBuffer aBuf = OUString::number(nIntValue, 16); - OUStringBuffer aStr; - comphelper::string::padToLength(aStr, 8 - aBuf.getLength(), '0'); - aStr.append(aBuf.getStr()); - - aValue.Name = "rsid"; - aValue.Value <<= aStr.makeStringAndClear(); - } - break; - case NS_ooxml::LN_CT_Style_qFormat: - aValue.Name = "qFormat"; - break; - case NS_ooxml::LN_CT_Style_semiHidden: - aValue.Name = "semiHidden"; - break; - case NS_ooxml::LN_CT_Style_unhideWhenUsed: - aValue.Name = "unhideWhenUsed"; - break; - case NS_ooxml::LN_CT_Style_uiPriority: - { - aValue.Name = "uiPriority"; - aValue.Value <<= OUString::number(nIntValue); - } - break; - case NS_ooxml::LN_CT_Style_link: - { - aValue.Name = "link"; - aValue.Value <<= sStringValue; - } - break; - case NS_ooxml::LN_CT_Style_locked: - aValue.Name = "locked"; - break; - } - pEntry->AppendInteropGrabBag(aValue); - } - 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 ) - { - auto pTblStylePrHandler = std::make_shared<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(); - - TableStyleSheetEntry * pTableEntry = dynamic_cast<TableStyleSheetEntry*>( pEntry ); - if (nType == TBL_STYLE_UNKNOWN) - { - pEntry->pProperties->InsertProps(pProps); - } - else - { - if (pTableEntry != nullptr) - pTableEntry->AddTblStylePr( nType, pProps ); - } - - if (nSprmId == NS_ooxml::LN_CT_Style_tblPr) - { - if (pTableEntry != nullptr) - pTableEntry->AppendInteropGrabBag(pTblStylePrHandler->getInteropGrabBag("tblPr")); - } - else if (nSprmId == NS_ooxml::LN_CT_Style_tblStylePr) - { - pTblStylePrHandler->appendInteropGrabBag("type", pTblStylePrHandler->getTypeString()); - if (pTableEntry != nullptr) - pTableEntry->AppendInteropGrabBag(pTblStylePrHandler->getInteropGrabBag("tblStylePr")); - } - } - break; - } - case NS_ooxml::LN_CT_PPrDefault_pPr: - case NS_ooxml::LN_CT_DocDefaults_pPrDefault: - if (nSprmId == NS_ooxml::LN_CT_DocDefaults_pPrDefault) - m_pImpl->m_rDMapper.SetDocDefaultsImport(true); - - m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pDefaultParaProps ); - resolveSprmProps( m_pImpl->m_rDMapper, rSprm ); - if ( nSprmId == NS_ooxml::LN_CT_DocDefaults_pPrDefault && m_pImpl->m_pDefaultParaProps && - !m_pImpl->m_pDefaultParaProps->isSet( PROP_PARA_TOP_MARGIN ) ) - { - SetDefaultParaProps( PROP_PARA_TOP_MARGIN, uno::makeAny( sal_Int32(0) ) ); - } - m_pImpl->m_rDMapper.PopStyleSheetProperties(); - applyDefaults( true ); - m_pImpl->m_bHasImportedDefaultParaProps = true; - if (nSprmId == NS_ooxml::LN_CT_DocDefaults_pPrDefault) - m_pImpl->m_rDMapper.SetDocDefaultsImport(false); - break; - case NS_ooxml::LN_CT_RPrDefault_rPr: - case NS_ooxml::LN_CT_DocDefaults_rPrDefault: - if (nSprmId == NS_ooxml::LN_CT_DocDefaults_rPrDefault) - m_pImpl->m_rDMapper.SetDocDefaultsImport(true); - - m_pImpl->m_rDMapper.PushStyleSheetProperties( m_pImpl->m_pDefaultCharProps ); - resolveSprmProps( m_pImpl->m_rDMapper, rSprm ); - m_pImpl->m_rDMapper.PopStyleSheetProperties(); - applyDefaults( false ); - if (nSprmId == NS_ooxml::LN_CT_DocDefaults_rPrDefault) - m_pImpl->m_rDMapper.SetDocDefaultsImport(false); - break; - case NS_ooxml::LN_CT_TblPrBase_jc: //table alignment - row properties! - m_pImpl->m_pCurrentEntry->pProperties->Insert( PROP_HORI_ORIENT, - uno::makeAny( ConversionHelper::convertTableJustification( nIntValue ))); - break; - case NS_ooxml::LN_CT_TrPrBase_jc: //table alignment - row properties! - 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 ) - { - auto pBorderHandler = std::make_shared<BorderHandler>(m_pImpl->m_rDMapper.IsOOXMLImport()); - pProperties->resolve(*pBorderHandler); - m_pImpl->m_pCurrentEntry->pProperties->InsertProps( - pBorderHandler->getProperties()); - } - } - break; - case NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize: - case NS_ooxml::LN_CT_TblPrBase_tblStyleColBandSize: - break; - case NS_ooxml::LN_CT_TblPrBase_tblCellMar: - //no cell margins in styles - break; - case NS_ooxml::LN_CT_LatentStyles_lsdException: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - { - tools::SvRef<LatentStyleHandler> pLatentStyleHandler(new LatentStyleHandler()); - pProperties->resolve(*pLatentStyleHandler); - beans::PropertyValue aValue; - aValue.Name = "lsdException"; - aValue.Value <<= comphelper::containerToSequence(pLatentStyleHandler->getAttributes()); - m_pImpl->m_pCurrentEntry->aLsdExceptions.push_back(aValue); - } - } - 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; - - tools::SvRef<TablePropertiesHandler> pTblHandler(new TablePropertiesHandler()); - 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()); - if (m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE) - { - if (nSprmId == NS_ooxml::LN_CT_Style_pPr) - m_pImpl->m_rDMapper.enableInteropGrabBag("pPr"); - else if (nSprmId == NS_ooxml::LN_CT_Style_rPr) - m_pImpl->m_rDMapper.enableInteropGrabBag("rPr"); - } - m_pImpl->m_rDMapper.sprmWithProps( rSprm, pProps ); - if (m_pImpl->m_pCurrentEntry->nStyleTypeCode == STYLE_TYPE_TABLE) - { - if (nSprmId == NS_ooxml::LN_CT_Style_pPr || nSprmId == NS_ooxml::LN_CT_Style_rPr) - { - TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(m_pImpl->m_pCurrentEntry.get()); - pTableEntry->AppendInteropGrabBag(m_pImpl->m_rDMapper.getInteropGrabBag()); - } - } - - m_pImpl->m_pCurrentEntry->pProperties->InsertProps(pProps); - - m_pImpl->m_rDMapper.PopStyleSheetProperties( ); - } - } - break; -} -} - - -void StyleSheetTable::lcl_entry(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.isEmpty()) - { - 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 - } - - if (!m_pImpl->m_pCurrentEntry->aLatentStyles.empty()) - { - // We have latent styles for this entry, then process them. - std::vector<beans::PropertyValue>& rLatentStyles = m_pImpl->m_pCurrentEntry->aLatentStyles; - - if (!m_pImpl->m_pCurrentEntry->aLsdExceptions.empty()) - { - std::vector<beans::PropertyValue>& rLsdExceptions = m_pImpl->m_pCurrentEntry->aLsdExceptions; - beans::PropertyValue aValue; - aValue.Name = "lsdExceptions"; - aValue.Value <<= comphelper::containerToSequence(rLsdExceptions); - rLatentStyles.push_back(aValue); - } - - uno::Sequence<beans::PropertyValue> aLatentStyles( comphelper::containerToSequence(rLatentStyles) ); - - // We can put all latent style info directly to the document interop - // grab bag, as we can be sure that only a single style entry has - // latent style info. - uno::Reference<beans::XPropertySet> xPropertySet(m_pImpl->m_xTextDocument, uno::UNO_QUERY); - auto aGrabBag = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(xPropertySet->getPropertyValue("InteropGrabBag").get< uno::Sequence<beans::PropertyValue> >()); - beans::PropertyValue aValue; - aValue.Name = "latentStyles"; - aValue.Value <<= aLatentStyles; - aGrabBag.push_back(aValue); - xPropertySet->setPropertyValue("InteropGrabBag", uno::makeAny(comphelper::containerToSequence(aGrabBag))); - } - - StyleSheetEntryPtr pEmptyEntry; - m_pImpl->m_pCurrentEntry = pEmptyEntry; -} -/*------------------------------------------------------------------------- - sorting helper - -----------------------------------------------------------------------*/ -namespace { - -class PropValVector -{ - std::vector<beans::PropertyValue> m_aValues; -public: - PropValVector(){} - - void Insert(const beans::PropertyValue& rVal); - uno::Sequence< uno::Any > getValues(); - uno::Sequence< OUString > getNames(); - const std::vector<beans::PropertyValue>& getProperties() const { return m_aValues; }; -}; - -} - -void PropValVector::Insert(const beans::PropertyValue& rVal) -{ - auto aIt = std::find_if(m_aValues.begin(), m_aValues.end(), - [&rVal](beans::PropertyValue& rPropVal) { return rPropVal.Name > rVal.Name; }); - if (aIt != m_aValues.end()) - { - m_aValues.insert( aIt, rVal ); - return; - } - m_aValues.push_back(rVal); -} - -uno::Sequence< uno::Any > PropValVector::getValues() -{ - std::vector<uno::Any> aRet; - std::transform(m_aValues.begin(), m_aValues.end(), std::back_inserter(aRet), [](const beans::PropertyValue& rValue) { return rValue.Value; }); - return comphelper::containerToSequence(aRet); -} - -uno::Sequence< OUString > PropValVector::getNames() -{ - std::vector<OUString> aRet; - std::transform(m_aValues.begin(), m_aValues.end(), std::back_inserter(aRet), [](const beans::PropertyValue& rValue) { return rValue.Name; }); - return comphelper::containerToSequence(aRet); -} - -void StyleSheetTable::ApplyNumberingStyleNameToParaStyles() -{ - 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> xParaStyles; - xStyleFamilies->getByName(getPropertyName( PROP_PARAGRAPH_STYLES )) >>= xParaStyles; - - if ( !xParaStyles.is() ) - return; - - for ( auto& pEntry : m_pImpl->m_aStyleSheetEntries ) - { - StyleSheetPropertyMap* pStyleSheetProperties = nullptr; - if ( pEntry->nStyleTypeCode == STYLE_TYPE_PARA && (pStyleSheetProperties = dynamic_cast<StyleSheetPropertyMap*>(pEntry->pProperties.get())) ) - { - // ListId 0 means turn off numbering - to cancel inheritance - so make sure that can be set. - // Ignore the special "chapter numbering" outline styles as they are handled internally. - if ( pStyleSheetProperties->GetListId() > -1 && pStyleSheetProperties->GetOutlineLevel() == -1 ) - { - uno::Reference< style::XStyle > xStyle; - xParaStyles->getByName( ConvertStyleName(pEntry->sStyleName) ) >>= xStyle; - - if ( !xStyle.is() ) - break; - - uno::Reference<beans::XPropertySet> xPropertySet( xStyle, uno::UNO_QUERY_THROW ); - const OUString sNumberingStyleName = m_pImpl->m_rDMapper.GetListStyleName( pStyleSheetProperties->GetListId() ); - if ( !sNumberingStyleName.isEmpty() || !pStyleSheetProperties->GetListId() ) - xPropertySet->setPropertyValue( getPropertyName(PROP_NUMBERING_STYLE_NAME), uno::makeAny(sNumberingStyleName) ); - } - } - } - } - catch( const uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "Failed applying numbering style name to Paragraph styles"); - } -} - -void StyleSheetTable::ApplyStyleSheets( const 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; - uno::Reference<container::XNameContainer> xNumberingStyles; - - xStyleFamilies->getByName(getPropertyName( PROP_CHARACTER_STYLES )) >>= xCharStyles; - xStyleFamilies->getByName(getPropertyName( PROP_PARAGRAPH_STYLES )) >>= xParaStyles; - xStyleFamilies->getByName("NumberingStyles") >>= xNumberingStyles; - if(xCharStyles.is() && xParaStyles.is()) - { - std::vector< ::std::pair<OUString, uno::Reference<style::XStyle>> > aMissingParent; - std::vector< ::std::pair<OUString, uno::Reference<style::XStyle>> > aMissingFollow; - std::vector<beans::PropertyValue> aTableStylesVec; - for( auto& pEntry : m_pImpl->m_aStyleSheetEntries ) - { - if( pEntry->nStyleTypeCode == STYLE_TYPE_UNKNOWN && !pEntry->sStyleName.isEmpty() ) - pEntry->nStyleTypeCode = STYLE_TYPE_PARA; // unspecified style types are considered paragraph styles - - if( pEntry->nStyleTypeCode == STYLE_TYPE_CHAR || pEntry->nStyleTypeCode == STYLE_TYPE_PARA || pEntry->nStyleTypeCode == STYLE_TYPE_LIST ) - { - bool bParaStyle = pEntry->nStyleTypeCode == STYLE_TYPE_PARA; - bool bListStyle = pEntry->nStyleTypeCode == STYLE_TYPE_LIST; - bool bInsert = false; - uno::Reference< container::XNameContainer > xStyles = bParaStyle ? xParaStyles : (bListStyle ? xNumberingStyles : xCharStyles); - uno::Reference< style::XStyle > xStyle; - const OUString sConvertedStyleName = ConvertStyleName( pEntry->sStyleName ); - - if(xStyles->hasByName( sConvertedStyleName )) - { - // When pasting, don't update existing styles. - if (!m_pImpl->m_bIsNewDoc) - { - continue; - } - xStyles->getByName( sConvertedStyleName ) >>= xStyle; - - { - StyleSheetTable_Impl::SetPropertiesToDefault(xStyle); - - // resolve import conflicts with built-in styles (only if defaults have been defined) - if ( m_pImpl->m_bHasImportedDefaultParaProps - && pEntry->sBaseStyleIdentifier.isEmpty() //imported style has no inheritance - && !xStyle->getParentStyle().isEmpty() ) //built-in style has a default inheritance - { - xStyle->setParentStyle( "" ); - } - } - } - else - { - bInsert = true; - xStyle.set(xDocFactory->createInstance( - bParaStyle ? - getPropertyName( PROP_SERVICE_PARA_STYLE ) : - (bListStyle ? OUString("com.sun.star.style.NumberingStyle") : getPropertyName( PROP_SERVICE_CHAR_STYLE ))), - uno::UNO_QUERY_THROW); - - // Numbering styles have to be inserted early, as e.g. the NumberingRules property is only available after insertion. - if (bListStyle) - { - xStyles->insertByName( sConvertedStyleName, uno::makeAny( xStyle ) ); - xStyle.set(xStyles->getByName(sConvertedStyleName), uno::UNO_QUERY_THROW); - - StyleSheetPropertyMap* pPropertyMap = dynamic_cast<StyleSheetPropertyMap*>(pEntry->pProperties.get()); - if (pPropertyMap && pPropertyMap->GetListId() == -1) - { - // No properties? Word default is 'none', Writer one is 'arabic', handle this. - uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY_THROW); - uno::Reference<container::XIndexReplace> xNumberingRules; - xPropertySet->getPropertyValue("NumberingRules") >>= xNumberingRules; - uno::Reference<container::XIndexAccess> xIndexAccess(xNumberingRules, uno::UNO_QUERY_THROW); - for (sal_Int32 i = 0; i < xIndexAccess->getCount(); ++i) - { - uno::Sequence< beans::PropertyValue > aLvlProps(1); - aLvlProps[0].Name = "NumberingType"; - aLvlProps[0].Value <<= style::NumberingType::NUMBER_NONE; - xNumberingRules->replaceByIndex(i, uno::makeAny(aLvlProps)); - xPropertySet->setPropertyValue("NumberingRules", uno::makeAny(xNumberingRules)); - } - } - } - } - if( !pEntry->sBaseStyleIdentifier.isEmpty() ) - { - try - { - //TODO: Handle cases where a paragraph <> character style relation is needed - StyleSheetEntryPtr pParent = FindStyleSheetByISTD( pEntry->sBaseStyleIdentifier ); - // Writer core doesn't support numbering styles having a parent style, it seems - if (pParent && !bListStyle) - { - const OUString sParentStyleName = ConvertStyleName( pParent->sStyleName ); - if ( !sParentStyleName.isEmpty() && !xStyles->hasByName( sParentStyleName ) ) - aMissingParent.emplace_back( sParentStyleName, xStyle ); - else - xStyle->setParentStyle( sParentStyleName ); - } - } - catch( const uno::RuntimeException& ) - { - OSL_FAIL( "Styles parent could not be set"); - } - } - else if( bParaStyle ) - { - // Paragraph styles that don't inherit from some parent need to apply the DocDefaults - pEntry->pProperties->InsertProps( m_pImpl->m_pDefaultParaProps, /*bOverwrite=*/false ); - - //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, aTwoHundredFortyTwip, false); - - // western font not already set -> apply first font - const FontEntry::Pointer_t pWesternFontEntry(rFontTable->getFontEntry( 0 )); - OUString sWesternFontName = pWesternFontEntry->sFontName; - pEntry->pProperties->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( sWesternFontName ), false); - - // CJK ... apply second font - const FontEntry::Pointer_t pCJKFontEntry(rFontTable->getFontEntry( 2 )); - pEntry->pProperties->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::makeAny( pCJKFontEntry->sFontName ), false); - pEntry->pProperties->Insert(PROP_CHAR_HEIGHT_ASIAN, 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, uno::makeAny( pCTLFontEntry->sFontName ), false); - pEntry->pProperties->Insert(PROP_CHAR_HEIGHT_COMPLEX, aTwoHundredFortyTwip, false); - } - } - } - - auto aPropValues = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(pEntry->pProperties->GetPropertyValues()); - - if( bParaStyle ) - { - // delay adding FollowStyle property: all styles need to be created first - if ( !pEntry->sNextStyleIdentifier.isEmpty() ) - { - StyleSheetEntryPtr pFollowStyle = FindStyleSheetByISTD( pEntry->sNextStyleIdentifier ); - if ( pFollowStyle && !pFollowStyle->sStyleName.isEmpty() ) - aMissingFollow.emplace_back( ConvertStyleName( pFollowStyle->sStyleName ), xStyle ); - } - - // Set the outline levels - StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : nullptr); - - if ( pStyleSheetProperties ) - { - beans::PropertyValue aLvlVal( getPropertyName( PROP_OUTLINE_LEVEL ), 0, - uno::makeAny( sal_Int16( pStyleSheetProperties->GetOutlineLevel( ) + 1 ) ), - beans::PropertyState_DIRECT_VALUE ); - aPropValues.push_back(aLvlVal); - - // tdf#95495 missing list level settings in custom styles in old DOCX: apply settings of the parent style - if (pStyleSheetProperties->GetListLevel() == -1 && pStyleSheetProperties->GetOutlineLevel() == -1) - { - const beans::PropertyValues aPropGrabBag = pEntry->GetInteropGrabBagSeq(); - for (const auto& rVal : aPropGrabBag) - { - if (rVal.Name == "customStyle" && rVal.Value == true) - { - OUString sBaseId = pEntry->sBaseStyleIdentifier; - for (const auto& aSheetProps : m_pImpl->m_aStyleSheetEntries) - { - if (aSheetProps->sStyleIdentifierD == sBaseId) - { - StyleSheetPropertyMap& rStyleSheetProps - = dynamic_cast<StyleSheetPropertyMap&>(*aSheetProps->pProperties); - pStyleSheetProperties->SetListLevel(rStyleSheetProps.GetListLevel()); - pStyleSheetProperties->SetOutlineLevel(rStyleSheetProps.GetOutlineLevel()); - break; - } - } - } - } - } - } - - uno::Reference< beans::XPropertyState >xState( xStyle, uno::UNO_QUERY_THROW ); - if( sConvertedStyleName == "Contents Heading" || - sConvertedStyleName == "User Index Heading" || - sConvertedStyleName == "Index Heading" ) - { - // remove Left/RightMargin values from TOX heading styles - //left margin is set to NULL by default - xState->setPropertyToDefault(getPropertyName( PROP_PARA_LEFT_MARGIN )); - } - else if ( sConvertedStyleName == "Text body" ) - xState->setPropertyToDefault(getPropertyName( PROP_PARA_BOTTOM_MARGIN )); - else if ( sConvertedStyleName == "Heading 1" || - sConvertedStyleName == "Heading 2" || - sConvertedStyleName == "Heading 3" || - sConvertedStyleName == "Heading 4" || - sConvertedStyleName == "Heading 5" || - sConvertedStyleName == "Heading 6" || - sConvertedStyleName == "Heading 7" || - sConvertedStyleName == "Heading 8" || - sConvertedStyleName == "Heading 9" ) - { - xState->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT )); - xState->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT_ASIAN )); - xState->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT_COMPLEX )); - xState->setPropertyToDefault(getPropertyName( PROP_CHAR_POSTURE )); - xState->setPropertyToDefault(getPropertyName( PROP_CHAR_POSTURE_ASIAN )); - xState->setPropertyToDefault(getPropertyName( PROP_CHAR_POSTURE_COMPLEX )); - xState->setPropertyToDefault(getPropertyName( PROP_CHAR_PROP_HEIGHT )); - xState->setPropertyToDefault(getPropertyName( PROP_CHAR_PROP_HEIGHT_ASIAN )); - xState->setPropertyToDefault(getPropertyName( PROP_CHAR_PROP_HEIGHT_COMPLEX)); - - } - } - - if ( !aPropValues.empty() ) - { - PropValVector aSortedPropVals; - for (const beans::PropertyValue& rValue : aPropValues) - { - // Don't add the style name properties - bool bIsParaStyleName = rValue.Name == "ParaStyleName"; - bool bIsCharStyleName = rValue.Name == "CharStyleName"; - if ( !bIsParaStyleName && !bIsCharStyleName ) - { - aSortedPropVals.Insert(rValue); - } - } - - try - { - uno::Reference< beans::XMultiPropertySet > xMultiPropertySet( xStyle, uno::UNO_QUERY_THROW); - try - { - xMultiPropertySet->setPropertyValues( aSortedPropVals.getNames(), aSortedPropVals.getValues() ); - } - catch ( const uno::Exception& ) - { - uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY_THROW); - for ( const beans::PropertyValue& rValue : aSortedPropVals.getProperties() ) - { - try - { - xPropertySet->setPropertyValue( rValue.Name, rValue.Value ); - } - catch ( const uno::Exception& ) - { - SAL_WARN( "writerfilter", "StyleSheetTable::ApplyStyleSheets could not set property " << rValue.Name ); - } - } - } - // Duplicate MSWord's single footnote reference into Footnote Characters and Footnote anchor - if( pEntry->sStyleName.equalsIgnoreAsciiCase("footnote reference") - || pEntry->sStyleName.equalsIgnoreAsciiCase("endnote reference") ) - { - uno::Reference< style::XStyle > xCopyStyle; - if( pEntry->sStyleName.equalsIgnoreAsciiCase("footnote reference") ) - xStyles->getByName( "Footnote anchor" ) >>= xCopyStyle; - else - xStyles->getByName( "Endnote anchor" ) >>= xCopyStyle; - - xMultiPropertySet.set( xCopyStyle, uno::UNO_QUERY_THROW); - xMultiPropertySet->setPropertyValues( aSortedPropVals.getNames(), aSortedPropVals.getValues() ); - } - } - catch( const lang::WrappedTargetException& rWrapped) - { -#ifdef DBG_UTIL - OUString aMessage("StyleSheetTable::ApplyStyleSheets: Some style properties could not be set"); - beans::UnknownPropertyException aUnknownPropertyException; - - if (rWrapped.TargetException >>= aUnknownPropertyException) - aMessage += ": " + aUnknownPropertyException.Message; - - SAL_WARN("writerfilter", aMessage); -#else - (void) rWrapped; -#endif - } - catch( const uno::Exception& ) - { - OSL_FAIL( "Some style properties could not be set"); - } - } - // Numbering style got inserted earlier. - if(bInsert && !bListStyle) - { - const OUString sParentStyle = xStyle->getParentStyle(); - if( !sParentStyle.isEmpty() && !xStyles->hasByName( sParentStyle ) ) - aMissingParent.emplace_back( sParentStyle, xStyle ); - - xStyles->insertByName( sConvertedStyleName, uno::makeAny( xStyle) ); - } - - beans::PropertyValues aGrabBag = pEntry->GetInteropGrabBagSeq(); - uno::Reference<beans::XPropertySet> xPropertySet(xStyle, uno::UNO_QUERY); - if (aGrabBag.hasElements()) - { - xPropertySet->setPropertyValue("StyleInteropGrabBag", uno::makeAny(aGrabBag)); - } - - // Only paragraph styles support automatic updates. - if (pEntry->bAutoRedefine && bParaStyle) - xPropertySet->setPropertyValue("IsAutoUpdate", uno::makeAny(true)); - } - else if(pEntry->nStyleTypeCode == STYLE_TYPE_TABLE) - { - // If this is a table style, save its contents as-is for roundtrip purposes. - TableStyleSheetEntry* pTableEntry = static_cast<TableStyleSheetEntry *>(pEntry.get()); - aTableStylesVec.push_back(pTableEntry->GetInteropGrabBag()); - - // if DocDefaults exist, MS Word includes these in the table style definition. - pEntry->pProperties->InsertProps( m_pImpl->m_pDefaultCharProps, /*bOverwrite=*/false ); - pEntry->pProperties->InsertProps( m_pImpl->m_pDefaultParaProps, /*bOverwrite=*/false ); - } - } - - // Update the styles that were created before their parents or next-styles - for( auto const & iter : aMissingParent ) - { - iter.second->setParentStyle( iter.first ); - } - - for( auto const & iter : aMissingFollow ) - { - try - { - uno::Reference<beans::XPropertySet> xPropertySet(iter.second, uno::UNO_QUERY); - xPropertySet->setPropertyValue( "FollowStyle", uno::makeAny(iter.first) ); - } - catch( uno::Exception & ) {} - } - - if (!aTableStylesVec.empty()) - { - // If we had any table styles, add a new document-level InteropGrabBag entry for them. - uno::Reference<beans::XPropertySet> xPropertySet(m_pImpl->m_xTextDocument, uno::UNO_QUERY); - uno::Any aAny = xPropertySet->getPropertyValue("InteropGrabBag"); - auto aGrabBag = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aAny.get< uno::Sequence<beans::PropertyValue> >()); - beans::PropertyValue aValue; - aValue.Name = "tableStyles"; - aValue.Value <<= comphelper::containerToSequence(aTableStylesVec); - aGrabBag.push_back(aValue); - xPropertySet->setPropertyValue("InteropGrabBag", uno::makeAny(comphelper::containerToSequence(aGrabBag))); - } - } - } - catch( const uno::Exception& ) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "Styles could not be imported completely"); - } -} - - -StyleSheetEntryPtr StyleSheetTable::FindStyleSheetByISTD(std::u16string_view sIndex) -{ - StyleSheetEntryPtr pRet; - for(const StyleSheetEntryPtr & rpEntry : m_pImpl->m_aStyleSheetEntries) - { - if( rpEntry->sStyleIdentifierD == sIndex) - { - pRet = rpEntry; - break; - } - } - return pRet; -} - - -StyleSheetEntryPtr StyleSheetTable::FindStyleSheetByConvertedStyleName(std::u16string_view sIndex) -{ - StyleSheetEntryPtr pRet; - for(const StyleSheetEntryPtr & rpEntry : m_pImpl->m_aStyleSheetEntries) - { - if( rpEntry->sConvertedStyleName == sIndex) - { - pRet = rpEntry; - break; - } - } - return pRet; -} - - -StyleSheetEntryPtr StyleSheetTable::FindDefaultParaStyle() -{ - return FindStyleSheetByISTD( m_pImpl->m_sDefaultParaStyleName ); -} - -const StyleSheetEntryPtr & StyleSheetTable::GetCurrentEntry() const -{ - return m_pImpl->m_pCurrentEntry; -} - -OUString StyleSheetTable::ConvertStyleName( const OUString& rWWName, bool bExtendedSearch) -{ - OUString sRet( rWWName ); - if( bExtendedSearch ) - { - //search for the rWWName in the IdentifierD of the existing styles and convert the sStyleName member - //TODO: performance issue - put styles list into a map sorted by its sStyleIdentifierD members - for( const auto& rStyleSheetEntryPtr : m_pImpl->m_aStyleSheetEntries ) - { - if( rWWName == rStyleSheetEntryPtr->sStyleIdentifierD ) - sRet = rStyleSheetEntryPtr->sStyleName; - } - } - - // create a map only once - static const std::map< OUString, OUString> StyleNameMap { - { "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" }, - { "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" }, - { "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" }, - { "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 Characters" }, - { "Footnote Reference", "Footnote Characters" }, -// { "Annotation Reference", "" }, - { "Line Number", "Line numbering" }, - { "Page Number", "Page Number" }, - { "endnote reference", "Endnote Characters" }, - { "Endnote Reference", "Endnote Characters" }, - { "endnote text", "Endnote" }, - { "Endnote Text", "Endnote" }, -// { "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" }, - { "FollowedHyperlink", "Visited Internet Link" }, - { "Emphasis", "Emphasis" }, -// { "Document Map", "" }, -// { "Plain Text", "" }, - { "NoList", "No List" }, - { "AbstractHeading", "Abstract Heading" }, - { "AbstractBody", "Abstract Body" }, - { "PageNumber", "page number" }, - { "TableNormal", "Normal Table" }, - { "DocumentMap", "Document Map" }, - }; - - // find style-name using map - if (const auto aIt = StyleNameMap.find(sRet); aIt != StyleNameMap.end()) - { - sRet = aIt->second; - } - else - { - // Style names which should not be used without a " (user)" suffix - static const o3tl::sorted_vector<OUString> ReservedStyleNames = [] { - o3tl::sorted_vector<OUString> set; - for (const auto& pair : StyleNameMap) - set.insert(pair.second); - return set; - }(); - // SwStyleNameMapper doc says: If the UI style name equals a - // programmatic name, then it must append " (user)" to the end. - if (ReservedStyleNames.find(sRet) != ReservedStyleNames.end()) - sRet += " (user)"; - } - - return sRet; -} - -void StyleSheetTable::applyDefaults(bool bParaProperties) -{ - try{ - - if (!m_pImpl->m_bIsNewDoc) - { - // tdf#72942: do not corrupts original styles in master document - // during inserting of text from second document - return; - } - - if(!m_pImpl->m_xTextDefaults.is()) - { - m_pImpl->m_xTextDefaults.set( - m_pImpl->m_rDMapper.GetTextFactory()->createInstance("com.sun.star.text.Defaults"), - uno::UNO_QUERY_THROW ); - } - - // WARNING: these defaults only take effect IF there is a DocDefaults style section. Normally there is, but not always. - if( bParaProperties && m_pImpl->m_pDefaultParaProps) - { - // tdf#87533 LO will have different defaults here, depending on the locale. Import with documented defaults - SetDefaultParaProps(PROP_WRITING_MODE, uno::makeAny(sal_Int16(text::WritingMode_LR_TB))); - SetDefaultParaProps(PROP_PARA_ADJUST, uno::makeAny(sal_Int16(style::ParagraphAdjust_LEFT))); - - // Widow/Orphan -> set both to two if not already set - uno::Any aTwo = uno::makeAny(sal_Int8(2)); - SetDefaultParaProps(PROP_PARA_WIDOWS, aTwo); - SetDefaultParaProps(PROP_PARA_ORPHANS, aTwo); - - uno::Reference<style::XStyleFamiliesSupplier> xStylesSupplier(m_pImpl->m_xTextDocument, uno::UNO_QUERY); - uno::Reference<container::XNameAccess> xStyleFamilies = xStylesSupplier->getStyleFamilies(); - uno::Reference<container::XNameAccess> xParagraphStyles; - xStyleFamilies->getByName("ParagraphStyles") >>= xParagraphStyles; - uno::Reference<beans::XPropertySet> xDefault; - // This is the built-in default style that every style inherits from - xParagraphStyles->getByName("Paragraph style") >>= xDefault; - - const uno::Sequence< beans::PropertyValue > aPropValues = m_pImpl->m_pDefaultParaProps->GetPropertyValues(); - for( const auto& rPropValue : aPropValues ) - { - try - { - xDefault->setPropertyValue(rPropValue.Name, rPropValue.Value); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "setPropertyValue"); - } - } - } - if( !bParaProperties && m_pImpl->m_pDefaultCharProps ) - { - // tdf#108350: Earlier in DomainMapper for DOCX, Calibri/11pt was set to match MSWord 2007+, - // but that is valid only if DocDefaults_rPrDefault is omitted. - // Now that DocDefaults_rPrDefault is known, the defaults should be reset to Times New Roman/10pt. - if ( m_pImpl->m_rDMapper.IsOOXMLImport() ) - m_pImpl->m_xTextDefaults->setPropertyValue( getPropertyName(PROP_CHAR_FONT_NAME), css::uno::Any(OUString("Times New Roman")) ); - - const uno::Sequence< beans::PropertyValue > aPropValues = m_pImpl->m_pDefaultCharProps->GetPropertyValues(); - for( const auto& rPropValue : aPropValues ) - { - try - { - m_pImpl->m_xTextDefaults->setPropertyValue( rPropValue.Name, rPropValue.Value ); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "exception"); - } - } - } - } - catch( const uno::Exception& ) - { - } -} - - -OUString StyleSheetTable::getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate ) -{ - //find out if any of the styles already has the required properties then return its name - OUString sListLabel = m_pImpl->HasListCharStyle(rCharProperties); - // Don't try to reuse an existing character style if requested. - if( !sListLabel.isEmpty() && !bAlwaysCreate) - 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("CharacterStyles") >>= xCharStyles; - //search for all character styles with the name sListLabel + <index> - sal_Int32 nStyleFound = 0; - const uno::Sequence< OUString > aStyleNames = xCharStyles->getElementNames(); - for( const auto& rStyleName : aStyleNames ) - { - OUString sSuffix; - if( rStyleName.startsWith( cListLabel, &sSuffix ) ) - { - sal_Int32 nSuffix = sSuffix.toInt32(); - if( nSuffix > 0 && nSuffix > nStyleFound ) - nStyleFound = nSuffix; - } - } - sListLabel = cListLabel + OUString::number( ++nStyleFound ); - //create a new one otherwise - uno::Reference< lang::XMultiServiceFactory > xDocFactory( m_pImpl->m_xTextDocument, uno::UNO_QUERY_THROW ); - try - { - uno::Reference< style::XStyle > xStyle( xDocFactory->createInstance( - getPropertyName( PROP_SERVICE_CHAR_STYLE )), uno::UNO_QUERY_THROW); - uno::Reference< beans::XPropertySet > xStyleProps(xStyle, uno::UNO_QUERY_THROW ); - for( const auto& rCharProp : rCharProperties) - { - try - { - xStyleProps->setPropertyValue( rCharProp.Name, rCharProp.Value ); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "StyleSheetTable::getOrCreateCharStyle - Style::setPropertyValue"); - } - } - xCharStyles->insertByName( sListLabel, uno::makeAny( xStyle) ); - m_pImpl->m_aListCharStylePropertyVector.emplace_back( sListLabel, rCharProperties ); - } - catch( const uno::Exception& ) - { - TOOLS_WARN_EXCEPTION( "writerfilter", "StyleSheetTable::getOrCreateCharStyle"); - } - - return sListLabel; -} - -}//namespace writerfilter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/StyleSheetTable.hxx b/writerfilter/source/dmapper/StyleSheetTable.hxx deleted file mode 100644 index 69469d19d37a..000000000000 --- a/writerfilter/source/dmapper/StyleSheetTable.hxx +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_STYLESHEETTABLE_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_STYLESHEETTABLE_HXX - -#include <memory> -#include "TblStylePrHandler.hxx" - -#include "DomainMapper.hxx" -#include <com/sun/star/beans/PropertyValues.hpp> -#include "PropertyMap.hxx" -#include "FontTable.hxx" -#include "LoggedResources.hxx" - -namespace com::sun::star::text { class XTextDocument; } - - -namespace writerfilter::dmapper -{ - - -enum StyleType -{ - STYLE_TYPE_UNKNOWN, - STYLE_TYPE_PARA, - STYLE_TYPE_CHAR, - STYLE_TYPE_TABLE, - STYLE_TYPE_LIST -}; -class StyleSheetTable; -typedef tools::SvRef<StyleSheetTable> StyleSheetTablePtr; - -struct StyleSheetTable_Impl; -class StyleSheetEntry : public virtual SvRefBase -{ - std::vector<css::beans::PropertyValue> m_aInteropGrabBag; -public: - OUString sStyleIdentifierD; // WW8 name - bool bIsDefaultStyle; - bool bInvalidHeight; - bool bHasUPE; //universal property expansion - StyleType nStyleTypeCode; //sgc - OUString sBaseStyleIdentifier; - OUString sNextStyleIdentifier; - OUString sStyleName; - const PropertyMapPtr pProperties; ///< always StyleSheetPropertyMap - OUString sConvertedStyleName; - std::vector<css::beans::PropertyValue> aLatentStyles; ///< Attributes of latentStyles - std::vector<css::beans::PropertyValue> aLsdExceptions; ///< List of lsdException attribute lists - bool bAutoRedefine; ///< Writer calls this auto-update. - - void AppendInteropGrabBag(const css::beans::PropertyValue& rValue); - css::beans::PropertyValue GetInteropGrabBag(); ///< Used for table styles, has a name. - css::beans::PropertyValues GetInteropGrabBagSeq() const; ///< Used for existing styles, just a list of properties. - - // Get all properties, merged with the all of the parent's properties - PropertyMapPtr GetMergedInheritedProperties(const StyleSheetTablePtr& pStyleSheetTable); - - StyleSheetEntry(); - virtual ~StyleSheetEntry() override; -}; - -typedef tools::SvRef<StyleSheetEntry> StyleSheetEntryPtr; - -class DomainMapper; -class StyleSheetTable : - public LoggedProperties, - public LoggedTable -{ - std::unique_ptr<StyleSheetTable_Impl> m_pImpl; - -public: - StyleSheetTable(DomainMapper& rDMapper, css::uno::Reference<css::text::XTextDocument> const& xTextDocument, bool bIsNewDoc); - virtual ~StyleSheetTable() override; - - void ApplyNumberingStyleNameToParaStyles(); - void ApplyStyleSheets( const FontTablePtr& rFontTable ); - StyleSheetEntryPtr FindStyleSheetByISTD(std::u16string_view sIndex); - StyleSheetEntryPtr FindStyleSheetByConvertedStyleName(std::u16string_view rIndex); - StyleSheetEntryPtr FindDefaultParaStyle(); - - OUString ConvertStyleName( const OUString& rWWName, bool bExtendedSearch = false ); - - OUString getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate ); - - void SetDefaultParaProps(PropertyIds eId, const css::uno::Any& rAny); - PropertyMapPtr const & GetDefaultParaProps() const; - /// Returns the default character properties. - PropertyMapPtr const & GetDefaultCharProps() const; - - const StyleSheetEntryPtr & GetCurrentEntry() const; - -private: - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - - // Table - virtual void lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) override; - - void applyDefaults(bool bParaProperties); -}; - - -class TableStyleSheetEntry : - public StyleSheetEntry -{ -public: - // Adds a new tblStylePr to the table style entry. This method - // fixes some possible properties conflicts, like borders ones. - void AddTblStylePr( TblStyleType nType, const PropertyMapPtr& pProps ); - - // Gets all the properties - // + corresponding to the mask, - // + from the parent styles - - // @param mask mask describing which properties to return - PropertyMapPtr GetProperties( sal_Int32 nMask); - - TableStyleSheetEntry( StyleSheetEntry const & aEntry ); - virtual ~TableStyleSheetEntry( ) override; - -private: - typedef std::map<TblStyleType, PropertyMapPtr> TblStylePrs; - TblStylePrs m_aStyles; - PropertyMapPtr GetLocalPropertiesFromMask( sal_Int32 nMask ); -}; - - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TDefTableHandler.cxx b/writerfilter/source/dmapper/TDefTableHandler.cxx deleted file mode 100644 index 9d7059feece6..000000000000 --- a/writerfilter/source/dmapper/TDefTableHandler.cxx +++ /dev/null @@ -1,458 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#include "TDefTableHandler.hxx" -#include "PropertyMap.hxx" -#include "ConversionHelper.hxx" -#include <ooxml/resourceids.hxx> -#include <filter/msfilter/util.hxx> -#include <tools/color.hxx> -#include <com/sun/star/table/BorderLine2.hpp> -#include <comphelper/sequence.hxx> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; - - -TDefTableHandler::TDefTableHandler() : -LoggedProperties("TDefTableHandler"), -m_nLineWidth(0), -m_nLineType(0), -m_nLineColor(0) -{ -} - - -TDefTableHandler::~TDefTableHandler() -{ -} - -OUString TDefTableHandler::getBorderTypeString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_Value_ST_Border_nil: return "nil"; - case NS_ooxml::LN_Value_ST_Border_none: return "none"; - case NS_ooxml::LN_Value_ST_Border_single: return "single"; - case NS_ooxml::LN_Value_ST_Border_thick: return "thick"; - case NS_ooxml::LN_Value_ST_Border_double: return "double"; - case NS_ooxml::LN_Value_ST_Border_dotted: return "dotted"; - case NS_ooxml::LN_Value_ST_Border_dashed: return "dashed"; - case NS_ooxml::LN_Value_ST_Border_dotDash: return "dotDash"; - case NS_ooxml::LN_Value_ST_Border_dotDotDash: return "dotDotDash"; - case NS_ooxml::LN_Value_ST_Border_triple: return "triple"; - case NS_ooxml::LN_Value_ST_Border_thinThickSmallGap: return "thinThickSmallGap"; - case NS_ooxml::LN_Value_ST_Border_thickThinSmallGap: return "thickThinSmallGap"; - case NS_ooxml::LN_Value_ST_Border_thinThickThinSmallGap: return "thinThickThinSmallGap"; - case NS_ooxml::LN_Value_ST_Border_thinThickMediumGap: return "thinThickMediumGap"; - case NS_ooxml::LN_Value_ST_Border_thickThinMediumGap: return "thickThinMediumGap"; - case NS_ooxml::LN_Value_ST_Border_thinThickThinMediumGap: return "thinThickThinMediumGap"; - case NS_ooxml::LN_Value_ST_Border_thinThickLargeGap: return "thinThickLargeGap"; - case NS_ooxml::LN_Value_ST_Border_thickThinLargeGap: return "thickThinLargeGap"; - case NS_ooxml::LN_Value_ST_Border_thinThickThinLargeGap: return "thinThickThinLargeGap"; - case NS_ooxml::LN_Value_ST_Border_wave: return "wave"; - case NS_ooxml::LN_Value_ST_Border_doubleWave: return "doubleWave"; - case NS_ooxml::LN_Value_ST_Border_dashSmallGap: return "dashSmallGap"; - case NS_ooxml::LN_Value_ST_Border_dashDotStroked: return "dashDotStroked"; - case NS_ooxml::LN_Value_ST_Border_threeDEmboss: return "threeDEmboss"; - case NS_ooxml::LN_Value_ST_Border_threeDEngrave: return "threeDEngrave"; - case NS_ooxml::LN_Value_ST_Border_outset: return "outset"; - case NS_ooxml::LN_Value_ST_Border_inset: return "inset"; - case NS_ooxml::LN_Value_ST_Border_apples: return "apples"; - case NS_ooxml::LN_Value_ST_Border_archedScallops: return "archedScallops"; - case NS_ooxml::LN_Value_ST_Border_babyPacifier: return "babyPacifier"; - case NS_ooxml::LN_Value_ST_Border_babyRattle: return "babyRattle"; - case NS_ooxml::LN_Value_ST_Border_balloons3Colors: return "balloons3Colors"; - case NS_ooxml::LN_Value_ST_Border_balloonsHotAir: return "balloonsHotAir"; - case NS_ooxml::LN_Value_ST_Border_basicBlackDashes: return "basicBlackDashes"; - case NS_ooxml::LN_Value_ST_Border_basicBlackDots: return "basicBlackDots"; - case NS_ooxml::LN_Value_ST_Border_basicBlackSquares: return "basicBlackSquares"; - case NS_ooxml::LN_Value_ST_Border_basicThinLines: return "basicThinLines"; - case NS_ooxml::LN_Value_ST_Border_basicWhiteDashes: return "basicWhiteDashes"; - case NS_ooxml::LN_Value_ST_Border_basicWhiteDots: return "basicWhiteDots"; - case NS_ooxml::LN_Value_ST_Border_basicWhiteSquares: return "basicWhiteSquares"; - case NS_ooxml::LN_Value_ST_Border_basicWideInline: return "basicWideInline"; - case NS_ooxml::LN_Value_ST_Border_basicWideMidline: return "basicWideMidline"; - case NS_ooxml::LN_Value_ST_Border_basicWideOutline: return "basicWideOutline"; - case NS_ooxml::LN_Value_ST_Border_bats: return "bats"; - case NS_ooxml::LN_Value_ST_Border_birds: return "birds"; - case NS_ooxml::LN_Value_ST_Border_birdsFlight: return "birdsFlight"; - case NS_ooxml::LN_Value_ST_Border_cabins: return "cabins"; - case NS_ooxml::LN_Value_ST_Border_cakeSlice: return "cakeSlice"; - case NS_ooxml::LN_Value_ST_Border_candyCorn: return "candyCorn"; - case NS_ooxml::LN_Value_ST_Border_celticKnotwork: return "celticKnotwork"; - case NS_ooxml::LN_Value_ST_Border_certificateBanner: return "certificateBanner"; - case NS_ooxml::LN_Value_ST_Border_chainLink: return "chainLink"; - case NS_ooxml::LN_Value_ST_Border_champagneBottle: return "champagneBottle"; - case NS_ooxml::LN_Value_ST_Border_checkedBarBlack: return "checkedBarBlack"; - case NS_ooxml::LN_Value_ST_Border_checkedBarColor: return "checkedBarColor"; - case NS_ooxml::LN_Value_ST_Border_checkered: return "checkered"; - case NS_ooxml::LN_Value_ST_Border_christmasTree: return "christmasTree"; - case NS_ooxml::LN_Value_ST_Border_circlesLines: return "circlesLines"; - case NS_ooxml::LN_Value_ST_Border_circlesRectangles: return "circlesRectangles"; - case NS_ooxml::LN_Value_ST_Border_classicalWave: return "classicalWave"; - case NS_ooxml::LN_Value_ST_Border_clocks: return "clocks"; - case NS_ooxml::LN_Value_ST_Border_compass: return "compass"; - case NS_ooxml::LN_Value_ST_Border_confetti: return "confetti"; - case NS_ooxml::LN_Value_ST_Border_confettiGrays: return "confettiGrays"; - case NS_ooxml::LN_Value_ST_Border_confettiOutline: return "confettiOutline"; - case NS_ooxml::LN_Value_ST_Border_confettiStreamers: return "confettiStreamers"; - case NS_ooxml::LN_Value_ST_Border_confettiWhite: return "confettiWhite"; - case NS_ooxml::LN_Value_ST_Border_cornerTriangles: return "cornerTriangles"; - case NS_ooxml::LN_Value_ST_Border_couponCutoutDashes: return "couponCutoutDashes"; - case NS_ooxml::LN_Value_ST_Border_couponCutoutDots: return "couponCutoutDots"; - case NS_ooxml::LN_Value_ST_Border_crazyMaze: return "crazyMaze"; - case NS_ooxml::LN_Value_ST_Border_creaturesButterfly: return "creaturesButterfly"; - case NS_ooxml::LN_Value_ST_Border_creaturesFish: return "creaturesFish"; - case NS_ooxml::LN_Value_ST_Border_creaturesInsects: return "creaturesInsects"; - case NS_ooxml::LN_Value_ST_Border_creaturesLadyBug: return "creaturesLadyBug"; - case NS_ooxml::LN_Value_ST_Border_crossStitch: return "crossStitch"; - case NS_ooxml::LN_Value_ST_Border_cup: return "cup"; - case NS_ooxml::LN_Value_ST_Border_decoArch: return "decoArch"; - case NS_ooxml::LN_Value_ST_Border_decoArchColor: return "decoArchColor"; - case NS_ooxml::LN_Value_ST_Border_decoBlocks: return "decoBlocks"; - case NS_ooxml::LN_Value_ST_Border_diamondsGray: return "diamondsGray"; - case NS_ooxml::LN_Value_ST_Border_doubleD: return "doubleD"; - case NS_ooxml::LN_Value_ST_Border_doubleDiamonds: return "doubleDiamonds"; - case NS_ooxml::LN_Value_ST_Border_earth1: return "earth1"; - case NS_ooxml::LN_Value_ST_Border_earth2: return "earth2"; - case NS_ooxml::LN_Value_ST_Border_eclipsingSquares1: return "eclipsingSquares1"; - case NS_ooxml::LN_Value_ST_Border_eclipsingSquares2: return "eclipsingSquares2"; - case NS_ooxml::LN_Value_ST_Border_eggsBlack: return "eggsBlack"; - case NS_ooxml::LN_Value_ST_Border_fans: return "fans"; - case NS_ooxml::LN_Value_ST_Border_film: return "film"; - case NS_ooxml::LN_Value_ST_Border_firecrackers: return "firecrackers"; - case NS_ooxml::LN_Value_ST_Border_flowersBlockPrint: return "flowersBlockPrint"; - case NS_ooxml::LN_Value_ST_Border_flowersDaisies: return "flowersDaisies"; - case NS_ooxml::LN_Value_ST_Border_flowersModern1: return "flowersModern1"; - case NS_ooxml::LN_Value_ST_Border_flowersModern2: return "flowersModern2"; - case NS_ooxml::LN_Value_ST_Border_flowersPansy: return "flowersPansy"; - case NS_ooxml::LN_Value_ST_Border_flowersRedRose: return "flowersRedRose"; - case NS_ooxml::LN_Value_ST_Border_flowersRoses: return "flowersRoses"; - case NS_ooxml::LN_Value_ST_Border_flowersTeacup: return "flowersTeacup"; - case NS_ooxml::LN_Value_ST_Border_flowersTiny: return "flowersTiny"; - case NS_ooxml::LN_Value_ST_Border_gems: return "gems"; - case NS_ooxml::LN_Value_ST_Border_gingerbreadMan: return "gingerbreadMan"; - case NS_ooxml::LN_Value_ST_Border_gradient: return "gradient"; - case NS_ooxml::LN_Value_ST_Border_handmade1: return "handmade1"; - case NS_ooxml::LN_Value_ST_Border_handmade2: return "handmade2"; - case NS_ooxml::LN_Value_ST_Border_heartBalloon: return "heartBalloon"; - case NS_ooxml::LN_Value_ST_Border_heartGray: return "heartGray"; - case NS_ooxml::LN_Value_ST_Border_hearts: return "hearts"; - case NS_ooxml::LN_Value_ST_Border_heebieJeebies: return "heebieJeebies"; - case NS_ooxml::LN_Value_ST_Border_holly: return "holly"; - case NS_ooxml::LN_Value_ST_Border_houseFunky: return "houseFunky"; - case NS_ooxml::LN_Value_ST_Border_hypnotic: return "hypnotic"; - case NS_ooxml::LN_Value_ST_Border_iceCreamCones: return "iceCreamCones"; - case NS_ooxml::LN_Value_ST_Border_lightBulb: return "lightBulb"; - case NS_ooxml::LN_Value_ST_Border_lightning1: return "lightning1"; - case NS_ooxml::LN_Value_ST_Border_lightning2: return "lightning2"; - case NS_ooxml::LN_Value_ST_Border_mapPins: return "mapPins"; - case NS_ooxml::LN_Value_ST_Border_mapleLeaf: return "mapleLeaf"; - case NS_ooxml::LN_Value_ST_Border_mapleMuffins: return "mapleMuffins"; - case NS_ooxml::LN_Value_ST_Border_marquee: return "marquee"; - case NS_ooxml::LN_Value_ST_Border_marqueeToothed: return "marqueeToothed"; - case NS_ooxml::LN_Value_ST_Border_moons: return "moons"; - case NS_ooxml::LN_Value_ST_Border_mosaic: return "mosaic"; - case NS_ooxml::LN_Value_ST_Border_musicNotes: return "musicNotes"; - case NS_ooxml::LN_Value_ST_Border_northwest: return "northwest"; - case NS_ooxml::LN_Value_ST_Border_ovals: return "ovals"; - case NS_ooxml::LN_Value_ST_Border_packages: return "packages"; - case NS_ooxml::LN_Value_ST_Border_palmsBlack: return "palmsBlack"; - case NS_ooxml::LN_Value_ST_Border_palmsColor: return "palmsColor"; - case NS_ooxml::LN_Value_ST_Border_paperClips: return "paperClips"; - case NS_ooxml::LN_Value_ST_Border_papyrus: return "papyrus"; - case NS_ooxml::LN_Value_ST_Border_partyFavor: return "partyFavor"; - case NS_ooxml::LN_Value_ST_Border_partyGlass: return "partyGlass"; - case NS_ooxml::LN_Value_ST_Border_pencils: return "pencils"; - case NS_ooxml::LN_Value_ST_Border_people: return "people"; - case NS_ooxml::LN_Value_ST_Border_peopleWaving: return "peopleWaving"; - case NS_ooxml::LN_Value_ST_Border_peopleHats: return "peopleHats"; - case NS_ooxml::LN_Value_ST_Border_poinsettias: return "poinsettias"; - case NS_ooxml::LN_Value_ST_Border_postageStamp: return "postageStamp"; - case NS_ooxml::LN_Value_ST_Border_pumpkin1: return "pumpkin1"; - case NS_ooxml::LN_Value_ST_Border_pushPinNote2: return "pushPinNote2"; - case NS_ooxml::LN_Value_ST_Border_pushPinNote1: return "pushPinNote1"; - case NS_ooxml::LN_Value_ST_Border_pyramids: return "pyramids"; - case NS_ooxml::LN_Value_ST_Border_pyramidsAbove: return "pyramidsAbove"; - case NS_ooxml::LN_Value_ST_Border_quadrants: return "quadrants"; - case NS_ooxml::LN_Value_ST_Border_rings: return "rings"; - case NS_ooxml::LN_Value_ST_Border_safari: return "safari"; - case NS_ooxml::LN_Value_ST_Border_sawtooth: return "sawtooth"; - case NS_ooxml::LN_Value_ST_Border_sawtoothGray: return "sawtoothGray"; - case NS_ooxml::LN_Value_ST_Border_scaredCat: return "scaredCat"; - case NS_ooxml::LN_Value_ST_Border_seattle: return "seattle"; - case NS_ooxml::LN_Value_ST_Border_shadowedSquares: return "shadowedSquares"; - case NS_ooxml::LN_Value_ST_Border_sharksTeeth: return "sharksTeeth"; - case NS_ooxml::LN_Value_ST_Border_shorebirdTracks: return "shorebirdTracks"; - case NS_ooxml::LN_Value_ST_Border_skyrocket: return "skyrocket"; - case NS_ooxml::LN_Value_ST_Border_snowflakeFancy: return "snowflakeFancy"; - case NS_ooxml::LN_Value_ST_Border_snowflakes: return "snowflakes"; - case NS_ooxml::LN_Value_ST_Border_sombrero: return "sombrero"; - case NS_ooxml::LN_Value_ST_Border_southwest: return "southwest"; - case NS_ooxml::LN_Value_ST_Border_stars: return "stars"; - case NS_ooxml::LN_Value_ST_Border_starsTop: return "starsTop"; - case NS_ooxml::LN_Value_ST_Border_stars3d: return "stars3d"; - case NS_ooxml::LN_Value_ST_Border_starsBlack: return "starsBlack"; - case NS_ooxml::LN_Value_ST_Border_starsShadowed: return "starsShadowed"; - case NS_ooxml::LN_Value_ST_Border_sun: return "sun"; - case NS_ooxml::LN_Value_ST_Border_swirligig: return "swirligig"; - case NS_ooxml::LN_Value_ST_Border_tornPaper: return "tornPaper"; - case NS_ooxml::LN_Value_ST_Border_tornPaperBlack: return "tornPaperBlack"; - case NS_ooxml::LN_Value_ST_Border_trees: return "trees"; - case NS_ooxml::LN_Value_ST_Border_triangleParty: return "triangleParty"; - case NS_ooxml::LN_Value_ST_Border_triangles: return "triangles"; - case NS_ooxml::LN_Value_ST_Border_tribal1: return "tribal1"; - case NS_ooxml::LN_Value_ST_Border_tribal2: return "tribal2"; - case NS_ooxml::LN_Value_ST_Border_tribal3: return "tribal3"; - case NS_ooxml::LN_Value_ST_Border_tribal4: return "tribal4"; - case NS_ooxml::LN_Value_ST_Border_tribal5: return "tribal5"; - case NS_ooxml::LN_Value_ST_Border_tribal6: return "tribal6"; - case NS_ooxml::LN_Value_ST_Border_twistedLines1: return "twistedLines1"; - case NS_ooxml::LN_Value_ST_Border_twistedLines2: return "twistedLines2"; - case NS_ooxml::LN_Value_ST_Border_vine: return "vine"; - case NS_ooxml::LN_Value_ST_Border_waveline: return "waveline"; - case NS_ooxml::LN_Value_ST_Border_weavingAngles: return "weavingAngles"; - case NS_ooxml::LN_Value_ST_Border_weavingBraid: return "weavingBraid"; - case NS_ooxml::LN_Value_ST_Border_weavingRibbon: return "weavingRibbon"; - case NS_ooxml::LN_Value_ST_Border_weavingStrips: return "weavingStrips"; - case NS_ooxml::LN_Value_ST_Border_whiteFlowers: return "whiteFlowers"; - case NS_ooxml::LN_Value_ST_Border_woodwork: return "woodwork"; - case NS_ooxml::LN_Value_ST_Border_xIllusions: return "xIllusions"; - case NS_ooxml::LN_Value_ST_Border_zanyTriangles: return "zanyTriangles"; - case NS_ooxml::LN_Value_ST_Border_zigZag: return "zigZag"; - case NS_ooxml::LN_Value_ST_Border_zigZagStitch: return "zigZagStitch"; - default: break; - } - return OUString(); -} - -OUString TDefTableHandler::getThemeColorTypeString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_Value_St_ThemeColor_dark1: return "dark1"; - case NS_ooxml::LN_Value_St_ThemeColor_light1: return "light1"; - case NS_ooxml::LN_Value_St_ThemeColor_dark2: return "dark2"; - case NS_ooxml::LN_Value_St_ThemeColor_light2: return "light2"; - case NS_ooxml::LN_Value_St_ThemeColor_accent1: return "accent1"; - case NS_ooxml::LN_Value_St_ThemeColor_accent2: return "accent2"; - case NS_ooxml::LN_Value_St_ThemeColor_accent3: return "accent3"; - case NS_ooxml::LN_Value_St_ThemeColor_accent4: return "accent4"; - case NS_ooxml::LN_Value_St_ThemeColor_accent5: return "accent5"; - case NS_ooxml::LN_Value_St_ThemeColor_accent6: return "accent6"; - case NS_ooxml::LN_Value_St_ThemeColor_hyperlink: return "hyperlink"; - case NS_ooxml::LN_Value_St_ThemeColor_followedHyperlink: return "followedHyperlink"; - case NS_ooxml::LN_Value_St_ThemeColor_none: return "none"; - case NS_ooxml::LN_Value_St_ThemeColor_background1: return "background1"; - case NS_ooxml::LN_Value_St_ThemeColor_text1: return "text1"; - case NS_ooxml::LN_Value_St_ThemeColor_background2: return "background2"; - case NS_ooxml::LN_Value_St_ThemeColor_text2: return "text2"; - default: break; - } - return OUString(); -} - -void TDefTableHandler::lcl_attribute(Id rName, Value & rVal) -{ - sal_Int32 nIntValue = rVal.getInt(); - switch( rName ) - { - case NS_ooxml::LN_CT_Border_sz: - // width of a single line in 1/8 pt, max of 32 pt -> twip * 5 / 2. - m_nLineWidth = nIntValue * 5 / 2; - appendGrabBag("sz", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Border_val: - m_nLineType = nIntValue; - appendGrabBag("val", TDefTableHandler::getBorderTypeString(nIntValue)); - break; - case NS_ooxml::LN_CT_Border_color: - appendGrabBag("color", OUString::fromUtf8(msfilter::util::ConvertColor(Color(ColorTransparency,nIntValue)))); - m_nLineColor = nIntValue; - break; - case NS_ooxml::LN_CT_Border_space: - appendGrabBag("space", OUString::number(nIntValue)); - break; - case NS_ooxml::LN_CT_Border_shadow: - //if 1 then line has shadow - unsupported - case NS_ooxml::LN_CT_Border_frame: - // ignored - break; - case NS_ooxml::LN_CT_Border_themeColor: - appendGrabBag("themeColor", TDefTableHandler::getThemeColorTypeString(nIntValue)); - break; - 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, const writerfilter::Reference<Properties>::Pointer_t& pProperties) -{ - if( !pProperties ) - return; - - m_nLineWidth = m_nLineType = m_nLineColor = 0; - std::vector<beans::PropertyValue> aSavedGrabBag; - if (!m_aInteropGrabBagName.isEmpty()) - { - aSavedGrabBag = m_aInteropGrabBag; - m_aInteropGrabBag.clear(); - } - pProperties->resolve( *this ); - table::BorderLine2 aBorderLine; - ConversionHelper::MakeBorderLine(m_nLineWidth, m_nLineType, m_nLineColor, aBorderLine, /*bIsOOXML=*/true); - const bool rtl = false; // TODO - switch( rName ) - { - case NS_ooxml::LN_CT_TcBorders_top: - m_aTopBorderLines.push_back(aBorderLine); - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("top")); - break; - case NS_ooxml::LN_CT_TcBorders_start: - if( rtl ) - m_aRightBorderLines.push_back(aBorderLine); - else - m_aLeftBorderLines.push_back(aBorderLine); - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("start")); - break; - case NS_ooxml::LN_CT_TcBorders_left: - m_aLeftBorderLines.push_back(aBorderLine); - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("left")); - break; - case NS_ooxml::LN_CT_TcBorders_bottom: - m_aBottomBorderLines.push_back(aBorderLine); - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("bottom")); - break; - case NS_ooxml::LN_CT_TcBorders_end: - if( rtl ) - m_aLeftBorderLines.push_back(aBorderLine); - else - m_aRightBorderLines.push_back(aBorderLine); - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("end")); - break; - case NS_ooxml::LN_CT_TcBorders_right: - m_aRightBorderLines.push_back(aBorderLine); - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("right")); - break; - case NS_ooxml::LN_CT_TcBorders_insideH: - m_aInsideHBorderLines.push_back(aBorderLine); - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("insideH")); - break; - case NS_ooxml::LN_CT_TcBorders_insideV: - m_aInsideVBorderLines.push_back(aBorderLine); - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("insideV")); - break; - case NS_ooxml::LN_CT_TcBorders_tl2br: - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("tl2br")); - break; - case NS_ooxml::LN_CT_TcBorders_tr2bl: - if (!m_aInteropGrabBagName.isEmpty()) - aSavedGrabBag.push_back(getInteropGrabBag("tr2bl")); - break; - default:; - } - if (!m_aInteropGrabBagName.isEmpty()) - m_aInteropGrabBag = aSavedGrabBag; -} - - -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_start: - case NS_ooxml::LN_CT_TcBorders_bottom: - case NS_ooxml::LN_CT_TcBorders_right: - case NS_ooxml::LN_CT_TcBorders_end: - 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:; - } -} - -void TDefTableHandler::fillCellProperties( const ::tools::SvRef< TablePropertyMap >& pCellProperties ) const -{ - if( !m_aTopBorderLines.empty() ) - pCellProperties->Insert( PROP_TOP_BORDER, uno::makeAny( m_aTopBorderLines[0] ) ); - if( !m_aLeftBorderLines.empty() ) - pCellProperties->Insert( PROP_LEFT_BORDER, uno::makeAny( m_aLeftBorderLines[0] ) ); - if( !m_aBottomBorderLines.empty() ) - pCellProperties->Insert( PROP_BOTTOM_BORDER, uno::makeAny( m_aBottomBorderLines[0] ) ); - if( !m_aRightBorderLines.empty() ) - pCellProperties->Insert( PROP_RIGHT_BORDER, uno::makeAny( m_aRightBorderLines[0] ) ); - if( !m_aInsideHBorderLines.empty() ) - pCellProperties->Insert( META_PROP_HORIZONTAL_BORDER, uno::makeAny( m_aInsideHBorderLines[0] ) ); - if( !m_aInsideVBorderLines.empty() ) - pCellProperties->Insert( META_PROP_VERTICAL_BORDER, uno::makeAny( m_aInsideVBorderLines[0] ) ); -} - - -void TDefTableHandler::enableInteropGrabBag(const OUString& aName) -{ - m_aInteropGrabBagName = aName; -} - -beans::PropertyValue TDefTableHandler::getInteropGrabBag(const OUString& aName) -{ - beans::PropertyValue aRet; - if (aName.isEmpty()) - aRet.Name = m_aInteropGrabBagName; - else - aRet.Name = aName; - - aRet.Value <<= comphelper::containerToSequence(m_aInteropGrabBag); - m_aInteropGrabBag.clear(); - return aRet; -} - -void TDefTableHandler::appendGrabBag(const OUString& aKey, const OUString& aValue) -{ - beans::PropertyValue aProperty; - aProperty.Name = aKey; - aProperty.Value <<= aValue; - m_aInteropGrabBag.push_back(aProperty); -} - -} //namespace writerfilter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TDefTableHandler.hxx b/writerfilter/source/dmapper/TDefTableHandler.hxx deleted file mode 100644 index 3c9ca8daf73f..000000000000 --- a/writerfilter/source/dmapper/TDefTableHandler.hxx +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TDEFTABLEHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TDEFTABLEHANDLER_HXX - -#include "LoggedResources.hxx" -#include <vector> -namespace com::sun::star{ - namespace table { - struct BorderLine2; - } - namespace beans { - struct PropertyValue; - } -} - -namespace writerfilter::dmapper -{ -class PropertyMap; -class TablePropertyMap; -class TDefTableHandler : public LoggedProperties -{ - std::vector<css::table::BorderLine2> m_aLeftBorderLines; - std::vector<css::table::BorderLine2> m_aRightBorderLines; - std::vector<css::table::BorderLine2> m_aTopBorderLines; - std::vector<css::table::BorderLine2> m_aBottomBorderLines; - std::vector<css::table::BorderLine2> m_aInsideHBorderLines; - std::vector<css::table::BorderLine2> m_aInsideVBorderLines; - - //values of the current border - sal_Int32 m_nLineWidth; - sal_Int32 m_nLineType; - sal_Int32 m_nLineColor; - - OUString m_aInteropGrabBagName; - std::vector<css::beans::PropertyValue> m_aInteropGrabBag; - void appendGrabBag(const OUString& aKey, const OUString& aValue); - - void localResolve(Id Name, const writerfilter::Reference<Properties>::Pointer_t& pProperties); - - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - -public: - TDefTableHandler(); - virtual ~TDefTableHandler() override; - - void fillCellProperties( const ::tools::SvRef< TablePropertyMap >& pCellProperties) const; - void enableInteropGrabBag(const OUString& aName); - css::beans::PropertyValue getInteropGrabBag(const OUString& aName = OUString()); - static OUString getBorderTypeString(sal_Int32 nType); - static OUString getThemeColorTypeString(sal_Int32 nType); -}; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TableData.hxx b/writerfilter/source/dmapper/TableData.hxx deleted file mode 100644 index 78ddf86ec049..000000000000 --- a/writerfilter/source/dmapper/TableData.hxx +++ /dev/null @@ -1,393 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEDATA_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEDATA_HXX - -#include <com/sun/star/text/XTextRange.hpp> - -#include "PropertyMap.hxx" - -#include <vector> - -namespace writerfilter::dmapper -{ - -/** - Class containing the data to describe a table cell. - */ -class CellData final : public virtual SvRefBase -{ - /** - Handle to start of cell. - */ - css::uno::Reference<css::text::XTextRange> mStart; - - /** - Handle to end of cell. - */ - css::uno::Reference<css::text::XTextRange> mEnd; - - /** - Pointer to properties of cell. - */ - TablePropertyMapPtr mpProps; - - bool mbOpen; - - sal_uInt32 m_nGridSpan; ///< number of grid columns in the parent table's table grid which this cell defines - -public: - typedef tools::SvRef<CellData> Pointer_t; - - CellData(css::uno::Reference<css::text::XTextRange> const & start, TablePropertyMapPtr pProps) - : mStart(start), mEnd(start), mpProps(pProps), mbOpen(true) - , m_nGridSpan(1) - { - } - - /** - Set the end handle of a cell. - - @param end the end handle of the cell - */ - void setEnd(css::uno::Reference<css::text::XTextRange> const & end) { mEnd = end; mbOpen = false; } - - /** - Adds properties to the cell. - - @param pProps the properties to add - */ - void insertProperties(TablePropertyMapPtr pProps) - { - if( mpProps ) - mpProps->InsertProps(pProps.get()); - else - mpProps = pProps; - } - - /** - Return start handle of the cell. - */ - const css::uno::Reference<css::text::XTextRange>& getStart() const { return mStart; } - - /** - Return end handle of the cell. - */ - const css::uno::Reference<css::text::XTextRange>& getEnd() const { return mEnd; } - - /** - Return properties of the cell. - */ - const TablePropertyMapPtr& getProperties() const { return mpProps; } - - bool isOpen() const { return mbOpen; } - - sal_uInt32 getGridSpan() const { return m_nGridSpan; } - void setGridSpan( sal_uInt32 nSpan ) { m_nGridSpan = nSpan; } -}; - -/** - Class to handle data of a table row. - */ -class RowData final : public virtual SvRefBase -{ - typedef ::std::vector<CellData::Pointer_t> Cells; - - /** - the cell data of the row - */ - Cells mCells; - - /** - the properties of the row - */ - mutable TablePropertyMapPtr mpProperties; - - sal_uInt32 m_nGridBefore; ///< number of grid columns in the parent table's table grid which must be skipped before the contents of this table row are added to the parent table - sal_uInt32 m_nGridAfter; ///< number of grid columns in the parent table's table grid which shall be left after the last cell in the table row - -public: - typedef tools::SvRef<RowData> Pointer_t; - - RowData() - : m_nGridBefore(0) - , m_nGridAfter(0) - { - } - - RowData(const RowData& rRowData) - : SvRefBase(), mCells(rRowData.mCells), mpProperties(rRowData.mpProperties) - , m_nGridBefore(rRowData.m_nGridBefore) - , m_nGridAfter(rRowData.m_nGridAfter) - { - } - - /** - Add a cell to the row. - - @param start the start handle of the cell - @param end the end handle of the cell - @param pProps the properties of the cell - @param bAddBefore true: add an empty cell at beginning of the row for gridBefore - */ - void addCell(const css::uno::Reference<css::text::XTextRange>& start, TablePropertyMapPtr pProps, bool bAddBefore = false) - { - CellData::Pointer_t pCellData(new CellData(start, pProps)); - if (bAddBefore) - { - mCells.insert(mCells.begin(), pCellData); - mCells[0]->setEnd(start); - } - else - mCells.push_back(pCellData); - } - - void endCell(const css::uno::Reference<css::text::XTextRange>& end) - { - if (mCells.size() > 0) - mCells.back()->setEnd(end); - } - - bool isCellOpen() const - { - return mCells.size() > 0 && mCells.back()->isOpen(); - } - - /** - Add properties to the row. - - @param pProperties the properties to set - */ - void insertProperties(TablePropertyMapPtr pProperties) - { - if( pProperties ) - { - if( !mpProperties ) - mpProperties = pProperties; - else - mpProperties->InsertProps(pProperties.get()); - } - } - - /** - Add properties to the last cell of the row. - */ - void insertCellProperties(TablePropertyMapPtr pProps) - { - if (!mCells.empty()) - mCells.back()->insertProperties(pProps); - } - - /** - Return number of cells in the row. - */ - unsigned int getCellCount() const - { - return mCells.size(); - } - - /** - Return start handle of a cell in the row. - - @param i index of the cell - */ - const css::uno::Reference<css::text::XTextRange>& getCellStart(unsigned int i) const - { - return mCells[i]->getStart(); - } - - /** - Return end handle of a cell in the row. - - @param i index of the cell - */ - const css::uno::Reference<css::text::XTextRange>& getCellEnd(unsigned int i) const - { - return mCells[i]->getEnd(); - } - - /** - Return the properties of a cell in the row. - - @param i index of the cell - */ - TablePropertyMapPtr const & getCellProperties(unsigned int i) const - { - return mCells[i]->getProperties(); - } - - /** - Return properties of the row. - */ - const TablePropertyMapPtr& getProperties() const - { - return mpProperties; - } - - sal_uInt32 getGridBefore() const { return m_nGridBefore; } - void setGridBefore(sal_uInt32 nSkipGrids) { m_nGridBefore = nSkipGrids; } - sal_uInt32 getGridAfter() const { return m_nGridAfter; } - void setGridAfter(sal_uInt32 nSkipGrids) { m_nGridAfter = nSkipGrids; } - sal_uInt32 getGridSpan(sal_uInt32 i) { return mCells[i]->getGridSpan(); } - std::vector< sal_uInt32 > getGridSpans() - { - std::vector< sal_uInt32 > nRet; - for (auto const& aCell: mCells) - nRet.push_back(aCell->getGridSpan()); - return nRet; - } - void setCurrentGridSpan(sal_uInt32 nSpan, bool bFirstCell = false) - { - if ( mCells.size() ) - { - if ( bFirstCell ) - mCells.front()->setGridSpan(nSpan); - else - mCells.back()->setGridSpan(nSpan); - } - } -}; - -/** - Class that holds the data of a table. - */ -class TableData : public virtual SvRefBase -{ - typedef RowData::Pointer_t RowPointer_t; - typedef ::std::vector<RowPointer_t> Rows; - - /** - the data of the rows of the table - */ - Rows mRows; - - /** - pointer to the data of the current row (while building up the table data). - */ - RowPointer_t mpRow; - - /** - depth of the current table in a hierarchy of tables - */ - unsigned int mnDepth; - - /** - initialize mpRow - */ - void newRow() { mpRow = RowPointer_t(new RowData()); } - -public: - typedef tools::SvRef<TableData> Pointer_t; - - explicit TableData(unsigned int nDepth) : mnDepth(nDepth) { newRow(); } - - /** - End the current row. - - Sets properties of the current row and pushes the row to the - back of the rows currently contained in the table. - - @param pProperties properties of the row to be ended - */ - void endRow(TablePropertyMapPtr pProperties) - { - mpRow->insertProperties(pProperties); - mRows.push_back(mpRow); - newRow(); - } - - /** - Add a cell to the current row. - - @param start start handle of the cell - @param end end handle of the cell - @param pProps properties of the cell - */ - void addCell(const css::uno::Reference<css::text::XTextRange>& start, TablePropertyMapPtr pProps) - { - mpRow->addCell(start, pProps); - } - - /** - End the current cell of the current row. - - @parm end end handle of the cell - */ - void endCell(const css::uno::Reference<css::text::XTextRange>& end) - { - mpRow->endCell(end); - } - - /** - Return if the current cell of the current row is open. - */ - bool isCellOpen() const - { - return mpRow->isCellOpen(); - } - - /** - Insert properties to the current cell of the current row. - - @param pProps the properties to add - */ - void insertCellProperties(TablePropertyMapPtr pProps) - { - mpRow->insertCellProperties(pProps); - } - - /** - Return number of rows in the table. - */ - unsigned int getRowCount() const - { - return mRows.size(); - } - - /** - Return depth of table in surrounding table hierarchy. - */ - unsigned int getDepth() const - { - return mnDepth; - } - - /** - Return row data of a certain row. - - @param i index of the row - */ - RowPointer_t const & getRow(unsigned int i) const - { - return mRows[i]; - } - - const RowPointer_t& getCurrentRow() const - { - return mpRow; - } -}; - -} - - -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_RESOURCEMODEL_TABLEDATA_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TableManager.cxx b/writerfilter/source/dmapper/TableManager.cxx deleted file mode 100644 index ea71e887adb3..000000000000 --- a/writerfilter/source/dmapper/TableManager.cxx +++ /dev/null @@ -1,603 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "TableManager.hxx" -#include <ooxml/resourceids.hxx> -#include "TagLogger.hxx" -#include "DomainMapperTableHandler.hxx" -#include "DomainMapper_Impl.hxx" -#include "util.hxx" - -#include <tools/diagnose_ex.h> - -namespace writerfilter::dmapper -{ -void TableManager::clearData() {} - -void TableManager::openCell(const css::uno::Reference<css::text::XTextRange>& rHandle, - const TablePropertyMapPtr& pProps) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.openCell"); - TagLogger::getInstance().chars(XTextRangeToString(rHandle)); - TagLogger::getInstance().endElement(); -#endif - - if (!mTableDataStack.empty()) - { - TableData::Pointer_t pTableData = mTableDataStack.top(); - - pTableData->addCell(rHandle, pProps); - } -} - -bool TableManager::isIgnore() const { return isRowEnd(); } - -sal_uInt32 TableManager::getGridBefore(sal_uInt32 nRow) -{ - assert(isInTable()); - if (nRow >= mTableDataStack.top()->getRowCount()) - return 0; - return mTableDataStack.top()->getRow(nRow)->getGridBefore(); -} - -sal_uInt32 TableManager::getCurrentGridBefore() -{ - return mTableDataStack.top()->getCurrentRow()->getGridBefore(); -} - -void TableManager::setCurrentGridBefore(sal_uInt32 nSkipGrids) -{ - mTableDataStack.top()->getCurrentRow()->setGridBefore(nSkipGrids); -} - -sal_uInt32 TableManager::getGridAfter(sal_uInt32 nRow) -{ - assert(isInTable()); - if (nRow >= mTableDataStack.top()->getRowCount()) - return 0; - return mTableDataStack.top()->getRow(nRow)->getGridAfter(); -} - -void TableManager::setCurrentGridAfter(sal_uInt32 nSkipGrids) -{ - assert(isInTable()); - mTableDataStack.top()->getCurrentRow()->setGridAfter(nSkipGrids); -} - -std::vector<sal_uInt32> TableManager::getCurrentGridSpans() -{ - return mTableDataStack.top()->getCurrentRow()->getGridSpans(); -} - -void TableManager::setCurrentGridSpan(sal_uInt32 nGridSpan, bool bFirstCell) -{ - mTableDataStack.top()->getCurrentRow()->setCurrentGridSpan(nGridSpan, bFirstCell); -} - -sal_uInt32 TableManager::findColumn(const sal_uInt32 nRow, const sal_uInt32 nCell) -{ - RowData::Pointer_t pRow = mTableDataStack.top()->getRow(nRow); - if (!pRow || nCell < pRow->getGridBefore() - || nCell >= pRow->getCellCount() - pRow->getGridAfter()) - { - return SAL_MAX_UINT32; - } - - // The gridSpans provide a one-based index, so add up all the spans of the PREVIOUS columns, - // and that result will provide the first possible zero-based number for the desired column. - sal_uInt32 nColumn = 0; - for (sal_uInt32 n = 0; n < nCell; ++n) - nColumn += pRow->getGridSpan(n); - return nColumn; -} - -sal_uInt32 TableManager::findColumnCell(const sal_uInt32 nRow, const sal_uInt32 nCol) -{ - RowData::Pointer_t pRow = mTableDataStack.top()->getRow(nRow); - if (!pRow || nCol < pRow->getGridBefore()) - return SAL_MAX_UINT32; - - sal_uInt32 nCell = 0; - sal_uInt32 nGrids = 0; - // The gridSpans give us a one-based index, but requested column is zero-based - so keep that in mind. - const sal_uInt32 nMaxCell = pRow->getCellCount() - pRow->getGridAfter() - 1; - for (const auto& rSpan : pRow->getGridSpans()) - { - nGrids += rSpan; - if (nCol < nGrids) - return nCell; - - ++nCell; - if (nCell > nMaxCell) - break; - } - return SAL_MAX_UINT32; // must be in gridAfter or invalid column request -} - -void TableManager::endOfRowAction() {} - -void TableManager::endOfCellAction() {} - -void TableManager::insertTableProps(const TablePropertyMapPtr& pProps) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.insertTableProps"); -#endif - - if (getTableProps() && getTableProps() != pProps) - getTableProps()->InsertProps(pProps.get()); - else - mState.setTableProps(pProps); - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void TableManager::insertRowProps(const TablePropertyMapPtr& pProps) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.insertRowProps"); -#endif - - if (getRowProps()) - getRowProps()->InsertProps(pProps.get()); - else - mState.setRowProps(pProps); - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void TableManager::cellProps(const TablePropertyMapPtr& pProps) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.cellProps"); -#endif - - if (getCellProps()) - getCellProps()->InsertProps(pProps.get()); - else - mState.setCellProps(pProps); - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void TableManager::tableExceptionProps(const TablePropertyMapPtr& pProps) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.tableExceptionProps"); -#endif - - if (getTableExceptionProps()) - getTableExceptionProps()->InsertProps(pProps.get()); - else - mState.setTableExceptionProps(pProps); - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void TableManager::utext(const sal_uInt8* data, std::size_t len) -{ - // optimization: cell/row end characters are the last characters in a run - - if (len > 0) - { - sal_Unicode nChar = data[(len - 1) * 2] + (data[(len - 1) * 2 + 1] << 8); - if (nChar == 0x7) - handle0x7(); - } -} - -void TableManager::text(const sal_uInt8* data, std::size_t len) -{ - // optimization: cell/row end characters are the last characters in a run - if (len > 0 && data[len - 1] == 0x7) - handle0x7(); -} - -void TableManager::handle0x7() -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.handle0x7"); -#endif - - if (mnTableDepthNew < 1) - mnTableDepthNew = 1; - - if (isInCell()) - endCell(); - else - endRow(); - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -bool TableManager::sprm(Sprm& rSprm) -{ - bool bRet = true; - switch (rSprm.getId()) - { - case NS_ooxml::LN_tblDepth: - { - Value::Pointer_t pValue = rSprm.getValue(); - - cellDepth(pValue->getInt()); - } - break; - case NS_ooxml::LN_inTbl: - inCell(); - break; - case NS_ooxml::LN_tblCell: - endCell(); - break; - case NS_ooxml::LN_tblRow: - endRow(); - break; - default: - bRet = false; - } - return bRet; -} - -void TableManager::closeCell(const css::uno::Reference<css::text::XTextRange>& rHandle) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.closeCell"); - TagLogger::getInstance().chars(XTextRangeToString(rHandle)); - TagLogger::getInstance().endElement(); -#endif - - if (!mTableDataStack.empty()) - { - TableData::Pointer_t pTableData = mTableDataStack.top(); - - pTableData->endCell(rHandle); - - if (mpTableDataHandler) - mpTableDataHandler->getDomainMapperImpl().ClearPreviousParagraph(); - } -} - -void TableManager::ensureOpenCell(const TablePropertyMapPtr& pProps) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.ensureOpenCell"); -#endif - - if (!mTableDataStack.empty()) - { - TableData::Pointer_t pTableData = mTableDataStack.top(); - - if (pTableData != nullptr) - { - if (!pTableData->isCellOpen()) - openCell(getHandle(), pProps); - else - pTableData->insertCellProperties(pProps); - } - } -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void TableManager::endParagraphGroup() -{ - sal_Int32 nTableDepthDifference = mnTableDepthNew - mnTableDepth; - - TablePropertyMapPtr pEmptyProps; - - while (nTableDepthDifference > 0) - { - ensureOpenCell(pEmptyProps); - startLevel(); - - --nTableDepthDifference; - } - while (nTableDepthDifference < 0) - { - endLevel(); - - ++nTableDepthDifference; - } - - mnTableDepth = mnTableDepthNew; - - if (mnTableDepth <= 0) - return; - - if (isRowEnd()) - { - endOfRowAction(); - mTableDataStack.top()->endRow(getRowProps()); - mState.resetRowProps(); - } - - else if (isInCell()) - { - ensureOpenCell(getCellProps()); - - if (mState.isCellEnd()) - { - endOfCellAction(); - closeCell(getHandle()); - } - } - mState.resetCellProps(); -} - -void TableManager::startParagraphGroup() -{ - mState.resetCellSpecifics(); - mnTableDepthNew = 0; -} - -void TableManager::resolveCurrentTable() -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.resolveCurrentTable"); -#endif - - if (mpTableDataHandler != nullptr) - { - try - { - TableData::Pointer_t pTableData = mTableDataStack.top(); - - unsigned int nRows = pTableData->getRowCount(); - - mpTableDataHandler->startTable(getTableProps()); - - for (unsigned int nRow = 0; nRow < nRows; ++nRow) - { - RowData::Pointer_t pRowData = pTableData->getRow(nRow); - - unsigned int nCells = pRowData->getCellCount(); - - mpTableDataHandler->startRow(pRowData->getProperties()); - - for (unsigned int nCell = 0; nCell < nCells; ++nCell) - { - mpTableDataHandler->startCell(pRowData->getCellStart(nCell), - pRowData->getCellProperties(nCell)); - - mpTableDataHandler->endCell(pRowData->getCellEnd(nCell)); - } - - mpTableDataHandler->endRow(); - } - - mpTableDataHandler->endTable(mTableDataStack.size() - 1, m_bTableStartsAtCellStart); - } - catch (css::uno::Exception const&) - { - TOOLS_WARN_EXCEPTION("writerfilter", "resolving of current table failed"); - } - } - mState.resetTableProps(); - clearData(); - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void TableManager::endLevel() -{ - if (mpTableDataHandler != nullptr) - resolveCurrentTable(); - - // Store the unfinished row as it will be used for the next table - if (mbKeepUnfinishedRow) - mpUnfinishedRow = mTableDataStack.top()->getCurrentRow(); - mState.endLevel(); - mTableDataStack.pop(); - -#ifdef DBG_UTIL - TableData::Pointer_t pTableData; - - if (!mTableDataStack.empty()) - pTableData = mTableDataStack.top(); - - TagLogger::getInstance().startElement("tablemanager.endLevel"); - TagLogger::getInstance().attribute("level", mTableDataStack.size()); - - if (pTableData != nullptr) - TagLogger::getInstance().attribute("openCell", pTableData->isCellOpen() ? "yes" : "no"); - - TagLogger::getInstance().endElement(); -#endif -} - -void TableManager::startLevel() -{ -#ifdef DBG_UTIL - TableData::Pointer_t pTableData; - - if (!mTableDataStack.empty()) - pTableData = mTableDataStack.top(); - - TagLogger::getInstance().startElement("tablemanager.startLevel"); - TagLogger::getInstance().attribute("level", mTableDataStack.size()); - - if (pTableData != nullptr) - TagLogger::getInstance().attribute("openCell", pTableData->isCellOpen() ? "yes" : "no"); - - TagLogger::getInstance().endElement(); -#endif - - TableData::Pointer_t pTableData2(new TableData(mTableDataStack.size())); - - // If we have an unfinished row stored here, then push it to the new TableData - if (mpUnfinishedRow) - { - for (unsigned int i = 0; i < mpUnfinishedRow->getCellCount(); ++i) - { - pTableData2->addCell(mpUnfinishedRow->getCellStart(i), - mpUnfinishedRow->getCellProperties(i)); - pTableData2->endCell(mpUnfinishedRow->getCellEnd(i)); - pTableData2->getCurrentRow()->setCurrentGridSpan(mpUnfinishedRow->getGridSpan(i)); - } - pTableData2->getCurrentRow()->setGridBefore(mpUnfinishedRow->getGridBefore()); - pTableData2->getCurrentRow()->setGridAfter(mpUnfinishedRow->getGridAfter()); - mpUnfinishedRow.clear(); - } - - mTableDataStack.push(pTableData2); - mState.startLevel(); -} - -bool TableManager::isInTable() -{ - bool bInTable = false; - if (!mTableDataStack.empty()) - bInTable = mTableDataStack.top()->getDepth() > 0; - return bInTable; -} - -void TableManager::handle(const css::uno::Reference<css::text::XTextRange>& rHandle) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.handle"); - TagLogger::getInstance().chars(XTextRangeToString(rHandle)); - TagLogger::getInstance().endElement(); -#endif - - setHandle(rHandle); -} - -void TableManager::setHandler(const tools::SvRef<DomainMapperTableHandler>& pTableDataHandler) -{ - mpTableDataHandler = pTableDataHandler; -} - -void TableManager::endRow() -{ -#ifdef DBG_UTIL - TagLogger::getInstance().element("tablemanager.endRow"); -#endif - TableData::Pointer_t pTableData = mTableDataStack.top(); - - // Add borderless w:gridBefore cell(s) to the row - sal_uInt32 nGridBefore = getCurrentGridBefore(); - if (pTableData && nGridBefore > 0 && pTableData->getCurrentRow()->getCellCount() > 0) - { - const css::uno::Reference<css::text::XTextRange>& xRowStart - = pTableData->getCurrentRow()->getCellStart(0); - if (xRowStart.is()) - { - try - { - // valid TextRange for table creation (not a nested table)? - xRowStart->getText()->createTextCursorByRange(xRowStart); - - for (unsigned int i = 0; i < nGridBefore; ++i) - { - css::table::BorderLine2 aBorderLine; - aBorderLine.Color = 0; - aBorderLine.InnerLineWidth = 0; - aBorderLine.OuterLineWidth = 0; - TablePropertyMapPtr pCellProperties(new TablePropertyMap); - pCellProperties->Insert(PROP_TOP_BORDER, css::uno::makeAny(aBorderLine)); - pCellProperties->Insert(PROP_LEFT_BORDER, css::uno::makeAny(aBorderLine)); - pCellProperties->Insert(PROP_BOTTOM_BORDER, css::uno::makeAny(aBorderLine)); - pCellProperties->Insert(PROP_RIGHT_BORDER, css::uno::makeAny(aBorderLine)); - pTableData->getCurrentRow()->addCell(xRowStart, pCellProperties, - /*bAddBefore=*/true); - } - } - catch (css::uno::Exception const&) - { - // don't add gridBefore cells in not valid TextRange - setCurrentGridBefore(0); - setCurrentGridSpan(getCurrentGridSpans().front() + nGridBefore, - /*bFirstCell=*/true); - } - } - } - - setRowEnd(true); -} - -void TableManager::endCell() -{ -#ifdef DBG_UTIL - TagLogger::getInstance().element("tablemanager.endCell"); -#endif - - setCellEnd(true); -} - -void TableManager::inCell() -{ -#ifdef DBG_UTIL - TagLogger::getInstance().element("tablemanager.inCell"); -#endif - setInCell(true); - - if (mnTableDepthNew < 1) - mnTableDepthNew = 1; -} - -void TableManager::cellDepth(sal_uInt32 nDepth) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("tablemanager.cellDepth"); - TagLogger::getInstance().attribute("depth", nDepth); - TagLogger::getInstance().endElement(); -#endif - - mnTableDepthNew = nDepth; -} - -void TableManager::setTableStartsAtCellStart(bool bTableStartsAtCellStart) -{ - m_bTableStartsAtCellStart = bTableStartsAtCellStart; -} - -void TableManager::setCellLastParaAfterAutospacing(bool bIsAfterAutospacing) -{ - m_bCellLastParaAfterAutospacing = bIsAfterAutospacing; -} - -TableManager::TableManager() - : mnTableDepthNew(0) - , mnTableDepth(0) - , mbKeepUnfinishedRow(false) - , m_bTableStartsAtCellStart(false) -{ - setRowEnd(false); - setInCell(false); - setCellEnd(false); - m_bCellLastParaAfterAutospacing = false; -} - -TableManager::~TableManager() = default; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TableManager.hxx b/writerfilter/source/dmapper/TableManager.hxx deleted file mode 100644 index 2dcf679e135f..000000000000 --- a/writerfilter/source/dmapper/TableManager.hxx +++ /dev/null @@ -1,524 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEMANAGER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEMANAGER_HXX - -#include <memory> -#include <stack> - -#include "PropertyMap.hxx" -#include "TableData.hxx" - -#include <dmapper/resourcemodel.hxx> - -namespace writerfilter::dmapper -{ - -class DomainMapperTableHandler; - -/** - The table manager. - - This class gets forwarded events from the tokenizer. It gathers the - table data and after ending the table generates events for the - table structure. The events have to be handles by a TableDataHandler. - - */ -class TableManager : public virtual SvRefBase -{ - class TableManagerState final - { - /** - properties of the current cell - */ - TablePropertyMapPtr mpCellProps; - - /** - properties of the current row - */ - TablePropertyMapPtr mpRowProps; - - /** - table exception properties of the current row - */ - TablePropertyMapPtr mpTableExceptionProps; - - /** - properties of the current table - */ - std::stack<TablePropertyMapPtr> mTableProps; - - /** - true if at the end of a row - */ - bool mbRowEnd; - - /** - true when in a cell - */ - bool mbInCell; - - /** - true when at the end of a cell - */ - bool mbCellEnd; - - public: - /** - Constructor - */ - TableManagerState() - : mbRowEnd(false), mbInCell(false), mbCellEnd(false) - { - } - - void startLevel() - { - TablePropertyMapPtr pProps; - mTableProps.push(pProps); - } - - void endLevel() - { - mTableProps.pop(); - } - - /** - Reset to initial state at beginning of row. - */ - void resetCellSpecifics() - { - mbRowEnd = false; - mbInCell = false; - mbCellEnd = false; - } - - void resetCellProps() - { - mpCellProps = getTableExceptionProps(); - } - - void setCellProps(TablePropertyMapPtr pProps) - { - mpCellProps = pProps; - } - - const TablePropertyMapPtr& getCellProps() const - { - return mpCellProps; - } - - void resetRowProps() - { - // reset also table exception and - // its copy set by the previous resetCellProps() - mpTableExceptionProps.clear(); - resetCellProps(); - mpRowProps.clear(); - } - - void setRowProps(TablePropertyMapPtr pProps) - { - mpRowProps = pProps; - } - - const TablePropertyMapPtr& getRowProps() const - { - return mpRowProps; - } - - void setTableExceptionProps(TablePropertyMapPtr pProps) - { - mpTableExceptionProps = pProps; - } - - const TablePropertyMapPtr& getTableExceptionProps() const - { - return mpTableExceptionProps; - } - - void resetTableProps() - { - if (mTableProps.size() > 0) - mTableProps.top().clear(); - } - - void setTableProps(TablePropertyMapPtr pProps) - { - if (mTableProps.size() > 0) - mTableProps.top() = pProps; - } - - TablePropertyMapPtr getTableProps() - { - TablePropertyMapPtr pResult; - - if (mTableProps.size() > 0) - pResult = mTableProps.top(); - - return pResult; - } - - void setInCell(bool bInCell) - { - mbInCell = bInCell; - } - - bool isInCell() const - { - return mbInCell; - } - - void setCellEnd(bool bCellEnd) - { - mbCellEnd = bCellEnd; - } - - bool isCellEnd() const - { - return mbCellEnd; - } - - void setRowEnd(bool bRowEnd) - { - mbRowEnd = bRowEnd; - } - - bool isRowEnd() const - { - return mbRowEnd; - } - }; - - /** - handle for the current position in document - */ - css::uno::Reference<css::text::XTextRange> mCurHandle; - - TableManagerState mState; - -protected: - TablePropertyMapPtr const & getCellProps() const - { - return mState.getCellProps(); - } - -public: - TablePropertyMapPtr const & getRowProps() const - { - return mState.getRowProps(); - } - - TablePropertyMapPtr const & getTableExceptionProps() const - { - return mState.getTableExceptionProps(); - } - -protected: - void setInCell(bool bInCell) - { - mState.setInCell(bInCell); - } - - bool isInCell() const - { - return mState.isInCell(); - } - - void setCellEnd(bool bCellEnd) - { - mState.setCellEnd(bCellEnd); - } - - void setRowEnd(bool bRowEnd) - { - mState.setRowEnd(bRowEnd); - } - - bool isRowEnd() const - { - return mState.isRowEnd(); - } - - TablePropertyMapPtr getTableProps() - { - return mState.getTableProps(); - } - - const css::uno::Reference<css::text::XTextRange>& getHandle() const - { - return mCurHandle; - } - - void setHandle(const css::uno::Reference<css::text::XTextRange>& rHandle) - { - mCurHandle = rHandle; - } - -private: - typedef tools::SvRef< css::uno::Reference<css::text::XTextRange> > T_p; - - /** - depth of the current cell - */ - sal_uInt32 mnTableDepthNew; - - /** - depth of the previous cell - */ - sal_uInt32 mnTableDepth; - - /** - stack of table data - - for each level of nested tables there is one frame in the stack - */ - std::stack<TableData::Pointer_t> mTableDataStack; - RowData::Pointer_t mpUnfinishedRow; - bool mbKeepUnfinishedRow; - /// If this is a nested table, does it start at cell start? - bool m_bTableStartsAtCellStart; - - bool m_bCellLastParaAfterAutospacing; - - /** - handler for resolveCurrentTable - */ - tools::SvRef<DomainMapperTableHandler> mpTableDataHandler; - - /** - Set flag which indicates the current handle is in a cell. - */ - void inCell(); - - /** - Set flag which indicate the current handle is at the end of a cell. - */ - void endCell(); - - /** - Set the table depth of the current cell. - - @param nDepth the cell depth - */ - void cellDepth(sal_uInt32 nDepth); - - /** - Set flag indication the current handle is at the end of a row. - */ - void endRow(); - - /** - Resolve the current table to the TableDataHandler. - */ - void resolveCurrentTable(); - - /** - Open a cell at current level. - */ - - void openCell(const css::uno::Reference<css::text::XTextRange>& rHandle, const TablePropertyMapPtr& pProps); - - /** - Close a cell at current level. - */ - void closeCell(const css::uno::Reference<css::text::XTextRange>& rHandle); - - /** - Ensure a cell is open at the current level. - */ - void ensureOpenCell(const TablePropertyMapPtr& pProps); - -protected: - /** - Return the current table difference, i.e. 1 if we are in the first cell of a new table, etc. - */ - sal_uInt32 getTableDepthDifference() const { return mnTableDepthNew - mnTableDepth; } - - sal_uInt32 getTableDepth() const { return mnTableDepthNew; } - - /** - Action to be carried out at the end of the last paragraph of a - cell. - */ - virtual void endOfCellAction(); - - /** - Action to be carried out at the end of the "table row" - paragraph. - */ - virtual void endOfRowAction(); - /** let the derived class clear their table related data - */ - virtual void clearData(); - - /** Should we keep the unfinished row in endLevel to initialize the table - data in the following startLevel. - */ - void setKeepUnfinishedRow(bool bKeep) - { - mbKeepUnfinishedRow = bKeep; - } - - -public: - TableManager(); - ~TableManager(); - - /** - Set handler for resolveCurrentTable. - - @param pTableDataHandler the handler - */ - void setHandler(const tools::SvRef<DomainMapperTableHandler>& pTableDataHandler); - - /** - Set the current handle. - - @param rHandle the handle - */ - void handle(const css::uno::Reference<css::text::XTextRange>& rHandle); - - /** - Start a new table level. - - A new context is pushed onto the table data stack, - */ - virtual void startLevel(); - - /** - End a table level. - - The current table is resolved and the context is popped from - the stack. - */ - virtual void endLevel(); - - /** - * Signal that the next paragraph definitely won't be part of any table. - */ - void endTable() - { - setRowEnd(false); - } - - /** - Tells whether a table has been started or not - */ - bool isInTable(); - - /** - Handle the start of a paragraph group. - */ - void startParagraphGroup(); - - /** - Handle the end of a paragraph group. - */ - void endParagraphGroup(); - - /** - Handle an SPRM at current handle. - - @param rSprm the SPRM - */ - virtual bool sprm(Sprm & rSprm); - - /** - Handle occurrence of character 0x7. - */ - void handle0x7(); - - /** - Handle 8 bit text at current handle. - - @param data array of characters - @param len number of characters to handle - */ - void text(const sal_uInt8 * data, size_t len); - - /** - Handle 16 bit text at current handle. - - @param data array of characters - @param len number of characters to handle - */ - void utext(const sal_uInt8 * data, size_t len); - - /** - Handle properties of the current cell. - - @param pProps the properties - */ - virtual void cellProps(const TablePropertyMapPtr& pProps); - - /** - Handle properties of the current row. - - @param pProps the properties - */ - virtual void insertRowProps(const TablePropertyMapPtr& pProps); - - /** - Handle table exception properties of the current row. - - @param pProps the properties - */ - virtual void tableExceptionProps(const TablePropertyMapPtr& pProps); - - /** - Handle properties of the current table. - - @param pProps the properties - */ - virtual void insertTableProps(const TablePropertyMapPtr& pProps); - - /** - Return if table manager has detected paragraph to ignore. - - If this function returns true the current paragraph contains - only control information, e.g. end of row. - */ - bool isIgnore() const; - - sal_uInt32 getGridBefore(sal_uInt32 nRow); - sal_uInt32 getCurrentGridBefore(); - void setCurrentGridBefore( sal_uInt32 nSkipGrids ); - sal_uInt32 getGridAfter(sal_uInt32 nRow); - void setCurrentGridAfter( sal_uInt32 nSkipGrids ); - std::vector<sal_uInt32> getCurrentGridSpans(); - void setCurrentGridSpan( sal_uInt32 nGridSpan, bool bFirstCell = false ); - /// Given a zero-based row/cell, return the zero-based grid it belongs to, or SAL_MAX_UINT16 for invalid. - sal_uInt32 findColumn( const sal_uInt32 nRow, const sal_uInt32 nCell ); - /// Given a zero-based row/col, return the zero-based cell describing that grid, or SAL_MAX_UINT16 for invalid. - sal_uInt32 findColumnCell( const sal_uInt32 nRow, const sal_uInt32 nCol ); - - void setTableStartsAtCellStart(bool bTableStartsAtCellStart); - void setCellLastParaAfterAutospacing(bool bIsAfterAutospacing); - bool isCellLastParaAfterAutospacing() const {return m_bCellLastParaAfterAutospacing;} -}; - -} - - - -#endif // INCLUDED_WRITERFILTER_INC_RESOURCEMODEL_TABLEMANAGER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TablePositionHandler.cxx b/writerfilter/source/dmapper/TablePositionHandler.cxx deleted file mode 100644 index 5eea4a00046e..000000000000 --- a/writerfilter/source/dmapper/TablePositionHandler.cxx +++ /dev/null @@ -1,154 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -#include "TablePositionHandler.hxx" -#include "ConversionHelper.hxx" -#include "TagLogger.hxx" -#include <ooxml/resourceids.hxx> -#include <com/sun/star/beans/PropertyValue.hpp> -#include <com/sun/star/text/HoriOrientation.hpp> -#include <com/sun/star/text/VertOrientation.hpp> -#include <com/sun/star/text/RelOrientation.hpp> -#include <comphelper/sequenceashashmap.hxx> - -namespace writerfilter::dmapper -{ -using namespace ::com::sun::star; - -TablePositionHandler::TablePositionHandler() - : LoggedProperties("TablePositionHandler") -{ -} - -TablePositionHandler::~TablePositionHandler() = default; - -void TablePositionHandler::lcl_attribute(Id nId, Value& rVal) -{ - switch (nId) - { - case NS_ooxml::LN_CT_TblPPr_vertAnchor: - m_aVertAnchor = rVal.getString(); - break; - case NS_ooxml::LN_CT_TblPPr_tblpYSpec: - m_aYSpec = rVal.getString(); - break; - case NS_ooxml::LN_CT_TblPPr_horzAnchor: - m_aHorzAnchor = rVal.getString(); - break; - case NS_ooxml::LN_CT_TblPPr_tblpXSpec: - m_aXSpec = rVal.getString(); - break; - case NS_ooxml::LN_CT_TblPPr_tblpY: - m_nY = rVal.getInt(); - break; - case NS_ooxml::LN_CT_TblPPr_tblpX: - m_nX = rVal.getInt(); - break; - case NS_ooxml::LN_CT_TblPPr_leftFromText: - m_nLeftFromText = rVal.getInt(); - break; - case NS_ooxml::LN_CT_TblPPr_rightFromText: - m_nRightFromText = rVal.getInt(); - break; - case NS_ooxml::LN_CT_TblPPr_topFromText: - m_nTopFromText = rVal.getInt(); - break; - case NS_ooxml::LN_CT_TblPPr_bottomFromText: - m_nBottomFromText = rVal.getInt(); - break; - default: -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - break; - } -} - -void TablePositionHandler::lcl_sprm(Sprm& /*rSprm*/) {} - -uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() const -{ - comphelper::SequenceAsHashMap aFrameProperties; - - aFrameProperties["LeftBorderDistance"] <<= sal_Int32(0); - aFrameProperties["RightBorderDistance"] <<= sal_Int32(0); - aFrameProperties["TopBorderDistance"] <<= sal_Int32(0); - aFrameProperties["BottomBorderDistance"] <<= sal_Int32(0); - - aFrameProperties["LeftMargin"] <<= ConversionHelper::convertTwipToMM100(m_nLeftFromText); - aFrameProperties["RightMargin"] <<= ConversionHelper::convertTwipToMM100(m_nRightFromText); - aFrameProperties["TopMargin"] <<= ConversionHelper::convertTwipToMM100(m_nTopFromText); - aFrameProperties["BottomMargin"] <<= ConversionHelper::convertTwipToMM100(m_nBottomFromText); - - table::BorderLine2 aEmptyBorder; - aFrameProperties["TopBorder"] <<= aEmptyBorder; - aFrameProperties["BottomBorder"] <<= aEmptyBorder; - aFrameProperties["LeftBorder"] <<= aEmptyBorder; - aFrameProperties["RightBorder"] <<= aEmptyBorder; - - // Horizontal positioning - sal_Int16 nHoriOrient = text::HoriOrientation::NONE; - if (m_aXSpec == "center") - nHoriOrient = text::HoriOrientation::CENTER; - else if (m_aXSpec == "inside") - nHoriOrient = text::HoriOrientation::INSIDE; - else if (m_aXSpec == "left") - nHoriOrient = text::HoriOrientation::LEFT; - else if (m_aXSpec == "outside") - nHoriOrient = text::HoriOrientation::OUTSIDE; - else if (m_aXSpec == "right") - nHoriOrient = text::HoriOrientation::RIGHT; - - sal_Int16 nHoriOrientRelation; - if (m_aHorzAnchor == "margin") - nHoriOrientRelation = text::RelOrientation::PAGE_PRINT_AREA; - else if (m_aHorzAnchor == "page") - nHoriOrientRelation = text::RelOrientation::PAGE_FRAME; - else if (m_aHorzAnchor == "text") - nHoriOrientRelation = text::RelOrientation::FRAME; - - aFrameProperties["HoriOrient"] <<= nHoriOrient; - aFrameProperties["HoriOrientRelation"] <<= nHoriOrientRelation; - aFrameProperties["HoriOrientPosition"] <<= ConversionHelper::convertTwipToMM100(m_nX); - - // Vertical positioning - sal_Int16 nVertOrient = text::VertOrientation::NONE; - if (m_aYSpec == "bottom") - nVertOrient = text::VertOrientation::BOTTOM; - else if (m_aYSpec == "center") - nVertOrient = text::VertOrientation::CENTER; - else if (m_aYSpec == "top") - nVertOrient = text::VertOrientation::TOP; - // TODO There are a few cases we can't map ATM. - - sal_Int16 nVertOrientRelation; - if (m_aVertAnchor == "margin") - nVertOrientRelation = text::RelOrientation::PAGE_PRINT_AREA; - else if (m_aVertAnchor == "page") - nVertOrientRelation = text::RelOrientation::PAGE_FRAME; - else if (m_aVertAnchor == "text") - nVertOrientRelation = text::RelOrientation::FRAME; - - aFrameProperties["VertOrient"] <<= nVertOrient; - aFrameProperties["VertOrientRelation"] <<= nVertOrientRelation; - aFrameProperties["VertOrientPosition"] <<= ConversionHelper::convertTwipToMM100(m_nY); - aFrameProperties["FillTransparence"] <<= sal_Int32(100); - - return aFrameProperties.getAsConstPropertyValueList(); -} - -bool TablePositionHandler::operator==(const TablePositionHandler& rHandler) const -{ - return m_aVertAnchor == rHandler.m_aVertAnchor && m_aYSpec == rHandler.m_aYSpec - && m_aHorzAnchor == rHandler.m_aHorzAnchor && m_aXSpec == rHandler.m_aXSpec - && m_nY == rHandler.m_nY && m_nX == rHandler.m_nX; -} - -} // namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TablePositionHandler.hxx b/writerfilter/source/dmapper/TablePositionHandler.hxx deleted file mode 100644 index 0a9a29d61f37..000000000000 --- a/writerfilter/source/dmapper/TablePositionHandler.hxx +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEPOSITIONHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEPOSITIONHANDLER_HXX - -#include "LoggedResources.hxx" - -namespace com::sun::star::beans -{ -struct PropertyValue; -} - -namespace writerfilter::dmapper -{ -/// Handler for floating table positioning -class TablePositionHandler : public LoggedProperties -{ - OUString m_aVertAnchor{ "margin" }; - OUString m_aYSpec; - OUString m_aHorzAnchor{ "text" }; - OUString m_aXSpec; - sal_Int32 m_nY = 0; - sal_Int32 m_nX = 0; - sal_Int32 m_nLeftFromText = 0; - sal_Int32 m_nRightFromText = 0; - sal_Int32 m_nTopFromText = 0; - sal_Int32 m_nBottomFromText = 0; - - // Properties - void lcl_attribute(Id nId, Value& rVal) override; - void lcl_sprm(Sprm& sprm) override; - -public: - sal_Int32 getY() const { return m_nY; } - sal_Int32 getX() const { return m_nX; } - sal_Int32 getLeftFromText() const { return m_nLeftFromText; } - sal_Int32 getRightFromText() const { return m_nRightFromText; } - sal_Int32 getTopFromText() const { return m_nTopFromText; } - sal_Int32 getBottomFromText() const { return m_nBottomFromText; } - - const OUString& getVertAnchor() const { return m_aVertAnchor; } - const OUString& getYSpec() const { return m_aYSpec; } - const OUString& getHorzAnchor() const { return m_aHorzAnchor; } - const OUString& getXSpec() const { return m_aXSpec; } - - TablePositionHandler(); - ~TablePositionHandler() override; - - /** Compute the UNO properties for the frame containing the table based - on the received tokens. - - Note that the properties will need to be adjusted with the table - properties before actually using them. - */ - css::uno::Sequence<css::beans::PropertyValue> getTablePosition() const; - - bool operator==(const TablePositionHandler& rHandler) const; -}; - -using TablePositionHandlerPtr = tools::SvRef<TablePositionHandler>; -} // namespace writerfilter::dmapper - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TablePropertiesHandler.cxx b/writerfilter/source/dmapper/TablePropertiesHandler.cxx deleted file mode 100644 index b2cb476e3623..000000000000 --- a/writerfilter/source/dmapper/TablePropertiesHandler.cxx +++ /dev/null @@ -1,394 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "BorderHandler.hxx" -#include "CellColorHandler.hxx" -#include "CellMarginHandler.hxx" -#include "ConversionHelper.hxx" -#include "MeasureHandler.hxx" -#include "TrackChangesHandler.hxx" -#include "TablePropertiesHandler.hxx" -#include "TagLogger.hxx" -#include "TDefTableHandler.hxx" -#include "DomainMapperTableManager.hxx" - -#include <ooxml/resourceids.hxx> - -#include <com/sun/star/text/VertOrientation.hpp> -#include <oox/token/tokens.hxx> - -using namespace com::sun::star; -using namespace oox; - -namespace writerfilter::dmapper { - - TablePropertiesHandler::TablePropertiesHandler() : - m_pCurrentInteropGrabBag(nullptr), - m_pTableManager( nullptr ) - { - } - - bool TablePropertiesHandler::sprm(Sprm & rSprm) - { -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("TablePropertiesHandler.sprm"); - TagLogger::getInstance().attribute("sprm", rSprm.toString()); -#endif - - bool bRet = true; - sal_uInt32 nSprmId = rSprm.getId(); - Value::Pointer_t pValue = rSprm.getValue(); - sal_Int32 nIntValue = (pValue ? pValue->getInt() : 0); - switch( nSprmId ) - { - case NS_ooxml::LN_CT_TrPrBase_jc: - case NS_ooxml::LN_CT_TblPrBase_jc: - { - sal_Int16 nOrient = ConversionHelper::convertTableJustification( nIntValue ); - TablePropertyMapPtr pTableMap( new TablePropertyMap ); - pTableMap->setValue( TablePropertyMap::HORI_ORIENT, nOrient ); - insertTableProps( pTableMap ); - } - break; - case NS_ooxml::LN_CT_TrPrBase_trHeight: - { - //contains unit and value - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { //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, uno::makeAny( pMeasureHandler->GetRowHeightSizeType() ), false); - pPropMap->Insert( PROP_HEIGHT, uno::makeAny(pMeasureHandler->getMeasureValue() )); - - insertRowProps(pPropMap); - } - } - break; - case NS_ooxml::LN_CT_TrPr_ins: - case NS_ooxml::LN_CT_TrPr_del: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - sal_Int32 nToken = sal_Int32(); - switch( nSprmId ) - { - case NS_ooxml::LN_CT_TrPr_ins: - nToken = XML_tableRowInsert; - break; - case NS_ooxml::LN_CT_TrPr_del: - nToken = XML_tableRowDelete; - break; - } - auto pTrackChangesHandler = std::make_shared<TrackChangesHandler>( nToken ); - pProperties->resolve(*pTrackChangesHandler); - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - - // Add the 'track changes' properties to the 'table row' via UNO. - // This way - in the SW core - when it receives this - it will create a new 'Table Redline' object for that row - uno::Sequence<beans::PropertyValue> aTableRedlineProperties = pTrackChangesHandler->getRedlineProperties(); - pPropMap->Insert( PROP_TABLE_REDLINE_PARAMS , uno::makeAny( aTableRedlineProperties )); - insertRowProps(pPropMap); - } - } - break; - case NS_ooxml::LN_CT_TcPrBase_cellIns: - case NS_ooxml::LN_CT_TcPrBase_cellDel: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - sal_Int32 nToken; - switch( nSprmId ) - { - case NS_ooxml::LN_CT_TcPrBase_cellIns: - nToken = XML_tableCellInsert; - break; - case NS_ooxml::LN_CT_TcPrBase_cellDel: - nToken = XML_tableCellDelete; - break; - default: - throw lang::IllegalArgumentException("illegal redline token type", nullptr, 0); - break; - } - auto pTrackChangesHandler = std::make_shared<TrackChangesHandler>( nToken ); - pProperties->resolve(*pTrackChangesHandler); - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - - // Add the 'track changes' properties to the 'table row' via UNO. - // This way - in the SW core - when it receives this - it will create a new 'Table Redline' object for that row - uno::Sequence<beans::PropertyValue> aTableRedlineProperties = pTrackChangesHandler->getRedlineProperties(); - pPropMap->Insert( PROP_TABLE_REDLINE_PARAMS , uno::makeAny( aTableRedlineProperties )); - cellProps(pPropMap); - } - } - break; - case NS_ooxml::LN_CT_TrPrBase_cantSplit: - { - //row can't break across pages if nIntValue == 1 - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - pPropMap->Insert( PROP_IS_SPLIT_ALLOWED, uno::makeAny( nIntValue != 1 ) ); - insertRowProps(pPropMap); - } - break; - case NS_ooxml::LN_CT_TcPrBase_vAlign: - { - sal_Int16 nVertOrient = text::VertOrientation::NONE; - switch( nIntValue ) - { - case NS_ooxml::LN_Value_ST_VerticalJc_center: nVertOrient = text::VertOrientation::CENTER; break; - case NS_ooxml::LN_Value_ST_VerticalJc_bottom: nVertOrient = text::VertOrientation::BOTTOM; break; - default:; - } - TablePropertyMapPtr pCellPropMap( new TablePropertyMap() ); - pCellPropMap->Insert( PROP_VERT_ORIENT, uno::makeAny( nVertOrient ) ); - //todo: in ooxml import the value of m_ncell is wrong - cellProps( pCellPropMap ); - if (m_pCurrentInteropGrabBag) - { - OUString aVertOrient; - switch( nIntValue ) - { - case NS_ooxml::LN_Value_ST_VerticalJc_top: aVertOrient = "top"; break; - case NS_ooxml::LN_Value_ST_VerticalJc_center: aVertOrient = "center"; break; - case NS_ooxml::LN_Value_ST_VerticalJc_both: aVertOrient = "both"; break; - case NS_ooxml::LN_Value_ST_VerticalJc_bottom: aVertOrient = "bottom"; break; - } - if (!aVertOrient.isEmpty()) - { - beans::PropertyValue aValue; - aValue.Name = "vAlign"; - aValue.Value <<= aVertOrient; - m_pCurrentInteropGrabBag->push_back(aValue); - } - } - } - 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 ) - { - auto pBorderHandler = std::make_shared<BorderHandler>(true); - if (m_pCurrentInteropGrabBag) - pBorderHandler->enableInteropGrabBag("tblBorders"); - pProperties->resolve(*pBorderHandler); - if (m_pCurrentInteropGrabBag) - m_pCurrentInteropGrabBag->push_back(pBorderHandler->getInteropGrabBag()); - TablePropertyMapPtr pTablePropMap( new TablePropertyMap ); - pTablePropMap->InsertProps(pBorderHandler->getProperties()); - -#ifdef DBG_UTIL - pTablePropMap->dumpXml(); -#endif - insertTableProps( pTablePropMap ); - } - } - break; - case NS_ooxml::LN_CT_TblPrBase_tblLayout: - { - DomainMapperTableManager* pManager = dynamic_cast<DomainMapperTableManager*>(m_pTableManager); - if (pManager) - pManager->SetLayoutType(static_cast<sal_uInt32>(nIntValue)); - } - break; - case NS_ooxml::LN_CT_TblPrEx_tblBorders: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties) - { - auto pBorderHandler = std::make_shared<BorderHandler>(true); - pProperties->resolve(*pBorderHandler); - TablePropertyMapPtr pTablePropMap( new TablePropertyMap ); - pTablePropMap->InsertProps(pBorderHandler->getProperties()); - -#ifdef DBG_UTIL - pTablePropMap->dumpXml(); -#endif - tableExceptionProps( 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 ) - { - //in OOXML there's one set of borders at each cell (if there is any) - tools::SvRef< TDefTableHandler > pTDefTableHandler( new TDefTableHandler()); - if (m_pCurrentInteropGrabBag) - pTDefTableHandler->enableInteropGrabBag("tcBorders"); - pProperties->resolve( *pTDefTableHandler ); - if (m_pCurrentInteropGrabBag) - m_pCurrentInteropGrabBag->push_back(pTDefTableHandler->getInteropGrabBag()); - TablePropertyMapPtr pCellPropMap( new TablePropertyMap ); - pTDefTableHandler->fillCellProperties( pCellPropMap ); - cellProps( pCellPropMap ); - } - } - break; - case NS_ooxml::LN_CT_TcPrBase_tcMar: - - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - { - auto pCellMarginHandler = std::make_shared<CellMarginHandler>(); - if (m_pCurrentInteropGrabBag) - pCellMarginHandler->enableInteropGrabBag("tcMar"); - pProperties->resolve(*pCellMarginHandler); - if (m_pCurrentInteropGrabBag) - m_pCurrentInteropGrabBag->push_back(pCellMarginHandler->getInteropGrabBag()); - TablePropertyMapPtr pCellProperties(new TablePropertyMap); - if (pCellMarginHandler->m_bTopMarginValid) - pCellProperties->Insert(PROP_TOP_BORDER_DISTANCE, uno::makeAny(pCellMarginHandler->m_nTopMargin)); - if (pCellMarginHandler->m_bLeftMarginValid) - pCellProperties->Insert(PROP_LEFT_BORDER_DISTANCE, uno::makeAny(pCellMarginHandler->m_nLeftMargin)); - if (pCellMarginHandler->m_bBottomMarginValid) - pCellProperties->Insert(PROP_BOTTOM_BORDER_DISTANCE, uno::makeAny(pCellMarginHandler->m_nBottomMargin)); - if (pCellMarginHandler->m_bRightMarginValid) - pCellProperties->Insert(PROP_RIGHT_BORDER_DISTANCE, uno::makeAny(pCellMarginHandler->m_nRightMargin)); - cellProps(pCellProperties); - } - } - break; -/* // tdf#123189 skip to keep MSO interoperability - case NS_ooxml::LN_CT_TblPrBase_shd: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties.get()) - { - std::shared_ptr<CellColorHandler> pCellColorHandler( new CellColorHandler); - pProperties->resolve( *pCellColorHandler ); - TablePropertyMapPtr pTablePropMap( new TablePropertyMap ); - insertTableProps( pCellColorHandler->getProperties() ); - } - } -*/ - break; - 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 ) - { - auto pCellColorHandler = std::make_shared<CellColorHandler>(); - pCellColorHandler->enableInteropGrabBag("shd"); //enable to store shd unsupported props in grab bag - pProperties->resolve( *pCellColorHandler ); - TablePropertyMapPtr pPropertyMap = pCellColorHandler->getProperties(); - beans::PropertyValue aGrabBag = pCellColorHandler->getInteropGrabBag(); - if (m_pCurrentInteropGrabBag) - m_pCurrentInteropGrabBag->push_back(aGrabBag); - pPropertyMap->Insert( PROP_CELL_INTEROP_GRAB_BAG, aGrabBag.Value ); - cellProps( pPropertyMap ); - } - } - 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 - // LN_CT_TblCellMar_start, LN_CT_TblCellMar_end - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - auto pCellMarginHandler = std::make_shared<CellMarginHandler>(); - if (m_pCurrentInteropGrabBag) - pCellMarginHandler->enableInteropGrabBag("tblCellMar"); - pProperties->resolve( *pCellMarginHandler ); - if (m_pCurrentInteropGrabBag) - m_pCurrentInteropGrabBag->push_back(pCellMarginHandler->getInteropGrabBag()); - 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) - { - MeasureHandlerPtr pHandler(new MeasureHandler); - if (m_pCurrentInteropGrabBag) - pHandler->enableInteropGrabBag("tblInd"); - pProperties->resolve( *pHandler ); - if (m_pCurrentInteropGrabBag) - m_pCurrentInteropGrabBag->push_back(pHandler->getInteropGrabBag()); - TablePropertyMapPtr pTblIndMap(new TablePropertyMap); - sal_uInt32 nTblInd = pHandler->getMeasureValue(); - pTblIndMap->setValue( TablePropertyMap::LEFT_MARGIN, nTblInd); - insertTableProps(pTblIndMap); - } - } - break; - case NS_ooxml::LN_CT_TcPrBase_hideMark: - if (nIntValue) - { - TablePropertyMapPtr pPropMap(new TablePropertyMap()); - pPropMap->Insert(PROP_CELL_HIDE_MARK, uno::makeAny(nIntValue)); - cellProps(pPropMap); - } - break; - default: - // Not handled here, give the next handler a chance. - bRet = false; - // However, these logically belong here, so save the value if necessary. - switch (nSprmId) - { - case NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize: - case NS_ooxml::LN_CT_TblPrBase_tblStyleColBandSize: - if (m_pCurrentInteropGrabBag) - { - beans::PropertyValue aValue; - aValue.Name = (nSprmId == NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize ? OUStringLiteral(u"tblStyleRowBandSize") : OUStringLiteral(u"tblStyleColBandSize")); - aValue.Value <<= nIntValue; - m_pCurrentInteropGrabBag->push_back(aValue); - } - break; - } - break; - } - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif - - return bRet; - } - - void TablePropertiesHandler::SetInteropGrabBag(std::vector<beans::PropertyValue>& rValue) - { - m_pCurrentInteropGrabBag = &rValue; - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TablePropertiesHandler.hxx b/writerfilter/source/dmapper/TablePropertiesHandler.hxx deleted file mode 100644 index 6ba81cf9010f..000000000000 --- a/writerfilter/source/dmapper/TablePropertiesHandler.hxx +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEPROPERTIESHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TABLEPROPERTIESHANDLER_HXX - -#include "PropertyMap.hxx" - -#include "TableManager.hxx" -#include <dmapper/resourcemodel.hxx> - -#include <vector> - -namespace writerfilter::dmapper { - -class DomainMapper; - -class TablePropertiesHandler final : public virtual SvRefBase -{ -private: - PropertyMapPtr m_pCurrentProperties; - std::vector<css::beans::PropertyValue>* m_pCurrentInteropGrabBag; - TableManager* m_pTableManager; - -public: - TablePropertiesHandler(); - - bool sprm(Sprm & sprm); - - void SetTableManager( TableManager* pTableManager ) - { - m_pTableManager = pTableManager; - }; - - void SetProperties( PropertyMapPtr pProperties ) - { - m_pCurrentProperties = pProperties; - }; - - void SetInteropGrabBag(std::vector<css::beans::PropertyValue>& rValue); - -private: - - void cellProps( TablePropertyMapPtr pProps ) - { - if ( m_pTableManager ) - m_pTableManager->cellProps( pProps ); - else - m_pCurrentProperties->InsertProps(pProps.get()); - }; - - void insertRowProps( TablePropertyMapPtr pProps ) - { - if ( m_pTableManager ) - m_pTableManager->insertRowProps( pProps ); - else - m_pCurrentProperties->InsertProps(pProps.get()); - }; - - void tableExceptionProps( TablePropertyMapPtr pProps ) - { - if ( m_pTableManager ) - m_pTableManager->tableExceptionProps( pProps ); - else - m_pCurrentProperties->InsertProps(pProps.get()); - }; - - void insertTableProps( TablePropertyMapPtr pProps ) - { - if ( m_pTableManager ) - m_pTableManager->insertTableProps( pProps ); - else - m_pCurrentProperties->InsertProps(pProps.get()); - }; -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TagLogger.cxx b/writerfilter/source/dmapper/TagLogger.cxx deleted file mode 100644 index a7443f056d29..000000000000 --- a/writerfilter/source/dmapper/TagLogger.cxx +++ /dev/null @@ -1,237 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <string.h> -#include "TagLogger.hxx" -#ifdef DBG_UTIL -#include <unotools/pathoptions.hxx> -#endif - -using namespace css; - -namespace writerfilter -{ - TagLogger::TagLogger() - : pWriter( nullptr ), pName( "DOMAINMAPPER" ) - { - } - - TagLogger::~TagLogger() - { - pWriter = nullptr; - pName = nullptr; - } - -#ifdef DBG_UTIL - void TagLogger::setFileName( const std::string & filename ) - { - if ( pWriter ) - endDocument(); - - std::string fileName; - char * temp = getenv("TAGLOGGERTMP"); - - if (temp != nullptr) - fileName += temp; - else - fileName += SvtPathOptions().GetTempPath().toUtf8().getStr(); - - std::string sPrefix = filename; - size_t nLastSlash = sPrefix.find_last_of('/'); - size_t nLastBackslash = sPrefix.find_last_of('\\'); - size_t nCutPos = nLastSlash; - if (nLastBackslash < nCutPos) - nCutPos = nLastBackslash; - if (nCutPos < sPrefix.size()) - sPrefix = sPrefix.substr(nCutPos + 1); - - fileName += "/"; - fileName += sPrefix; - fileName += "."; - fileName += pName; - fileName += ".xml"; - - pWriter = xmlNewTextWriterFilename( fileName.c_str(), 0 ); - xmlTextWriterSetIndent(pWriter,1); - xmlTextWriterSetIndentString(pWriter, BAD_CAST(" ")); - xmlTextWriterSetIndent( pWriter, 4 ); - } - - void TagLogger::startDocument() - { - if (!pWriter) - return; - xmlTextWriterStartDocument( pWriter, nullptr, nullptr, nullptr ); - xmlTextWriterStartElement( pWriter, BAD_CAST( "root" ) ); - } - - void TagLogger::endDocument() - { - if (!pWriter) - return; - xmlTextWriterEndDocument( pWriter ); - xmlFreeTextWriter( pWriter ); - pWriter = nullptr; - } - -#endif - -namespace { - -struct TheTagLogger: - public rtl::Static<TagLogger, TheTagLogger> -{}; - -} - - TagLogger& TagLogger::getInstance() - { - return TheTagLogger::get(); - } - -#ifdef DBG_UTIL - void TagLogger::element(const std::string & name) - { - startElement(name); - endElement(); - } - - void TagLogger::unoPropertySet(const uno::Reference<beans::XPropertySet>& rPropSet) - { - uno::Reference<beans::XPropertySetInfo> xPropSetInfo(rPropSet->getPropertySetInfo()); - const uno::Sequence<beans::Property> aProps(xPropSetInfo->getProperties()); - - startElement( "unoPropertySet" ); - - for (beans::Property const & prop : aProps) - { - startElement( "property" ); - OUString sName(prop.Name); - - attribute( "name", sName ); - try - { - attribute( "value", rPropSet->getPropertyValue( sName ) ); - } - catch (const uno::Exception &) - { - startElement( "exception" ); - - chars(std::string("getPropertyValue(\"")); - chars(sName); - chars(std::string("\")")); - - endElement( ); - } - endElement( ); - } - endElement( ); - } - - void TagLogger::startElement(const std::string & name) - { - if (!pWriter) - return; - xmlChar* xmlName = xmlCharStrdup( name.c_str() ); - xmlTextWriterStartElement( pWriter, xmlName ); - xmlFree( xmlName ); - } -#endif - - void TagLogger::attribute(const std::string & name, const std::string & value) - { - if (!pWriter) - return; - xmlChar* xmlName = xmlCharStrdup( name.c_str() ); - xmlChar* xmlValue = xmlCharStrdup( value.c_str() ); - xmlTextWriterWriteAttribute( pWriter, xmlName, xmlValue ); - - xmlFree( xmlValue ); - xmlFree( xmlName ); - } - -#ifdef DBG_UTIL - void TagLogger::attribute(const std::string & name, std::u16string_view value) - { - attribute( name, OUStringToOString( value, RTL_TEXTENCODING_ASCII_US ).getStr() ); - } - - void TagLogger::attribute(const std::string & name, sal_uInt32 value) - { - if (!pWriter) - return; - xmlChar* xmlName = xmlCharStrdup( name.c_str() ); - xmlTextWriterWriteFormatAttribute( pWriter, xmlName, - "%" SAL_PRIuUINT32, value ); - xmlFree( xmlName ); - } - - void TagLogger::attribute(const std::string & name, const uno::Any& aAny) - { - if (!pWriter) - return; - - sal_Int32 nInt = 0; - float nFloat = 0.0; - OUString aStr; - - xmlChar* xmlName = xmlCharStrdup( name.c_str() ); - if ( aAny >>= nInt ) - { - xmlTextWriterWriteFormatAttribute( pWriter, xmlName, - "%" SAL_PRIdINT32, nInt ); - } - else if ( aAny >>= nFloat ) - { - xmlTextWriterWriteFormatAttribute( pWriter, xmlName, - "%f", nFloat ); - } - else if ( aAny >>= aStr ) - { - attribute( name, aStr ); - } - xmlFree( xmlName ); - } - - void TagLogger::chars(const std::string & rChars) - { - if (!pWriter) - return; - xmlChar* xmlChars = xmlCharStrdup( rChars.c_str() ); - xmlTextWriterWriteString( pWriter, xmlChars ); - xmlFree( xmlChars ); - } - - void TagLogger::chars(std::u16string_view rChars) - { - chars(OUStringToOString(rChars, RTL_TEXTENCODING_ASCII_US).getStr()); - } - - void TagLogger::endElement() - { - if (!pWriter) - return; - xmlTextWriterEndElement( pWriter ); - } - -#endif - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TagLogger.hxx b/writerfilter/source/dmapper/TagLogger.hxx deleted file mode 100644 index f28b58b59f26..000000000000 --- a/writerfilter/source/dmapper/TagLogger.hxx +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TAGLOGGER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TAGLOGGER_HXX - -#include <rtl/ustring.hxx> -#include <tools/ref.hxx> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <string> -#include <string_view> -#include <libxml/xmlwriter.h> - -namespace writerfilter -{ - - class TagLogger - { - private: - xmlTextWriterPtr pWriter; - const char* pName; - - public: - explicit TagLogger(); - ~TagLogger(); - - static TagLogger& getInstance(); - -#ifdef DBG_UTIL - void setFileName(const std::string & filename); - void startDocument(); - void endDocument(); - - void element(const std::string & name); - void unoPropertySet(const css::uno::Reference<css::beans::XPropertySet>& rPropSet); - void startElement(const std::string & name); -#endif - void attribute(const std::string & name, const std::string & value); -#ifdef DBG_UTIL - void attribute(const std::string & name, std::u16string_view value); - void attribute(const std::string & name, sal_uInt32 value); - void attribute(const std::string & name, const css::uno::Any& aAny); - void chars(const std::string & chars); - void chars(std::u16string_view chars); - void endElement(); -#endif - }; -} - -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TAGLOGGER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TblStylePrHandler.cxx b/writerfilter/source/dmapper/TblStylePrHandler.cxx deleted file mode 100644 index 001cecbd9f86..000000000000 --- a/writerfilter/source/dmapper/TblStylePrHandler.cxx +++ /dev/null @@ -1,259 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "TblStylePrHandler.hxx" -#include "TagLogger.hxx" -#include "CellMarginHandler.hxx" -#include "PropertyMap.hxx" -#include "MeasureHandler.hxx" -#include <ooxml/resourceids.hxx> -#include <comphelper/sequence.hxx> - - -using namespace css; - -namespace writerfilter::dmapper { - -TblStylePrHandler::TblStylePrHandler( DomainMapper & rDMapper ) : -LoggedProperties("TblStylePrHandler"), -m_rDMapper( rDMapper ), -m_pTablePropsHandler(new TablePropertiesHandler()), -m_nType( TBL_STYLE_UNKNOWN ), -m_pProperties( new PropertyMap ) -{ -} - -TblStylePrHandler::~TblStylePrHandler( ) -{ -} - -OUString TblStylePrHandler::getTypeString() const -{ - switch (m_nType) - { - case TBL_STYLE_WHOLETABLE: return "wholeTable"; - case TBL_STYLE_FIRSTROW: return "firstRow"; - case TBL_STYLE_LASTROW: return "lastRow"; - case TBL_STYLE_FIRSTCOL: return "firstCol"; - case TBL_STYLE_LASTCOL: return "lastCol"; - case TBL_STYLE_BAND1VERT: return "band1Vert"; - case TBL_STYLE_BAND2VERT: return "band2Vert"; - case TBL_STYLE_BAND1HORZ: return "band1Horz"; - case TBL_STYLE_BAND2HORZ: return "band2Horz"; - case TBL_STYLE_NECELL: return "neCell"; - case TBL_STYLE_NWCELL: return "nwCell"; - case TBL_STYLE_SECELL: return "seCell"; - case TBL_STYLE_SWCELL: return "swCell"; - default: break; - } - return OUString(); -} - -void TblStylePrHandler::lcl_attribute(Id rName, Value & rVal) -{ - - switch ( rName ) - { - case NS_ooxml::LN_CT_TblStyleOverrideType: - { - switch (rVal.getInt()) - { - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_wholeTable: - m_nType = TBL_STYLE_WHOLETABLE; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_firstRow: - m_nType = TBL_STYLE_FIRSTROW; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_lastRow: - m_nType = TBL_STYLE_LASTROW; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_firstCol: - m_nType = TBL_STYLE_FIRSTCOL; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_lastCol: - m_nType = TBL_STYLE_LASTCOL; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_band1Vert: - m_nType = TBL_STYLE_BAND1VERT; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_band2Vert: - m_nType = TBL_STYLE_BAND2VERT; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_band1Horz: - m_nType = TBL_STYLE_BAND1HORZ; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_band2Horz: - m_nType = TBL_STYLE_BAND2HORZ; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_neCell: - m_nType = TBL_STYLE_NECELL; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_nwCell: - m_nType = TBL_STYLE_NWCELL; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_seCell: - m_nType = TBL_STYLE_SECELL; - break; - case NS_ooxml::LN_Value_ST_TblStyleOverrideType_swCell: - m_nType = TBL_STYLE_SWCELL; - break; - } - } - break; - } -} - -void TblStylePrHandler::lcl_sprm(Sprm & rSprm) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("TblStylePrHandler.sprm"); - TagLogger::getInstance().attribute("sprm", rSprm.toString()); -#endif - - 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: - { - std::vector<beans::PropertyValue> aSavedGrabBag; - bool bGrabBag = rSprm.getId() == NS_ooxml::LN_CT_PPrBase || - rSprm.getId() == NS_ooxml::LN_EG_RPrBase || - rSprm.getId() == NS_ooxml::LN_CT_TblPrBase || - rSprm.getId() == NS_ooxml::LN_CT_TrPrBase || - rSprm.getId() == NS_ooxml::LN_CT_TcPrBase; - if (bGrabBag) - { - std::swap(aSavedGrabBag, m_aInteropGrabBag); - } - resolveSprmProps( rSprm ); - if (bGrabBag) - { - if (rSprm.getId() == NS_ooxml::LN_CT_PPrBase) - aSavedGrabBag.push_back(getInteropGrabBag("pPr")); - else if (rSprm.getId() == NS_ooxml::LN_EG_RPrBase) - aSavedGrabBag.push_back(getInteropGrabBag("rPr")); - else if (rSprm.getId() == NS_ooxml::LN_CT_TblPrBase) - aSavedGrabBag.push_back(getInteropGrabBag("tblPr")); - else if (rSprm.getId() == NS_ooxml::LN_CT_TrPrBase) - aSavedGrabBag.push_back(getInteropGrabBag("trPr")); - else if (rSprm.getId() == NS_ooxml::LN_CT_TcPrBase) - aSavedGrabBag.push_back(getInteropGrabBag("tcPr")); - std::swap(m_aInteropGrabBag, aSavedGrabBag); - } - } - break; - case NS_ooxml::LN_CT_TrPrBase_tblHeader: - { - m_pProperties->Insert( PROP_HEADER_ROW_COUNT, uno::makeAny(sal_Int32(1))); - beans::PropertyValue aValue; - aValue.Name = "tblHeader"; - aValue.Value <<= true; - m_aInteropGrabBag.push_back(aValue); - } - break; - case NS_ooxml::LN_CT_TblPrBase_tblInd: - { - //contains unit and value - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - { - MeasureHandlerPtr pMeasureHandler( new MeasureHandler ); - pProperties->resolve(*pMeasureHandler); - TablePropertyMapPtr pPropMap( new TablePropertyMap ); - pPropMap->setValue( TablePropertyMap::LEFT_MARGIN, pMeasureHandler->getMeasureValue() ); - m_pProperties->Insert( PROP_LEFT_MARGIN, uno::makeAny(pMeasureHandler->getMeasureValue()) ); - } - } - break; - case NS_ooxml::LN_CT_TblPrBase_tblCellMar: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if ( pProperties ) - { - auto pCellMarginHandler = std::make_shared<CellMarginHandler>(); - pCellMarginHandler->enableInteropGrabBag("tblCellMar"); - pProperties->resolve( *pCellMarginHandler ); - m_aInteropGrabBag.push_back(pCellMarginHandler->getInteropGrabBag()); - - if( pCellMarginHandler->m_bTopMarginValid ) - m_pProperties->Insert( META_PROP_CELL_MAR_TOP, uno::makeAny(pCellMarginHandler->m_nTopMargin) ); - if( pCellMarginHandler->m_bBottomMarginValid ) - m_pProperties->Insert( META_PROP_CELL_MAR_BOTTOM, uno::makeAny(pCellMarginHandler->m_nBottomMargin) ); - if( pCellMarginHandler->m_bLeftMarginValid ) - m_pProperties->Insert( META_PROP_CELL_MAR_LEFT, uno::makeAny(pCellMarginHandler->m_nLeftMargin) ); - if( pCellMarginHandler->m_bRightMarginValid ) - m_pProperties->Insert( META_PROP_CELL_MAR_RIGHT, uno::makeAny(pCellMarginHandler->m_nRightMargin) ); - } - } - break; - default: - // Tables specific properties have to handled here - m_pTablePropsHandler->SetProperties( m_pProperties ); - m_pTablePropsHandler->SetInteropGrabBag(m_aInteropGrabBag); - bool bRet = m_pTablePropsHandler->sprm( rSprm ); - - if ( !bRet ) - { - // The DomainMapper can handle some of the properties - m_rDMapper.PushStyleSheetProperties( m_pProperties, true ); - // Just pass a non-empty string, the array will have a single element anyway. - m_rDMapper.enableInteropGrabBag("TblStylePrHandler"); - m_rDMapper.sprm( rSprm ); - uno::Sequence<beans::PropertyValue> aGrabBag = m_rDMapper.getInteropGrabBag().Value.get< uno::Sequence<beans::PropertyValue> >(); - if (aGrabBag.hasElements()) - m_aInteropGrabBag.push_back(aGrabBag[0]); - m_rDMapper.PopStyleSheetProperties( true ); - } - } - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void TblStylePrHandler::resolveSprmProps(Sprm & rSprm) -{ - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - pProperties->resolve(*this); -} - -void TblStylePrHandler::appendInteropGrabBag(const OUString& aKey, const OUString& aValue) -{ - beans::PropertyValue aProperty; - aProperty.Name = aKey; - aProperty.Value <<= aValue; - m_aInteropGrabBag.push_back(aProperty); -} - -beans::PropertyValue TblStylePrHandler::getInteropGrabBag(const OUString& aName) -{ - beans::PropertyValue aRet; - aRet.Name = aName; - - aRet.Value <<= comphelper::containerToSequence(m_aInteropGrabBag); - return aRet; -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TblStylePrHandler.hxx b/writerfilter/source/dmapper/TblStylePrHandler.hxx deleted file mode 100644 index df493eb11187..000000000000 --- a/writerfilter/source/dmapper/TblStylePrHandler.hxx +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TBLSTYLEPRHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TBLSTYLEPRHANDLER_HXX - -#include "TablePropertiesHandler.hxx" - -#include "DomainMapper.hxx" -#include "LoggedResources.hxx" -#include <memory> -#include <vector> - -namespace writerfilter::dmapper { - -class DomainMapper; - -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 TblStylePrHandler : public LoggedProperties -{ -private: - DomainMapper & m_rDMapper; - std::unique_ptr<TablePropertiesHandler> m_pTablePropsHandler; - - TblStyleType m_nType; - PropertyMapPtr m_pProperties; - std::vector<css::beans::PropertyValue> m_aInteropGrabBag; - - // Properties - virtual void lcl_attribute(Id Name, Value & val) override; - virtual void lcl_sprm(Sprm & sprm) override; - -public: - explicit TblStylePrHandler( DomainMapper & rDMapper ); - virtual ~TblStylePrHandler( ) override; - - const PropertyMapPtr& getProperties() const { return m_pProperties; }; - TblStyleType getType() const { return m_nType; }; - OUString getTypeString() const; - void appendInteropGrabBag(const OUString& aKey, const OUString& aValue); - css::beans::PropertyValue getInteropGrabBag(const OUString& aName); - -private: - - void resolveSprmProps(Sprm & rSprm); -}; - -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TextEffectsHandler.cxx b/writerfilter/source/dmapper/TextEffectsHandler.cxx deleted file mode 100644 index 3288556c8979..000000000000 --- a/writerfilter/source/dmapper/TextEffectsHandler.cxx +++ /dev/null @@ -1,803 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - */ - -#include <sal/config.h> - -#include <map> - -#include "TextEffectsHandler.hxx" - -#include <rtl/ustrbuf.hxx> -#include <comphelper/string.hxx> -#include <ooxml/resourceids.hxx> -#include <comphelper/sequenceashashmap.hxx> -#include <oox/drawingml/drawingmltypes.hxx> - -namespace writerfilter::dmapper -{ - -using namespace com::sun::star; - -namespace -{ - -OUString lclGetNameForElementId(sal_uInt32 aId) -{ - static std::map<sal_uInt32, OUString> aIdMap; - if(aIdMap.empty()) - { - aIdMap[NS_ooxml::LN_EG_ColorChoice_srgbClr] = "srgbClr"; - aIdMap[NS_ooxml::LN_EG_ColorChoice_schemeClr] = "schemeClr"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_tint] = "tint"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_shade] = "shade"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_alpha] = "alpha"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_hueMod] = "hueMod"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_sat] = "sat"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_satOff] = "satOff"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_satMod] = "satMod"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_lum] = "lum"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_lumOff] = "lumOff"; - aIdMap[NS_ooxml::LN_EG_ColorTransform_lumMod] = "lumMod"; - aIdMap[NS_ooxml::LN_EG_FillProperties_noFill] = "noFill"; - aIdMap[NS_ooxml::LN_EG_FillProperties_solidFill] = "solidFill"; - aIdMap[NS_ooxml::LN_EG_FillProperties_gradFill] = "gradFill"; - aIdMap[NS_ooxml::LN_CT_GradientFillProperties_gsLst] = "gsLst"; - aIdMap[NS_ooxml::LN_CT_GradientStopList_gs] = "gs"; - aIdMap[NS_ooxml::LN_CT_GradientStop_pos] = "pos"; - aIdMap[NS_ooxml::LN_EG_ShadeProperties_lin] = "lin"; - aIdMap[NS_ooxml::LN_EG_ShadeProperties_path] = "path"; - aIdMap[NS_ooxml::LN_CT_PathShadeProperties_fillToRect] = "fillToRect"; - aIdMap[NS_ooxml::LN_EG_LineDashProperties_prstDash] = "prstDash"; - aIdMap[NS_ooxml::LN_EG_LineJoinProperties_round] = "round"; - aIdMap[NS_ooxml::LN_EG_LineJoinProperties_bevel] = "bevel"; - aIdMap[NS_ooxml::LN_EG_LineJoinProperties_miter] = "miter"; - aIdMap[NS_ooxml::LN_CT_Scene3D_camera] = "camera"; - aIdMap[NS_ooxml::LN_CT_Scene3D_lightRig] = "lightRig"; - aIdMap[NS_ooxml::LN_CT_LightRig_rot] = "rot"; - aIdMap[NS_ooxml::LN_CT_Props3D_bevelT] = "bevelT"; - aIdMap[NS_ooxml::LN_CT_Props3D_bevelB] = "bevelB"; - aIdMap[NS_ooxml::LN_CT_Props3D_extrusionClr] = "extrusionClr"; - aIdMap[NS_ooxml::LN_CT_Props3D_contourClr] = "contourClr"; - aIdMap[NS_ooxml::LN_CT_StylisticSets_styleSet] = "styleSet"; - } - return aIdMap[aId]; -} - -constexpr OUStringLiteral constAttributesSequenceName = u"attributes"; - -} - -OUString TextEffectsHandler::getSchemeColorValTypeString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_SchemeColorVal_bg1: return "bg1"; - case NS_ooxml::LN_ST_SchemeColorVal_tx1: return "tx1"; - case NS_ooxml::LN_ST_SchemeColorVal_bg2: return "bg2"; - case NS_ooxml::LN_ST_SchemeColorVal_tx2: return "tx2"; - case NS_ooxml::LN_ST_SchemeColorVal_accent1: return "accent1"; - case NS_ooxml::LN_ST_SchemeColorVal_accent2: return "accent2"; - case NS_ooxml::LN_ST_SchemeColorVal_accent3: return "accent3"; - case NS_ooxml::LN_ST_SchemeColorVal_accent4: return "accent4"; - case NS_ooxml::LN_ST_SchemeColorVal_accent5: return "accent5"; - case NS_ooxml::LN_ST_SchemeColorVal_accent6: return "accent6"; - case NS_ooxml::LN_ST_SchemeColorVal_hlink: return "hlink"; - case NS_ooxml::LN_ST_SchemeColorVal_folHlink: return "folHlink"; - case NS_ooxml::LN_ST_SchemeColorVal_dk1: return "dk1"; - case NS_ooxml::LN_ST_SchemeColorVal_lt1: return "lt1"; - case NS_ooxml::LN_ST_SchemeColorVal_dk2: return "dk2"; - case NS_ooxml::LN_ST_SchemeColorVal_lt2: return "lt2"; - case NS_ooxml::LN_ST_SchemeColorVal_phClr: return "phClr"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getRectAlignmentString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_RectAlignment_none: return "none"; - case NS_ooxml::LN_ST_RectAlignment_tl: return "tl"; - case NS_ooxml::LN_ST_RectAlignment_t: return "t"; - case NS_ooxml::LN_ST_RectAlignment_tr: return "tr"; - case NS_ooxml::LN_ST_RectAlignment_l: return "l"; - case NS_ooxml::LN_ST_RectAlignment_ctr: return "ctr"; - case NS_ooxml::LN_ST_RectAlignment_r: return "r"; - case NS_ooxml::LN_ST_RectAlignment_bl: return "bl"; - case NS_ooxml::LN_ST_RectAlignment_b: return "b"; - case NS_ooxml::LN_ST_RectAlignment_br: return "br"; - - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getLineCapString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_LineCap_rnd: return "rnd"; - case NS_ooxml::LN_ST_LineCap_sq: return "sq"; - case NS_ooxml::LN_ST_LineCap_flat: return "flat"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getCompoundLineString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_CompoundLine_sng: return "sng"; - case NS_ooxml::LN_ST_CompoundLine_dbl: return "dbl"; - case NS_ooxml::LN_ST_CompoundLine_thickThin: return "thickThin"; - case NS_ooxml::LN_ST_CompoundLine_thinThick: return "thinThick"; - case NS_ooxml::LN_ST_CompoundLine_tri: return "tri"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getPenAlignmentString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_PenAlignment_ctr: return "ctr"; - case NS_ooxml::LN_ST_PenAlignment_in: return "in"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getOnOffString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_OnOff_true: return "true"; - case NS_ooxml::LN_ST_OnOff_false: return "false"; - case NS_ooxml::LN_ST_OnOff_1: return "1"; - case NS_ooxml::LN_ST_OnOff_0: return "0"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getPathShadeTypeString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_PathShadeType_shape: return "shape"; - case NS_ooxml::LN_ST_PathShadeType_circle: return "circle"; - case NS_ooxml::LN_ST_PathShadeType_rect: return "rect"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getPresetLineDashValString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_PresetLineDashVal_solid: return "solid"; - case NS_ooxml::LN_ST_PresetLineDashVal_dot: return "dot"; - case NS_ooxml::LN_ST_PresetLineDashVal_sysDot: return "sysDot"; - case NS_ooxml::LN_ST_PresetLineDashVal_dash: return "dash"; - case NS_ooxml::LN_ST_PresetLineDashVal_sysDash: return "sysDash"; - case NS_ooxml::LN_ST_PresetLineDashVal_lgDash: return "lgDash"; - case NS_ooxml::LN_ST_PresetLineDashVal_dashDot: return "dashDot"; - case NS_ooxml::LN_ST_PresetLineDashVal_sysDashDot: return "sysDashDot"; - case NS_ooxml::LN_ST_PresetLineDashVal_lgDashDot: return "lgDashDot"; - case NS_ooxml::LN_ST_PresetLineDashVal_lgDashDotDot: return "lgDashDotDot"; - case NS_ooxml::LN_ST_PresetLineDashVal_sysDashDotDot: return "sysDashDotDot"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getPresetCameraTypeString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_PresetCameraType_legacyObliqueTopLeft: return "legacyObliqueTopLeft"; - case NS_ooxml::LN_ST_PresetCameraType_legacyObliqueTop: return "legacyObliqueTop"; - case NS_ooxml::LN_ST_PresetCameraType_legacyObliqueTopRight: return "legacyObliqueTopRight"; - case NS_ooxml::LN_ST_PresetCameraType_legacyObliqueLeft: return "legacyObliqueLeft"; - case NS_ooxml::LN_ST_PresetCameraType_legacyObliqueFront: return "legacyObliqueFront"; - case NS_ooxml::LN_ST_PresetCameraType_legacyObliqueRight: return "legacyObliqueRight"; - case NS_ooxml::LN_ST_PresetCameraType_legacyObliqueBottomLeft: return "legacyObliqueBottomLeft"; - case NS_ooxml::LN_ST_PresetCameraType_legacyObliqueBottom: return "legacyObliqueBottom"; - case NS_ooxml::LN_ST_PresetCameraType_legacyObliqueBottomRight: return "legacyObliqueBottomRight"; - case NS_ooxml::LN_ST_PresetCameraType_legacyPerspectiveTopLeft: return "legacyPerspectiveTopLeft"; - case NS_ooxml::LN_ST_PresetCameraType_legacyPerspectiveTop: return "legacyPerspectiveTop"; - case NS_ooxml::LN_ST_PresetCameraType_legacyPerspectiveTopRight: return "legacyPerspectiveTopRight"; - case NS_ooxml::LN_ST_PresetCameraType_legacyPerspectiveLeft: return "legacyPerspectiveLeft"; - case NS_ooxml::LN_ST_PresetCameraType_legacyPerspectiveFront: return "legacyPerspectiveFront"; - case NS_ooxml::LN_ST_PresetCameraType_legacyPerspectiveRight: return "legacyPerspectiveRight"; - case NS_ooxml::LN_ST_PresetCameraType_legacyPerspectiveBottomLeft: return "legacyPerspectiveBottomLeft"; - case NS_ooxml::LN_ST_PresetCameraType_legacyPerspectiveBottom: return "legacyPerspectiveBottom"; - case NS_ooxml::LN_ST_PresetCameraType_legacyPerspectiveBottomRight: return "legacyPerspectiveBottomRight"; - case NS_ooxml::LN_ST_PresetCameraType_orthographicFront: return "orthographicFront"; - case NS_ooxml::LN_ST_PresetCameraType_isometricTopUp: return "isometricTopUp"; - case NS_ooxml::LN_ST_PresetCameraType_isometricTopDown: return "isometricTopDown"; - case NS_ooxml::LN_ST_PresetCameraType_isometricBottomUp: return "isometricBottomUp"; - case NS_ooxml::LN_ST_PresetCameraType_isometricBottomDown: return "isometricBottomDown"; - case NS_ooxml::LN_ST_PresetCameraType_isometricLeftUp: return "isometricLeftUp"; - case NS_ooxml::LN_ST_PresetCameraType_isometricLeftDown: return "isometricLeftDown"; - case NS_ooxml::LN_ST_PresetCameraType_isometricRightUp: return "isometricRightUp"; - case NS_ooxml::LN_ST_PresetCameraType_isometricRightDown: return "isometricRightDown"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis1Left: return "isometricOffAxis1Left"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis1Right: return "isometricOffAxis1Right"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis1Top: return "isometricOffAxis1Top"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis2Left: return "isometricOffAxis2Left"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis2Right: return "isometricOffAxis2Right"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis2Top: return "isometricOffAxis2Top"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis3Left: return "isometricOffAxis3Left"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis3Right: return "isometricOffAxis3Right"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis3Bottom: return "isometricOffAxis3Bottom"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis4Left: return "isometricOffAxis4Left"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis4Right: return "isometricOffAxis4Right"; - case NS_ooxml::LN_ST_PresetCameraType_isometricOffAxis4Bottom: return "isometricOffAxis4Bottom"; - case NS_ooxml::LN_ST_PresetCameraType_obliqueTopLeft: return "obliqueTopLeft"; - case NS_ooxml::LN_ST_PresetCameraType_obliqueTop: return "obliqueTop"; - case NS_ooxml::LN_ST_PresetCameraType_obliqueTopRight: return "obliqueTopRight"; - case NS_ooxml::LN_ST_PresetCameraType_obliqueLeft: return "obliqueLeft"; - case NS_ooxml::LN_ST_PresetCameraType_obliqueRight: return "obliqueRight"; - case NS_ooxml::LN_ST_PresetCameraType_obliqueBottomLeft: return "obliqueBottomLeft"; - case NS_ooxml::LN_ST_PresetCameraType_obliqueBottom: return "obliqueBottom"; - case NS_ooxml::LN_ST_PresetCameraType_obliqueBottomRight: return "obliqueBottomRight"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveFront: return "perspectiveFront"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveLeft: return "perspectiveLeft"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveRight: return "perspectiveRight"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveAbove: return "perspectiveAbove"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveBelow: return "perspectiveBelow"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveAboveLeftFacing: return "perspectiveAboveLeftFacing"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveAboveRightFacing: return "perspectiveAboveRightFacing"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveContrastingLeftFacing: return "perspectiveContrastingLeftFacing"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveContrastingRightFacing: return "perspectiveContrastingRightFacing"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveHeroicLeftFacing: return "perspectiveHeroicLeftFacing"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveHeroicRightFacing: return "perspectiveHeroicRightFacing"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveHeroicExtremeLeftFacing: return "perspectiveHeroicExtremeLeftFacing"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveHeroicExtremeRightFacing: return "perspectiveHeroicExtremeRightFacing"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveRelaxed: return "perspectiveRelaxed"; - case NS_ooxml::LN_ST_PresetCameraType_perspectiveRelaxedModerately: return "perspectiveRelaxedModerately"; - default: break; - } - return OUString(); -} - - -OUString TextEffectsHandler::getLightRigTypeString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_LightRigType_legacyFlat1: return "legacyFlat1"; - case NS_ooxml::LN_ST_LightRigType_legacyFlat2: return "legacyFlat2"; - case NS_ooxml::LN_ST_LightRigType_legacyFlat3: return "legacyFlat3"; - case NS_ooxml::LN_ST_LightRigType_legacyFlat4: return "legacyFlat4"; - case NS_ooxml::LN_ST_LightRigType_legacyNormal1: return "legacyNormal1"; - case NS_ooxml::LN_ST_LightRigType_legacyNormal2: return "legacyNormal2"; - case NS_ooxml::LN_ST_LightRigType_legacyNormal3: return "legacyNormal3"; - case NS_ooxml::LN_ST_LightRigType_legacyNormal4: return "legacyNormal4"; - case NS_ooxml::LN_ST_LightRigType_legacyHarsh1: return "legacyHarsh1"; - case NS_ooxml::LN_ST_LightRigType_legacyHarsh2: return "legacyHarsh2"; - case NS_ooxml::LN_ST_LightRigType_legacyHarsh3: return "legacyHarsh3"; - case NS_ooxml::LN_ST_LightRigType_legacyHarsh4: return "legacyHarsh4"; - case NS_ooxml::LN_ST_LightRigType_threePt: return "threePt"; - case NS_ooxml::LN_ST_LightRigType_balanced: return "balanced"; - case NS_ooxml::LN_ST_LightRigType_soft: return "soft"; - case NS_ooxml::LN_ST_LightRigType_harsh: return "harsh"; - case NS_ooxml::LN_ST_LightRigType_flood: return "flood"; - case NS_ooxml::LN_ST_LightRigType_contrasting: return "contrasting"; - case NS_ooxml::LN_ST_LightRigType_morning: return "morning"; - case NS_ooxml::LN_ST_LightRigType_sunrise: return "sunrise"; - case NS_ooxml::LN_ST_LightRigType_sunset: return "sunset"; - case NS_ooxml::LN_ST_LightRigType_chilly: return "chilly"; - case NS_ooxml::LN_ST_LightRigType_freezing: return "freezing"; - case NS_ooxml::LN_ST_LightRigType_flat: return "flat"; - case NS_ooxml::LN_ST_LightRigType_twoPt: return "twoPt"; - case NS_ooxml::LN_ST_LightRigType_glow: return "glow"; - case NS_ooxml::LN_ST_LightRigType_brightRoom: return "brightRoom"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getLightRigDirectionString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_LightRigDirection_tl: return "tl"; - case NS_ooxml::LN_ST_LightRigDirection_t: return "t"; - case NS_ooxml::LN_ST_LightRigDirection_tr: return "tr"; - case NS_ooxml::LN_ST_LightRigDirection_l: return "l"; - case NS_ooxml::LN_ST_LightRigDirection_r: return "r"; - case NS_ooxml::LN_ST_LightRigDirection_bl: return "bl"; - case NS_ooxml::LN_ST_LightRigDirection_b: return "b"; - case NS_ooxml::LN_ST_LightRigDirection_br: return "br"; - - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getBevelPresetTypeString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_BevelPresetType_relaxedInset: return "relaxedInset"; - case NS_ooxml::LN_ST_BevelPresetType_circle: return "circle"; - case NS_ooxml::LN_ST_BevelPresetType_slope: return "slope"; - case NS_ooxml::LN_ST_BevelPresetType_cross: return "cross"; - case NS_ooxml::LN_ST_BevelPresetType_angle: return "angle"; - case NS_ooxml::LN_ST_BevelPresetType_softRound: return "softRound"; - case NS_ooxml::LN_ST_BevelPresetType_convex: return "convex"; - case NS_ooxml::LN_ST_BevelPresetType_coolSlant: return "coolSlant"; - case NS_ooxml::LN_ST_BevelPresetType_divot: return "divot"; - case NS_ooxml::LN_ST_BevelPresetType_riblet: return "riblet"; - case NS_ooxml::LN_ST_BevelPresetType_hardEdge: return "hardEdge"; - case NS_ooxml::LN_ST_BevelPresetType_artDeco: return "artDeco"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getPresetMaterialTypeString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_PresetMaterialType_legacyMatte: return "legacyMatte"; - case NS_ooxml::LN_ST_PresetMaterialType_legacyPlastic: return "legacyPlastic"; - case NS_ooxml::LN_ST_PresetMaterialType_legacyMetal: return "legacyMetal"; - case NS_ooxml::LN_ST_PresetMaterialType_legacyWireframe: return "legacyWireframe"; - case NS_ooxml::LN_ST_PresetMaterialType_matte: return "matte"; - case NS_ooxml::LN_ST_PresetMaterialType_plastic: return "plastic"; - case NS_ooxml::LN_ST_PresetMaterialType_metal: return "metal"; - case NS_ooxml::LN_ST_PresetMaterialType_warmMatte: return "warmMatte"; - case NS_ooxml::LN_ST_PresetMaterialType_translucentPowder: return "translucentPowder"; - case NS_ooxml::LN_ST_PresetMaterialType_powder: return "powder"; - case NS_ooxml::LN_ST_PresetMaterialType_dkEdge: return "dkEdge"; - case NS_ooxml::LN_ST_PresetMaterialType_softEdge: return "softEdge"; - case NS_ooxml::LN_ST_PresetMaterialType_clear: return "clear"; - case NS_ooxml::LN_ST_PresetMaterialType_flat: return "flat"; - case NS_ooxml::LN_ST_PresetMaterialType_softmetal: return "softmetal"; - case NS_ooxml::LN_ST_PresetMaterialType_none: return "none"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getLigaturesString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_Ligatures_none: return "none"; - case NS_ooxml::LN_ST_Ligatures_standard: return "standard"; - case NS_ooxml::LN_ST_Ligatures_contextual: return "contextual"; - case NS_ooxml::LN_ST_Ligatures_historical: return "historical"; - case NS_ooxml::LN_ST_Ligatures_discretional: return "discretional"; - case NS_ooxml::LN_ST_Ligatures_standardContextual: return "standardContextual"; - case NS_ooxml::LN_ST_Ligatures_standardHistorical: return "standardHistorical"; - case NS_ooxml::LN_ST_Ligatures_contextualHistorical: return "contextualHistorical"; - case NS_ooxml::LN_ST_Ligatures_standardDiscretional: return "standardDiscretional"; - case NS_ooxml::LN_ST_Ligatures_contextualDiscretional: return "contextualDiscretional"; - case NS_ooxml::LN_ST_Ligatures_historicalDiscretional: return "historicalDiscretional"; - case NS_ooxml::LN_ST_Ligatures_standardContextualHistorical: return "standardContextualHistorical"; - case NS_ooxml::LN_ST_Ligatures_standardContextualDiscretional: return "standardContextualDiscretional"; - case NS_ooxml::LN_ST_Ligatures_standardHistoricalDiscretional: return "standardHistoricalDiscretional"; - case NS_ooxml::LN_ST_Ligatures_contextualHistoricalDiscretional: return "contextualHistoricalDiscretional"; - case NS_ooxml::LN_ST_Ligatures_all: return "all"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getNumFormString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_NumForm_default: return "default"; - case NS_ooxml::LN_ST_NumForm_lining: return "lining"; - case NS_ooxml::LN_ST_NumForm_oldStyle: return "oldStyle"; - default: break; - } - return OUString(); -} - -OUString TextEffectsHandler::getNumSpacingString(sal_Int32 nType) -{ - switch (nType) - { - case NS_ooxml::LN_ST_NumSpacing_default: return "default"; - case NS_ooxml::LN_ST_NumSpacing_proportional: return "proportional"; - case NS_ooxml::LN_ST_NumSpacing_tabular: return "tabular"; - default: break; - } - return OUString(); -} - -void TextEffectsHandler::convertElementIdToPropertyId(sal_Int32 aElementId) -{ - switch(aElementId) - { - case NS_ooxml::LN_glow_glow: - maPropertyId = PROP_CHAR_GLOW_TEXT_EFFECT; - maElementName = "glow"; - break; - case NS_ooxml::LN_shadow_shadow: - maPropertyId = PROP_CHAR_SHADOW_TEXT_EFFECT; - maElementName = "shadow"; - break; - case NS_ooxml::LN_reflection_reflection: - maPropertyId = PROP_CHAR_REFLECTION_TEXT_EFFECT; - maElementName = "reflection"; - break; - case NS_ooxml::LN_textOutline_textOutline: - maPropertyId = PROP_CHAR_TEXTOUTLINE_TEXT_EFFECT; - maElementName = "textOutline"; - break; - case NS_ooxml::LN_textFill_textFill: - maPropertyId = PROP_CHAR_TEXTFILL_TEXT_EFFECT; - maElementName = "textFill"; - break; - case NS_ooxml::LN_scene3d_scene3d: - maPropertyId = PROP_CHAR_SCENE3D_TEXT_EFFECT; - maElementName = "scene3d"; - break; - case NS_ooxml::LN_props3d_props3d: - maPropertyId = PROP_CHAR_PROPS3D_TEXT_EFFECT; - maElementName = "props3d"; - break; - case NS_ooxml::LN_ligatures_ligatures: - maPropertyId = PROP_CHAR_LIGATURES_TEXT_EFFECT; - maElementName = "ligatures"; - break; - case NS_ooxml::LN_numForm_numForm: - maPropertyId = PROP_CHAR_NUMFORM_TEXT_EFFECT; - maElementName = "numForm"; - break; - case NS_ooxml::LN_numSpacing_numSpacing: - maPropertyId = PROP_CHAR_NUMSPACING_TEXT_EFFECT; - maElementName = "numSpacing"; - break; - case NS_ooxml::LN_stylisticSets_stylisticSets: - maPropertyId = PROP_CHAR_STYLISTICSETS_TEXT_EFFECT; - maElementName = "stylisticSets"; - break; - case NS_ooxml::LN_cntxtAlts_cntxtAlts: - maPropertyId = PROP_CHAR_CNTXTALTS_TEXT_EFFECT; - maElementName = "cntxtAlts"; - break; - default: - break; - } -} - -TextEffectsHandler::TextEffectsHandler(sal_uInt32 aElementId) : - LoggedProperties("TextEffectsHandler") -{ - convertElementIdToPropertyId(aElementId); - mpGrabBagStack.reset(new oox::GrabBagStack(maElementName)); -} - -TextEffectsHandler::~TextEffectsHandler() -{ -} - - -void TextEffectsHandler::lcl_attribute(Id aName, Value& aValue) -{ - if (mpGrabBagStack->getCurrentName() != constAttributesSequenceName) - mpGrabBagStack->push(constAttributesSequenceName); - - switch(aName) - { - case NS_ooxml::LN_CT_Percentage_val: - case NS_ooxml::LN_CT_PositiveFixedPercentage_val: - case NS_ooxml::LN_CT_PositivePercentage_val: - mpGrabBagStack->addInt32("val", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Glow_rad: - mpGrabBagStack->addInt32("rad", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_SchemeColor_val: - { - OUString aString = getSchemeColorValTypeString(sal_Int32(aValue.getInt())); - mpGrabBagStack->addString("val", aString); - } - break; - case NS_ooxml::LN_CT_SRgbColor_val: - { - OUString aBuffer = OUString::number(aValue.getInt(), 16); - OUStringBuffer aString; - comphelper::string::padToLength(aString, 6 - aBuffer.getLength(), '0'); - aString.append(aBuffer.getStr()); - mpGrabBagStack->addString("val", aString.makeStringAndClear().toAsciiUpperCase()); - } - break; - case NS_ooxml::LN_CT_Shadow_blurRad: - case NS_ooxml::LN_CT_Reflection_blurRad: - mpGrabBagStack->addInt32("blurRad", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Reflection_stA: - mpGrabBagStack->addInt32("stA", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Reflection_stPos: - mpGrabBagStack->addInt32("stPos", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Reflection_endA: - mpGrabBagStack->addInt32("endA", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Reflection_endPos: - mpGrabBagStack->addInt32("endPos", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Shadow_dist: - case NS_ooxml::LN_CT_Reflection_dist: - mpGrabBagStack->addInt32("dist", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Shadow_dir: - case NS_ooxml::LN_CT_Reflection_dir: - mpGrabBagStack->addInt32("dir", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Reflection_fadeDir: - mpGrabBagStack->addInt32("fadeDir", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Shadow_sx: - case NS_ooxml::LN_CT_Reflection_sx: - mpGrabBagStack->addInt32("sx", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Shadow_sy: - case NS_ooxml::LN_CT_Reflection_sy: - mpGrabBagStack->addInt32("sy", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Shadow_kx: - case NS_ooxml::LN_CT_Reflection_kx: - mpGrabBagStack->addInt32("kx", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Shadow_ky: - case NS_ooxml::LN_CT_Reflection_ky: - mpGrabBagStack->addInt32("ky", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Shadow_algn: - case NS_ooxml::LN_CT_Reflection_algn: - { - uno::Any aAny = uno::makeAny(getRectAlignmentString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("algn", aAny); - } - break; - case NS_ooxml::LN_CT_TextOutlineEffect_w: - mpGrabBagStack->addInt32("w", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_TextOutlineEffect_cap: - { - uno::Any aAny = uno::makeAny(getLineCapString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("cap", aAny); - } - break; - case NS_ooxml::LN_CT_TextOutlineEffect_cmpd: - { - uno::Any aAny = uno::makeAny(getCompoundLineString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("cmpd", aAny); - } - break; - case NS_ooxml::LN_CT_TextOutlineEffect_algn: - { - uno::Any aAny = uno::makeAny(getPenAlignmentString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("algn", aAny); - } - break; - case NS_ooxml::LN_CT_GradientStop_pos: - mpGrabBagStack->addInt32("pos", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_LinearShadeProperties_ang: - mpGrabBagStack->addInt32("ang", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_LinearShadeProperties_scaled: - { - uno::Any aAny = uno::makeAny(getOnOffString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("scaled", aAny); - } - break; - case NS_ooxml::LN_CT_PathShadeProperties_path: - { - uno::Any aAny = uno::makeAny(getPathShadeTypeString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("path", aAny); - } - break; - case NS_ooxml::LN_CT_RelativeRect_l: - mpGrabBagStack->addInt32("l", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_RelativeRect_t: - mpGrabBagStack->addInt32("t", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_RelativeRect_r: - mpGrabBagStack->addInt32("r", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_RelativeRect_b: - mpGrabBagStack->addInt32("b", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_PresetLineDashProperties_val: - { - uno::Any aAny = uno::makeAny(getPresetLineDashValString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("val", aAny); - } - break; - case NS_ooxml::LN_CT_LineJoinMiterProperties_lim: - mpGrabBagStack->addInt32("lim", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Camera_prst: - { - uno::Any aAny = uno::makeAny(getPresetCameraTypeString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("prst", aAny); - } - break; - case NS_ooxml::LN_CT_LightRig_rig: - { - uno::Any aAny = uno::makeAny(getLightRigTypeString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("rig", aAny); - } - break; - case NS_ooxml::LN_CT_LightRig_dir: - { - uno::Any aAny = uno::makeAny(getLightRigDirectionString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("dir", aAny); - } - break; - case NS_ooxml::LN_CT_SphereCoords_lat: - mpGrabBagStack->addInt32("lat", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_SphereCoords_lon: - mpGrabBagStack->addInt32("lon", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_SphereCoords_rev: - mpGrabBagStack->addInt32("rev", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Props3D_extrusionH: - mpGrabBagStack->addInt32("extrusionH", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Props3D_contourW: - mpGrabBagStack->addInt32("contourW", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Props3D_prstMaterial: - { - uno::Any aAny = uno::makeAny(getPresetMaterialTypeString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("prstMaterial", aAny); - } - break; - case NS_ooxml::LN_CT_Bevel_w: - mpGrabBagStack->addInt32("w", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Bevel_h: - mpGrabBagStack->addInt32("h", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_Bevel_prst: - { - uno::Any aAny = uno::makeAny(getBevelPresetTypeString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("prst", aAny); - } - break; - case NS_ooxml::LN_CT_Ligatures_val: - { - uno::Any aAny = uno::makeAny(getLigaturesString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("val", aAny); - } - break; - case NS_ooxml::LN_CT_NumForm_val: - { - uno::Any aAny = uno::makeAny(getNumFormString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("val", aAny); - } - break; - case NS_ooxml::LN_CT_NumSpacing_val: - { - uno::Any aAny = uno::makeAny(getNumSpacingString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("val", aAny); - } - break; - case NS_ooxml::LN_CT_StyleSet_id: - mpGrabBagStack->addInt32("id", sal_Int32(aValue.getInt())); - break; - case NS_ooxml::LN_CT_StyleSet_val: - case NS_ooxml::LN_CT_OnOff_val: - { - uno::Any aAny = uno::makeAny(getOnOffString(sal_Int32(aValue.getInt()))); - mpGrabBagStack->appendElement("val", aAny); - } - break; - default: - break; - } -} - -void TextEffectsHandler::lcl_sprm(Sprm& rSprm) -{ - if (mpGrabBagStack->getCurrentName() == constAttributesSequenceName) - mpGrabBagStack->pop(); - - sal_uInt32 nSprmId = rSprm.getId(); - OUString aElementName = lclGetNameForElementId(nSprmId); - if(aElementName.isEmpty()) - { - // Element is unknown -> leave. - return; - } - - mpGrabBagStack->push(aElementName); - - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( !pProperties ) - return; - - pProperties->resolve( *this ); - - if (mpGrabBagStack->getCurrentName() == constAttributesSequenceName) - mpGrabBagStack->pop(); - - mpGrabBagStack->pop(); -} - -beans::PropertyValue TextEffectsHandler::getInteropGrabBag() -{ - beans::PropertyValue aReturn = mpGrabBagStack->getRootProperty(); - mpGrabBagStack.reset(); - return aReturn; -} - -sal_uInt8 TextEffectsHandler::GetTextFillSolidFillAlpha(const css::beans::PropertyValue& rValue) -{ - if (rValue.Name != "textFill") - { - return 0; - } - - uno::Sequence<beans::PropertyValue> aPropertyValues; - rValue.Value >>= aPropertyValues; - comphelper::SequenceAsHashMap aMap(aPropertyValues); - auto it = aMap.find("solidFill"); - if (it == aMap.end()) - { - return 0; - } - - comphelper::SequenceAsHashMap aSolidFillMap(it->second); - it = aSolidFillMap.find("srgbClr"); - if (it == aSolidFillMap.end()) - { - return 0; - } - - comphelper::SequenceAsHashMap aSrgbClrMap(it->second); - it = aSrgbClrMap.find("alpha"); - if (it == aSrgbClrMap.end()) - { - return 0; - } - - comphelper::SequenceAsHashMap aAlphaMap(it->second); - it = aAlphaMap.find("attributes"); - if (it == aAlphaMap.end()) - { - return 0; - } - - comphelper::SequenceAsHashMap aAttributesMap(it->second); - it = aAttributesMap.find("val"); - if (it == aAttributesMap.end()) - { - return 0; - } - sal_Int32 nVal = 0; - it->second >>= nVal; - return nVal / oox::drawingml::PER_PERCENT; -} - -} // namespace - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TextEffectsHandler.hxx b/writerfilter/source/dmapper/TextEffectsHandler.hxx deleted file mode 100644 index d7df31d85515..000000000000 --- a/writerfilter/source/dmapper/TextEffectsHandler.hxx +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TEXTEFFECTSHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TEXTEFFECTSHANDLER_HXX - -#include "LoggedResources.hxx" - -#include <com/sun/star/beans/PropertyValue.hpp> - -#include "PropertyIds.hxx" - -#include <oox/helper/grabbagstack.hxx> - -#include <memory> -#include <optional> - -namespace writerfilter::dmapper -{ -/// Class to process all text effects like glow, textOutline, ... -class TextEffectsHandler : public LoggedProperties -{ -private: - std::optional<PropertyIds> maPropertyId; - OUString maElementName; - std::unique_ptr<oox::GrabBagStack> mpGrabBagStack; - - void convertElementIdToPropertyId(sal_Int32 aElementId); - - // LoggedProperties - virtual void lcl_attribute(Id aName, Value& aValue) override; - virtual void lcl_sprm(Sprm& sprm) override; - -public: - explicit TextEffectsHandler(sal_uInt32 aElementId); - virtual ~TextEffectsHandler() override; - - const std::optional<PropertyIds>& getGrabBagPropertyId() const { return maPropertyId; } - - css::beans::PropertyValue getInteropGrabBag(); - - static OUString getSchemeColorValTypeString(sal_Int32 nType); - static OUString getRectAlignmentString(sal_Int32 nType); - static OUString getLineCapString(sal_Int32 nType); - static OUString getCompoundLineString(sal_Int32 nType); - static OUString getPenAlignmentString(sal_Int32 nType); - static OUString getOnOffString(sal_Int32 nType); - static OUString getPathShadeTypeString(sal_Int32 nType); - static OUString getPresetLineDashValString(sal_Int32 nType); - static OUString getPresetCameraTypeString(sal_Int32 nType); - static OUString getLightRigTypeString(sal_Int32 nType); - static OUString getLightRigDirectionString(sal_Int32 nType); - static OUString getBevelPresetTypeString(sal_Int32 nType); - static OUString getPresetMaterialTypeString(sal_Int32 nType); - static OUString getLigaturesString(sal_Int32 nType); - static OUString getNumFormString(sal_Int32 nType); - static OUString getNumSpacingString(sal_Int32 nType); - - static sal_uInt8 GetTextFillSolidFillAlpha(const css::beans::PropertyValue& rValue); -}; -} - -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TEXTEFFECTSHANDLER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ThemeTable.cxx b/writerfilter/source/dmapper/ThemeTable.cxx deleted file mode 100644 index ffa2262cdecc..000000000000 --- a/writerfilter/source/dmapper/ThemeTable.cxx +++ /dev/null @@ -1,564 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "TagLogger.hxx" -#include "ThemeTable.hxx" -#include <i18nlangtag/languagetag.hxx> -#include <ooxml/resourceids.hxx> - -#include <map> - -using namespace com::sun::star; - -namespace writerfilter::dmapper -{ - -struct ThemeTable_Impl -{ - ThemeTable_Impl() : - m_currentThemeFontId(0), - m_currentFontThemeEntry(), - m_supplementalFontId(0) - {} - std::map<sal_uInt32, std::map<sal_uInt32, OUString> > m_themeFontMap; - sal_uInt32 m_currentThemeFontId; - std::map<sal_uInt32, OUString> m_currentFontThemeEntry; - OUString m_supplementalFontName; - sal_uInt32 m_supplementalFontId; - OUString m_themeFontLangEastAsia; - OUString m_themeFontLangBidi; -}; - -ThemeTable::ThemeTable() -: LoggedProperties("ThemeTable") -, LoggedTable("ThemeTable") -, m_pImpl( new ThemeTable_Impl ) -{ - -} - -ThemeTable::~ThemeTable() -{ -} - -void ThemeTable::lcl_attribute(Id Name, Value & val) -{ - OUString sValue = val.getString(); - switch(Name) - { - case NS_ooxml::LN_CT_TextFont_typeface: - if (!sValue.isEmpty()) - m_pImpl->m_currentFontThemeEntry[m_pImpl->m_currentThemeFontId] = sValue; - break; - case NS_ooxml::LN_CT_SupplementalFont_script: - if (!sValue.isEmpty()) - { - if (sValue == m_pImpl->m_themeFontLangBidi) - m_pImpl->m_supplementalFontId = NS_ooxml::LN_CT_FontCollection_cs; - else if (sValue == m_pImpl->m_themeFontLangEastAsia) - m_pImpl->m_supplementalFontId = NS_ooxml::LN_CT_FontCollection_ea; - } - break; - case NS_ooxml::LN_CT_SupplementalFont_typeface: - if (!sValue.isEmpty()) - m_pImpl->m_supplementalFontName = sValue; - break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - } - } - if(m_pImpl->m_supplementalFontId && m_pImpl->m_supplementalFontName.getLength() > 0) - { - m_pImpl->m_currentFontThemeEntry[m_pImpl->m_supplementalFontId] = m_pImpl->m_supplementalFontName; - m_pImpl->m_supplementalFontName.clear(); - m_pImpl->m_supplementalFontId = 0; - } -} - -void ThemeTable::lcl_sprm(Sprm& rSprm) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("ThemeTable.sprm"); - TagLogger::getInstance().chars(rSprm.toString()); -#endif - - m_pImpl->m_supplementalFontName.clear(); - m_pImpl->m_supplementalFontId = 0; - - sal_uInt32 nSprmId = rSprm.getId(); - switch(nSprmId) - { - case NS_ooxml::LN_CT_BaseStyles_fontScheme: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - 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, OUString>(); - if( pProperties ) - 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 ) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_FontCollection_font: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties ) - pProperties->resolve(*this); - } - break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - } - } -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void ThemeTable::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("ThemeTable.entry"); -#endif - - ref->resolve(*this); - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -OUString ThemeTable::getStringForTheme(const Id id) -{ - switch (id) - { - case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: - return "majorEastAsia"; - case NS_ooxml::LN_Value_ST_Theme_majorBidi: - return "majorBidi"; - case NS_ooxml::LN_Value_ST_Theme_majorAscii: - return "majorAscii"; - case NS_ooxml::LN_Value_ST_Theme_majorHAnsi: - return "majorHAnsi"; - case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: - return "minorEastAsia"; - case NS_ooxml::LN_Value_ST_Theme_minorBidi: - return "minorBidi"; - case NS_ooxml::LN_Value_ST_Theme_minorAscii: - return "minorAscii"; - case NS_ooxml::LN_Value_ST_Theme_minorHAnsi: - return "minorHAnsi"; - } - return OUString(); -} -OUString ThemeTable::getFontNameForTheme(const Id id) const -{ - std::map<sal_uInt32, 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 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, OUString>::const_iterator Iter = tmpThemeFontMap.find(NS_ooxml::LN_CT_FontCollection_latin); - if (Iter != tmpThemeFontMap.end()) - return Iter->second; - return OUString(); - } - case NS_ooxml::LN_Value_ST_Theme_majorBidi: - case NS_ooxml::LN_Value_ST_Theme_minorBidi: - { - std::map<sal_uInt32, OUString>::const_iterator Iter = tmpThemeFontMap.find(NS_ooxml::LN_CT_FontCollection_cs); - if (Iter != tmpThemeFontMap.end()) - return Iter->second; - return OUString(); - } - case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: - case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: - { - std::map<sal_uInt32, OUString>::const_iterator Iter = tmpThemeFontMap.find(NS_ooxml::LN_CT_FontCollection_ea); - if (Iter != tmpThemeFontMap.end()) - return Iter->second; - return OUString(); - } - default: - return OUString(); - } -} - -void ThemeTable::setThemeFontLangProperties(const uno::Sequence<beans::PropertyValue>& aPropSeq) -{ - for (const auto& rProp : aPropSeq) - { - OUString sLocaleName; - rProp.Value >>= sLocaleName; - if (rProp.Name == "eastAsia") - m_pImpl->m_themeFontLangEastAsia = fromLocaleToScriptTag(sLocaleName); - if (rProp.Name == "bidi") - m_pImpl->m_themeFontLangBidi = fromLocaleToScriptTag(sLocaleName); - - } -} - -OUString ThemeTable::fromLocaleToScriptTag(const OUString& sLocale) -{ - return fromLCIDToScriptTag(LanguageTag::convertToLanguageType(sLocale)); -} - -OUString ThemeTable::fromLCIDToScriptTag(LanguageType lang) -{ - // conversion list from: - // http://blogs.msdn.com/b/officeinteroperability/archive/2013/04/22/office-open-xml-themes-schemes-and-fonts.aspx - switch (static_cast<sal_uInt16>(lang)) - { - case 0x429 : // lidFarsi - case 0x401 : // lidArabic - case 0x801 : // lidIraq - case 0xc01 : // lidEgyptian - case 0x1001 : // lidLibya - case 0x1401 : // lidAlgerian - case 0x1801 : // lidMorocco - case 0x1c01 : // lidTunisia - case 0x2001 : // lidOman - case 0x2401 : // lidYemen - case 0x2801 : // lidSyria - case 0x2c01 : // lidJordan - case 0x3001 : // lidLebanon - case 0x3401 : // lidKuwait - case 0x3801 : // lidUAE - case 0x3c01 : // lidBahrain - case 0x4001 : // lidQatar - case 0x420 : // lidUrdu - case 0x846 : // lidPunjabiPakistan - case 0x859 : // lidSindhiPakistan - case 0x45f : // lidTamazight - case 0x460 : // lidKashmiri - case 0x463 : // lidPashto - case 0x48c : // lidDari - return "Arab"; - case 0x42b : // lidArmenian - return "Armn"; - case 0x445 : // lidBengali - case 0x845 : // lidBengaliBangladesh - case 0x44d : // lidAssamese - case 0x458 : // lidManipuri - return "Beng"; - case 0x45d : // lidInuktitut - return "Cans"; - case 0x45c : // lidCherokee - return "Cher"; - case 0x419 : // lidRussian - case 0x402 : // lidBulgarian - case 0x281a : // lidSerbianCyrillic - case 0x422 : // lidUkranian - case 0x819 : // lidRussianMoldavia - case 0xc1a : // lidSerbianCyrillicSerbMont - case 0x1c1a : // lidSerbianBosniaHerzegovinaCyrillic - case 0x201a : // lidBosnianBosniaHerzegovinaCyrillic - case 0x301a : // lidSerbianMontenegroCyrillic - case 0x423 : // lidByelorussian - case 0x428 : // lidTajik - case 0x82c : // lidAzeriCyrillic - case 0x42f : // lidMacedonian - case 0x43f : // lidKazakh - case 0x440 : // lidKyrgyz - case 0x843 : // lidUzbekCyrillic - case 0x444 : // lidTatar - case 0x450 : // lidMongolian - case 0x46d : // lidBashkir - case 0x485 : // lidSakha - return "Cyrl"; - case 0x439 : // lidHindi - case 0x44e : // lidMarathi - case 0x44f : // lidSanskrit - case 0x457 : // lidKonkani - case 0x459 : // lidSindhi - case 0x860 : // lidKashmiriIndia - case 0x461 : // lidNepali - case 0x861 : // lidNepaliIndia - return "Deva"; - case 0x45e : // lidAmharic - case 0x473 : // lidTigrignaEthiopic - case 0x873 : // lidTigrignaEritrea - return "Ethi"; - case 0x437 : // lidGeorgian - return "Geor"; - case 0x408 : // lidGreek - return "Grek"; - case 0x447 : // lidGujarati - return "Gujr"; - case 0x446 : // lidPunjabi - return "Guru"; - case 0x412 : // lidKoreanExtWansung - return "Hang"; - case 0x804 : // lidChineseSimp - case 0x1004 : // lidSingapore - return "Hans"; - case 0x404 : // lidChineseTrad - case 0xc04 : // lidHongkong - case 0x1404 : // lidMacau - return "Hant"; - case 0x40d : // lidHebrew - case 0x43d : // lidYiddish - return "Hebr"; - case 0x411 : // lidJapanese - return "Jpan"; - case 0x453 : // lidKhmer - return "Khmr"; - case 0x44b : // lidKannada - return "Knda"; - case 0x454 : // lidLao - return "Laoo"; - case 0x409 : // lidAmerican - case 0xc09 : // lidAustralian - case 0x809 : // lidBritish - case 0x1009 : // lidEnglishCanadian - case 0x403 : // lidCatalan - case 0x406 : // lidDanish - case 0x413 : // lidDutch - case 0x813 : // lidDutchBelgian - case 0x479 : // lidPapiamentu - case 0x40b : // lidFinnish - case 0x40c : // lidFrench - case 0xc0c : // lidFrenchCanadian - case 0x407 : // lidGerman - case 0x807 : // lidSwissGerman - case 0xc07 : // lidAustrianGerman - case 0x1007 : // lidGermanLuxembourg - case 0x1407 : // lidGermanLiechtenstein - case 0x410 : // lidItalian - case 0x414 : // lidNorskBokmal - case 0x814 : // lidNorskNynorsk - case 0x416 : // lidPortBrazil - case 0x816 : // lidPortIberian - case 0x40a : // lidSpanish - case 0x41d : // lidSwedish - case 0x405 : // lidCzech - case 0x40e : // lidHungarian - case 0x415 : // lidPolish - case 0x41f : // lidTurkish - case 0x42d : // lidBasque - case 0x424 : // lidSlovenian - case 0x426 : // lidLatvian - case 0x427 : // lidLithuanian - case 0x418 : // lidRomanian - case 0x818 : // lidRomanianMoldavia - case 0x241a : // lidSerbianLatin - case 0x41a : // lidCroatian, lidCroat - case 0x491 : // lidGaelicScots - case 0x83c : // lidGaelicIrish - case 0x430 : // lidSutu - case 0x431 : // lidTsonga - case 0x432 : // lidTswana - case 0x433 : // lidVenda - case 0x434 : // lidXhosa - case 0x435 : // lidZulu - case 0x436 : // lidAfrikaans - case 0x425 : // lidEstonian - case 0x456 : // lidGalician - case 0x41b : // lidSlovak - case 0x1409 : // lidEnglishNewZealand - case 0x1809 : // lidEnglishIreland - case 0x1c09 : // lidEnglishSouthAfrica - case 0x2009 : // lidEnglishJamaica - case 0x2409 : // lidEnglishCaribbean - case 0x2809 : // lidEnglishBelize - case 0x2c09 : // lidEnglishTrinidad - case 0x3009 : // lidEnglishZimbabwe - case 0x3409 : // lidEnglishPhilippines - case 0x3809 : // lidEnglishIndonesia - case 0x3c09 : // lidEnglishHongKong - case 0x4009 : // lidEnglishIndia - case 0x4409 : // lidEnglishMalaysia - case 0x4809 : // lidEnglishSingapore - case 0x80a : // lidSpanishMexican, lidMexican - case 0xc0a : // lidSpanishModern - case 0x100a : // lidGuatemala - case 0x140a : // lidCostaRica - case 0x180a : // lidPanama - case 0x1c0a : // lidDominicanRepublic - case 0x200a : // lidSpanishSA, lidVenezuela - case 0x240a : // lidColombia - case 0x280a : // lidPeru - case 0x2c0a : // lidArgentina - case 0x300a : // lidEcuador - case 0x340a : // lidChile - case 0x380a : // lidUruguay - case 0x3c0a : // lidParguay - case 0x400a : // lidBolivia - case 0x440a : // lidElSalvador - case 0x480a : // lidHonduras - case 0x4c0a : // lidNicaragua - case 0x500a : // lidPuertoRico - case 0x540a : // lidSpanishUS - case 0x80c : // lidFrenchBelgian - case 0x100c : // lidFrenchSwiss - case 0x140c : // lidFrenchLuxembourg - case 0x180c : // lidFrenchMonaco - case 0x1c0c : // lidFrenchWestIndies - case 0x200c : // lidFrenchReunion - case 0x240c : // lidFrenchCongoDRC, lidFrenchZaire - case 0x280c : // lidFrenchSenegal - case 0x2c0c : // lidFrenchCameroon - case 0x300c : // lidFrenchCotedIvoire - case 0x340c : // lidFrenchMali - case 0x3c0c : // lidFrenchHaiti - case 0x380c : // lidFrenchMorocco - case 0x40f : // lidIcelandic - case 0x810 : // lidItalianSwiss - case 0x417 : // lidRhaetoRomanic, lidRomanic - case 0x81a : // lidSerbianLatinSerbMont, lidCroatSerbo - case 0x101a : // lidBosniaHerzegovina - case 0x141a : // lidBosnianBosniaHerzegovinaLatin - case 0x181a : // lidSerbianBosniaHerzegovinaLatin - case 0x2c1a : // lidSerbianMontenegroLatin - case 0x41c : // lidAlbanian - case 0x81d : // lidSwedishFinland - case 0x421 : // lidBahasa, lidIndonesian - case 0x42c : // lidAzeriLatin - case 0x42e : // lidSorbian - case 0x82e : // lidLowerSorbian - case 0x438 : // lidFaeroese - case 0x43a : // lidMaltese - case 0x43b : // lidSamiLappish - case 0x83b : // lidNorthSamiSwe - case 0xc3b : // lidNorthernSamiFi - case 0x103b : // lidLuleSamiNor - case 0x143b : // lidLuleSamiSwe - case 0x183b : // lidSouthSamiNor - case 0x1c3b : // lidSouthSamiSwe - case 0x203b : // lidSkoltSami - case 0x243b : // lidInariSami - case 0x43e : // lidMalaysian - case 0x83e : // lidMalayBrunei - case 0x441 : // lidSwahili - case 0x442 : // lidTurkmen - case 0x443 : // lidUzbekLatin - case 0x452 : // lidWelsh - case 0x85d : // lidInuktitutLatin - case 0x85f : // lidTamazightLatin - case 0x462 : // lidFrisian - case 0x464 : // lidFilipino - case 0x466 : // lidEdo - case 0x467 : // lidFulfulde - case 0x468 : // lidHausa - case 0x469 : // lidIbibio - case 0x46a : // lidYoruba - case 0x46b : // lidQuechuaBol - case 0x86b : // lidQuechuaEcu - case 0xc6b : // lidQuechuaPe - case 0x46c : // lidSesothoSaLeboa - case 0x46e : // lidLuxembourgish - case 0x46f : // lidGreenlandic - case 0x470 : // lidIgbo - case 0x471 : // lidKanuri - case 0x472 : // lidOromo - case 0x474 : // lidGuarani - case 0x475 : // lidHawaiian - case 0x476 : // lidLatin - case 0x477 : // lidSomali - case 0x47a : // lidMapudungun - case 0x47c : // lidMohawk - case 0x47e : // lidBreton - case 0x481 : // lidMaori - case 0x482 : // lidOccitan - case 0x483 : // lidCorsican - case 0x484 : // lidAlsatian - case 0x486 : // lidKiche - case 0x487 : // lidKinyarwanda - case 0x488 : // lidWolof - return "Latn"; - case 0x44c : // lidMalayalam - return "Mlym"; - case 0x850 : // lidMongolianMongo - return "Mong"; - case 0x455 : // lidBurmese - return "Mymr"; - case 0x448 : // lidOriya - return "Orya"; - case 0x45b : // lidSinhalese - return "Sinh"; - case 0x45a : // lidSyriac - return "Syrc"; - case 0x449 : // lidTamil - return "Taml"; - case 0x44a : // lidTelugu - return "Telu"; - case 0x465 : // lidMaldivian - return "Thaa"; - case 0x41e : // lidThai - return "Thai"; - case 0x451 : // lidTibetan - case 0x851 : // lidBhutanese - return "Tibt"; - case 0x480 : // lidUighur - return "Uigh"; - case 0x42a : // lidVietnamese - return "Viet"; - case 0x478 : // lidYi - return "Yiii"; - default: - return OUString(); - } -} - -} //namespace writerfilter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ThemeTable.hxx b/writerfilter/source/dmapper/ThemeTable.hxx deleted file mode 100644 index eed737020247..000000000000 --- a/writerfilter/source/dmapper/ThemeTable.hxx +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_THEMETABLE_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_THEMETABLE_HXX - -#include "LoggedResources.hxx" -#include <com/sun/star/beans/PropertyValue.hpp> -#include <i18nlangtag/lang.h> -#include <memory> - -namespace writerfilter::dmapper -{ -struct ThemeTable_Impl; - -class ThemeTable : public LoggedProperties, public LoggedTable -{ - std::unique_ptr<ThemeTable_Impl> m_pImpl; - -public: - ThemeTable(); - virtual ~ThemeTable() override; - - OUString getFontNameForTheme(const Id id) const; - static OUString getStringForTheme(const Id id); - void setThemeFontLangProperties(const css::uno::Sequence<css::beans::PropertyValue>& aPropSeq); - -private: - // Properties - virtual void lcl_attribute(Id Name, Value& val) override; - virtual void lcl_sprm(Sprm& sprm) override; - - // Table - virtual void lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) override; - - // Helper methods - static OUString fromLocaleToScriptTag(const OUString& sLocale); - static OUString fromLCIDToScriptTag(LanguageType lang); -}; -typedef tools::SvRef<ThemeTable> ThemeTablePtr; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TrackChangesHandler.cxx b/writerfilter/source/dmapper/TrackChangesHandler.cxx deleted file mode 100644 index 212f88261c4a..000000000000 --- a/writerfilter/source/dmapper/TrackChangesHandler.cxx +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -#include "TrackChangesHandler.hxx" -#include "PropertyMap.hxx" -#include "ConversionHelper.hxx" -#include <ooxml/resourceids.hxx> -#include <oox/token/tokens.hxx> -#include <osl/diagnose.h> - -namespace writerfilter::dmapper { - -using namespace ::com::sun::star; -using namespace oox; - - -TrackChangesHandler::TrackChangesHandler( sal_Int32 nToken ) : - LoggedProperties("TrackChangesHandler"), - m_pRedlineParams(new RedlineParams) -{ - m_pRedlineParams->m_nToken = nToken; -} - - -TrackChangesHandler::~TrackChangesHandler() -{ -} - - -void TrackChangesHandler::lcl_attribute(Id rName, Value & rVal) -{ - OUString sStringValue = rVal.getString(); - switch( rName ) - { - case NS_ooxml::LN_CT_TrackChange_author: - { - m_pRedlineParams->m_sAuthor = sStringValue; - } - break; - case NS_ooxml::LN_CT_TrackChange_date: - { - m_pRedlineParams->m_sDate = sStringValue; - } - break; - case NS_ooxml::LN_CT_Markup_id: - break; - default: - OSL_FAIL( "unknown attribute"); - } -} - -uno::Sequence<beans::PropertyValue> TrackChangesHandler::getRedlineProperties() const -{ - uno::Sequence< beans::PropertyValue > aRedlineProperties(3); - beans::PropertyValue* pRedlineProperties = aRedlineProperties.getArray(); - - OUString sType; - switch ( m_pRedlineParams->m_nToken & 0xffff ) - { - case XML_tableRowInsert: - sType = getPropertyName( PROP_TABLE_ROW_INSERT ); - break; - case XML_tableRowDelete: - sType = getPropertyName( PROP_TABLE_ROW_DELETE ); - break; - case XML_tableCellInsert: - sType = getPropertyName( PROP_TABLE_CELL_INSERT ); - break; - case XML_tableCellDelete: - sType = getPropertyName( PROP_TABLE_CELL_DELETE ); - break; - } - - pRedlineProperties[0].Name = getPropertyName( PROP_REDLINE_TYPE ); - pRedlineProperties[0].Value <<= sType; - pRedlineProperties[1].Name = getPropertyName( PROP_REDLINE_AUTHOR ); - pRedlineProperties[1].Value <<= m_pRedlineParams->m_sAuthor; - pRedlineProperties[2].Name = getPropertyName( PROP_REDLINE_DATE_TIME ); - pRedlineProperties[2].Value <<= ConversionHelper::ConvertDateStringToDateTime( m_pRedlineParams->m_sDate ); - //pRedlineProperties[3].Name = getPropertyName( PROP_REDLINE_REVERT_PROPERTIES ); - //pRedlineProperties[3].Value <<= pRedline->m_aRevertProperties; - - return aRedlineProperties; -} - -void TrackChangesHandler::lcl_sprm(Sprm &) {} - -} //namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/TrackChangesHandler.hxx b/writerfilter/source/dmapper/TrackChangesHandler.hxx deleted file mode 100644 index bd29fc4a20b2..000000000000 --- a/writerfilter/source/dmapper/TrackChangesHandler.hxx +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TRACKCHANGESHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_TRACKCHANGESHANDLER_HXX - -#include "LoggedResources.hxx" -#include <com/sun/star/beans/PropertyValue.hpp> -#include <dmapper/PropertyMap.hxx> - -namespace writerfilter::dmapper -{ -/** Handler for sprms that contain 'track changes' attributes - - Author - - Date - - ID - (This class is based on work done in 'MeasureHandler') - */ -class TrackChangesHandler : public LoggedProperties -{ - RedlineParamsPtr m_pRedlineParams; - - // Properties - virtual void lcl_attribute(Id Name, Value& val) override; - virtual void lcl_sprm(Sprm& sprm) override; - -public: - explicit TrackChangesHandler(sal_Int32 nToken); - virtual ~TrackChangesHandler() override; - - /// Compute the UNO properties for the track changes object based on the received tokens. - css::uno::Sequence<css::beans::PropertyValue> getRedlineProperties() const; -}; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/WrapPolygonHandler.cxx b/writerfilter/source/dmapper/WrapPolygonHandler.cxx deleted file mode 100644 index 3f693b45f389..000000000000 --- a/writerfilter/source/dmapper/WrapPolygonHandler.cxx +++ /dev/null @@ -1,217 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <com/sun/star/drawing/PointSequence.hpp> -#include <com/sun/star/text/GraphicCrop.hpp> -#include <comphelper/sequence.hxx> -#include <tools/UnitConversion.hxx> - -#include <ooxml/resourceids.hxx> - -#include "WrapPolygonHandler.hxx" -#include "util.hxx" - -#include <sal/log.hxx> - -namespace writerfilter { - -using namespace com::sun::star; - -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::Pointer_t WrapPolygon::move(const awt::Point & rPoint) const -{ - WrapPolygon::Pointer_t pResult(new WrapPolygon); - - Points_t::const_iterator aIt = begin(); - Points_t::const_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) const -{ - WrapPolygon::Pointer_t pResult(new WrapPolygon); - - Points_t::const_iterator aIt = begin(); - Points_t::const_iterator aItEnd = end(); - - while (aIt != aItEnd) - { - awt::Point aPoint((Fraction(tools::Long(aIt->X)) * rFractionX).operator long(), (Fraction(tools::Long(aIt->Y)) * rFractionY).operator long()); - pResult->addPoint(aPoint); - ++aIt; - } - - return pResult; -} - -WrapPolygon::Pointer_t WrapPolygon::correctWordWrapPolygon(const awt::Size & rSrcSize) const -{ - WrapPolygon::Pointer_t pResult; - - const tools::Long nWrap100Percent = 21600; - - Fraction aMove(nWrap100Percent, rSrcSize.Width); - aMove = aMove * Fraction(convertTwipToMm100(15), 1); - awt::Point aMovePoint(aMove.operator long(), 0); - pResult = move(aMovePoint); - - Fraction aScaleX = nWrap100Percent / (nWrap100Percent + aMove); - Fraction aScaleY = nWrap100Percent / (nWrap100Percent - aMove); - pResult = pResult->scale(aScaleX, aScaleY); - - Fraction aScaleSrcX(rSrcSize.Width, nWrap100Percent); - Fraction aScaleSrcY(rSrcSize.Height, nWrap100Percent); - pResult = pResult->scale(aScaleSrcX, aScaleSrcY); - - return pResult; -} - -WrapPolygon::Pointer_t WrapPolygon::correctWordWrapPolygonPixel(const awt::Size & rSrcSize) const -{ - WrapPolygon::Pointer_t pResult; - - /* - * https://msdn.microsoft.com/en-us/library/ee342530.aspx - * - * Image wrapping polygons in Microsoft Word use a fixed coordinate space - * that is 21600 units x 21600 units. Coordinate (0,0) is the upper left - * corner of the image and coordinate (21600,21600) is the lower right - * corner of the image. Microsoft Word scales the size of the wrapping - * polygon units to fit the size of the image. The 21600 value is a legacy - * artifact from the drawing layer of early versions of Microsoft Office. - */ - const tools::Long nWrap100Percent = 21600; - - Fraction aScaleX(rSrcSize.Width, nWrap100Percent); - Fraction aScaleY(rSrcSize.Height, nWrap100Percent); - pResult = scale(aScaleX, aScaleY); - - return pResult; -} - -WrapPolygon::Pointer_t WrapPolygon::correctCrop(const awt::Size& rGraphicSize, - const text::GraphicCrop& rGraphicCrop) const -{ - WrapPolygon::Pointer_t pResult; - - Fraction aScaleX(rGraphicSize.Width - rGraphicCrop.Left - rGraphicCrop.Right, - rGraphicSize.Width); - Fraction aScaleY(rGraphicSize.Height - rGraphicCrop.Top - rGraphicCrop.Bottom, - rGraphicSize.Height); - pResult = scale(aScaleX, aScaleY); - - awt::Point aMove(rGraphicCrop.Left, rGraphicCrop.Top); - pResult = pResult->move(aMove); - - return pResult; -} - -drawing::PointSequenceSequence WrapPolygon::getPointSequenceSequence() const -{ - drawing::PointSequenceSequence aPolyPolygon(1); - drawing::PointSequence aPolygon = comphelper::containerToSequence(mPoints); - aPolyPolygon[0] = aPolygon; - return aPolyPolygon; -} - -WrapPolygonHandler::WrapPolygonHandler() - : LoggedProperties("WrapPolygonHandler") - , mpPolygon(new WrapPolygon) - , mnX(0) - , mnY(0) -{ -} - -WrapPolygonHandler::~WrapPolygonHandler() -{ -} - -void WrapPolygonHandler::lcl_attribute(Id Name, Value & val) -{ - sal_Int32 nIntValue = val.getInt(); - - switch(Name) - { - case NS_ooxml::LN_CT_Point2D_x: - mnX = nIntValue; - break; - case NS_ooxml::LN_CT_Point2D_y: - mnY = nIntValue; - break; - default: - SAL_WARN("writerfilter", "WrapPolygonHandler::lcl_attribute: unhandled token: " << Name); - break; - } -} - -void WrapPolygonHandler::lcl_sprm(Sprm & _sprm) -{ - switch (_sprm.getId()) - { - case NS_ooxml::LN_CT_WrapPath_lineTo: - case NS_ooxml::LN_CT_WrapPath_start: - { - resolveSprmProps(*this, _sprm); - - awt::Point aPoint(mnX, mnY); - mpPolygon->addPoint(aPoint); - } - break; - default: - SAL_WARN("writerfilter", "WrapPolygonHandler::lcl_sprm: unhandled token: " << _sprm.getId()); - break; - } -} - - -}} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/WrapPolygonHandler.hxx b/writerfilter/source/dmapper/WrapPolygonHandler.hxx deleted file mode 100644 index 2267ce8f35e8..000000000000 --- a/writerfilter/source/dmapper/WrapPolygonHandler.hxx +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_WRAPPOLYGONHANDLER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_WRAPPOLYGONHANDLER_HXX - -#include <com/sun/star/drawing/PointSequenceSequence.hpp> -#include "LoggedResources.hxx" -#include <tools/fract.hxx> -#include <vector> - -namespace com::sun::star::text -{ -struct GraphicCrop; -} - -namespace writerfilter::dmapper -{ -/// Handles <wp:wrapPolygon> from DOCX and the pWrapPolygonVertices shape property from RTF. -class WrapPolygon final : public virtual SvRefBase -{ -public: - typedef std::vector<css::awt::Point> Points_t; - typedef ::tools::SvRef<WrapPolygon> Pointer_t; - -private: - Points_t mPoints; - -public: - WrapPolygon(); - ~WrapPolygon() override; - - void addPoint(const css::awt::Point& rPoint); - - Points_t::const_iterator begin() const; - Points_t::const_iterator end() const; - - WrapPolygon::Pointer_t move(const css::awt::Point& rMove) const; - WrapPolygon::Pointer_t scale(const Fraction& rFractionX, const Fraction& rFractionY) const; - WrapPolygon::Pointer_t correctWordWrapPolygon(const css::awt::Size& rSrcSize) const; - WrapPolygon::Pointer_t correctWordWrapPolygonPixel(const css::awt::Size& rSrcSize) const; - WrapPolygon::Pointer_t correctCrop(const css::awt::Size& rGraphicSize, - const css::text::GraphicCrop& rGraphicCrop) const; - css::drawing::PointSequenceSequence getPointSequenceSequence() const; -}; - -class WrapPolygonHandler : public LoggedProperties -{ -public: - WrapPolygonHandler(); - virtual ~WrapPolygonHandler() override; - - const WrapPolygon::Pointer_t& getPolygon() const { return mpPolygon; } - -private: - WrapPolygon::Pointer_t mpPolygon; - - sal_Int32 mnX; - sal_Int32 mnY; - - // Properties - virtual void lcl_attribute(Id Name, Value& val) override; - virtual void lcl_sprm(Sprm& sprm) override; -}; -} - -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_WRAPPOLYGONHANDLER_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/domainmapperfactory.cxx b/writerfilter/source/dmapper/domainmapperfactory.cxx deleted file mode 100644 index 1e52cfc36fcc..000000000000 --- a/writerfilter/source/dmapper/domainmapperfactory.cxx +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "DomainMapper.hxx" -#include "TagLogger.hxx" -#include <unotools/mediadescriptor.hxx> - -namespace writerfilter::dmapper -{ -Stream::Pointer_t -DomainMapperFactory::createMapper(css::uno::Reference<css::uno::XComponentContext> const& xContext, - css::uno::Reference<css::io::XInputStream> const& xInputStream, - css::uno::Reference<css::lang::XComponent> const& xModel, - bool bRepairStorage, SourceDocumentType eDocumentType, - utl::MediaDescriptor const& rMediaDesc) -{ -#ifdef DBG_UTIL - OUString sURL - = rMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_URL(), OUString()); - ::std::string sURLc = OUStringToOString(sURL, RTL_TEXTENCODING_ASCII_US).getStr(); - - if (getenv("SW_DEBUG_WRITERFILTER")) - TagLogger::getInstance().setFileName(sURLc); - TagLogger::getInstance().startDocument(); -#endif - - return Stream::Pointer_t(new DomainMapper(xContext, xInputStream, xModel, bRepairStorage, - eDocumentType, rMediaDesc)); -} - -} // namespace writerfilter::dmapper - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/util.cxx b/writerfilter/source/dmapper/util.cxx deleted file mode 100644 index d5b23a3d46bc..000000000000 --- a/writerfilter/source/dmapper/util.cxx +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <string> -#include "util.hxx" - -namespace writerfilter::dmapper -{ -using namespace com::sun::star; - -std::string XTextRangeToString(uno::Reference<text::XTextRange> const& textRange) -{ - std::string result; - -#ifdef DBG_UTIL - if (textRange) - { - OUString aOUStr; - - try - { - aOUStr = textRange->getString(); - } - catch (const uno::Exception& rException) - { - result += "(exception: "; - result += rException.Message.toUtf8().getStr(); - result += ")"; - } - - OString aOStr(aOUStr.getStr(), aOUStr.getLength(), RTL_TEXTENCODING_ASCII_US); - - result = aOStr.getStr(); - } - else - { - result = "(nil)"; - } -#else - (void)textRange; -#endif - - return result; -} - -void resolveSprmProps(Properties& rHandler, Sprm& rSprm) -{ - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties) - pProperties->resolve(rHandler); -} -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/util.hxx b/writerfilter/source/dmapper/util.hxx deleted file mode 100644 index 5a94a5d0932d..000000000000 --- a/writerfilter/source/dmapper/util.hxx +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_DMAPPER_UTIL_HXX -#define INCLUDED_WRITERFILTER_SOURCE_DMAPPER_UTIL_HXX - -#include <com/sun/star/text/XTextRange.hpp> -#include <string> -#include <dmapper/resourcemodel.hxx> - -namespace writerfilter::dmapper -{ -std::string XTextRangeToString(css::uno::Reference<css::text::XTextRange> const& textRange); -void resolveSprmProps(Properties& rHandler, Sprm& rSprm); -} - -#endif // INCLUDED_WRITERFILTER_SOURCE_DMAPPER_UTIL_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |