25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/text/PositionLayoutDir.hpp>
27 #include <com/sun/star/drawing/XShapes3.hpp>
48 #include <unordered_map>
49 #include <string_view>
54 class ShapeGroupContext;
58 using namespace ::
std;
66 css::uno::Reference< css::drawing::XShape > mxConnector;
67 OUString aDestShapeId;
68 sal_Int32 nDestGlueId;
88 std::shared_ptr<XMLShapeImportPageContextImpl>
mpNext;
107 constexpr OUStringLiteral
gsEndShape(u
"EndShape");
113 const uno::Reference< frame::XModel>& rModel,
116 mrImporter( rImporter )
118 mpImpl->mpGroupContext =
nullptr;
121 mpImpl->mbHandleProgressBar =
false;
143 uno::Reference< lang::XServiceInfo > xInfo( rImporter.
GetModel(), uno::UNO_QUERY );
144 mpImpl->mbIsPresentationShapesSupported = xInfo.is() && xInfo->supportsService(
"com.sun.star.presentation.PresentationDocument" );
149 SAL_WARN_IF( !
mpImpl->maConnections.empty(),
"xmloff",
"XMLShapeImportHelper::restoreConnections() was not called!" );
172 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
173 uno::Reference< drawing::XShapes >
const & rShapes)
243 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
244 uno::Reference< drawing::XShapes >
const & rShapes,
245 bool bTemporaryShape)
363 const uno::Reference< xml::sax::XFastAttributeList>& rAttrList,
364 uno::Reference< drawing::XShapes >
const & rShapes,
365 const uno::Reference< xml::sax::XFastAttributeList>& rFrameAttrList)
370 if( rFrameAttrList.is() )
371 xCombinedAttrList->add(rFrameAttrList);
429 for(
auto& aIter : *xCombinedAttrList)
442 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
444 css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
458 const uno::Reference< xml::sax::XFastAttributeList >&,
459 uno::Reference< drawing::XShapes >& rShapes)
461 if( rShape.is() && rShapes.is() )
464 rShapes->add( rShape );
466 uno::Reference<beans::XPropertySet> xPropertySet(rShape, uno::UNO_QUERY);
467 if (xPropertySet.is())
469 xPropertySet->setPropertyValue(
"HandlePathObjScale",
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 );
518 uno::Reference<drawing::XShape> xShape;
520 bool operator<(
const ZOrderHint& rComp)
const {
return nShould < rComp.nShould; }
525 class ShapeGroupContext
528 uno::Reference< drawing::XShapes > mxShapes;
529 std::vector<SdXMLEventContextData> maEventData;
530 vector<ZOrderHint> maZOrderList;
531 vector<ZOrderHint> maUnsortedList;
533 sal_Int32 mnCurrentZ;
534 std::shared_ptr<ShapeGroupContext> mpParentContext;
536 ShapeGroupContext( uno::Reference< drawing::XShapes >
const & rShapes, std::shared_ptr<ShapeGroupContext> pParentContext );
538 void popGroupAndPostProcess();
540 void moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos );
545 ShapeGroupContext::ShapeGroupContext( uno::Reference< drawing::XShapes >
const & rShapes, std::shared_ptr<ShapeGroupContext> pParentContext )
546 : mxShapes( rShapes ), mnCurrentZ( 0 ), mpParentContext(
std::move(pParentContext) )
550 void 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" );
581 void 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)
620 aNewHint.nIs = nCount;
621 aNewHint.nShould = -1;
623 maUnsortedList.insert(maUnsortedList.begin(), aNewHint);
628 bool bSorted = std::is_sorted(maZOrderList.begin(), maZOrderList.end(),
629 [](
const ZOrderHint& rLeft,
const ZOrderHint& rRight)
630 {
return rLeft.nShould < rRight.nShould; } );
636 std::sort(maZOrderList.begin(), maZOrderList.end());
638 uno::Reference<drawing::XShapes3> xShapes3(mxShapes, uno::UNO_QUERY);
641 uno::Sequence<sal_Int32> aNewOrder(maZOrderList.size() + maUnsortedList.size());
642 auto pNewOrder = aNewOrder.getArray();
645 for (
const ZOrderHint& rHint : maZOrderList)
648 for (vector<ZOrderHint>::iterator aIt = maUnsortedList.begin(); aIt != maUnsortedList.end() && nIndex < rHint.nShould; )
650 pNewOrder[nIndex++] = (*aIt).nIs;
651 aIt = maUnsortedList.erase(aIt);
654 pNewOrder[nIndex] = rHint.nIs;
660 xShapes3->sort(aNewOrder);
661 maZOrderList.clear();
664 catch (
const css::lang::IllegalArgumentException& )
670 sal_Int32 nIndex = 0;
671 for (
const ZOrderHint& rHint : maZOrderList)
673 for (vector<ZOrderHint>::iterator aIt = maUnsortedList.begin(); aIt != maUnsortedList.end() && nIndex < rHint.nShould; )
675 moveShape( (*aIt).nIs, nIndex++ );
676 aIt = maUnsortedList.erase(aIt);
680 if(rHint.nIs != nIndex )
681 moveShape( rHint.nIs, nIndex );
685 maZOrderList.clear();
690 mpImpl->mpGroupContext = std::make_shared<ShapeGroupContext>( rShapes,
mpImpl->mpGroupContext );
700 mpImpl->mpGroupContext->maEventData.push_back(rData);
709 if( !
mpImpl->mpGroupContext )
714 mpImpl->mpGroupContext->popGroupAndPostProcess();
716 catch(
const uno::Exception& )
722 mpImpl->mpGroupContext =
mpImpl->mpGroupContext->mpParentContext;
727 if( !
mpImpl->mpGroupContext)
731 aNewHint.nIs =
mpImpl->mpGroupContext->mnCurrentZ++;
732 aNewHint.nShould = nZIndex;
733 aNewHint.xShape = xShape;
738 mpImpl->mpGroupContext->maUnsortedList.push_back(aNewHint);
743 mpImpl->mpGroupContext->maZOrderList.push_back(aNewHint);
749 auto it = std::find_if(
mpImpl->mpGroupContext->maZOrderList.begin(),
mpImpl->mpGroupContext->maZOrderList.end(), [&xShape](
const ZOrderHint& rHint)
751 return rHint.xShape == xShape;
753 if (it ==
mpImpl->mpGroupContext->maZOrderList.end())
757 sal_Int32 nZIndex = it->nIs;
759 for (it =
mpImpl->mpGroupContext->maZOrderList.begin(); it !=
mpImpl->mpGroupContext->maZOrderList.end();)
761 if (it->nIs == nZIndex)
765 it =
mpImpl->mpGroupContext->maZOrderList.erase(it);
766 mpImpl->mpGroupContext->mnCurrentZ--;
769 else if (it->nIs > nZIndex)
780 const OUString& rDestShapeId,
781 sal_Int32 nDestGlueId )
783 ConnectionHint aHint;
784 aHint.mxConnector = rConnectorShape;
785 aHint.bStart = bStart;
786 aHint.aDestShapeId = rDestShapeId;
787 aHint.nDestGlueId = nDestGlueId;
789 mpImpl->maConnections.push_back( aHint );
794 const vector<ConnectionHint>::size_type nCount =
mpImpl->maConnections.size();
795 for( vector<ConnectionHint>::size_type
i = 0;
i < nCount;
i++ )
797 ConnectionHint& rHint =
mpImpl->maConnections[
i];
798 uno::Reference< beans::XPropertySet > xConnector( rHint.mxConnector, uno::UNO_QUERY );
799 if( xConnector.is() )
805 OUString aStr1(
"EdgeLine1Delta");
806 OUString aStr2(
"EdgeLine2Delta");
807 OUString aStr3(
"EdgeLine3Delta");
808 aLine1Delta = xConnector->getPropertyValue(aStr1);
809 aLine2Delta = xConnector->getPropertyValue(aStr2);
810 aLine3Delta = xConnector->getPropertyValue(aStr3);
815 uno::Reference< drawing::XShape > xShape(
824 sal_Int32 nGlueId = rHint.nDestGlueId < 4 ? rHint.nDestGlueId :
getGluePointId( xShape, rHint.nDestGlueId );
832 xConnector->setPropertyValue(aStr1, aLine1Delta );
833 xConnector->setPropertyValue(aStr2, aLine2Delta );
834 xConnector->setPropertyValue(aStr3, aLine3Delta );
837 mpImpl->maConnections.clear();
854 sal_Int32 nSourceId, sal_Int32 nDestinnationId )
857 mpPageContext->maShapeGluePointsMap[xShape][nSourceId] = nDestinnationId;
865 ShapeGluePointsMap::iterator aShapeIter(
mpPageContext->maShapeGluePointsMap.find( xShape ) );
866 if( aShapeIter !=
mpPageContext->maShapeGluePointsMap.end() )
868 for (
auto& rShapeId : (*aShapeIter).second )
870 if ( rShapeId.second != -1 )
871 rShapeId.second += n;
883 ShapeGluePointsMap::iterator aShapeIter(
mpPageContext->maShapeGluePointsMap.find( xShape ) );
884 if( aShapeIter !=
mpPageContext->maShapeGluePointsMap.end() )
886 GluePointIdMap::iterator aIdIter = (*aShapeIter).second.find(nSourceId);
887 if( aIdIter != (*aShapeIter).second.end() )
888 return (*aIdIter).second;
898 const std::shared_ptr<XMLShapeImportPageContextImpl> pOldContext =
mpPageContext;
899 mpPageContext = std::make_shared<XMLShapeImportPageContextImpl>();
919 mpImpl->mbHandleProgressBar =
true;
924 return mpImpl->mbHandleProgressBar;
930 return mpImpl->mbIsPresentationShapesSupported;
css::uno::Reference< css::drawing::XShape > mxShape
bool operator<(const tSchXMLIndexWithPart &rFirst, const tSchXMLIndexWithPart &rSecond)
rtl::Reference< SvXMLImportPropertyMapper > mpPresPagePropsMapper
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)
bool mbIsPresentationShapesSupported
bool IsHandleProgressBarEnabled() const
constexpr OUStringLiteral gsEndGluePointIndex(u"EndGluePointIndex")
XMLShapeImportHelper(SvXMLImport &rImporter, const css::uno::Reference< css::frame::XModel > &rModel, SvXMLImportPropertyMapper *pExtMapper=nullptr)
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...
const rtl::Reference< XMLTableImport > & GetShapeTableImport()
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
constexpr OUStringLiteral gsStartShape(u"StartShape")
rtl::Reference< SvXMLImportPropertyMapper > mpPropertySetMapper
bool IsShapePositionInHoriL2R() const
const XMLPropertyMapEntry aXMLSDPresPageProps[]
void setHyperlink(const OUString &rHyperlink)
void pushGroupForPostProcessing(css::uno::Reference< css::drawing::XShapes > &rShapes)
const css::uno::Reference< css::uno::XInterface > & getReference(const OUString &rIdentifier) const
std::shared_ptr< ShapeGroupContext > mpGroupContext
rtl::Reference< XMLTableImport > mxShapeTableImport
virtual ~XMLShapeImportHelper() override
#define XMLOFF_WARN_UNKNOWN(area, rIter)
::comphelper::UnoInterfaceToUniqueIdentifierMapper & getInterfaceToIdentifierMapper()
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
static OUString getPrefixAndNameFromToken(sal_Int32 nToken)
rtl::Reference< SvXMLStylesContext > mxAutoStylesContext
void SetAutoStylesContext(SvXMLStylesContext *pNew)
bool IsPresentationShapesSupported() const
queries the capability of the current model to create presentation shapes
void popGroupAndPostProcess()
std::vector< ConnectionHint > maConnections
void shapeWithZIndexAdded(css::uno::Reference< css::drawing::XShape > const &rShape, sal_Int32 nZIndex)
void restoreConnections()
void enableHandleProgressBar()
defines if the import should increment the progress bar or not
#define DBG_UNHANDLED_EXCEPTION(...)
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 ...
#define DBG_ASSERT(sCon, aError)
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...
rtl::Reference< SvXMLStylesContext > mxStylesContext
ShapeGluePointsMap maShapeGluePointsMap
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.
static SvXMLImportPropertyMapper * CreateParaDefaultExtPropMapper(SvXMLImport &)
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 ...
std::unique_ptr< XMLShapeImportHelperImpl > mpImpl
void moveGluePointMapping(const css::uno::Reference< css::drawing::XShape > &xShape, const sal_Int32 n)
moves all current DestinationId's for rXShape by n
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)
This class deliberately does not support XWeak, to improve performance when loading large documents...
void addShapeConnection(css::uno::Reference< css::drawing::XShape > const &rConnectorShape, bool bStart, const OUString &rDestShapeId, sal_Int32 nDestGlueId)
std::shared_ptr< XMLShapeImportPageContextImpl > mpPageContext
std::map< sal_Int32, sal_Int32 > GluePointIdMap
this map store all gluepoint id mappings for shapes that had user defined gluepoints.
std::shared_ptr< XMLShapeImportPageContextImpl > mpNext
#define SAL_WARN_IF(condition, area, stream)
uno::Reference< drawing::XShapes > mxShapes
Handling of tokens in XML:
#define SAL_INFO(area, stream)
void SetStylesContext(SvXMLStylesContext *pNew)
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...
#define XML_ELEMENT(prefix, name)
rtl::Reference< XMLSdPropHdlFactory > mpSdPropHdlFactory
virtual bool processAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter &)
const css::uno::Reference< css::frame::XModel > & GetModel() const
this struct is created for each startPage() call and stores information that is needed during import ...
std::unordered_map< css::uno::Reference< css::drawing::XShape >, GluePointIdMap > ShapeGluePointsMap
Reference< XSingleServiceFactory > xFactory
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
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)
static SvXMLImportPropertyMapper * CreateParaExtPropMapper(SvXMLImport &)
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...
constexpr OUStringLiteral gsEndShape(u"EndShape")
void ChainImportMapper(const rtl::Reference< SvXMLImportPropertyMapper > &rMapper)
this class is to enable adding members to the XMLShapeImportHelper without getting incompatible ...
static SvXMLImportPropertyMapper * CreateShapePropMapper(const css::uno::Reference< css::frame::XModel > &rModel, SvXMLImport &rImport)
creates a property mapper for external chaining
constexpr OUStringLiteral gsStartGluePointIndex(u"StartGluePointIndex")
bool IsTableShapeSupported() const