From 3d9ebded1358395ed81db7a63629b046aec2aeac Mon Sep 17 00:00:00 2001 From: Cédric Bosdonnat Date: Wed, 6 Oct 2010 23:34:50 +0200 Subject: Misc improvements for docx VML import --- oox/inc/oox/helper/helper.hxx | 4 +- oox/inc/oox/vml/vmlshape.hxx | 2 + oox/inc/oox/vml/vmlshapecontainer.hxx | 2 + oox/inc/oox/vml/vmlshapecontext.hxx | 17 +++++ oox/source/shape/ShapeContextHandler.cxx | 3 + oox/source/vml/vmldrawingfragment.cxx | 2 +- oox/source/vml/vmlshape.cxx | 83 ++++++++++++++++++++-- oox/source/vml/vmlshapecontext.cxx | 23 ++++++ writerfilter/inc/ooxml/OOXMLDocument.hxx | 3 + writerfilter/source/dmapper/OLEHandler.cxx | 2 +- writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 10 +++ writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 3 + .../source/ooxml/OOXMLFastContextHandler.cxx | 20 ++++-- 13 files changed, 158 insertions(+), 16 deletions(-) diff --git a/oox/inc/oox/helper/helper.hxx b/oox/inc/oox/helper/helper.hxx index c68fe9ce83f8..7943f7357824 100644 --- a/oox/inc/oox/helper/helper.hxx +++ b/oox/inc/oox/helper/helper.hxx @@ -94,8 +94,8 @@ const sal_uInt8 WINDOWS_CHARSET_OEM = 255; // ---------------------------------------------------------------------------- const sal_Int32 API_RGB_TRANSPARENT = -1; /// Transparent color for API calls. -const sal_Int32 API_RGB_BLACK = 0x00000; /// Black color for API calls. -const sal_Int32 API_RGB_WHITE = 0xFFFFF; /// White color for API calls. +const sal_Int32 API_RGB_BLACK = 0x000000; /// Black color for API calls. +const sal_Int32 API_RGB_WHITE = 0xFFFFFF; /// White color for API calls. const sal_Int16 API_LINE_NONE = 0; const sal_Int16 API_LINE_HAIR = 2; diff --git a/oox/inc/oox/vml/vmlshape.hxx b/oox/inc/oox/vml/vmlshape.hxx index 7c770df28477..1b5fc99f3eda 100644 --- a/oox/inc/oox/vml/vmlshape.hxx +++ b/oox/inc/oox/vml/vmlshape.hxx @@ -209,6 +209,8 @@ class SimpleShape : public ShapeBase public: explicit SimpleShape( Drawing& rDrawing, const ::rtl::OUString& rService ); + void setService( rtl::OUString aService ) { maService = aService; } + protected: /** Creates the corresponding XShape and inserts it into the passed container. */ virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > diff --git a/oox/inc/oox/vml/vmlshapecontainer.hxx b/oox/inc/oox/vml/vmlshapecontainer.hxx index a878fda2b74c..e1c141cd4cc6 100644 --- a/oox/inc/oox/vml/vmlshapecontainer.hxx +++ b/oox/inc/oox/vml/vmlshapecontainer.hxx @@ -95,6 +95,8 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor = 0 ) const; + inline void clearShapes( ) { maShapes.clear( ); } + private: typedef RefVector< ShapeType > ShapeTypeVector; typedef RefVector< ShapeBase > ShapeVector; diff --git a/oox/inc/oox/vml/vmlshapecontext.hxx b/oox/inc/oox/vml/vmlshapecontext.hxx index bda7d90f34e2..aaa3fed61e82 100644 --- a/oox/inc/oox/vml/vmlshapecontext.hxx +++ b/oox/inc/oox/vml/vmlshapecontext.hxx @@ -40,6 +40,7 @@ struct ShapeClientData; struct ShapeModel; class ShapeBase; class GroupShape; +class RectangleShape; class ShapeContainer; @@ -118,6 +119,9 @@ private: /** Processes the 'points' attribute. */ void setPoints( const ::rtl::OUString& rPoints ); +protected: + ShapeBase& mrShape; + private: ShapeModel& mrShapeModel; }; @@ -141,6 +145,19 @@ private: // ============================================================================ +class RectangleShapeContext : public ShapeContext +{ +public: + explicit RectangleShapeContext( + ::oox::core::ContextHandler2Helper& rParent, + const AttributeList& rAttribs, + RectangleShape& rShape ); + + virtual ::oox::core::ContextHandlerRef + onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); +}; +// ============================================================================ + } // namespace vml } // namespace oox diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx index e253d43e56e7..ec2f162628ad 100644 --- a/oox/source/shape/ShapeContextHandler.cxx +++ b/oox/source/shape/ShapeContextHandler.cxx @@ -226,7 +226,10 @@ ShapeContextHandler::getShape() throw (uno::RuntimeException) { mpDrawing->finalizeFragmentImport(); if( const ::oox::vml::ShapeBase* pShape = mpDrawing->getShapes().getFirstShape() ) + { + mpDrawing->getShapes( ).clearShapes( ); xResult = pShape->convertAndInsert( xShapes ); + } } else if (mpShape.get() != NULL) { diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx index 333df72bbaf7..b2b73e90f90e 100644 --- a/oox/source/vml/vmldrawingfragment.cxx +++ b/oox/source/vml/vmldrawingfragment.cxx @@ -60,7 +60,7 @@ ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const At { // DOCX filter handles plain shape elements with this fragment handler case VMLDRAWING_WORD: - if( isRootElement() ) + if ( getNamespace( nElement ) == NMSP_VML ) return ShapeContextBase::createShapeContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); break; diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index d557a7f50354..2b7ec4925a6e 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -29,12 +29,20 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include #include "properties.hxx" #include "oox/helper/graphichelper.hxx" #include "oox/helper/propertymap.hxx" @@ -47,6 +55,8 @@ #include "oox/vml/vmlshapecontainer.hxx" using ::rtl::OUString; +using ::com::sun::star::beans::XPropertySet; +using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY; @@ -65,6 +75,8 @@ using ::com::sun::star::drawing::XShape; using ::com::sun::star::drawing::XShapes; using ::oox::core::XmlFilterBase; +using namespace ::com::sun::star::text; + namespace oox { namespace vml { @@ -124,13 +136,62 @@ void lclInsertXShape( const Reference< XShapes >& rxShapes, const Reference< XSh } } +void lclInsertTextFrame( const XmlFilterBase& rFilter, const Reference< XShape >& rxShape ) +{ + OSL_ENSURE( rxShape.is(), "lclInsertTextFrame - missing XShape" ); + if ( rxShape.is( ) ) + { + try + { + Reference< XTextDocument > xDoc( rFilter.getModel( ), UNO_QUERY_THROW ); + Reference< XTextContent > xCtnt( rxShape, UNO_QUERY_THROW ); + xCtnt->attach( xDoc->getText( )->getStart( ) ); + } + catch( Exception& ) + { + } + } +} + void lclSetXShapeRect( const Reference< XShape >& rxShape, const Rectangle& rShapeRect ) { OSL_ENSURE( rxShape.is(), "lclSetXShapeRect - missing XShape" ); if( rxShape.is() ) { - rxShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); - rxShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); + Reference< XTextFrame > xTextFrame( rxShape, UNO_QUERY ); + if ( !xTextFrame.is( ) ) + { + rxShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); + rxShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); + } + else + { + Reference< XPropertySet > xProps( xTextFrame, UNO_QUERY_THROW ); + try + { + // The size + xProps->setPropertyValue( OUString::createFromAscii( "SizeType" ), Any( SizeType::FIX ) ); + xProps->setPropertyValue( OUString::createFromAscii( "FrameIsAutomaticHeight" ), Any( sal_False ) ); + xProps->setPropertyValue( OUString::createFromAscii( "Height" ), Any( rShapeRect.Height ) ); + xProps->setPropertyValue( OUString::createFromAscii( "Width" ), Any( rShapeRect.Width ) ); + + // The position + xProps->setPropertyValue( OUString::createFromAscii( "HoriOrientPosition" ), Any( rShapeRect.X ) ); + xProps->setPropertyValue( OUString::createFromAscii( "HoriOrientRelation" ), + Any( RelOrientation::FRAME ) ); + xProps->setPropertyValue( OUString::createFromAscii( "HoriOrient" ), + Any( HoriOrientation::NONE ) ); + + xProps->setPropertyValue( OUString::createFromAscii( "VertOrientPosition" ), Any( rShapeRect.Y ) ); + xProps->setPropertyValue( OUString::createFromAscii( "VertOrientRelation" ), + Any( RelOrientation::FRAME ) ); + xProps->setPropertyValue( OUString::createFromAscii( "VertOrient" ), + Any( VertOrientation::NONE ) ); + } + catch ( Exception& ) + { + } + } } } @@ -138,8 +199,12 @@ Reference< XShape > lclCreateAndInsertXShape( const XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes, const OUString& rService, const Rectangle& rShapeRect ) { Reference< XShape > xShape = lclCreateXShape( rFilter, rService ); - lclInsertXShape( rxShapes, xShape ); + if ( rService.equalsAscii( "com.sun.star.text.TextFrame" ) ) + lclInsertTextFrame( rFilter, xShape ); + else + lclInsertXShape( rxShapes, xShape ); lclSetXShapeRect( xShape, rShapeRect ); + return xShape; } @@ -197,11 +262,19 @@ Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) cons Rectangle ShapeType::getAbsRectangle() const { const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper(); + + sal_Int32 nWidth = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maWidth, 0, true, true ); + if ( nWidth == 0 ) + nWidth = 1; + + sal_Int32 nHeight = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maHeight, 0, true, true ); + if ( nHeight == 0 ) + nHeight = 1; + return Rectangle( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maLeft, 0, true, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginLeft, 0, true, true ), ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginTop, 0, false, true ), - ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maWidth, 0, true, true ), - ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maHeight, 0, false, true ) ); + nWidth, nHeight ); } Rectangle ShapeType::getRelRectangle() const diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx index 08115d4f8d25..a25122bb6f6c 100644 --- a/oox/source/vml/vmlshapecontext.cxx +++ b/oox/source/vml/vmlshapecontext.cxx @@ -155,6 +155,7 @@ ShapeContextBase::ShapeContextBase( ContextHandler2Helper& rParent ) : case VML_TOKEN( shape ): return new ShapeContext( rParent, rAttribs, rShapes.createShape< ComplexShape >() ); case VML_TOKEN( rect ): + return new RectangleShapeContext( rParent, rAttribs, rShapes.createShape< RectangleShape >() ); case VML_TOKEN( roundrect ): return new ShapeContext( rParent, rAttribs, rShapes.createShape< RectangleShape >() ); case VML_TOKEN( oval ): @@ -278,6 +279,7 @@ void ShapeTypeContext::setStyle( const OUString& rStyle ) ShapeContext::ShapeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, ShapeBase& rShape ) : ShapeTypeContext( rParent, rAttribs, rShape ), + mrShape( rShape ), mrShapeModel( rShape.getShapeModel() ) { // collect shape specific attributes @@ -288,6 +290,11 @@ ShapeContext::ShapeContext( ContextHandler2Helper& rParent, const AttributeList& ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { + // Custom shape in Writer with a textbox are transformed into a frame + if ( nElement == ( NMSP_VML + XML_textbox ) ) + dynamic_cast( mrShape ).setService( + OUString::createFromAscii( "com.sun.star.text.TextFrame" ) ); + // Excel specific shape client data if( isRootElement() && (nElement == VMLX_TOKEN( ClientData )) ) return new ShapeClientDataContext( *this, rAttribs, mrShapeModel.createClientData() ); @@ -325,6 +332,22 @@ ContextHandlerRef GroupShapeContext::onCreateContext( sal_Int32 nElement, const // ============================================================================ +RectangleShapeContext::RectangleShapeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, RectangleShape& rShape ) : + ShapeContext( rParent, rAttribs, rShape ) +{ +} + +ContextHandlerRef RectangleShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) +{ + if ( nElement == ( NMSP_VML + XML_textbox ) ) + dynamic_cast< SimpleShape &>( mrShape ).setService( + OUString::createFromAscii( "com.sun.star.text.TextFrame" ) ); + + // The parent class's context is fine + return ShapeContext::onCreateContext( nElement, rAttribs ); +} +// ============================================================================ + } // namespace vml } // namespace oox diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx index 8cfbcad6fc2a..58e75b30bb38 100644 --- a/writerfilter/inc/ooxml/OOXMLDocument.hxx +++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -244,6 +245,8 @@ public: virtual void setXNoteType(const Id & nId) = 0; virtual const Id & getXNoteType() const = 0; virtual const ::rtl::OUString & getTarget() const = 0; + virtual uno::Reference getShapeContext( ) = 0; + virtual void setShapeContext( uno::Reference xContext ) = 0; }; diff --git a/writerfilter/source/dmapper/OLEHandler.cxx b/writerfilter/source/dmapper/OLEHandler.cxx index 65f76f11cbfc..8bcc630b2ea8 100644 --- a/writerfilter/source/dmapper/OLEHandler.cxx +++ b/writerfilter/source/dmapper/OLEHandler.cxx @@ -54,7 +54,7 @@ using namespace ::com::sun::star; OLEHandler::OLEHandler() : m_nDxaOrig(0), m_nDyaOrig(0), - m_nWrapMode(0) + m_nWrapMode(1) { } /*-- 23.04.2008 10:46:14--------------------------------------------------- diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index 248334136de5..3eb1791580f3 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -400,6 +400,16 @@ uno::Reference OOXMLDocumentImpl::getStorageStream() return mpStream->getStorageStream(); } +void OOXMLDocumentImpl::setShapeContext( uno::Reference xContext ) +{ + mxShapeContext = xContext; +} + +uno::Reference OOXMLDocumentImpl::getShapeContext( ) +{ + return mxShapeContext; +} + OOXMLDocument * OOXMLDocumentFactory::createDocument (OOXMLStream::Pointer_t pStream) diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx index d7aa2d1f94e8..72478265bc87 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx @@ -47,6 +47,7 @@ class OOXMLDocumentImpl : public OOXMLDocument uno::Reference mxModel; uno::Reference mxDrawPage; + uno::Reference mxShapeContext; bool mbIsSubstream; @@ -109,6 +110,8 @@ public: virtual void setXNoteType(const Id & rId); virtual const Id & getXNoteType() const; virtual const ::rtl::OUString & getTarget() const; + virtual uno::Reference getShapeContext( ); + virtual void setShapeContext( uno::Reference xContext ); }; }} #endif // OOXML_DOCUMENT_IMPL_HXX diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx index 20ee49258c00..b37397b906d7 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx @@ -1913,13 +1913,19 @@ OOXMLFastContextHandlerShape::OOXMLFastContextHandlerShape uno::Reference rServiceManager (xContext->getServiceManager()); - mrShapeContext.set - (rServiceManager-> - createInstanceWithContext - (::rtl::OUString - (RTL_CONSTASCII_USTRINGPARAM - ("com.sun.star.xml.sax.FastShapeContextHandler")), xContext), - uno::UNO_QUERY); + mrShapeContext.set( getDocument( )->getShapeContext( ) ); + if ( !mrShapeContext.is( ) ) + { + // Define the shape context for the whole document + mrShapeContext.set + (rServiceManager-> + createInstanceWithContext + (::rtl::OUString + (RTL_CONSTASCII_USTRINGPARAM + ("com.sun.star.xml.sax.FastShapeContextHandler")), xContext), + uno::UNO_QUERY); + getDocument()->setShapeContext( mrShapeContext ); + } if (mrShapeContext.is()) { -- cgit v1.2.3