Files
odfstudio/oox/inc/drawingml/connectorhelper.hxx
T
Regina Henschel 0430adb42b Import Wordprocessing Canvas, wpc:wpc element
Currently LibreOffice uses the VML fallback, when a docx document has a
wpc:wpc element. This patch implements to use the choice part with the
wpc:wpc element. That is often called 'drawing canvas'.

The patch uses a similar approach as for SmartArt. The drawing canvas is
imported as group shape and for the background an additional rectangular
shape is inserted as first in the children vector.

Not using VML has the advantage, that the custom shape import is used
for preset shapes. VML import produces problems because some properties
are not available in VML or the current VML import has deficits. The
test suite shows examples, what is better without using the VML
fallback. Affected bug reports are e.g. tdf#104671 or tdf#154828.

A drawing canvas must be used in Word for connector shapes. A connector
in Word on the drawing canvas is not written as cxnSp element, but as
ordinary wsp element with additional wps:cNvCnPr child element. The patch
generates a connector in such case.

Unsolved problems:

The path of a curved connector in OOXML is basically incompatible to
the path which LibreOffice generates. This patch uses the default
path for a curved connector. Same is done in import in Impress. Using
the VML fallback had generated a custom shape with the current path
and handles, but the connections to the target shapes were lost.

Export to docx is missing. The drawing canvas is not recreated,
instead a group with the additional background shape is exported. That
is no regression, using VML has produced a group too on export.

I don't know whether XML_graphicFrame can occur in
WordprocessingCanvasContext. At least charts and math equations are
not possible on the drawing canvas in Word.

Import of WordArt shapes does not work. That is not regression. It
works neither in the VML import.

Change-Id: I04bf8407efd1939cdf3137775f8afad420b74014
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156629
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
2023-11-15 11:13:31 +01:00

108 lines
4.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* 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/.
*/
#pragma once
#include <sal/types.h>
#include <basegfx/point/b2dpoint.hxx>
#include <drawingml/customshapeproperties.hxx>
#include <oox/drawingml/shape.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
#include <rtl/ustring.hxx>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <vector>
namespace ConnectorHelper
{
/* ToDo: Other place? It uses getShapePresetTypeName() and that is only used in shape.cxx in
Shape::createAndInsert() for "mso-orig-shape-type" property in GrabBag and for msConnectorName.
In both cases it is immediately converted to OUString. So perhaps let
getShapePresetTypeName() return an OUString directly?
*/
rtl::OUString getShapePresetTypeNameOUString(
const oox::drawingml::CustomShapePropertiesPtr& pCustomShapePropertiesPtr);
/**
* Some preset shapes use the default connector site but in order right, bottom, left, top.
* The function detects this.
* @param rShapeType The shape type identifier as it is used in the prst attribute in OOXML.
* @return true if this shape type has the right, bottom, left, top order of connection site.
*/
bool hasClockwiseCxn(const OUString& rShapeType);
/**
* Calculates the handle positions based on the definition in presetShapeDefinitions.xml and the
* actual size of the connector shape. It transforms the handles positions to the actual used
* connector layout. It transforms the handle coordinates to Hmm.
* The vector rHandlePositions is cleared and then filled with the actual handle positions. It is
* empty if the geometry does not use handles, e.g. "bentConnector2" and "curvedConnector2".
* This method works both for bentConnector and curvedConnector.
* @pre pConnector is not empty and points to a ooxml::drawing::Shape that represents a connector
* shape.
* @param [in] pConnector pointer to a connector shape
* @param [in, out] rHandlePositions contains the calculated handle positions.
*/
void getOOXHandlePositionsHmm(const oox::drawingml::ShapePtr& pConnector,
std::vector<basegfx::B2DPoint>& rHandlePositions);
/**
* OOXML defines the connector shapes so, that the start point is top-left and the leaving
* direction is horizontal. Other layout is done by flipV, flipH and 90deg, 180deg or 270deg
* rotation of the connector shape. This method collects these transformations into a
* B2DHomMatrix.
* @param [in] pConnector is pointer to a oox::drawing::Shape.
* @return a newly created B2DHomMatrix. It might be the unit matrix.
*/
basegfx::B2DHomMatrix getConnectorTransformMatrix(const oox::drawingml::ShapePtr& pConnector);
/**
* Calulates the handle positions of a connector of type ConnectorType_STANDARD. Such connector
* corresponds to the OOXML bentConnector shapes, aka "ElbowConnector". The calculation is based on
* the actual polygon of the connector. The coordinates are always returned in Hmm, even for shapes
* on a text document draw page.
* The vector rHandlePositions is cleaned and then filled with the actual handle positions. It
* is empty if the geometry does not use handles.
* @param [in] rXShape interface of a connector shape.
* @param [in,out] rHandlePositions contains the calculated handle positions.
*/
void getLOBentHandlePositionsHmm(const oox::drawingml::ShapePtr& pConnector,
std::vector<basegfx::B2DPoint>& rHandlePositions);
/**
* Sets the properties "StartShape", "EndShape", "StartGluePointIndex" and "EndGluePointIndex". Thus
* it actually connects the shapes. Connecting generates the default connector path.
* @param rConnector The connector shape
* @param [in] A flat map of target shape candidates, indexed by their msId.
*/
void applyConnections(oox::drawingml::ShapePtr& rConnector, oox::drawingml::ShapeIdMap& rShapeMap);
/**
* Calculates the difference between handle positions in OOXML and the default handle positions in
* LibreOffice. The difference is written to "EdgeLine1Delta", "EdgeLine2Delta" and "EdgeLine3Delta"
* properties. It uses the connector polygon.
* @pre The referenced connector has type ConnectorType_STANDARD and has the default connector path.
* @param pConnector refers to the shape whose handles are adapted.
*/
void applyBentHandleAdjustments(oox::drawingml::ShapePtr pConnector);
} // end namespace ConnecorHelper
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */