This makes both sw/qa/extras/ooxmltok/data/n705956-{1|2}.docx testcases work at the same time. As far as I understand it, the .docx filter calls into oox and at the end if gets the shape, while the shape is removed from the ShapeContainer. In the case of recursion caused by <w:pict><v:shape><w:txbxContent><w:pict><v:shape>, clearing the whole list is wrong. Also, the OSL_ENSURE seems to suggest that there should not be more than one shape inserted by each read. So simply consider maShapes to be a stack when importing .docx . Change-Id: I7263aeaf74c8d31a05e64c56b880cbc6b00d7dd6
357 lines
11 KiB
C++
357 lines
11 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#include "ShapeContextHandler.hxx"
|
|
#include "oox/vml/vmldrawingfragment.hxx"
|
|
#include "oox/vml/vmlshape.hxx"
|
|
#include "oox/vml/vmlshapecontainer.hxx"
|
|
|
|
namespace oox { namespace shape {
|
|
|
|
using namespace ::com::sun::star;
|
|
using namespace core;
|
|
using namespace drawingml;
|
|
|
|
::rtl::OUString SAL_CALL ShapeContextHandler_getImplementationName()
|
|
{
|
|
return CREATE_OUSTRING( "com.sun.star.comp.oox.ShapeContextHandler" );
|
|
}
|
|
|
|
uno::Sequence< ::rtl::OUString > SAL_CALL
|
|
ShapeContextHandler_getSupportedServiceNames()
|
|
{
|
|
uno::Sequence< ::rtl::OUString > s(1);
|
|
s[0] = CREATE_OUSTRING( "com.sun.star.xml.sax.FastShapeContextHandler" );
|
|
return s;
|
|
}
|
|
|
|
uno::Reference< uno::XInterface > SAL_CALL
|
|
ShapeContextHandler_createInstance( const uno::Reference< uno::XComponentContext > & context)
|
|
SAL_THROW((uno::Exception))
|
|
{
|
|
return static_cast< ::cppu::OWeakObject* >( new ShapeContextHandler(context) );
|
|
}
|
|
|
|
|
|
ShapeContextHandler::ShapeContextHandler
|
|
(uno::Reference< uno::XComponentContext > const & context) :
|
|
mnStartToken(0), m_xContext(context)
|
|
{
|
|
try
|
|
{
|
|
mxFilterBase.set( new ShapeFilterBase(context) );
|
|
}
|
|
catch( uno::Exception& )
|
|
{
|
|
}
|
|
}
|
|
|
|
ShapeContextHandler::~ShapeContextHandler()
|
|
{
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler>
|
|
ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element )
|
|
{
|
|
if (! mxGraphicShapeContext.is())
|
|
{
|
|
FragmentHandlerRef rFragmentHandler
|
|
(new ShapeFragmentHandler(*mxFilterBase, msRelationFragmentPath));
|
|
ShapePtr pMasterShape;
|
|
|
|
switch (Element & 0xffff)
|
|
{
|
|
case XML_graphic:
|
|
mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
|
|
mxGraphicShapeContext.set
|
|
(new GraphicalObjectFrameContext(*rFragmentHandler, pMasterShape, mpShape, true));
|
|
break;
|
|
case XML_pic:
|
|
mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" ));
|
|
mxGraphicShapeContext.set
|
|
(new GraphicShapeContext(*rFragmentHandler, pMasterShape, mpShape));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return mxGraphicShapeContext;
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler>
|
|
ShapeContextHandler::getDrawingShapeContext()
|
|
{
|
|
if (!mxDrawingFragmentHandler.is())
|
|
{
|
|
mpDrawing.reset( new oox::vml::Drawing( *mxFilterBase, mxDrawPage, oox::vml::VMLDRAWING_WORD ) );
|
|
mxDrawingFragmentHandler.set
|
|
(dynamic_cast<ContextHandler *>
|
|
(new oox::vml::DrawingFragment
|
|
( *mxFilterBase, msRelationFragmentPath, *mpDrawing )));
|
|
}
|
|
|
|
return mxDrawingFragmentHandler;
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler>
|
|
ShapeContextHandler::getContextHandler()
|
|
{
|
|
uno::Reference<xml::sax::XFastContextHandler> xResult;
|
|
|
|
switch (getNamespace( mnStartToken ))
|
|
{
|
|
case NMSP_doc:
|
|
case NMSP_vml:
|
|
xResult.set(getDrawingShapeContext());
|
|
break;
|
|
default:
|
|
xResult.set(getGraphicShapeContext(mnStartToken));
|
|
break;
|
|
}
|
|
|
|
return xResult;
|
|
}
|
|
|
|
// ::com::sun::star::xml::sax::XFastContextHandler:
|
|
void SAL_CALL ShapeContextHandler::startFastElement
|
|
(::sal_Int32 Element,
|
|
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
|
|
throw (uno::RuntimeException, xml::sax::SAXException)
|
|
{
|
|
static const ::rtl::OUString sInputStream
|
|
(RTL_CONSTASCII_USTRINGPARAM ("InputStream"));
|
|
|
|
uno::Sequence<beans::PropertyValue> aSeq(1);
|
|
aSeq[0].Name = sInputStream;
|
|
aSeq[0].Value <<= mxInputStream;
|
|
mxFilterBase->filter(aSeq);
|
|
|
|
mpThemePtr.reset(new Theme());
|
|
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xContextHandler->startFastElement(Element, Attribs);
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::startUnknownElement
|
|
(const ::rtl::OUString & Namespace, const ::rtl::OUString & Name,
|
|
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
|
|
throw (uno::RuntimeException, xml::sax::SAXException)
|
|
{
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xContextHandler->startUnknownElement(Namespace, Name, Attribs);
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::endFastElement(::sal_Int32 Element)
|
|
throw (uno::RuntimeException, xml::sax::SAXException)
|
|
{
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xContextHandler->endFastElement(Element);
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::endUnknownElement
|
|
(const ::rtl::OUString & Namespace,
|
|
const ::rtl::OUString & Name)
|
|
throw (uno::RuntimeException, xml::sax::SAXException)
|
|
{
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xContextHandler->endUnknownElement(Namespace, Name);
|
|
}
|
|
|
|
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
|
|
ShapeContextHandler::createFastChildContext
|
|
(::sal_Int32 Element,
|
|
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
|
|
throw (uno::RuntimeException, xml::sax::SAXException)
|
|
{
|
|
uno::Reference< xml::sax::XFastContextHandler > xResult;
|
|
uno::Reference< xml::sax::XFastContextHandler > xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xResult.set(xContextHandler->createFastChildContext
|
|
(Element, Attribs));
|
|
|
|
return xResult;
|
|
}
|
|
|
|
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
|
|
ShapeContextHandler::createUnknownChildContext
|
|
(const ::rtl::OUString & Namespace,
|
|
const ::rtl::OUString & Name,
|
|
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
|
|
throw (uno::RuntimeException, xml::sax::SAXException)
|
|
{
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
return xContextHandler->createUnknownChildContext
|
|
(Namespace, Name, Attribs);
|
|
|
|
return uno::Reference< xml::sax::XFastContextHandler >();
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::characters(const ::rtl::OUString & aChars)
|
|
throw (uno::RuntimeException, xml::sax::SAXException)
|
|
{
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xContextHandler->characters(aChars);
|
|
}
|
|
|
|
// ::com::sun::star::xml::sax::XFastShapeContextHandler:
|
|
uno::Reference< drawing::XShape > SAL_CALL
|
|
ShapeContextHandler::getShape() throw (uno::RuntimeException)
|
|
{
|
|
uno::Reference< drawing::XShape > xResult;
|
|
uno::Reference< drawing::XShapes > xShapes( mxDrawPage, uno::UNO_QUERY );
|
|
|
|
if (mxFilterBase.is() && xShapes.is())
|
|
{
|
|
if ( getContextHandler() == getDrawingShapeContext() )
|
|
{
|
|
mpDrawing->finalizeFragmentImport();
|
|
if( const ::oox::vml::ShapeBase* pShape = mpDrawing->getShapes().takeLastShape() )
|
|
xResult = pShape->convertAndInsert( xShapes );
|
|
}
|
|
else if (mpShape.get() != NULL)
|
|
{
|
|
basegfx::B2DHomMatrix aTransformation;
|
|
mpShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes, aTransformation);
|
|
xResult.set(mpShape->getXShape());
|
|
mxGraphicShapeContext.clear( );
|
|
}
|
|
}
|
|
|
|
return xResult;
|
|
}
|
|
|
|
css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
|
|
ShapeContextHandler::getDrawPage() throw (css::uno::RuntimeException)
|
|
{
|
|
return mxDrawPage;
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::setDrawPage
|
|
(const css::uno::Reference< css::drawing::XDrawPage > & the_value)
|
|
throw (css::uno::RuntimeException)
|
|
{
|
|
mxDrawPage = the_value;
|
|
}
|
|
|
|
css::uno::Reference< css::frame::XModel > SAL_CALL
|
|
ShapeContextHandler::getModel() throw (css::uno::RuntimeException)
|
|
{
|
|
if( !mxFilterBase.is() )
|
|
throw uno::RuntimeException();
|
|
return mxFilterBase->getModel();
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::setModel
|
|
(const css::uno::Reference< css::frame::XModel > & the_value)
|
|
throw (css::uno::RuntimeException)
|
|
{
|
|
if( !mxFilterBase.is() )
|
|
throw uno::RuntimeException();
|
|
uno::Reference<lang::XComponent> xComp(the_value, uno::UNO_QUERY_THROW);
|
|
mxFilterBase->setTargetDocument(xComp);
|
|
}
|
|
|
|
uno::Reference< io::XInputStream > SAL_CALL
|
|
ShapeContextHandler::getInputStream() throw (uno::RuntimeException)
|
|
{
|
|
return mxInputStream;
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::setInputStream
|
|
(const uno::Reference< io::XInputStream > & the_value)
|
|
throw (uno::RuntimeException)
|
|
{
|
|
mxInputStream = the_value;
|
|
}
|
|
|
|
::rtl::OUString SAL_CALL ShapeContextHandler::getRelationFragmentPath()
|
|
throw (uno::RuntimeException)
|
|
{
|
|
return msRelationFragmentPath;
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::setRelationFragmentPath
|
|
(const ::rtl::OUString & the_value)
|
|
throw (uno::RuntimeException)
|
|
{
|
|
msRelationFragmentPath = the_value;
|
|
}
|
|
|
|
::sal_Int32 SAL_CALL ShapeContextHandler::getStartToken() throw (::com::sun::star::uno::RuntimeException)
|
|
{
|
|
return mnStartToken;
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::setStartToken( ::sal_Int32 _starttoken ) throw (::com::sun::star::uno::RuntimeException)
|
|
{
|
|
mnStartToken = _starttoken;
|
|
|
|
|
|
}
|
|
|
|
::rtl::OUString ShapeContextHandler::getImplementationName()
|
|
throw (css::uno::RuntimeException)
|
|
{
|
|
return ShapeContextHandler_getImplementationName();
|
|
}
|
|
|
|
uno::Sequence< ::rtl::OUString > ShapeContextHandler::getSupportedServiceNames()
|
|
throw (css::uno::RuntimeException)
|
|
{
|
|
return ShapeContextHandler_getSupportedServiceNames();
|
|
}
|
|
|
|
::sal_Bool SAL_CALL ShapeContextHandler::supportsService
|
|
(const ::rtl::OUString & ServiceName) throw (css::uno::RuntimeException)
|
|
{
|
|
uno::Sequence< ::rtl::OUString > aSeq = getSupportedServiceNames();
|
|
|
|
if (aSeq[0].equals(ServiceName))
|
|
return sal_True;
|
|
|
|
return sal_False;
|
|
}
|
|
|
|
}}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|