25#include <com/sun/star/beans/XPropertySet.hpp>
26#include <com/sun/star/text/PositionLayoutDir.hpp>
27#include <com/sun/star/drawing/XShapes3.hpp>
47#include <unordered_map>
53class ShapeGroupContext;
64 css::uno::Reference< css::drawing::XShape > mxConnector;
65 OUString aDestShapeId;
66 sal_Int32 nDestGlueId;
86 std::shared_ptr<XMLShapeImportPageContextImpl>
mpNext;
110 SvXMLImport& rImporter,
111 const uno::Reference< frame::XModel>& rModel,
114 mrImporter( rImporter )
116 mpImpl->mpGroupContext =
nullptr;
119 mpImpl->mbHandleProgressBar =
false;
141 uno::Reference< lang::XServiceInfo > xInfo( rImporter.GetModel(), uno::UNO_QUERY );
142 mpImpl->mbIsPresentationShapesSupported = xInfo.is() && xInfo->supportsService(
"com.sun.star.presentation.PresentationDocument" );
147 SAL_WARN_IF( !
mpImpl->maConnections.empty(),
"xmloff",
"XMLShapeImportHelper::restoreConnections() was not called!" );
168 SvXMLImport& rImport,
170 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
171 uno::Reference< drawing::XShapes >
const & rShapes)
239 SvXMLImport& rImport,
241 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
242 uno::Reference< drawing::XShapes >
const & rShapes,
243 bool bTemporaryShape)
359 SvXMLImport& rImport,
361 const uno::Reference< xml::sax::XFastAttributeList>& rAttrList,
362 uno::Reference< drawing::XShapes >
const & rShapes,
363 const uno::Reference< xml::sax::XFastAttributeList>& rFrameAttrList)
368 if( rFrameAttrList.is() )
369 xCombinedAttrList->add(rFrameAttrList);
395 if( rImport.IsTableShapeSupported() )
420 SAL_INFO(
"xmloff",
"unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
427 for(
auto& aIter : *xCombinedAttrList)
430 SAL_INFO(
"xmloff",
"unknown attribute " << SvXMLImport::getPrefixAndNameFromToken(aIter.getToken()) <<
" value=" << aIter.toString());
440 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
442 css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
456 const uno::Reference< xml::sax::XFastAttributeList >&,
457 uno::Reference< drawing::XShapes >& rShapes)
459 if( rShape.is() && rShapes.is() )
462 rShapes->add( rShape );
464 uno::Reference<beans::XPropertySet> xPropertySet(rShape, uno::UNO_QUERY);
465 if (xPropertySet.is())
467 static constexpr OUStringLiteral sHandlePathObjScale =
u"HandlePathObjScale";
468 xPropertySet->setPropertyValue(sHandlePathObjScale,
uno::Any(
true));
478 css::uno::Reference< css::drawing::XShape >& rShape,
479 const css::uno::Reference< css::xml::sax::XFastAttributeList >&,
480 css::uno::Reference< css::drawing::XShapes >&)
495 uno::Reference< beans::XPropertySet > xPropSet(rShape, uno::UNO_QUERY);
499 xPropSet->getPropertySetInfo()->hasPropertyByName(
500 "PositionLayoutDir") )
503 aPosLayoutDir <<= text::PositionLayoutDir::PositionInHoriL2R;
504 xPropSet->setPropertyValue(
"PositionLayoutDir", aPosLayoutDir );
518 drawing::XShape* pShape;
520 bool operator<(
const ZOrderHint& rComp)
const {
return nShould < rComp.nShould; }
525class ShapeGroupContext
528 uno::Reference< drawing::XShapes > mxShapes;
529 std::vector<SdXMLEventContextData> maEventData;
530 std::vector<ZOrderHint> maZOrderList;
531 std::vector<ZOrderHint> maUnsortedList;
533 sal_Int32 mnCurrentZ;
534 std::shared_ptr<ShapeGroupContext> mpParentContext;
536 ShapeGroupContext( uno::Reference< drawing::XShapes > xShapes, std::shared_ptr<ShapeGroupContext> pParentContext );
538 void popGroupAndPostProcess();
540 void moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos );
545ShapeGroupContext::ShapeGroupContext( uno::Reference< drawing::XShapes > xShapes, std::shared_ptr<ShapeGroupContext> pParentContext )
546: mxShapes(
std::move( xShapes )), mnCurrentZ( 0 ), mpParentContext(
std::move(pParentContext) )
550void ShapeGroupContext::moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos )
552 uno::Any aAny( mxShapes->getByIndex( nSourcePos ) );
553 uno::Reference< beans::XPropertySet > xPropSet;
556 if( !(xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName(
"ZOrder" )) )
559 xPropSet->setPropertyValue(
"ZOrder",
uno::Any(nDestPos) );
561 for( ZOrderHint& rHint : maZOrderList )
563 if( rHint.nIs < nSourcePos )
565 DBG_ASSERT(rHint.nIs >= nDestPos,
"Shape sorting failed" );
570 for( ZOrderHint& rHint : maUnsortedList )
572 if( rHint.nIs < nSourcePos )
574 SAL_WARN_IF( rHint.nIs < nDestPos,
"xmloff",
"shape sorting failed" );
581void ShapeGroupContext::popGroupAndPostProcess()
583 if (!maEventData.empty())
586 for (
auto& event : maEventData)
587 event.ApplyProperties();
592 if( maZOrderList.empty() )
601 sal_Int32
nCount = mxShapes->getCount();
603 nCount -= maZOrderList.size();
604 nCount -= maUnsortedList.size();
609 for (ZOrderHint& rHint : maZOrderList)
611 for (ZOrderHint& rHint : maUnsortedList)
616 aNewHint.pShape =
nullptr;
622 aNewHint.nShould = -1;
624 maUnsortedList.insert(maUnsortedList.begin(), aNewHint);
629 bool bSorted = std::is_sorted(maZOrderList.begin(), maZOrderList.end(),
630 [](
const ZOrderHint& rLeft,
const ZOrderHint& rRight)
631 { return rLeft.nShould < rRight.nShould; } );
637 std::sort(maZOrderList.begin(), maZOrderList.end());
639 uno::Reference<drawing::XShapes3> xShapes3(mxShapes, uno::UNO_QUERY);
642 uno::Sequence<sal_Int32> aNewOrder(maZOrderList.size() + maUnsortedList.size());
643 auto pNewOrder = aNewOrder.getArray();
646 for (
const ZOrderHint& rHint : maZOrderList)
649 for (std::vector<ZOrderHint>::iterator aIt = maUnsortedList.begin(); aIt != maUnsortedList.end() && nIndex < rHint.nShould; )
651 pNewOrder[
nIndex++] = (*aIt).nIs;
652 aIt = maUnsortedList.erase(aIt);
655 pNewOrder[
nIndex] = rHint.nIs;
661 xShapes3->sort(aNewOrder);
662 maZOrderList.clear();
665 catch (
const css::lang::IllegalArgumentException& )
672 for (
const ZOrderHint& rHint : maZOrderList)
674 for (std::vector<ZOrderHint>::iterator aIt = maUnsortedList.begin(); aIt != maUnsortedList.end() && nIndex < rHint.nShould; )
676 moveShape( (*aIt).nIs, nIndex++ );
677 aIt = maUnsortedList.erase(aIt);
681 if(rHint.nIs != nIndex )
682 moveShape( rHint.nIs, nIndex );
686 maZOrderList.clear();
691 mpImpl->mpGroupContext = std::make_shared<ShapeGroupContext>( rShapes,
mpImpl->mpGroupContext );
701 mpImpl->mpGroupContext->maEventData.push_back(rData);
710 if( !
mpImpl->mpGroupContext )
715 mpImpl->mpGroupContext->popGroupAndPostProcess();
717 catch(
const uno::Exception& )
723 mpImpl->mpGroupContext =
mpImpl->mpGroupContext->mpParentContext;
728 if( !
mpImpl->mpGroupContext)
732 aNewHint.nIs =
mpImpl->mpGroupContext->mnCurrentZ++;
733 aNewHint.nShould = nZIndex;
734 aNewHint.pShape = xShape.get();
739 mpImpl->mpGroupContext->maUnsortedList.push_back(aNewHint);
744 mpImpl->mpGroupContext->maZOrderList.push_back(aNewHint);
750 auto it = std::find_if(
mpImpl->mpGroupContext->maZOrderList.begin(),
mpImpl->mpGroupContext->maZOrderList.end(), [&xShape](
const ZOrderHint& rHint)
752 return rHint.pShape == xShape.get();
754 if (it ==
mpImpl->mpGroupContext->maZOrderList.end())
758 sal_Int32 nZIndex = it->nIs;
760 for (it =
mpImpl->mpGroupContext->maZOrderList.begin(); it !=
mpImpl->mpGroupContext->maZOrderList.end();)
762 if (it->nIs == nZIndex)
766 it =
mpImpl->mpGroupContext->maZOrderList.erase(it);
767 mpImpl->mpGroupContext->mnCurrentZ--;
770 else if (it->nIs > nZIndex)
781 const OUString& rDestShapeId,
782 sal_Int32 nDestGlueId )
784 ConnectionHint aHint;
785 aHint.mxConnector = rConnectorShape;
786 aHint.bStart = bStart;
787 aHint.aDestShapeId = rDestShapeId;
788 aHint.nDestGlueId = nDestGlueId;
790 mpImpl->maConnections.push_back( aHint );
795 const std::vector<ConnectionHint>::size_type
nCount =
mpImpl->maConnections.size();
796 for( std::vector<ConnectionHint>::size_type
i = 0;
i <
nCount;
i++ )
798 ConnectionHint& rHint =
mpImpl->maConnections[
i];
799 uno::Reference< beans::XPropertySet > xConnector( rHint.mxConnector, uno::UNO_QUERY );
800 if( xConnector.is() )
806 OUString aStr1(
"EdgeLine1Delta");
807 OUString aStr2(
"EdgeLine2Delta");
808 OUString aStr3(
"EdgeLine3Delta");
809 aLine1Delta = xConnector->getPropertyValue(aStr1);
810 aLine2Delta = xConnector->getPropertyValue(aStr2);
811 aLine3Delta = xConnector->getPropertyValue(aStr3);
816 uno::Reference< drawing::XShape > xShape(
817 mrImporter.getInterfaceToIdentifierMapper().getReference( rHint.aDestShapeId ), uno::UNO_QUERY );
825 sal_Int32 nGlueId = rHint.nDestGlueId < 4 ? rHint.nDestGlueId :
getGluePointId( xShape, rHint.nDestGlueId );
833 xConnector->setPropertyValue(aStr1, aLine1Delta );
834 xConnector->setPropertyValue(aStr2, aLine2Delta );
835 xConnector->setPropertyValue(aStr3, aLine3Delta );
838 mpImpl->maConnections.clear();
855 sal_Int32 nSourceId, sal_Int32 nDestinnationId )
858 mpPageContext->maShapeGluePointsMap[xShape][nSourceId] = nDestinnationId;
866 ShapeGluePointsMap::iterator aShapeIter(
mpPageContext->maShapeGluePointsMap.find( xShape ) );
867 if( aShapeIter !=
mpPageContext->maShapeGluePointsMap.end() )
869 for (
auto& rShapeId : (*aShapeIter).second )
871 if ( rShapeId.second != -1 )
872 rShapeId.second +=
n;
884 ShapeGluePointsMap::iterator aShapeIter(
mpPageContext->maShapeGluePointsMap.find( xShape ) );
885 if( aShapeIter !=
mpPageContext->maShapeGluePointsMap.end() )
887 GluePointIdMap::iterator aIdIter = (*aShapeIter).second.find(nSourceId);
888 if( aIdIter != (*aShapeIter).second.end() )
889 return (*aIdIter).second;
899 const std::shared_ptr<XMLShapeImportPageContextImpl> pOldContext =
mpPageContext;
900 mpPageContext = std::make_shared<XMLShapeImportPageContextImpl>();
920 mpImpl->mbHandleProgressBar =
true;
925 return mpImpl->mbHandleProgressBar;
931 return mpImpl->mbIsPresentationShapesSupported;
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
virtual bool processAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter &)
This class deliberately does not support XWeak, to improve performance when loading large documents.
void ChainImportMapper(const rtl::Reference< SvXMLImportPropertyMapper > &rMapper)
void setHyperlink(const OUString &rHyperlink)
rtl::Reference< SvXMLImportPropertyMapper > mpPresPagePropsMapper
void addGluePointMapping(css::uno::Reference< css::drawing::XShape > const &xShape, sal_Int32 nSourceId, sal_Int32 nDestinnationId)
adds a mapping for a gluepoint identifier from an xml file to the identifier created after inserting ...
void shapeRemoved(const css::uno::Reference< css::drawing::XShape > &rShape)
Updates the z-order of other shapes to be consistent again, needed due to the removal of rShape.
void popGroupAndPostProcess()
static SvXMLShapeContext * CreateGroupChildContext(SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > const &rShapes, bool bTemporaryShape=false)
void addShapeConnection(css::uno::Reference< css::drawing::XShape > const &rConnectorShape, bool bStart, const OUString &rDestShapeId, sal_Int32 nDestGlueId)
virtual ~XMLShapeImportHelper() override
virtual void addShape(css::uno::Reference< css::drawing::XShape > &rShape, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > &rShapes)
this function is called whenever the implementation classes like to add this new shape to the given X...
virtual void finishShape(css::uno::Reference< css::drawing::XShape > &rShape, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > &rShapes)
this function is called whenever the implementation classes have finished importing a shape to the gi...
rtl::Reference< SvXMLImportPropertyMapper > mpPropertySetMapper
void pushGroupForPostProcessing(css::uno::Reference< css::drawing::XShapes > &rShapes)
rtl::Reference< SvXMLStylesContext > mxAutoStylesContext
void restoreConnections()
rtl::Reference< XMLTableImport > mxShapeTableImport
rtl::Reference< XMLSdPropHdlFactory > mpSdPropHdlFactory
static SvXMLShapeContext * CreateFrameChildContext(SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > const &rShapes, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xFrameAttrList)
void shapeWithZIndexAdded(css::uno::Reference< css::drawing::XShape > const &rShape, sal_Int32 nZIndex)
XMLShapeImportHelper(SvXMLImport &rImporter, const css::uno::Reference< css::frame::XModel > &rModel, SvXMLImportPropertyMapper *pExtMapper=nullptr)
bool IsHandleProgressBarEnabled() const
void moveGluePointMapping(const css::uno::Reference< css::drawing::XShape > &xShape, const sal_Int32 n)
moves all current DestinationId's for rXShape by n
sal_Int32 getGluePointId(const css::uno::Reference< css::drawing::XShape > &xShape, sal_Int32 nSourceId)
retrieves a mapping for a gluepoint identifier from the current xml file to the identifier created af...
void SetAutoStylesContext(SvXMLStylesContext *pNew)
void addShapeEvents(SdXMLEventContextData &rData)
void endPage(css::uno::Reference< css::drawing::XShapes > const &rShapes)
this method must be calling after the last shape is imported for the given page Calls to this method ...
void enableHandleProgressBar()
defines if the import should increment the progress bar or not
std::shared_ptr< XMLShapeImportPageContextImpl > mpPageContext
static SvXMLShapeContext * Create3DSceneChildContext(SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > const &rShapes)
void startPage(css::uno::Reference< css::drawing::XShapes > const &rShapes)
this method must be calling before the first shape is imported for the given page.
std::unique_ptr< XMLShapeImportHelperImpl > mpImpl
bool IsPresentationShapesSupported() const
queries the capability of the current model to create presentation shapes
rtl::Reference< SvXMLStylesContext > mxStylesContext
static SvXMLImportPropertyMapper * CreateShapePropMapper(const css::uno::Reference< css::frame::XModel > &rModel, SvXMLImport &rImport)
creates a property mapper for external chaining
void SetStylesContext(SvXMLStylesContext *pNew)
const rtl::Reference< XMLTableImport > & GetShapeTableImport()
static SvXMLImportPropertyMapper * CreateParaExtPropMapper(SvXMLImport &)
static SvXMLImportPropertyMapper * CreateParaDefaultExtPropMapper(SvXMLImport &)
#define DBG_ASSERT(sCon, aError)
#define DBG_UNHANDLED_EXCEPTION(...)
Reference< XSingleServiceFactory > xFactory
#define SAL_WARN_IF(condition, area, stream)
#define SAL_INFO(area, stream)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
Handling of tokens in XML:
const XMLPropertyMapEntry aXMLSDPresPageProps[]
constexpr OUStringLiteral gsEndGluePointIndex(u"EndGluePointIndex")
constexpr OUStringLiteral gsStartShape(u"StartShape")
constexpr OUStringLiteral gsEndShape(u"EndShape")
std::map< sal_Int32, sal_Int32 > GluePointIdMap
this map store all gluepoint id mappings for shapes that had user defined gluepoints.
constexpr OUStringLiteral gsStartGluePointIndex(u"StartGluePointIndex")
std::unordered_map< css::uno::Reference< css::drawing::XShape >, GluePointIdMap > ShapeGluePointsMap
css::uno::Reference< css::drawing::XShape > mxShape
this class is to enable adding members to the XMLShapeImportHelper without getting incompatible
bool mbIsPresentationShapesSupported
std::shared_ptr< ShapeGroupContext > mpGroupContext
std::vector< ConnectionHint > maConnections
this struct is created for each startPage() call and stores information that is needed during import ...
std::shared_ptr< XMLShapeImportPageContextImpl > mpNext
ShapeGluePointsMap maShapeGluePointsMap
uno::Reference< drawing::XShapes > mxShapes
bool operator<(const tSchXMLIndexWithPart &rFirst, const tSchXMLIndexWithPart &rSecond)
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
#define XMLOFF_WARN_UNKNOWN(area, rIter)
#define XML_ELEMENT(prefix, name)