diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2014-08-17 21:35:48 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-08-22 07:56:40 -0500 |
commit | 3680f2d74964c38f153fd26a09d773a0592a1aa6 (patch) | |
tree | e31e30ef7a9c2090a4d2d31d5451206d69fb3b01 /writerfilter | |
parent | 0a9fb15268c938cc4e3cc69c222cec1849064679 (diff) |
fix reading even/odd page breaks from .docx (bnc#519228)
We map Word's even/odd page breaks to Writer's left/right page styles. And we cannot
just set any page style to be left/right, because that could set e.g. the default
page style as such, which would make all normal pages that way. So instead we need
to make a copy of the relevant page style, as the original page style as its follow,
copy all the properties and headers/footers, and use this copy to get the page break.
(cherry picked from commit b32881b6723072c8d1a652ea147d12e75766d504)
Conflicts:
sw/qa/extras/ooxmlimport/ooxmlimport.cxx
Change-Id: Id0d2568de91ac2de4afb0ba3a6eedd9cec46f878
Reviewed-on: https://gerrit.libreoffice.org/11025
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'writerfilter')
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.cxx | 180 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.hxx | 2 |
2 files changed, 107 insertions, 75 deletions
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index 0b47cad74416..2512a9d5b0ea 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -22,6 +22,7 @@ #include <ConversionHelper.hxx> #include <i18nutil/paper.hxx> #include <rtl/ustring.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> @@ -31,6 +32,7 @@ #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/XStyle.hpp> #include <com/sun/star/table/ShadowFormat.hpp> #include <com/sun/star/text/RelOrientation.hpp> #include <com/sun/star/text/WritingMode.hpp> @@ -713,6 +715,74 @@ bool SectionPropertyMap::HasFooter(bool bFirstPage) const #define MIN_HEAD_FOOT_HEIGHT 100 //minimum header/footer height +void SectionPropertyMap::CopyHeaderFooter( uno::Reference< beans::XPropertySet > xPrevStyle, + uno::Reference< beans::XPropertySet > xStyle ) +{ + PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); + + try { + // Loop over the Header and Footer properties to copy them + static const PropertyIds aProperties[] = + { + PROP_HEADER_TEXT, + PROP_FOOTER_TEXT, + }; + + bool bHasPrevHeader = false; + bool bHasHeader = false; + + OUString sHeaderIsOn = rPropNameSupplier.GetName( PROP_HEADER_IS_ON ); + if (xPrevStyle.is()) + xPrevStyle->getPropertyValue( sHeaderIsOn ) >>= bHasPrevHeader; + if (xStyle.is()) + xStyle->getPropertyValue( sHeaderIsOn ) >>= bHasHeader; + bool bCopyHeader = bHasPrevHeader && !bHasHeader; + + if ( bCopyHeader ) + xStyle->setPropertyValue( sHeaderIsOn, uno::makeAny( sal_True ) ); + + bool bHasPrevFooter = false; + bool bHasFooter = false; + + OUString sFooterIsOn = rPropNameSupplier.GetName( PROP_FOOTER_IS_ON ); + if (xPrevStyle.is()) + xPrevStyle->getPropertyValue( sFooterIsOn ) >>= bHasPrevFooter; + if (xStyle.is()) + xStyle->getPropertyValue( sFooterIsOn ) >>= bHasFooter; + bool bCopyFooter = bHasPrevFooter && !bHasFooter; + + if ( bCopyFooter && xStyle.is() ) + xStyle->setPropertyValue( sFooterIsOn, uno::makeAny( sal_True ) ); + + // Copying the text properties + for ( int i = 0, nNbProps = 2; i < nNbProps; i++ ) + { + bool bIsHeader = ( i < nNbProps / 2 ); + PropertyIds aPropId = aProperties[i]; + OUString sName = rPropNameSupplier.GetName( aPropId ); + + if ( ( bIsHeader && bCopyHeader ) || ( !bIsHeader && bCopyFooter ) ) + { + SAL_INFO("writerfilter", "Copying " << sName); + // TODO has to be copied + 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& e ) + { + SAL_INFO("writerfilter", "An exception occurred in SectionPropertyMap::CopyHeaderFooter( ) - " << e.Message); + } +} + void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl ) { SAL_INFO("writerfilter", "START>>> SectionPropertyMap::CopyLastHeaderFooter()"); @@ -727,70 +797,7 @@ void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Imp rDM_Impl.GetPageStyles(), rDM_Impl.GetTextFactory(), bFirstPage ); - - PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier(); - - try { - // Loop over the Header and Footer properties to copy them - static const PropertyIds aProperties[] = - { - PROP_HEADER_TEXT, - PROP_FOOTER_TEXT, - }; - - bool bHasPrevHeader = false; - bool bHasHeader = false; - - OUString sHeaderIsOn = rPropNameSupplier.GetName( PROP_HEADER_IS_ON ); - if (xPrevStyle.is()) - xPrevStyle->getPropertyValue( sHeaderIsOn ) >>= bHasPrevHeader; - if (xStyle.is()) - xStyle->getPropertyValue( sHeaderIsOn ) >>= bHasHeader; - bool bCopyHeader = bHasPrevHeader && !bHasHeader; - - if ( bCopyHeader ) - xStyle->setPropertyValue( sHeaderIsOn, uno::makeAny( sal_True ) ); - - bool bHasPrevFooter = false; - bool bHasFooter = false; - - OUString sFooterIsOn = rPropNameSupplier.GetName( PROP_FOOTER_IS_ON ); - if (xPrevStyle.is()) - xPrevStyle->getPropertyValue( sFooterIsOn ) >>= bHasPrevFooter; - if (xStyle.is()) - xStyle->getPropertyValue( sFooterIsOn ) >>= bHasFooter; - bool bCopyFooter = bHasPrevFooter && !bHasFooter; - - if ( bCopyFooter && xStyle.is() ) - xStyle->setPropertyValue( sFooterIsOn, uno::makeAny( sal_True ) ); - - // Copying the text properties - for ( int i = 0, nNbProps = 2; i < nNbProps; i++ ) - { - bool bIsHeader = ( i < nNbProps / 2 ); - PropertyIds aPropId = aProperties[i]; - OUString sName = rPropNameSupplier.GetName( aPropId ); - - if ( ( bIsHeader && bCopyHeader ) || ( !bIsHeader && bCopyFooter ) ) - { - SAL_INFO("writerfilter", "Copying " << sName); - // TODO has to be copied - 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& e ) - { - SAL_INFO("writerfilter", "An exception occurred in SectionPropertyMap::CopyLastHeaderFooter( ) - " << e.Message); - } + CopyHeaderFooter( xPrevStyle, xStyle ); } SAL_INFO("writerfilter", "END>>> SectionPropertyMap::CopyLastHeaderFooter()"); } @@ -963,7 +970,8 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) } } - //depending on the break type no page styles should be created + // break type : 0 - No break 1 - New Column 2 - New page 3 - Even page 4 - odd page + // depending on the break type no page styles should be created // If the section type is missing, but we have columns, then this should be // handled as a continuous section break. if(m_nBreakType == 0 || (m_nBreakType == -1 && m_nColumnCount > 0)) @@ -1138,22 +1146,44 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) { //now apply this break at the first paragraph of this section uno::Reference<beans::XPropertySet> xRangeProperties(lcl_GetRangeProperties(m_bIsFirstSection, rDM_Impl, m_xStartingRange)); - /* break type - 0 - No break 1 - New Column 2 - New page 3 - Even page 4 - odd page */ + + // 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 == 3 || m_nBreakType == 4) + { + OUString* pageStyle = m_bTitlePage ? &m_sFirstPageStyleName : &m_sFollowPageStyleName; + OUString evenOddStyleName = lcl_FindUnusedPageStyleName(rDM_Impl.GetPageStyles()->getElementNames()); + 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()); + uno::Sequence< beans::Property > propertyList( pagePropertiesInfo->getProperties()); + for( int i = 0; i < propertyList.getLength(); ++i ) + { + if(( propertyList[i].Attributes & beans::PropertyAttribute::READONLY ) == 0 ) + evenOddStyle->setPropertyValue( propertyList[ i ].Name, pageProperties->getPropertyValue( propertyList[ i ].Name )); + } + evenOddStyle->setPropertyValue("FollowStyle", uno::makeAny(*pageStyle)); + rDM_Impl.GetPageStyles()->insertByName( evenOddStyleName, uno::makeAny( evenOddStyle ) ); + evenOddStyle->setPropertyValue("HeaderIsOn", uno::makeAny(sal_False)); + evenOddStyle->setPropertyValue("FooterIsOn", uno::makeAny(sal_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 == 3) + evenOddStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_PAGE_STYLE_LAYOUT), uno::makeAny(style::PageStyleLayout_LEFT)); + else if (m_nBreakType == 4) + evenOddStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_PAGE_STYLE_LAYOUT), uno::makeAny(style::PageStyleLayout_RIGHT)); + } + if (xRangeProperties.is() && rDM_Impl.IsNewDoc()) xRangeProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_PAGE_DESC_NAME ), uno::makeAny( m_bTitlePage ? m_sFirstPageStyleName : m_sFollowPageStyleName )); - // handle page breaks with odd/even page numbering - style::PageStyleLayout nPageStyleLayout(style::PageStyleLayout_ALL); - if (m_nBreakType == 3) - nPageStyleLayout = style::PageStyleLayout_LEFT; - else if (m_nBreakType == 4) - nPageStyleLayout = style::PageStyleLayout_RIGHT; - if (nPageStyleLayout) - xFollowPageStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_PAGE_STYLE_LAYOUT), uno::makeAny(nPageStyleLayout)); if(m_bPageNoRestart || m_nPageNumber >= 0) { sal_Int16 nPageNumber = m_nPageNumber >= 0 ? static_cast< sal_Int16 >(m_nPageNumber) : 1; diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index ccfb897c1bf1..5c12df27ff87 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -205,6 +205,8 @@ class SectionPropertyMap : public PropertyMap ::com::sun::star::uno::Reference< com::sun::star::text::XTextColumns > ApplyColumnProperties( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xFollowPageStyle ); void CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl ); + void CopyHeaderFooter( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPrevStyle, + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xStyle ); void PrepareHeaderFooterProperties( bool bFirstPage ); bool HasHeader( bool bFirstPage ) const; bool HasFooter( bool bFirstPage ) const; |