687 lines
26 KiB
C++
687 lines
26 KiB
C++
/* -*- 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/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
|
|
#include <com/sun/star/container/XIdentifierContainer.hpp>
|
|
#include <com/sun/star/xml/dom/XDocument.hpp>
|
|
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
|
|
|
|
#include <oox/shape/ShapeContextHandler.hxx>
|
|
#include <oox/shape/ShapeDrawingFragmentHandler.hxx>
|
|
#include "LockedCanvasContext.hxx"
|
|
#include "WordprocessingCanvasContext.hxx"
|
|
#include "WpsContext.hxx"
|
|
#include "WpgContext.hxx"
|
|
#include <basegfx/matrix/b2dhommatrix.hxx>
|
|
#include <oox/vml/vmldrawingfragment.hxx>
|
|
#include <oox/vml/vmlshape.hxx>
|
|
#include <oox/vml/vmlshapecontainer.hxx>
|
|
#include <oox/shape/ShapeFilterBase.hxx>
|
|
#include <oox/token/namespaces.hxx>
|
|
#include <oox/token/tokens.hxx>
|
|
#include <oox/drawingml/theme.hxx>
|
|
#include <oox/drawingml/themefragmenthandler.hxx>
|
|
#include <svx/svdogrp.hxx>
|
|
#include <svx/svdoedge.hxx>
|
|
#include <svx/svdobj.hxx>
|
|
|
|
#include <drawingml/connectorhelper.hxx>
|
|
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
namespace oox::shape {
|
|
using namespace core;
|
|
using namespace drawingml;
|
|
|
|
ShapeContextHandler::ShapeContextHandler(rtl::Reference<ShapeFilterBase> xFilterBase) :
|
|
m_bFullWPGSUpport(false),
|
|
mxShapeFilterBase(std::move(xFilterBase))
|
|
|
|
{
|
|
}
|
|
|
|
ShapeContextHandler::~ShapeContextHandler()
|
|
{
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getLockedCanvasContext(sal_Int32 nElement)
|
|
{
|
|
if (!mxLockedCanvasContext.is())
|
|
{
|
|
FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
|
|
|
|
switch (nElement & 0xffff)
|
|
{
|
|
case XML_lockedCanvas:
|
|
mxLockedCanvasContext.set(new LockedCanvasContext(*rFragmentHandler));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return static_cast<ContextHandler *>(mxLockedCanvasContext.get());
|
|
}
|
|
|
|
/*
|
|
* This method creates new ChartGraphicDataContext Object.
|
|
*/
|
|
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getChartShapeContext(sal_Int32 nElement)
|
|
{
|
|
if (!mxChartShapeContext.is())
|
|
{
|
|
switch (nElement & 0xffff)
|
|
{
|
|
case XML_chart:
|
|
{
|
|
std::unique_ptr<ContextHandler2Helper> pFragmentHandler(
|
|
new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
|
|
mpShape = std::make_shared<Shape>("com.sun.star.drawing.OLE2Shape" );
|
|
mxChartShapeContext.set(new ChartGraphicDataContext(*pFragmentHandler, mpShape, true));
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return mxChartShapeContext;
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getWpsContext(sal_Int32 nStartElement, sal_Int32 nElement)
|
|
{
|
|
if (!mxWpsContext.is())
|
|
{
|
|
FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
|
|
|
|
uno::Reference<drawing::XShape> xShape;
|
|
// No element happens in case of pretty-printed XML, bodyPr is the case when we are called again after <wps:txbx>.
|
|
if (!nElement || nElement == WPS_TOKEN(bodyPr))
|
|
// Assume that this is just a continuation of the previous shape.
|
|
xShape = mxSavedShape;
|
|
|
|
switch (getBaseToken(nStartElement))
|
|
{
|
|
case XML_wsp:
|
|
mxWpsContext.set(new WpsContext(
|
|
*rFragmentHandler,
|
|
xShape,
|
|
nullptr,
|
|
std::make_shared<oox::drawingml::Shape>(
|
|
"com.sun.star.drawing.CustomShape")));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return mxWpsContext;
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getWpgContext(sal_Int32 nElement)
|
|
{
|
|
if (!mxWpgContext.is())
|
|
{
|
|
FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
|
|
|
|
switch (getBaseToken(nElement))
|
|
{
|
|
case XML_wgp:
|
|
{
|
|
mxWpgContext.set(new WpgContext(*rFragmentHandler, oox::drawingml::ShapePtr()));
|
|
mxWpgContext->setFullWPGSupport(m_bFullWPGSUpport);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return static_cast<ContextHandler *>(mxWpgContext.get());
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler> const &
|
|
ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element )
|
|
{
|
|
if (! mxGraphicShapeContext.is())
|
|
{
|
|
auto pFragmentHandler = std::make_shared<ShapeFragmentHandler>(*mxShapeFilterBase, msRelationFragmentPath);
|
|
|
|
switch (Element & 0xffff)
|
|
{
|
|
case XML_graphic:
|
|
mpShape = std::make_shared<Shape>("com.sun.star.drawing.GraphicObjectShape" );
|
|
mxGraphicShapeContext.set
|
|
(new GraphicalObjectFrameContext(*pFragmentHandler, nullptr, mpShape, true));
|
|
break;
|
|
case XML_pic:
|
|
mpShape = std::make_shared<Shape>("com.sun.star.drawing.GraphicObjectShape" );
|
|
mxGraphicShapeContext.set
|
|
(new GraphicShapeContext(*pFragmentHandler, nullptr, mpShape));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return mxGraphicShapeContext;
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler>
|
|
ShapeContextHandler::getDrawingShapeContext()
|
|
{
|
|
if (!mxDrawingFragmentHandler.is())
|
|
{
|
|
mpDrawing = std::make_shared<oox::vml::Drawing>( *mxShapeFilterBase, mxDrawPage, oox::vml::VMLDRAWING_WORD );
|
|
mxDrawingFragmentHandler.set
|
|
(new oox::vml::DrawingFragment
|
|
( *mxShapeFilterBase, msRelationFragmentPath, *mpDrawing ));
|
|
}
|
|
else
|
|
{
|
|
// Reset the handler if fragment path has changed
|
|
OUString sHandlerFragmentPath = mxDrawingFragmentHandler->getFragmentPath();
|
|
if ( msRelationFragmentPath != sHandlerFragmentPath )
|
|
{
|
|
mxDrawingFragmentHandler.clear();
|
|
mxDrawingFragmentHandler.set
|
|
(new oox::vml::DrawingFragment
|
|
( *mxShapeFilterBase, msRelationFragmentPath, *mpDrawing ));
|
|
}
|
|
}
|
|
return static_cast<ContextHandler *>(mxDrawingFragmentHandler.get());
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler>
|
|
ShapeContextHandler::getDiagramShapeContext()
|
|
{
|
|
if (!mxDiagramShapeContext.is())
|
|
{
|
|
auto pFragmentHandler = std::make_shared<ShapeFragmentHandler>(*mxShapeFilterBase, msRelationFragmentPath);
|
|
mpShape = std::make_shared<Shape>();
|
|
mpShape->setSize(maSize);
|
|
mxDiagramShapeContext.set(new DiagramGraphicDataContext(*pFragmentHandler, mpShape));
|
|
}
|
|
|
|
return mxDiagramShapeContext;
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getWordprocessingCanvasContext(sal_Int32 nElement)
|
|
{
|
|
if (!mxWordprocessingCanvasContext.is())
|
|
{
|
|
FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
|
|
|
|
switch (getBaseToken(nElement))
|
|
{
|
|
case XML_wpc:
|
|
mxWordprocessingCanvasContext.set(new WordprocessingCanvasContext(*rFragmentHandler, maSize));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return static_cast<ContextHandler *>(mxWordprocessingCanvasContext.get());
|
|
}
|
|
|
|
uno::Reference<xml::sax::XFastContextHandler>
|
|
ShapeContextHandler::getContextHandler(sal_Int32 nElement)
|
|
{
|
|
uno::Reference<xml::sax::XFastContextHandler> xResult;
|
|
const sal_uInt32 nStartToken = getStartToken();
|
|
|
|
switch (getNamespace( nStartToken ))
|
|
{
|
|
case NMSP_doc:
|
|
case NMSP_vml:
|
|
xResult.set(getDrawingShapeContext());
|
|
break;
|
|
case NMSP_dmlDiagram:
|
|
xResult.set(getDiagramShapeContext());
|
|
break;
|
|
case NMSP_dmlLockedCanvas:
|
|
xResult.set(getLockedCanvasContext(nStartToken));
|
|
break;
|
|
case NMSP_dmlChart:
|
|
xResult.set(getChartShapeContext(nStartToken));
|
|
break;
|
|
case NMSP_wps:
|
|
xResult.set(getWpsContext(nStartToken, nElement));
|
|
break;
|
|
case NMSP_wpg:
|
|
xResult.set(getWpgContext(nStartToken));
|
|
break;
|
|
case NMSP_wpc:
|
|
xResult.set(getWordprocessingCanvasContext(nStartToken));
|
|
break;
|
|
default:
|
|
xResult.set(getGraphicShapeContext(nStartToken));
|
|
break;
|
|
}
|
|
|
|
return xResult;
|
|
}
|
|
|
|
// css::xml::sax::XFastContextHandler:
|
|
void SAL_CALL ShapeContextHandler::startFastElement
|
|
(::sal_Int32 Element,
|
|
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
|
|
{
|
|
mxShapeFilterBase->filter(maMediaDescriptor);
|
|
|
|
if (Element == DGM_TOKEN(relIds) || Element == LC_TOKEN(lockedCanvas) || Element == C_TOKEN(chart) ||
|
|
Element == WPS_TOKEN(wsp) || Element == WPG_TOKEN(wgp) || Element == OOX_TOKEN(dmlPicture, pic)
|
|
|| Element == WPC_TOKEN(wpc))
|
|
{
|
|
// Parse the theme relation, if available; the diagram won't have colors without it.
|
|
if (!mpThemePtr && !msRelationFragmentPath.isEmpty())
|
|
{
|
|
// Get Target for Type = "officeDocument" from _rels/.rels file
|
|
// aOfficeDocumentFragmentPath is pointing to "word/document.xml" for docx & to "ppt/presentation.xml" for pptx
|
|
FragmentHandlerRef rFragmentHandlerRef(new ShapeFragmentHandler(*mxShapeFilterBase, u"/"_ustr));
|
|
OUString aOfficeDocumentFragmentPath = rFragmentHandlerRef->getFragmentPathFromFirstTypeFromOfficeDoc( u"officeDocument" );
|
|
|
|
// Get the theme DO NOT use msRelationFragmentPath for getting theme as for a document there is a single theme in document.xml.rels
|
|
// and the same is used by header and footer as well.
|
|
FragmentHandlerRef rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, aOfficeDocumentFragmentPath));
|
|
OUString aThemeFragmentPath = rFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"theme" );
|
|
|
|
if (!aThemeFragmentPath.isEmpty())
|
|
{
|
|
mpThemePtr = std::make_shared<Theme>();
|
|
auto pTheme = std::make_shared<model::Theme>();
|
|
mpThemePtr->setTheme(pTheme);
|
|
uno::Reference<xml::sax::XFastSAXSerializable> xDoc(mxShapeFilterBase->importFragment(aThemeFragmentPath), uno::UNO_QUERY_THROW);
|
|
mxShapeFilterBase->importFragment(new ThemeFragmentHandler(*mxShapeFilterBase, aThemeFragmentPath, *mpThemePtr, *pTheme), xDoc);
|
|
mxShapeFilterBase->setCurrentTheme(mpThemePtr);
|
|
}
|
|
}
|
|
else if (mpThemePtr && !mxShapeFilterBase->getCurrentTheme())
|
|
{
|
|
mxShapeFilterBase->setCurrentTheme(mpThemePtr);
|
|
}
|
|
|
|
createFastChildContext(Element, Attribs);
|
|
}
|
|
|
|
// Entering VML block (startFastElement() is called for the outermost tag),
|
|
// handle possible recursion.
|
|
if ( getContextHandler() == getDrawingShapeContext() )
|
|
mpDrawing->getShapes().pushMark();
|
|
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xContextHandler->startFastElement(Element, Attribs);
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::startUnknownElement
|
|
(const OUString & Namespace, const OUString & Name,
|
|
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
|
|
{
|
|
if ( getContextHandler() == getDrawingShapeContext() )
|
|
mpDrawing->getShapes().pushMark();
|
|
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xContextHandler->startUnknownElement(Namespace, Name, Attribs);
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::endFastElement(::sal_Int32 Element)
|
|
{
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xContextHandler->endFastElement(Element);
|
|
// In case a textbox is sent, and later we get additional properties for
|
|
// the textbox, then the wps context is not cleared, so do that here.
|
|
if (Element != (NMSP_wps | XML_wsp))
|
|
return;
|
|
|
|
uno::Reference<lang::XServiceInfo> xServiceInfo(mxSavedShape, uno::UNO_QUERY);
|
|
bool bTextFrame = xServiceInfo.is() && xServiceInfo->supportsService(u"com.sun.star.text.TextFrame"_ustr);
|
|
bool bTextBox = false;
|
|
if (!bTextFrame)
|
|
{
|
|
uno::Reference<beans::XPropertySet> xPropertySet(mxSavedShape, uno::UNO_QUERY);
|
|
if (xPropertySet.is())
|
|
xPropertySet->getPropertyValue(u"TextBox"_ustr) >>= bTextBox;
|
|
}
|
|
if (bTextFrame || bTextBox)
|
|
mxWpsContext.clear();
|
|
mxSavedShape.clear();
|
|
}
|
|
|
|
void SAL_CALL ShapeContextHandler::endUnknownElement
|
|
(const OUString & Namespace,
|
|
const OUString & Name)
|
|
{
|
|
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)
|
|
{
|
|
uno::Reference< xml::sax::XFastContextHandler > xResult;
|
|
uno::Reference< xml::sax::XFastContextHandler > xContextHandler(getContextHandler(Element));
|
|
|
|
if (xContextHandler.is())
|
|
xResult.set(xContextHandler->createFastChildContext
|
|
(Element, Attribs));
|
|
|
|
return xResult;
|
|
}
|
|
|
|
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
|
|
ShapeContextHandler::createUnknownChildContext
|
|
(const OUString & Namespace,
|
|
const OUString & Name,
|
|
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
|
|
{
|
|
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 OUString & aChars)
|
|
{
|
|
uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
|
|
|
|
if (xContextHandler.is())
|
|
xContextHandler->characters(aChars);
|
|
}
|
|
|
|
namespace // helpers for case mxWordprocessingCanvasContext
|
|
{
|
|
void lcl_createShapeMap(oox::drawingml::ShapePtr rShapePtr,
|
|
oox::drawingml::ShapeIdMap& rShapeMap)
|
|
{
|
|
std::vector< ShapePtr >& rChildren = rShapePtr->getChildren();
|
|
if (rChildren.empty())
|
|
return;
|
|
for (auto& pIt : rChildren)
|
|
{
|
|
rShapeMap[pIt->getId()] = pIt; // add child itself
|
|
lcl_createShapeMap(pIt, rShapeMap); // and all its descendants
|
|
}
|
|
}
|
|
|
|
} // end anonymous namespace
|
|
|
|
uno::Reference< drawing::XShape >
|
|
ShapeContextHandler::getShape()
|
|
{
|
|
uno::Reference< drawing::XShape > xResult;
|
|
uno::Reference< drawing::XShapes > xShapes = mxDrawPage;
|
|
|
|
if (mxShapeFilterBase && xShapes.is())
|
|
{
|
|
if ( getContextHandler() == getDrawingShapeContext() )
|
|
{
|
|
mpDrawing->finalizeFragmentImport();
|
|
if( std::shared_ptr< vml::ShapeBase > pShape = mpDrawing->getShapes().takeLastShape() )
|
|
xResult = pShape->convertAndInsert( xShapes );
|
|
// Only now remove the recursion mark, because getShape() is called in writerfilter
|
|
// after endFastElement().
|
|
mpDrawing->getShapes().popMark();
|
|
}
|
|
else if (mxDiagramShapeContext.is())
|
|
{
|
|
basegfx::B2DHomMatrix aMatrix;
|
|
if (mpShape->getExtDrawings().empty())
|
|
{
|
|
mpShape->addShape( *mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, mpShape->getFillProperties() );
|
|
xResult = mpShape->getXShape();
|
|
}
|
|
else
|
|
{
|
|
// Prerendered diagram output is available, then use that, and throw away the original result.
|
|
for (auto const& extDrawing : mpShape->getExtDrawings())
|
|
{
|
|
OUString aFragmentPath(mxDiagramShapeContext->getFragmentPathFromRelId(extDrawing));
|
|
oox::drawingml::ShapePtr pShapePtr = std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" );
|
|
pShapePtr->setDiagramType();
|
|
mxShapeFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxShapeFilterBase, aFragmentPath, pShapePtr));
|
|
pShapePtr->setDiagramDoms(mpShape->getDiagramDoms());
|
|
pShapePtr->keepDiagramDrawing(*mxShapeFilterBase, aFragmentPath);
|
|
|
|
if (mpShape->getFontRefColorForNodes().isUsed())
|
|
applyFontRefColor(pShapePtr, mpShape->getFontRefColorForNodes());
|
|
|
|
// migrate IDiagramHelper to new oox::Shape (from mpShape which was loaded
|
|
// to pShapePtr where the geometry is now constructed)
|
|
mpShape->migrateDiagramHelperToNewShape(pShapePtr);
|
|
|
|
if (!mpShape->getChildren().empty())
|
|
{
|
|
// first child is diagram background - we want to keep it, as drawingML fallback doesn't contain it
|
|
auto& aChildren = pShapePtr->getChildren();
|
|
ShapePtr pBackground = mpShape->getChildren().front();
|
|
aChildren.insert(aChildren.begin(), pBackground);
|
|
}
|
|
|
|
pShapePtr->addShape( *mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShapePtr->getFillProperties() );
|
|
xResult = pShapePtr->getXShape();
|
|
}
|
|
mpShape.reset();
|
|
}
|
|
mxDiagramShapeContext.clear();
|
|
}
|
|
else if (mxLockedCanvasContext.is())
|
|
{
|
|
ShapePtr pShape = mxLockedCanvasContext->getShape();
|
|
if (pShape)
|
|
{
|
|
basegfx::B2DHomMatrix aMatrix;
|
|
pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
|
|
xResult = pShape->getXShape();
|
|
mxLockedCanvasContext.clear();
|
|
}
|
|
}
|
|
else if (mxWordprocessingCanvasContext.is())
|
|
{
|
|
// group which represents the drawing canvas
|
|
ShapePtr pShape = mxWordprocessingCanvasContext->getShape();
|
|
if (pShape)
|
|
{
|
|
basegfx::B2DHomMatrix aMatrix;
|
|
pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
|
|
|
|
// create a flat map of all shapes in the drawing canvas group.
|
|
oox::drawingml::ShapeIdMap aShapeMap;
|
|
lcl_createShapeMap(pShape, aShapeMap);
|
|
|
|
// Traverse aShapeMap and generate edge related properties.
|
|
for (auto& rIt : aShapeMap)
|
|
{
|
|
if ((rIt.second)->getServiceName() == "com.sun.star.drawing.ConnectorShape")
|
|
{
|
|
ConnectorHelper::applyConnections(rIt.second, aShapeMap);
|
|
|
|
if (rIt.second->getConnectorName() == u"bentConnector3"_ustr
|
|
|| rIt.second->getConnectorName() == u"bentConnector4"_ustr
|
|
|| rIt.second->getConnectorName() == u"bentConnector5"_ustr)
|
|
{
|
|
ConnectorHelper::applyBentHandleAdjustments(rIt.second);
|
|
}
|
|
else if (rIt.second->getConnectorName() == u"curvedConnector3"_ustr
|
|
|| rIt.second->getConnectorName() == u"curvedConnector4"_ustr
|
|
|| rIt.second->getConnectorName() == u"curvedConnector5"_ustr)
|
|
{
|
|
ConnectorHelper::applyCurvedHandleAdjustments(rIt.second);
|
|
}
|
|
// else use the default path of LibreOffice.
|
|
// curveConnector2 and bentConnector2 do not have handles.
|
|
}
|
|
}
|
|
xResult = pShape->getXShape();
|
|
mxWordprocessingCanvasContext.clear();
|
|
}
|
|
}
|
|
//NMSP_dmlChart == getNamespace( mnStartToken ) check is introduced to make sure that
|
|
//mnStartToken is set as NMSP_dmlChart in setStartToken.
|
|
//Only in case it is set then only the below block of code for ChartShapeContext should be executed.
|
|
else if (mxChartShapeContext.is() && (NMSP_dmlChart == getNamespace( getStartToken() )))
|
|
{
|
|
basegfx::B2DHomMatrix aMatrix;
|
|
oox::drawingml::ShapePtr xShapePtr( mxChartShapeContext->getShape());
|
|
// See SwXTextDocument::createInstance(), ODF import uses the same hack.
|
|
xShapePtr->setServiceName(u"com.sun.star.drawing.temporaryForXMLImportOLE2Shape"_ustr);
|
|
xShapePtr->addShape( *mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, xShapePtr->getFillProperties() );
|
|
xResult = xShapePtr->getXShape();
|
|
mxChartShapeContext.clear();
|
|
}
|
|
else if (mxWpsContext.is())
|
|
{
|
|
ShapePtr pShape = mxWpsContext->getShape();
|
|
if (pShape)
|
|
{
|
|
basegfx::B2DHomMatrix aMatrix;
|
|
pShape->setPosition(maPosition);
|
|
pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
|
|
xResult = pShape->getXShape();
|
|
mxSavedShape = xResult;
|
|
mxWpsContext.clear();
|
|
}
|
|
}
|
|
else if (mxWpgContext.is())
|
|
{
|
|
ShapePtr pShape = mxWpgContext->getShape();
|
|
if (pShape)
|
|
{
|
|
basegfx::B2DHomMatrix aMatrix;
|
|
pShape->setPosition(maPosition);
|
|
pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
|
|
xResult = pShape->getXShape();
|
|
mxSavedShape = xResult;
|
|
mxWpgContext.clear();
|
|
}
|
|
}
|
|
else if (mpShape)
|
|
{
|
|
basegfx::B2DHomMatrix aTransformation;
|
|
|
|
if (maPosition.X != 0 || maPosition.Y != 0)
|
|
{
|
|
// We got a position from writerfilter/, store that in the shape, otherwise the
|
|
// position won't be set.
|
|
mpShape->setWps(true);
|
|
mpShape->setPosition(maPosition);
|
|
}
|
|
|
|
mpShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aTransformation, mpShape->getFillProperties() );
|
|
xResult.set(mpShape->getXShape());
|
|
mxGraphicShapeContext.clear( );
|
|
}
|
|
}
|
|
|
|
if (xResult)
|
|
popStartToken();
|
|
return xResult;
|
|
}
|
|
|
|
void ShapeContextHandler::setDrawPage(const css::uno::Reference< css::drawing::XDrawPage > & the_value)
|
|
{
|
|
mxDrawPage = the_value;
|
|
}
|
|
|
|
void ShapeContextHandler::setModel(const css::uno::Reference< css::frame::XModel > & the_value)
|
|
{
|
|
if( !mxShapeFilterBase.is() )
|
|
throw uno::RuntimeException();
|
|
uno::Reference<lang::XComponent> xComp(the_value, uno::UNO_QUERY_THROW);
|
|
mxShapeFilterBase->setTargetDocument(xComp);
|
|
}
|
|
|
|
void ShapeContextHandler::setRelationFragmentPath(const OUString & the_value)
|
|
{
|
|
msRelationFragmentPath = the_value;
|
|
}
|
|
|
|
sal_Int32 ShapeContextHandler::getStartToken() const
|
|
{
|
|
assert(mnStartTokenStack.size() && "This stack must not be empty!");
|
|
return mnStartTokenStack.top();
|
|
}
|
|
|
|
void ShapeContextHandler::popStartToken()
|
|
{
|
|
if (mnStartTokenStack.size() > 1)
|
|
mnStartTokenStack.pop();
|
|
}
|
|
|
|
void ShapeContextHandler::pushStartToken( sal_Int32 _starttoken )
|
|
{
|
|
mnStartTokenStack.push(_starttoken);
|
|
}
|
|
|
|
void ShapeContextHandler::setPosition(const awt::Point& rPosition)
|
|
{
|
|
maPosition = rPosition;
|
|
}
|
|
|
|
void ShapeContextHandler::setSize(const awt::Size& rSize)
|
|
{
|
|
maSize = rSize;
|
|
}
|
|
|
|
void ShapeContextHandler::setDocumentProperties(const uno::Reference<document::XDocumentProperties>& xDocProps)
|
|
{
|
|
mxDocumentProperties = xDocProps;
|
|
mxShapeFilterBase->checkDocumentProperties(mxDocumentProperties);
|
|
}
|
|
|
|
void ShapeContextHandler::setMediaDescriptor(const uno::Sequence<beans::PropertyValue>& rMediaDescriptor)
|
|
{
|
|
maMediaDescriptor = rMediaDescriptor;
|
|
}
|
|
|
|
void ShapeContextHandler::setGraphicMapper(css::uno::Reference<css::graphic::XGraphicMapper> const & rxGraphicMapper)
|
|
{
|
|
mxShapeFilterBase->setGraphicMapper(rxGraphicMapper);
|
|
}
|
|
|
|
void ShapeContextHandler::applyFontRefColor(const oox::drawingml::ShapePtr& pShape,
|
|
const oox::drawingml::Color& rFontRefColor)
|
|
{
|
|
pShape->getShapeStyleRefs()[XML_fontRef].maPhClr = rFontRefColor;
|
|
std::vector<oox::drawingml::ShapePtr>& vChildren = pShape->getChildren();
|
|
for (auto const& child : vChildren)
|
|
{
|
|
applyFontRefColor(child, rFontRefColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|