summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2012-11-21 09:46:38 +0000
committerArmin Le Grand <alg@apache.org>2012-11-21 09:46:38 +0000
commit202a345c32488dfc0ca6640f80dc2392a62911bc (patch)
tree39eb0e037b24d6c280b8e70765824349168cab22
parent4ae2ee84957b49f9b691341b8d9e93f920903d3c (diff)
#121379# When loading MultiImage, avoid registering xShape with ID until the winner is decided to not have multiple shapes registering with the same ID
Notes
Notes: prefer: 450cd772aa734cfcb989c8cedd3c0a454db74a34
-rw-r--r--xmloff/inc/xmloff/xmlmultiimagehelper.hxx5
-rw-r--r--xmloff/source/core/xmlmultiimagehelper.cxx65
-rw-r--r--xmloff/source/draw/ximpshap.cxx42
-rw-r--r--xmloff/source/draw/ximpshap.hxx10
-rw-r--r--xmloff/source/text/XMLTextFrameContext.cxx3
5 files changed, 89 insertions, 36 deletions
diff --git a/xmloff/inc/xmloff/xmlmultiimagehelper.hxx b/xmloff/inc/xmloff/xmlmultiimagehelper.hxx
index c7ce4bae7570..ea5edc92fe1b 100644
--- a/xmloff/inc/xmloff/xmlmultiimagehelper.hxx
+++ b/xmloff/inc/xmloff/xmlmultiimagehelper.hxx
@@ -43,8 +43,9 @@ public:
~multiImageImportHelper();
/// solve multiple imported images. The most valuable one is choosen,
- /// see imlementation for evtl. changing weights and/or adding filetypes
- void solveMultipleImages();
+ /// see imlementation for evtl. changing weights and/or adding filetypes.
+ /// returns the winner of the contest (which can be 0 when no candidates)
+ const SvXMLImportContext* solveMultipleImages();
/// add a content to the remembered image import contexts
void addContent(const SvXMLImportContext& rSvXMLImportContext);
diff --git a/xmloff/source/core/xmlmultiimagehelper.cxx b/xmloff/source/core/xmlmultiimagehelper.cxx
index 9047ac9d125c..9accd4984575 100644
--- a/xmloff/source/core/xmlmultiimagehelper.cxx
+++ b/xmloff/source/core/xmlmultiimagehelper.cxx
@@ -94,44 +94,57 @@ multiImageImportHelper::~multiImageImportHelper()
}
}
-void multiImageImportHelper::solveMultipleImages()
+const SvXMLImportContext* multiImageImportHelper::solveMultipleImages()
{
- if(maImplContextVector.size() > 1)
- {
- // multiple child contexts were imported, decide which is the most valuable one
- // and remove the rest
- sal_uInt32 nIndexOfPreferred(maImplContextVector.size());
- sal_uInt32 nBestQuality(0), a(0);
+ const SvXMLImportContext* pRetval = 0;
- for(a = 0; a < maImplContextVector.size(); a++)
+ if(maImplContextVector.size())
+ {
+ if(maImplContextVector.size() > 1)
{
- const rtl::OUString aStreamURL(getGraphicURLFromImportContext(**maImplContextVector[a]));
- const sal_uInt32 nNewQuality(getQualityIndex(aStreamURL));
+ // multiple child contexts were imported, decide which is the most valuable one
+ // and remove the rest
+ sal_uInt32 nIndexOfPreferred(maImplContextVector.size());
+ sal_uInt32 nBestQuality(0), a(0);
- if(nNewQuality > nBestQuality)
+ for(a = 0; a < maImplContextVector.size(); a++)
{
- nBestQuality = nNewQuality;
- nIndexOfPreferred = a;
+ const rtl::OUString aStreamURL(getGraphicURLFromImportContext(**maImplContextVector[a]));
+ const sal_uInt32 nNewQuality(getQualityIndex(aStreamURL));
+
+ if(nNewQuality > nBestQuality)
+ {
+ nBestQuality = nNewQuality;
+ nIndexOfPreferred = a;
+ }
}
- }
- // correct if needed, default is to use the last entry
- if(nIndexOfPreferred >= maImplContextVector.size())
- {
- nIndexOfPreferred = maImplContextVector.size() - 1;
- }
+ // correct if needed, default is to use the last entry
+ if(nIndexOfPreferred >= maImplContextVector.size())
+ {
+ nIndexOfPreferred = maImplContextVector.size() - 1;
+ }
- // Take out the most valuable one
- const std::vector< SvXMLImportContextRef* >::iterator aRemove(maImplContextVector.begin() + nIndexOfPreferred);
- delete *aRemove;
- maImplContextVector.erase(aRemove);
+ // get the winner
+ pRetval = *maImplContextVector[nIndexOfPreferred];
- // remove the rest from parent
- for(a = 0; a < maImplContextVector.size(); a++)
+ // remove the rest from parent
+ for(a = 0; a < maImplContextVector.size(); a++)
+ {
+ if(a != nIndexOfPreferred)
+ {
+ removeGraphicFromImportContext(**maImplContextVector[a]);
+ }
+ }
+ }
+ else
{
- removeGraphicFromImportContext(**maImplContextVector[a]);
+ // only one, winner is implicit
+ pRetval = *maImplContextVector[0];
}
}
+
+ return pRetval;
}
void multiImageImportHelper::addContent(const SvXMLImportContext& rSvXMLImportContext)
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index cef6ec5c005a..d2140a3d05b7 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -466,8 +466,16 @@ void SdXMLShapeContext::AddShape(uno::Reference< drawing::XShape >& xShape)
if( maShapeId.getLength() )
{
- uno::Reference< uno::XInterface > xRef( xShape, uno::UNO_QUERY );
- GetImport().getInterfaceToIdentifierMapper().registerReference( maShapeId, xRef );
+ const SdXMLGraphicObjectShapeContext* pGSC = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(this);
+
+ /* avoid registering when LateRegister is needed. E.g. MultiImage support where in-between multiple
+ xShapes with the same ID would be registered. Registration is done after deciding which image
+ to keep, see calls to solveMultipleImages */
+ if(!pGSC || !pGSC->getLateAddToIdentifierMapper())
+ {
+ uno::Reference< uno::XInterface > xRef( xShape, uno::UNO_QUERY );
+ GetImport().getInterfaceToIdentifierMapper().registerReference( maShapeId, xRef );
+ }
}
// #91065# count only if counting for shape import is enabled
@@ -2288,7 +2296,8 @@ SdXMLGraphicObjectShapeContext::SdXMLGraphicObjectShapeContext(
uno::Reference< drawing::XShapes >& rShapes,
sal_Bool bTemporaryShape)
: SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
- maURL()
+ maURL(),
+ mbLateAddToIdentifierMapper(false)
{
}
@@ -3428,9 +3437,16 @@ SvXMLImportContext *SdXMLFrameShapeContext::CreateChildContext( sal_uInt16 nPref
mbSupportsReplacement = IsXMLToken(rLocalName, XML_OBJECT ) || IsXMLToken(rLocalName, XML_OBJECT_OLE);
setSupportsMultipleContents(IsXMLToken(rLocalName, XML_IMAGE));
- if(getSupportsMultipleContents() && dynamic_cast< SdXMLGraphicObjectShapeContext* >(pContext))
+ if(getSupportsMultipleContents())
{
- addContent(*mxImplContext);
+ SdXMLGraphicObjectShapeContext* pGSC = dynamic_cast< SdXMLGraphicObjectShapeContext* >(pContext);
+
+ if(pGSC)
+ {
+ // mark context as LateAdd to avoid conflicts with multiple objects registering with the same ID
+ pGSC->setLateAddToIdentifierMapper(true);
+ addContent(*mxImplContext);
+ }
}
}
else if(getSupportsMultipleContents() && XML_NAMESPACE_DRAW == nPrefix && IsXMLToken(rLocalName, XML_IMAGE))
@@ -3440,8 +3456,12 @@ SvXMLImportContext *SdXMLFrameShapeContext::CreateChildContext( sal_uInt16 nPref
GetImport(), nPrefix, rLocalName, xAttrList, mxShapes, mxAttrList);
mxImplContext = pContext;
- if(dynamic_cast< SdXMLGraphicObjectShapeContext* >(pContext))
+ SdXMLGraphicObjectShapeContext* pGSC = dynamic_cast< SdXMLGraphicObjectShapeContext* >(pContext);
+
+ if(pGSC)
{
+ // mark context as LateAdd to avoid conflicts with multiple objects registering with the same ID
+ pGSC->setLateAddToIdentifierMapper(true);
addContent(*mxImplContext);
}
}
@@ -3504,7 +3524,15 @@ void SdXMLFrameShapeContext::StartElement(const uno::Reference< xml::sax::XAttri
void SdXMLFrameShapeContext::EndElement()
{
/// solve if multiple image child contexts were imported
- solveMultipleImages();
+ const SvXMLImportContext* pWinner = solveMultipleImages();
+ const SdXMLGraphicObjectShapeContext* pGSCWinner = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(pWinner);
+
+ /// if we have a winner and it's on LateAdd, add it now
+ if(pGSCWinner && pGSCWinner->getLateAddToIdentifierMapper() && pGSCWinner->getShapeId().getLength())
+ {
+ uno::Reference< uno::XInterface > xRef( pGSCWinner->getShape(), uno::UNO_QUERY );
+ GetImport().getInterfaceToIdentifierMapper().registerReference( pGSCWinner->getShapeId(), xRef );
+ }
if( !mxImplContext.Is() )
{
diff --git a/xmloff/source/draw/ximpshap.hxx b/xmloff/source/draw/ximpshap.hxx
index e8fe3725312f..a1dc22c4c070 100644
--- a/xmloff/source/draw/ximpshap.hxx
+++ b/xmloff/source/draw/ximpshap.hxx
@@ -118,6 +118,9 @@ public:
// this is called from the parent group for each unparsed attribute in the attribute list
virtual void processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue );
+
+ /// access to ShapeId for evtl. late adding
+ const rtl::OUString& getShapeId() const { return maShapeId; }
};
//////////////////////////////////////////////////////////////////////////////
@@ -404,6 +407,9 @@ private:
::rtl::OUString maURL;
::com::sun::star::uno::Reference < ::com::sun::star::io::XOutputStream > mxBase64Stream;
+ /// bitfield
+ bool mbLateAddToIdentifierMapper : 1;
+
public:
TYPEINFO();
@@ -421,6 +427,10 @@ public:
// this is called from the parent group for each unparsed attribute in the attribute list
virtual void processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue );
+
+ /// support for LateAddToIdentifierMapper
+ bool getLateAddToIdentifierMapper() const { return mbLateAddToIdentifierMapper; }
+ void setLateAddToIdentifierMapper(bool bNew) { mbLateAddToIdentifierMapper = bNew; }
};
//////////////////////////////////////////////////////////////////////////////
diff --git a/xmloff/source/text/XMLTextFrameContext.cxx b/xmloff/source/text/XMLTextFrameContext.cxx
index 3e741e2f65f9..c5e9f723d2f9 100644
--- a/xmloff/source/text/XMLTextFrameContext.cxx
+++ b/xmloff/source/text/XMLTextFrameContext.cxx
@@ -1440,7 +1440,8 @@ XMLTextFrameContext::~XMLTextFrameContext()
void XMLTextFrameContext::EndElement()
{
/// solve if multiple image child contexts were imported
- solveMultipleImages();
+ /// the winner is returned, if something has yet to be done with it
+ /*const SvXMLImportContext* pWinner =*/ solveMultipleImages();
SvXMLImportContext *pContext = &m_xImplContext;
XMLTextFrameContext_Impl *pImpl = PTR_CAST( XMLTextFrameContext_Impl, pContext );