Resolves: #i124143# for draw:frame containing multiple draw:image...

and draw:glue-point it is necessary to move the GluePoints from the last
draw:image where they were automatically imported to the surviving one if these
are different

(cherry picked from commit c011af1087411a9bacd29cd479c807e698b2e92c)

Conflicts:
	xmloff/inc/xmloff/xmlictxt.hxx
	xmloff/source/core/xmlmultiimagehelper.cxx
	xmloff/source/draw/ximpshap.cxx
	xmloff/source/draw/ximpshap.hxx

Change-Id: I8f6c875767e9cbfee74838742401356df002b051
This commit is contained in:
Armin Le Grand 2014-02-04 17:42:05 +00:00 committed by Caolán McNamara
parent 461550cdb5
commit 258e6f93e8
7 changed files with 125 additions and 3 deletions

View File

@ -387,12 +387,17 @@ public:
void addGluePointMapping( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape,
sal_Int32 nSourceId, sal_Int32 nDestinnationId );
/** find mapping for given DestinationID. This allows to extract the original draw:id imported with a draw:glue-point */
sal_Int32 findGluePointMapping(
const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape,
sal_Int32 nDestinnationId ) const;
/** moves all current DestinationId's for rXShape by n */
void moveGluePointMapping( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, const sal_Int32 n );
/** retrieves a mapping for a glue point identifier from the current xml file to the identifier created after
inserting the new glue point into the core. The mapping must be initialized first with addGluePointMapping() */
sal_Int32 getGluePointId( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, sal_Int32 nSourceId );
sal_Int32 getGluePointId( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, sal_Int32 nSourceId );
/** this method must be calling before the first shape is imported for the given page.
Calls to this method can be nested */

View File

@ -89,6 +89,11 @@ public:
/** This method is called for all characters that are contained in the
* current element. The default is to ignore them. */
virtual void Characters( const OUString& rChars );
// #i124143# allow to copy evtl. useful data from another temporary import context, e.g. used to
// support multiple images and to rescue evtl. GluePoints imported with one of the
// to be deprecated contents
virtual void onDemandRescueUsefulDataFromTemporary( const SvXMLImportContext& rCandidate );
};
SV_DECL_REF( SvXMLImportContext )

View File

@ -69,5 +69,8 @@ void SvXMLImportContext::Characters( const OUString& )
{
}
void SvXMLImportContext::onDemandRescueUsefulDataFromTemporary( const SvXMLImportContext& )
{
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -120,7 +120,16 @@ SvXMLImportContextRef MultiImageImportHelper::solveMultipleImages()
// remove the rest from parent
for(a = 0; a < maImplContextVector.size(); a++)
{
removeGraphicFromImportContext(**maImplContextVector[a]);
SvXMLImportContext& rCandidate = **maImplContextVector[a];
if(pContext)
{
// #i124143# evtl. copy imported GluePoints before deprecating
// this graphic and context
pContext->onDemandRescueUsefulDataFromTemporary(rCandidate);
}
removeGraphicFromImportContext(rCandidate);
}
}
else if (maImplContextVector.size() == 1)

View File

@ -1031,6 +1031,35 @@ void XMLShapeImportHelper::addGluePointMapping( com::sun::star::uno::Reference<
mpPageContext->maShapeGluePointsMap[xShape][nSourceId] = nDestinnationId;
}
/** find mapping for given DestinationID. This allows to extract the original draw:id imported with a draw:glue-point */
sal_Int32 XMLShapeImportHelper::findGluePointMapping(
const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape,
sal_Int32 nDestinnationId ) const
{
if( mpPageContext )
{
ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );
if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
{
GluePointIdMap::iterator aShapeIdIter = (*aShapeIter).second.begin();
GluePointIdMap::iterator aShapeIdEnd = (*aShapeIter).second.end();
while ( aShapeIdIter != aShapeIdEnd )
{
if ( (*aShapeIdIter).second == nDestinnationId )
{
return (*aShapeIdIter).first;
}
aShapeIdIter++;
}
}
}
return -1;
}
/** moves all current DestinationId's by n */
void XMLShapeImportHelper::moveGluePointMapping( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, const sal_Int32 n )
{
@ -1053,7 +1082,7 @@ void XMLShapeImportHelper::moveGluePointMapping( const com::sun::star::uno::Refe
/** retrieves a mapping for a glue point identifier from the current xml file to the identifier created after
inserting the new glue point into the core. The mapping must be initialized first with addGluePointMapping() */
sal_Int32 XMLShapeImportHelper::getGluePointId( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, sal_Int32 nSourceId )
sal_Int32 XMLShapeImportHelper::getGluePointId( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, sal_Int32 nSourceId )
{
if( mpPageContext )
{

View File

@ -917,6 +917,73 @@ sal_Bool SdXMLShapeContext::isPresentationShape() const
return sal_False;
}
void SdXMLShapeContext::onDemandRescueUsefulDataFromTemporary( const SvXMLImportContext& rCandidate )
{
const SdXMLShapeContext* pCandidate = dynamic_cast< const SdXMLShapeContext* >(&rCandidate);
if(!mxGluePoints.is() && pCandidate)
{
// try to rescue GluePoints from rCandidate to local if we not yet have GluePoints by copying them
uno::Reference< drawing::XGluePointsSupplier > xSourceSupplier( pCandidate->getShape(), uno::UNO_QUERY );
if( !xSourceSupplier.is() )
return;
uno::Reference< container::XIdentifierAccess > xSourceGluePoints( xSourceSupplier->getGluePoints(), uno::UNO_QUERY );
if( !xSourceGluePoints.is() )
return;
uno::Sequence< sal_Int32 > aSourceIdSequence( xSourceGluePoints->getIdentifiers() );
const sal_Int32 nSourceCount(aSourceIdSequence.getLength());
UniReference< XMLShapeImportHelper > xSourceShapeImportHelper(const_cast< SdXMLShapeContext* >(pCandidate)->GetImport().GetShapeImport());
if(nSourceCount)
{
// rCandidate has GluePoints; prepare the GluePoint container for the local shape
uno::Reference< drawing::XGluePointsSupplier > xSupplier( mxShape, uno::UNO_QUERY );
if( !xSupplier.is() )
return;
mxGluePoints = uno::Reference< container::XIdentifierContainer >::query( xSupplier->getGluePoints() );
if( !mxGluePoints.is() )
return;
drawing::GluePoint2 aSourceGluePoint;
for( sal_Int32 nSourceIndex(0); nSourceIndex < nSourceCount; nSourceIndex++ )
{
const sal_Int32 nSourceIdentifier = aSourceIdSequence[nSourceIndex];
// loop over GluePoints which are UserDefined (avoid the auto mapped ones)
if((xSourceGluePoints->getByIdentifier( nSourceIdentifier ) >>= aSourceGluePoint)
&& aSourceGluePoint.IsUserDefined)
{
// get original mappingID back, this is the draw:id imported with a draw:glue-point
const sal_Int32 nDestinnationId = xSourceShapeImportHelper->findGluePointMapping(
pCandidate->getShape(),
nSourceIdentifier );
if(-1 != nSourceIdentifier)
{
// if we got that we are able to add a copy of that GluePoint to the local
// context and xShape since we have all information that the source shape
// and context had at import time
try
{
const sal_Int32 nInternalId = mxGluePoints->insert( uno::makeAny( aSourceGluePoint ) );
GetImport().GetShapeImport()->addGluePointMapping( mxShape, nDestinnationId, nInternalId );
}
catch (const uno::Exception& e)
{
SAL_WARN("xmloff", "exception during setting of glue points: " << e.Message);
}
}
}
}
}
}
}
TYPEINIT1( SdXMLRectShapeContext, SdXMLShapeContext );
SdXMLRectShapeContext::SdXMLRectShapeContext(

View File

@ -115,6 +115,10 @@ public:
// this is called from the parent group for each unparsed attribute in the attribute list
virtual void processAttribute( sal_uInt16 nPrefix, const OUString& rLocalName, const OUString& rValue );
// allow to copy evtl. useful data from another temporary import context, e.g. used to
// support multiple images
virtual void onDemandRescueUsefulDataFromTemporary( const SvXMLImportContext& rCandidate );
};
// draw:rect context