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;
65 css::uno::Reference< css::drawing::XShape > mxConnector;
66 OUString aDestShapeId;
67 sal_Int32 nDestGlueId;
87 std::shared_ptr<XMLShapeImportPageContextImpl>
mpNext;
111 SvXMLImport& rImporter,
112 const uno::Reference< frame::XModel>& rModel,
115 mrImporter( rImporter )
117 mpImpl->mpGroupContext =
nullptr;
120 mpImpl->mbHandleProgressBar =
false;
142 uno::Reference< lang::XServiceInfo > xInfo( rImporter.GetModel(), uno::UNO_QUERY );
143 mpImpl->mbIsPresentationShapesSupported = xInfo.is() && xInfo->supportsService(
"com.sun.star.presentation.PresentationDocument" );
148 SAL_WARN_IF( !
mpImpl->maConnections.empty(),
"xmloff",
"XMLShapeImportHelper::restoreConnections() was not called!" );
169 SvXMLImport& rImport,
171 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
172 uno::Reference< drawing::XShapes >
const & rShapes)
240 SvXMLImport& rImport,
242 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
243 uno::Reference< drawing::XShapes >
const & rShapes,
244 bool bTemporaryShape)
360 SvXMLImport& rImport,
362 const uno::Reference< xml::sax::XFastAttributeList>& rAttrList,
363 uno::Reference< drawing::XShapes >
const & rShapes,
364 const uno::Reference< xml::sax::XFastAttributeList>& rFrameAttrList)
369 if( rFrameAttrList.is() )
370 xCombinedAttrList->add(rFrameAttrList);
396 if( rImport.IsTableShapeSupported() )
421 SAL_INFO(
"xmloff",
"unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
428 for(
auto& aIter : *xCombinedAttrList)
431 SAL_INFO(
"xmloff",
"unknown attribute " << SvXMLImport::getPrefixAndNameFromToken(aIter.getToken()) <<
" value=" << aIter.toString());
441 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
443 css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
457 const uno::Reference< xml::sax::XFastAttributeList >&,
458 uno::Reference< drawing::XShapes >& rShapes)
460 if( rShape.is() && rShapes.is() )
463 rShapes->add( rShape );
465 uno::Reference<beans::XPropertySet> xPropertySet(rShape, uno::UNO_QUERY);
466 if (xPropertySet.is())
468 static constexpr OUStringLiteral sHandlePathObjScale =
u"HandlePathObjScale";
469 xPropertySet->setPropertyValue(sHandlePathObjScale,
uno::Any(
true));
479 css::uno::Reference< css::drawing::XShape >& rShape,
480 const css::uno::Reference< css::xml::sax::XFastAttributeList >&,
481 css::uno::Reference< css::drawing::XShapes >&)
496 uno::Reference< beans::XPropertySet > xPropSet(rShape, uno::UNO_QUERY);
500 xPropSet->getPropertySetInfo()->hasPropertyByName(
501 "PositionLayoutDir") )
504 aPosLayoutDir <<= text::PositionLayoutDir::PositionInHoriL2R;
505 xPropSet->setPropertyValue(
"PositionLayoutDir", aPosLayoutDir );
519 drawing::XShape* pShape;
521 bool operator<(
const ZOrderHint& rComp)
const {
return nShould < rComp.nShould; }
526class ShapeGroupContext
529 uno::Reference< drawing::XShapes > mxShapes;
530 std::vector<SdXMLEventContextData> maEventData;
531 vector<ZOrderHint> maZOrderList;
532 vector<ZOrderHint> maUnsortedList;
534 sal_Int32 mnCurrentZ;
535 std::shared_ptr<ShapeGroupContext> mpParentContext;
537 ShapeGroupContext( uno::Reference< drawing::XShapes > xShapes, std::shared_ptr<ShapeGroupContext> pParentContext );
539 void popGroupAndPostProcess();
541 void moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos );
546ShapeGroupContext::ShapeGroupContext( uno::Reference< drawing::XShapes > xShapes, std::shared_ptr<ShapeGroupContext> pParentContext )
547: mxShapes(
std::move( xShapes )), mnCurrentZ( 0 ), mpParentContext(
std::move(pParentContext) )
551void ShapeGroupContext::moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos )
553 uno::Any aAny( mxShapes->getByIndex( nSourcePos ) );
554 uno::Reference< beans::XPropertySet > xPropSet;
557 if( !(xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName(
"ZOrder" )) )
560 xPropSet->setPropertyValue(
"ZOrder",
uno::Any(nDestPos) );
562 for( ZOrderHint& rHint : maZOrderList )
564 if( rHint.nIs < nSourcePos )
566 DBG_ASSERT(rHint.nIs >= nDestPos,
"Shape sorting failed" );
571 for( ZOrderHint& rHint : maUnsortedList )
573 if( rHint.nIs < nSourcePos )
575 SAL_WARN_IF( rHint.nIs < nDestPos,
"xmloff",
"shape sorting failed" );
582void ShapeGroupContext::popGroupAndPostProcess()
584 if (!maEventData.empty())
587 for (
auto& event : maEventData)
588 event.ApplyProperties();
593 if( maZOrderList.empty() )
602 sal_Int32
nCount = mxShapes->getCount();
604 nCount -= maZOrderList.size();
605 nCount -= maUnsortedList.size();
610 for (ZOrderHint& rHint : maZOrderList)
612 for (ZOrderHint& rHint : maUnsortedList)
617 aNewHint.pShape =
nullptr;
623 aNewHint.nShould = -1;
625 maUnsortedList.insert(maUnsortedList.begin(), aNewHint);
630 bool bSorted = std::is_sorted(maZOrderList.begin(), maZOrderList.end(),
631 [](
const ZOrderHint& rLeft,
const ZOrderHint& rRight)
632 { return rLeft.nShould < rRight.nShould; } );
638 std::sort(maZOrderList.begin(), maZOrderList.end());
640 uno::Reference<drawing::XShapes3> xShapes3(mxShapes, uno::UNO_QUERY);
643 uno::Sequence<sal_Int32> aNewOrder(maZOrderList.size() + maUnsortedList.size());
644 auto pNewOrder = aNewOrder.getArray();
647 for (
const ZOrderHint& rHint : maZOrderList)
650 for (vector<ZOrderHint>::iterator aIt = maUnsortedList.begin(); aIt != maUnsortedList.end() && nIndex < rHint.nShould; )
652 pNewOrder[
nIndex++] = (*aIt).nIs;
653 aIt = maUnsortedList.erase(aIt);
656 pNewOrder[
nIndex] = rHint.nIs;
662 xShapes3->sort(aNewOrder);
663 maZOrderList.clear();
666 catch (
const css::lang::IllegalArgumentException& )
673 for (
const ZOrderHint& rHint : maZOrderList)
675 for (vector<ZOrderHint>::iterator aIt = maUnsortedList.begin(); aIt != maUnsortedList.end() && nIndex < rHint.nShould; )
677 moveShape( (*aIt).nIs, nIndex++ );
678 aIt = maUnsortedList.erase(aIt);
682 if(rHint.nIs != nIndex )
683 moveShape( rHint.nIs, nIndex );
687 maZOrderList.clear();
692 mpImpl->mpGroupContext = std::make_shared<ShapeGroupContext>( rShapes,
mpImpl->mpGroupContext );
702 mpImpl->mpGroupContext->maEventData.push_back(rData);
711 if( !
mpImpl->mpGroupContext )
716 mpImpl->mpGroupContext->popGroupAndPostProcess();
718 catch(
const uno::Exception& )
724 mpImpl->mpGroupContext =
mpImpl->mpGroupContext->mpParentContext;
729 if( !
mpImpl->mpGroupContext)
733 aNewHint.nIs =
mpImpl->mpGroupContext->mnCurrentZ++;
734 aNewHint.nShould = nZIndex;
735 aNewHint.pShape = xShape.get();
740 mpImpl->mpGroupContext->maUnsortedList.push_back(aNewHint);
745 mpImpl->mpGroupContext->maZOrderList.push_back(aNewHint);
751 auto it = std::find_if(
mpImpl->mpGroupContext->maZOrderList.begin(),
mpImpl->mpGroupContext->maZOrderList.end(), [&xShape](
const ZOrderHint& rHint)
753 return rHint.pShape == xShape.get();
755 if (it ==
mpImpl->mpGroupContext->maZOrderList.end())
759 sal_Int32 nZIndex = it->nIs;
761 for (it =
mpImpl->mpGroupContext->maZOrderList.begin(); it !=
mpImpl->mpGroupContext->maZOrderList.end();)
763 if (it->nIs == nZIndex)
767 it =
mpImpl->mpGroupContext->maZOrderList.erase(it);
768 mpImpl->mpGroupContext->mnCurrentZ--;
771 else if (it->nIs > nZIndex)
782 const OUString& rDestShapeId,
783 sal_Int32 nDestGlueId )
785 ConnectionHint aHint;
786 aHint.mxConnector = rConnectorShape;
787 aHint.bStart = bStart;
788 aHint.aDestShapeId = rDestShapeId;
789 aHint.nDestGlueId = nDestGlueId;
791 mpImpl->maConnections.push_back( aHint );
796 const vector<ConnectionHint>::size_type
nCount =
mpImpl->maConnections.size();
797 for( vector<ConnectionHint>::size_type
i = 0;
i <
nCount;
i++ )
799 ConnectionHint& rHint =
mpImpl->maConnections[
i];
800 uno::Reference< beans::XPropertySet > xConnector( rHint.mxConnector, uno::UNO_QUERY );
801 if( xConnector.is() )
807 OUString aStr1(
"EdgeLine1Delta");
808 OUString aStr2(
"EdgeLine2Delta");
809 OUString aStr3(
"EdgeLine3Delta");
810 aLine1Delta = xConnector->getPropertyValue(aStr1);
811 aLine2Delta = xConnector->getPropertyValue(aStr2);
812 aLine3Delta = xConnector->getPropertyValue(aStr3);
817 uno::Reference< drawing::XShape > xShape(
818 mrImporter.getInterfaceToIdentifierMapper().getReference( rHint.aDestShapeId ), uno::UNO_QUERY );
826 sal_Int32 nGlueId = rHint.nDestGlueId < 4 ? rHint.nDestGlueId :
getGluePointId( xShape, rHint.nDestGlueId );
834 xConnector->setPropertyValue(aStr1, aLine1Delta );
835 xConnector->setPropertyValue(aStr2, aLine2Delta );
836 xConnector->setPropertyValue(aStr3, aLine3Delta );
839 mpImpl->maConnections.clear();
856 sal_Int32 nSourceId, sal_Int32 nDestinnationId )
859 mpPageContext->maShapeGluePointsMap[xShape][nSourceId] = nDestinnationId;
867 ShapeGluePointsMap::iterator aShapeIter(
mpPageContext->maShapeGluePointsMap.find( xShape ) );
868 if( aShapeIter !=
mpPageContext->maShapeGluePointsMap.end() )
870 for (
auto& rShapeId : (*aShapeIter).second )
872 if ( rShapeId.second != -1 )
873 rShapeId.second +=
n;
885 ShapeGluePointsMap::iterator aShapeIter(
mpPageContext->maShapeGluePointsMap.find( xShape ) );
886 if( aShapeIter !=
mpPageContext->maShapeGluePointsMap.end() )
888 GluePointIdMap::iterator aIdIter = (*aShapeIter).second.find(nSourceId);
889 if( aIdIter != (*aShapeIter).second.end() )
890 return (*aIdIter).second;
900 const std::shared_ptr<XMLShapeImportPageContextImpl> pOldContext =
mpPageContext;
901 mpPageContext = std::make_shared<XMLShapeImportPageContextImpl>();
921 mpImpl->mbHandleProgressBar =
true;
926 return mpImpl->mbHandleProgressBar;
932 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)