Hello, could somebody more knowledgeable of Writer internals please review this?
While working on support for stacking order in the .docx filter, I found out that setting z-order for an image using UNO and later trying to retrieve the value fails. The attached sw.patch fixes that for me, and I checked that .odt export/import (which uses it too) still works. But I have no idea what the difference actually is, besides making reading use the same value like writing. -- Lubos Lunak l.lu...@suse.cz
diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx index f8d2c90..91c8d89 100644 --- a/sw/source/core/unocore/unoframe.cxx +++ b/sw/source/core/unocore/unoframe.cxx @@ -1598,7 +1598,7 @@ uno::Any SwXFrame::getPropertyValue(const OUString& rPropertyName) } else if(FN_UNO_Z_ORDER == pEntry->nWID) { - const SdrObject* pObj = pFmt->FindRealSdrObject(); + const SdrObject* pObj = pFmt->FindSdrObject(); if( pObj ) { aAny <<= (sal_Int32)pObj->GetOrdNum();
diff --git a/writerfilter/inc/dmapper/DomainMapper.hxx b/writerfilter/inc/dmapper/DomainMapper.hxx index 4713763..95ddc6f 100644 --- a/writerfilter/inc/dmapper/DomainMapper.hxx +++ b/writerfilter/inc/dmapper/DomainMapper.hxx @@ -36,6 +36,7 @@ #include <map> #include <vector> +#include <boost/scoped_ptr.hpp> namespace com{ namespace sun {namespace star{ namespace beans{ @@ -65,6 +66,7 @@ class PropertyMap; class DomainMapper_Impl; class ListsManager; class StyleSheetTable; +class GraphicZOrderHelper; // different context types require different sprm handling (e.g. names) enum SprmType @@ -113,6 +115,7 @@ public: ::rtl::OUString getOrCreateCharStyle( PropertyValueVector_t& rCharProperties ); boost::shared_ptr< StyleSheetTable > GetStyleSheetTable( ); + GraphicZOrderHelper* graphicZOrderHelper(); private: // Stream @@ -150,6 +153,7 @@ private: sal_Unicode getFillCharFromValue(const sal_Int32 nIntValue); sal_Int32 mnBackgroundColor; bool mbIsHighlightSet; + boost::scoped_ptr< GraphicZOrderHelper > zOrderHelper; }; } // namespace dmapper diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 54fe0a0..dcc20cf 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -71,6 +71,7 @@ #include <tools/color.hxx> #include <CellColorHandler.hxx> #include <SectionColumnHandler.hxx> +#include <GraphicHelpers.hxx> using namespace ::com::sun::star; using namespace ::rtl; @@ -3755,6 +3756,13 @@ StyleSheetTablePtr DomainMapper::GetStyleSheetTable( ) return m_pImpl->GetStyleSheetTable( ); } +GraphicZOrderHelper* DomainMapper::graphicZOrderHelper() +{ + if( zOrderHelper.get() == NULL ) + zOrderHelper.reset( new GraphicZOrderHelper ); + return zOrderHelper.get(); +} + } //namespace dmapper } //namespace writerfilter diff --git a/writerfilter/source/dmapper/GraphicHelpers.cxx b/writerfilter/source/dmapper/GraphicHelpers.cxx index cdafb8e..819dc6f 100644 --- a/writerfilter/source/dmapper/GraphicHelpers.cxx +++ b/writerfilter/source/dmapper/GraphicHelpers.cxx @@ -216,6 +216,47 @@ sal_Int32 WrapHandler::getWrapMode( ) return nMode; } + +void GraphicZOrderHelper::addItem( uno::Reference< beans::XPropertySet > props, sal_Int32 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 ) +{ + Items::const_iterator it = items.begin(); + while( it != items.end()) + { + // std::map is iterated sorted by key + if( it->first > relativeHeight ) + break; // this is the first one higher, we belong right before it + else + ++it; + } + if( it == items.end()) // we're topmost + { + if( items.empty()) + return 0; + sal_Int32 itemZOrder; + --it; + if( it->second->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier() + .GetName( PROP_Z_ORDER )) >>= itemZOrder ) + return itemZOrder + 1; // after the topmost + } + else + { + sal_Int32 itemZOrder; + if( it->second->getPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier() + .GetName( PROP_Z_ORDER )) >>= itemZOrder ) + return itemZOrder; // before the item + } + SAL_WARN( "writerfilter", "findZOrder() didn't find item z-order" ); + return 0; // this should not(?) happen +} + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/GraphicHelpers.hxx b/writerfilter/source/dmapper/GraphicHelpers.hxx index 80ddc93..f87b6f9 100644 --- a/writerfilter/source/dmapper/GraphicHelpers.hxx +++ b/writerfilter/source/dmapper/GraphicHelpers.hxx @@ -51,6 +51,16 @@ public: }; typedef boost::shared_ptr<WrapHandler> WrapHandlerPtr; +class WRITERFILTER_DLLPRIVATE GraphicZOrderHelper +{ +public: + void addItem( uno::Reference< beans::XPropertySet > props, sal_Int32 relativeHeight ); + sal_Int32 findZOrder( sal_Int32 relativeHeight ); +private: + typedef std::map< sal_Int32, uno::Reference< beans::XPropertySet > > Items; + Items items; +}; + } } #endif diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx index e74951b..5a0aded 100644 --- a/writerfilter/source/dmapper/GraphicImport.cxx +++ b/writerfilter/source/dmapper/GraphicImport.cxx @@ -210,6 +210,7 @@ public: sal_Int32 nBottomCrop; bool bUseSimplePos; + sal_Int32 zOrder; sal_Int16 nHoriOrient; sal_Int16 nHoriRelation; @@ -276,6 +277,7 @@ public: ,nRightCrop (0) ,nBottomCrop(0) ,bUseSimplePos(false) + ,zOrder(-1) ,nHoriOrient( text::HoriOrientation::NONE ) ,nHoriRelation( text::RelOrientation::FRAME ) ,bPageToggle( false ) @@ -835,7 +837,7 @@ void GraphicImport::lcl_attribute(Id nName, Value & val) m_pImpl->bUseSimplePos = nIntValue > 0; break; case NS_ooxml::LN_CT_Anchor_relativeHeight: // 90988; - //z-order + m_pImpl->zOrder = nIntValue; break; case NS_ooxml::LN_CT_Anchor_behindDoc: // 90989; - in background if( nIntValue > 0 ) @@ -1454,6 +1456,14 @@ uno::Reference< text::XTextContent > GraphicImport::createGraphicObject( const b uno::makeAny( m_pImpl->bVertFlip )); xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_BACK_COLOR ), uno::makeAny( m_pImpl->nFillColor )); + + if( m_pImpl->zOrder >= 0 ) + { + GraphicZOrderHelper* zOrderHelper = m_pImpl->rDomainMapper.graphicZOrderHelper(); + xGraphicObjectProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_Z_ORDER ), + uno::makeAny( zOrderHelper->findZOrder( m_pImpl->zOrder ))); + zOrderHelper->addItem( xGraphicObjectProperties, m_pImpl->zOrder ); + } //there seems to be no way to detect the original size via _real_ API uno::Reference< beans::XPropertySet > xGraphicProperties( xGraphic, uno::UNO_QUERY_THROW ); diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx index 64f562a..cc7bba7 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -322,6 +322,7 @@ const rtl::OUString& PropertyNameSupplier::GetName( PropertyIds eId ) const case PROP_FRM_DIRECTION: sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FRMDirection")); break; case PROP_EMBEDDED_OBJECT : sName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EmbeddedObject")); break; case PROP_IS_VISIBLE: sName = "IsVisible"; break; + case PROP_Z_ORDER: sName = "ZOrder"; break; } ::std::pair<PropertyNameMap_t::iterator,bool> aInsertIt = m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, sName )); diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx index c6e5369..0c6c25b 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -295,6 +295,7 @@ enum PropertyIds /*253*/ ,PROP_FRM_DIRECTION ,PROP_EMBEDDED_OBJECT ,PROP_PARA_CONTEXT_MARGIN + ,PROP_Z_ORDER }; struct PropertyNameSupplier_Impl; class PropertyNameSupplier
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice