Advanced Diagram support: Continue isolate oox-Shapes

As preparations to use the Diagram ModelData further isolate
it from the oox-library-only drawingML Shape used for import.
It is necessary to completely isolate the Diagram ModelData
from the Diagram import mechanism as a preparation to be
able to re-create that Shapes on-demand anytime if needed
for re-layout(s).

Also removed one unused loadDiagram implementation and
streamlined the AdvancedDiagramHelper some more.

Change-Id: I7a7c55389e0d00f70c02db73ce2c3ff9ce7a5b22
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132058
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
This commit is contained in:
Armin Le Grand (Allotropia)
2022-03-24 16:31:42 +01:00
committed by Armin Le Grand
parent 272a90c45a
commit b658fdc335
9 changed files with 104 additions and 109 deletions
@@ -47,15 +47,6 @@ void loadDiagram( ShapePtr const & pShape,
const OUString& rColorStylePath,
const oox::core::Relations& rRelations );
void loadDiagram(ShapePtr const& pShape,
DiagramDataPtr pDiagramData,
const css::uno::Reference<css::xml::dom::XDocument>& layoutDom,
const css::uno::Reference<css::xml::dom::XDocument>& styleDom,
const css::uno::Reference<css::xml::dom::XDocument>& colorDom,
core::XmlFilterBase& rFilter);
// OOX_DLLPUBLIC void reloadDiagram(SdrObject* pObj, core::XmlFilterBase& rFilter);
}
#endif
+41 -13
View File
@@ -46,16 +46,33 @@ void Connection::dump() const
<< mnSourceOrder << ", dstOrd " << mnDestOrder);
}
void Point::dump() const
void Point::dump(const Shape* pShape) const
{
SAL_INFO(
"oox.drawingml",
"pt text " << mpShape.get() << ", cnxId " << msCnxId << ", modelId "
"pt text " << pShape << ", cnxId " << msCnxId << ", modelId "
<< msModelId << ", type " << mnType);
}
} // oox::drawingml::dgm namespace
Shape* DiagramData::getOrCreateAssociatedShape(const dgm::Point& rPoint, bool bCreateOnDemand) const
{
if(maPointShapeMap.end() == maPointShapeMap.find(rPoint.msModelId))
{
const_cast<DiagramData*>(this)->maPointShapeMap[rPoint.msModelId] = ShapePtr();
}
const ShapePtr& rShapePtr = maPointShapeMap.find(rPoint.msModelId)->second;
if(!rShapePtr && bCreateOnDemand)
{
const_cast<ShapePtr&>(rShapePtr) = std::make_shared<Shape>();
}
return rShapePtr.get();
}
DiagramData::DiagramData() :
mpFillProperties( std::make_shared<FillProperties>() )
{
@@ -79,7 +96,7 @@ void DiagramData::dump() const
SAL_INFO("oox.drawingml", "Dgm: DiagramData # of pt: " << maPoints.size() );
for (const auto& rPoint : maPoints)
rPoint.dump();
rPoint.dump(getOrCreateAssociatedShape(rPoint));
}
void DiagramData::getChildrenString(OUStringBuffer& rBuf, const dgm::Point* pPoint, sal_Int32 nLevel) const
@@ -87,13 +104,18 @@ void DiagramData::getChildrenString(OUStringBuffer& rBuf, const dgm::Point* pPoi
if (!pPoint)
return;
Shape* pShape(getOrCreateAssociatedShape(*pPoint));
if(!pShape)
return;
if (nLevel > 0)
{
for (sal_Int32 i = 0; i < nLevel-1; i++)
rBuf.append('\t');
rBuf.append('+');
rBuf.append(' ');
rBuf.append(pPoint->mpShape->getTextBody()->toString());
if(pShape->getTextBody())
rBuf.append(pShape->getTextBody()->toString());
rBuf.append('\n');
}
@@ -131,9 +153,12 @@ std::vector<std::pair<OUString, OUString>> DiagramData::getChildren(const OUStri
aChildren.resize(rCxn.mnSourceOrder + 1);
const auto pChild = maPointNameMap.find(rCxn.msDestId);
if (pChild != maPointNameMap.end())
{
Shape* pShape(getOrCreateAssociatedShape(*(pChild->second)));
aChildren[rCxn.mnSourceOrder] = std::make_pair(
pChild->second->msModelId,
pChild->second->mpShape->getTextBody()->toString());
nullptr != pShape && pShape->getTextBody() ? pShape->getTextBody()->toString() : OUString());
}
}
// HACK: empty items shouldn't appear there
@@ -174,11 +199,12 @@ OUString DiagramData::addNode(const OUString& rText)
dgm::Point aDataPoint;
aDataPoint.mnType = XML_node;
aDataPoint.msModelId = sNewNodeId;
aDataPoint.mpShape = std::make_shared<Shape>();
aDataPoint.mpShape->setTextBody(std::make_shared<TextBody>());
Shape* pShape(getOrCreateAssociatedShape(aDataPoint, true));
pShape->setTextBody(std::make_shared<TextBody>());
TextRunPtr pTextRun = std::make_shared<TextRun>();
pTextRun->getText() = rText;
aDataPoint.mpShape->getTextBody()->addParagraph().addRun(pTextRun);
pShape->getTextBody()->addParagraph().addRun(pTextRun);
OUString sDataSibling;
for (const auto& aCxn : maConnections)
@@ -193,7 +219,10 @@ OUString DiagramData::addNode(const OUString& rText)
dgm::Point aPresPoint;
aPresPoint.mnType = XML_pres;
aPresPoint.msModelId = OStringToOUString(comphelper::xml::generateGUIDString(), RTL_TEXTENCODING_UTF8);
aPresPoint.mpShape = std::make_shared<Shape>();
// create pesPoint shape
getOrCreateAssociatedShape(aPresPoint, true);
aPresPoint.msPresentationAssociationId = aDataPoint.msModelId;
if (!sPresSibling.isEmpty())
{
@@ -356,9 +385,8 @@ void DiagramData::build()
#endif
// does currpoint have any text set?
if( point.mpShape &&
point.mpShape->getTextBody() &&
!point.mpShape->getTextBody()->isEmpty() )
Shape* pShape(getOrCreateAssociatedShape(point));
if( nullptr != pShape && pShape->getTextBody() && !pShape->getTextBody()->isEmpty() )
{
#ifdef DEBUG_OOX_DIAGRAM
static sal_Int32 nCount=0;
@@ -367,7 +395,7 @@ void DiagramData::build()
<< " ["
<< "label=\""
<< OUStringToOString(
point.mpShape->getTextBody()->toString(),
pShape->getTextBody()->toString(),
RTL_TEXTENCODING_UTF8).getStr()
<< "\"" << "];" << std::endl;
output << "\t"
+20 -6
View File
@@ -92,9 +92,8 @@ struct Point
mbCustomText(false),
mbIsPlaceholder(false)
{}
void dump() const;
ShapePtr mpShape;
void dump(const Shape* pShape) const;
OUString msCnxId;
OUString msModelId;
@@ -146,22 +145,26 @@ typedef std::vector< Point > Points;
class DiagramData
{
public:
typedef std::map< OUString, ShapePtr > PointShapeMap;
typedef std::map< OUString, dgm::Point* > PointNameMap;
typedef std::map< OUString,
std::vector<dgm::Point*> > PointsNameMap;
typedef std::map< OUString, std::vector<dgm::Point*> > PointsNameMap;
typedef std::map< OUString, const dgm::Connection* > ConnectionNameMap;
struct SourceIdAndDepth
{
OUString msSourceId;
sal_Int32 mnDepth = 0;
};
/// Tracks connections: destination id -> {destination order, details} map.
typedef std::map< OUString,
std::map<sal_Int32, SourceIdAndDepth > > StringMap;
typedef std::map< OUString, std::map<sal_Int32, SourceIdAndDepth > > StringMap;
DiagramData();
virtual ~DiagramData() {}
// creates temporary processing data from model data
void build();
FillPropertiesPtr & getFillProperties()
{ return mpFillProperties; }
dgm::Connections & getConnections()
@@ -184,14 +187,25 @@ public:
OUString addNode(const OUString& rText);
bool removeNode(const OUString& rNodeId);
Shape* getOrCreateAssociatedShape(const dgm::Point& rPoint, bool bCreateOnDemand = false) const;
private:
void getChildrenString(OUStringBuffer& rBuf, const dgm::Point* pPoint, sal_Int32 nLevel) const;
void addConnection(sal_Int32 nType, const OUString& sSourceId, const OUString& sDestId);
// evtl. existing alternative imported visualization identifier
::std::vector<OUString> maExtDrawings;
// the model definition,
// - FillStyle
// - logic connections/assoziations
// - data point entries
FillPropertiesPtr mpFillProperties;
dgm::Connections maConnections;
dgm::Points maPoints;
// temporary processing data
PointShapeMap maPointShapeMap;
PointNameMap maPointNameMap;
PointsNameMap maPointsPresNameMap;
ConnectionNameMap maConnectionNameMap;
@@ -203,9 +203,11 @@ class PtContext
public:
PtContext( ContextHandler2Helper const & rParent,
const AttributeList& rAttribs,
dgm::Point & rPoint):
dgm::Point & rPoint,
DiagramData& rDiagramData):
ContextHandler2( rParent ),
mrPoint( rPoint )
mrPoint( rPoint ),
mrDiagramData( rDiagramData )
{
mrPoint.msModelId = rAttribs.getString( XML_modelId ).get();
@@ -229,15 +231,15 @@ public:
case DGM_TOKEN( prSet ):
return new PropertiesContext( *this, mrPoint, rAttribs );
case DGM_TOKEN( spPr ):
if( !mrPoint.mpShape )
mrPoint.mpShape = std::make_shared<Shape>();
return new ShapePropertiesContext( *this, *(mrPoint.mpShape) );
{
Shape* pShape(mrDiagramData.getOrCreateAssociatedShape(mrPoint, true));
return new ShapePropertiesContext( *this, *pShape );
}
case DGM_TOKEN( t ):
{
Shape* pShape(mrDiagramData.getOrCreateAssociatedShape(mrPoint, true));
TextBodyPtr xTextBody = std::make_shared<TextBody>();
if( !mrPoint.mpShape )
mrPoint.mpShape = std::make_shared<Shape>();
mrPoint.mpShape->setTextBody( xTextBody );
pShape->setTextBody( xTextBody );
return new TextBodyContext( *this, *xTextBody );
}
default:
@@ -248,6 +250,7 @@ public:
private:
dgm::Point& mrPoint;
DiagramData& mrDiagramData;
};
// CT_PtList
@@ -255,9 +258,10 @@ class PtListContext
: public ContextHandler2
{
public:
PtListContext( ContextHandler2Helper const & rParent, dgm::Points& rPoints) :
PtListContext( ContextHandler2Helper const & rParent, dgm::Points& rPoints, DiagramData& rDiagramData) :
ContextHandler2( rParent ),
mrPoints( rPoints )
mrPoints( rPoints ),
mrDiagramData( rDiagramData )
{}
virtual ContextHandlerRef
onCreateContext( sal_Int32 aElementToken,
@@ -269,7 +273,7 @@ public:
{
// CT_Pt
mrPoints.emplace_back( );
return new PtContext( *this, rAttribs, mrPoints.back() );
return new PtContext( *this, rAttribs, mrPoints.back(), mrDiagramData );
}
default:
break;
@@ -279,6 +283,7 @@ public:
private:
dgm::Points& mrPoints;
DiagramData& mrDiagramData;
};
// CT_BackgroundFormatting
@@ -349,7 +354,7 @@ DataModelContext::onCreateContext( ::sal_Int32 aElement,
return new CxnListContext( *this, mpDataModel->getConnections() );
case DGM_TOKEN( ptLst ):
// CT_PtList
return new PtListContext( *this, mpDataModel->getPoints() );
return new PtListContext( *this, mpDataModel->getPoints(), *mpDataModel );
case DGM_TOKEN( bg ):
// CT_BackgroundFormatting
return new BackgroundFormattingContext( *this, mpDataModel );
-45
View File
@@ -414,51 +414,6 @@ void loadDiagram( ShapePtr const & pShape,
pShape->prepareDiagramHelper(pDiagram, rFilter.getCurrentThemePtr());
}
void loadDiagram(ShapePtr const& pShape,
DiagramDataPtr pDiagramData,
const uno::Reference<xml::dom::XDocument>& layoutDom,
const uno::Reference<xml::dom::XDocument>& styleDom,
const uno::Reference<xml::dom::XDocument>& colorDom,
core::XmlFilterBase& rFilter)
{
DiagramPtr pDiagram = std::make_shared<Diagram>();
pDiagram->setData(pDiagramData);
DiagramLayoutPtr pLayout = std::make_shared<DiagramLayout>(*pDiagram);
pDiagram->setLayout(pLayout);
// layout
if (layoutDom.is())
{
rtl::Reference<core::FragmentHandler> xRefLayout(
new DiagramLayoutFragmentHandler(rFilter, OUString(), pLayout));
importFragment(rFilter, layoutDom, "OOXLayout", pDiagram, xRefLayout);
}
// style
if (styleDom.is())
{
rtl::Reference<core::FragmentHandler> xRefQStyle(
new DiagramQStylesFragmentHandler(rFilter, OUString(), pDiagram->getStyles()));
importFragment(rFilter, styleDom, "OOXStyle", pDiagram, xRefQStyle);
}
// colors
if (colorDom.is())
{
rtl::Reference<core::FragmentHandler> xRefColorStyle(
new ColorFragmentHandler(rFilter, OUString(), pDiagram->getColors()));
importFragment(rFilter, colorDom, "OOXColor", pDiagram, xRefColorStyle);
}
// diagram loaded. now lump together & attach to shape
pDiagram->addTo(pShape);
}
const oox::drawingml::Color&
DiagramColor::getColorByIndex(const std::vector<oox::drawingml::Color>& rColors, sal_Int32 nIndex)
{
@@ -39,12 +39,11 @@ bool AdvancedDiagramHelper::hasDiagramData() const
AdvancedDiagramHelper::AdvancedDiagramHelper(
const std::shared_ptr< Diagram >& rDiagramPtr,
const std::shared_ptr<::oox::drawingml::Theme>& rTheme,
const Shape& rSourceShape)
css::awt::Size aImportSize)
: IDiagramHelper()
, mpDiagramPtr(rDiagramPtr)
, mpThemePtr(rTheme)
, maImportSize(rSourceShape.getSize())
, maImportPosition(rSourceShape.getPosition())
, maImportSize(aImportSize)
{
}
@@ -70,7 +69,6 @@ void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget)
oox::drawingml::ShapePtr pShapePtr = std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" );
pShapePtr->setDiagramType();
pShapePtr->setSize(maImportSize);
pShapePtr->setPosition(maImportPosition);
pShapePtr->getFillProperties() = *mpDiagramPtr->getData()->getFillProperties();
// Re-create the oox::Shapes for the diagram content
@@ -47,7 +47,6 @@ class AdvancedDiagramHelper final : public IDiagramHelper
const std::shared_ptr<::oox::drawingml::Theme> mpThemePtr;
css::awt::Size maImportSize;
css::awt::Point maImportPosition;
bool hasDiagramData() const;
@@ -55,7 +54,7 @@ public:
AdvancedDiagramHelper(
const std::shared_ptr< Diagram >& rDiagramPtr,
const std::shared_ptr<::oox::drawingml::Theme>& rTheme,
const Shape& rSourceShape);
css::awt::Size aImportSize);
virtual ~AdvancedDiagramHelper();
// re-create XShapes
@@ -1898,7 +1898,8 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const dgm::Point* pPresNode
continue;
}
if (!aDataNode2->second->mpShape)
Shape* pDataNode2Shape(mrDgm.getData()->getOrCreateAssociatedShape(*aDataNode2->second));
if (nullptr == pDataNode2Shape)
{
//busted, skip it
continue;
@@ -1909,11 +1910,11 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const dgm::Point* pPresNode
if (rItem.mnDepth == 0)
{
// grab shape attr from topmost element(s)
rShape->getShapeProperties() = aDataNode2->second->mpShape->getShapeProperties();
rShape->getLineProperties() = aDataNode2->second->mpShape->getLineProperties();
rShape->getFillProperties() = aDataNode2->second->mpShape->getFillProperties();
rShape->getCustomShapeProperties() = aDataNode2->second->mpShape->getCustomShapeProperties();
rShape->setMasterTextListStyle( aDataNode2->second->mpShape->getMasterTextListStyle() );
rShape->getShapeProperties() = pDataNode2Shape->getShapeProperties();
rShape->getLineProperties() = pDataNode2Shape->getLineProperties();
rShape->getFillProperties() = pDataNode2Shape->getFillProperties();
rShape->getCustomShapeProperties() = pDataNode2Shape->getCustomShapeProperties();
rShape->setMasterTextListStyle( pDataNode2Shape->getMasterTextListStyle() );
SAL_INFO(
"oox.drawingml",
@@ -1927,14 +1928,14 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const dgm::Point* pPresNode
{
// If no real topmost element, then take properties from the one that's the closest
// to topmost.
rShape->getLineProperties() = aDataNode2->second->mpShape->getLineProperties();
rShape->getFillProperties() = aDataNode2->second->mpShape->getFillProperties();
rShape->getLineProperties() = pDataNode2Shape->getLineProperties();
rShape->getFillProperties() = pDataNode2Shape->getFillProperties();
}
// append text with right outline level
if( aDataNode2->second->mpShape->getTextBody() &&
!aDataNode2->second->mpShape->getTextBody()->getParagraphs().empty() &&
!aDataNode2->second->mpShape->getTextBody()->getParagraphs().front()->getRuns().empty() )
if( pDataNode2Shape->getTextBody() &&
!pDataNode2Shape->getTextBody()->getParagraphs().empty() &&
!pDataNode2Shape->getTextBody()->getParagraphs().front()->getRuns().empty() )
{
TextBodyPtr pTextBody=rShape->getTextBody();
if( !pTextBody )
@@ -1943,15 +1944,15 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const dgm::Point* pPresNode
// also copy text attrs
pTextBody->getTextListStyle() =
aDataNode2->second->mpShape->getTextBody()->getTextListStyle();
pDataNode2Shape->getTextBody()->getTextListStyle();
pTextBody->getTextProperties() =
aDataNode2->second->mpShape->getTextBody()->getTextProperties();
pDataNode2Shape->getTextBody()->getTextProperties();
rShape->setTextBody(pTextBody);
}
const TextParagraphVector& rSourceParagraphs
= aDataNode2->second->mpShape->getTextBody()->getParagraphs();
= pDataNode2Shape->getTextBody()->getParagraphs();
for (const auto& pSourceParagraph : rSourceParagraphs)
{
TextParagraph& rPara = pTextBody->addParagraph();
@@ -1960,7 +1961,7 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const dgm::Point* pPresNode
for (const auto& pRun : pSourceParagraph->getRuns())
rPara.addRun(pRun);
const TextBodyPtr& rBody = aDataNode2->second->mpShape->getTextBody();
const TextBodyPtr& rBody = pDataNode2Shape->getTextBody();
rPara.getProperties().apply(rBody->getParagraphs().front()->getProperties());
}
}
@@ -1974,8 +1975,9 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const dgm::Point* pPresNode
" processing shape type "
<< rShape->getCustomShapeProperties()->getShapePresetType()
<< " for layout node named \"" << msName << "\"");
if (pPresNode->mpShape)
rShape->getFillProperties().assignUsed(pPresNode->mpShape->getFillProperties());
Shape* pPresNodeShape(mrDgm.getData()->getOrCreateAssociatedShape(*pPresNode));
if (nullptr != pPresNodeShape)
rShape->getFillProperties().assignUsed(pPresNodeShape->getFillProperties());
}
// TODO(Q1): apply styling & coloring - take presentation
+4 -1
View File
@@ -208,7 +208,10 @@ void Shape::prepareDiagramHelper(
// Prepare Diagram data collecting for this Shape
if( nullptr == mpDiagramHelper && FRAMETYPE_DIAGRAM == meFrameType )
{
mpDiagramHelper = new AdvancedDiagramHelper(rDiagramPtr, rTheme, *this);
mpDiagramHelper = new AdvancedDiagramHelper(
rDiagramPtr,
rTheme,
getSize());
}
}