2010-10-12 15:53:47 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-06-21 14:30:25 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
2006-09-17 09:21:40 +00:00
|
|
|
|
2011-07-20 22:27:51 +02:00
|
|
|
#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
|
2004-11-26 18:30:10 +00:00
|
|
|
|
2012-10-22 13:26:47 +01:00
|
|
|
using namespace ::com::sun::star;
|
2004-11-26 18:30:10 +00:00
|
|
|
using ::com::sun::star::uno::Reference;
|
|
|
|
using ::com::sun::star::uno::XInterface;
|
|
|
|
|
|
|
|
namespace comphelper
|
|
|
|
{
|
|
|
|
|
|
|
|
UnoInterfaceToUniqueIdentifierMapper::UnoInterfaceToUniqueIdentifierMapper()
|
|
|
|
: mnNextId( 1 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
const OUString& UnoInterfaceToUniqueIdentifierMapper::registerReference( const Reference< XInterface >& rInterface )
|
|
|
|
{
|
2012-10-22 13:26:47 +01:00
|
|
|
// Be certain that the references we store in our table are to the
|
|
|
|
// leading / primary XInterface - cf. findReference
|
|
|
|
uno::Reference< uno::XInterface > xRef( rInterface, uno::UNO_QUERY );
|
|
|
|
|
2004-11-26 18:30:10 +00:00
|
|
|
IdMap_t::const_iterator aIter;
|
2012-10-22 13:26:47 +01:00
|
|
|
if( findReference( xRef, aIter ) )
|
2004-11-26 18:30:10 +00:00
|
|
|
{
|
|
|
|
return (*aIter).first;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-07-10 11:01:00 +02:00
|
|
|
OUString aId( "id" );
|
2013-08-21 15:07:31 +02:00
|
|
|
aId += OUString::number( mnNextId++ );
|
2012-10-22 13:26:47 +01:00
|
|
|
return (*maEntries.insert( IdMap_t::value_type( aId, xRef ) ).first).first;
|
2004-11-26 18:30:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnoInterfaceToUniqueIdentifierMapper::registerReference( const OUString& rIdentifier, const Reference< XInterface >& rInterface )
|
|
|
|
{
|
|
|
|
IdMap_t::const_iterator aIter;
|
2012-10-22 13:26:47 +01:00
|
|
|
|
|
|
|
// Be certain that the references we store in our table are to the
|
|
|
|
// leading / primary XInterface - cf. findReference
|
|
|
|
uno::Reference< uno::XInterface > xRef( rInterface, uno::UNO_QUERY );
|
|
|
|
|
|
|
|
if( findReference( xRef, aIter ) )
|
2004-11-26 18:30:10 +00:00
|
|
|
{
|
|
|
|
return rIdentifier != (*aIter).first;
|
|
|
|
}
|
2013-05-15 11:05:45 +02:00
|
|
|
else if( findIdentifier( rIdentifier, aIter ) )
|
2004-11-26 18:30:10 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-05-15 11:05:45 +02:00
|
|
|
insertReference( rIdentifier, xRef );
|
|
|
|
}
|
2004-11-26 18:30:10 +00:00
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
return true;
|
|
|
|
}
|
2004-11-26 18:30:10 +00:00
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
void UnoInterfaceToUniqueIdentifierMapper::registerReferenceAlways( const OUString& rIdentifier, const Reference< XInterface >& rInterface )
|
|
|
|
{
|
|
|
|
// Be certain that the references we store in our table are to the
|
|
|
|
// leading / primary XInterface - cf. findReference
|
|
|
|
uno::Reference< uno::XInterface > xRef( rInterface, uno::UNO_QUERY );
|
2004-11-26 18:30:10 +00:00
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
insertReference( rIdentifier, xRef );
|
2004-11-26 18:30:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const OUString& UnoInterfaceToUniqueIdentifierMapper::getIdentifier( const Reference< XInterface >& rInterface ) const
|
|
|
|
{
|
|
|
|
IdMap_t::const_iterator aIter;
|
|
|
|
if( findReference( rInterface, aIter ) )
|
|
|
|
{
|
|
|
|
return (*aIter).first;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
static const OUString aEmpty;
|
|
|
|
return aEmpty;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const Reference< XInterface >& UnoInterfaceToUniqueIdentifierMapper::getReference( const OUString& rIdentifier ) const
|
|
|
|
{
|
|
|
|
IdMap_t::const_iterator aIter;
|
|
|
|
if( findIdentifier( rIdentifier, aIter ) )
|
|
|
|
{
|
|
|
|
return (*aIter).second;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
static const Reference< XInterface > aEmpty;
|
|
|
|
return aEmpty;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnoInterfaceToUniqueIdentifierMapper::findReference( const Reference< XInterface >& rInterface, IdMap_t::const_iterator& rIter ) const
|
|
|
|
{
|
2012-10-22 13:26:47 +01:00
|
|
|
uno::Reference< uno::XInterface > xRef( rInterface, uno::UNO_QUERY );
|
|
|
|
|
2004-11-26 18:30:10 +00:00
|
|
|
rIter = maEntries.begin();
|
2012-10-22 13:26:47 +01:00
|
|
|
|
2004-11-26 18:30:10 +00:00
|
|
|
const IdMap_t::const_iterator aEnd( maEntries.end() );
|
|
|
|
while( rIter != aEnd )
|
|
|
|
{
|
2012-10-22 13:26:47 +01:00
|
|
|
// The Reference == operator, does a repeated queryInterface on
|
|
|
|
// this to ensure we got the right XInterface base-class. However,
|
|
|
|
// we can be sure that this has been done already by the time we
|
|
|
|
// get to here.
|
|
|
|
if( (*rIter).second.get() == xRef.get() )
|
2004-11-26 18:30:10 +00:00
|
|
|
return true;
|
|
|
|
|
2015-03-13 14:16:51 +01:00
|
|
|
++rIter;
|
2004-11-26 18:30:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnoInterfaceToUniqueIdentifierMapper::findIdentifier( const OUString& rIdentifier, IdMap_t::const_iterator& rIter ) const
|
|
|
|
{
|
|
|
|
rIter = maEntries.find( rIdentifier );
|
|
|
|
return rIter != maEntries.end();
|
|
|
|
}
|
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
void UnoInterfaceToUniqueIdentifierMapper::insertReference( const OUString& rIdentifier, const Reference< XInterface >& rInterface )
|
fdo#60075 open drawings with connector attached to SVG
This problem arises when there is a connector attached to draw:frame
element with multiple draw:image elements in it. The import code expects
that they are different representations of the same image (I have not
found if this is specified in ODF), so it only selects the most
"suitable" for import. To do that, it imports them all and then removes
all but the selected one. The image import context,
SdXMLGraphicObjectShapeContext, shares the parent frame's attributes,
which means that all the images in a frame have got the same ID. in
SdXMLGraphicObjectShapeContext::AddShape, the created css::draw::XShape
is registered with its ID... That means that anything that refers to the
frame's ID, like a draw:connector, will always get the _first_ image in
the frame.
Solution is to extend comphelper::UnoInterfaceToUniqueIdentifierMapper
to allow reserving an identifier and setting an interface for it later.
That way, SdXMLFrameShapeContext can reserve its own ID before it starts
importing the first draw:image, and then set the selected XShape at the
end.
Change-Id: I2e11cfd38e1e3534df2b3c01d85da0d755a266c3
2013-05-03 06:15:30 +02:00
|
|
|
{
|
2013-05-15 11:05:45 +02:00
|
|
|
maEntries[rIdentifier] = rInterface;
|
fdo#60075 open drawings with connector attached to SVG
This problem arises when there is a connector attached to draw:frame
element with multiple draw:image elements in it. The import code expects
that they are different representations of the same image (I have not
found if this is specified in ODF), so it only selects the most
"suitable" for import. To do that, it imports them all and then removes
all but the selected one. The image import context,
SdXMLGraphicObjectShapeContext, shares the parent frame's attributes,
which means that all the images in a frame have got the same ID. in
SdXMLGraphicObjectShapeContext::AddShape, the created css::draw::XShape
is registered with its ID... That means that anything that refers to the
frame's ID, like a draw:connector, will always get the _first_ image in
the frame.
Solution is to extend comphelper::UnoInterfaceToUniqueIdentifierMapper
to allow reserving an identifier and setting an interface for it later.
That way, SdXMLFrameShapeContext can reserve its own ID before it starts
importing the first draw:image, and then set the selected XShape at the
end.
Change-Id: I2e11cfd38e1e3534df2b3c01d85da0d755a266c3
2013-05-03 06:15:30 +02:00
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
// see if this is a reference like something we would generate in the future
|
|
|
|
const sal_Unicode *p = rIdentifier.getStr();
|
|
|
|
sal_Int32 nLength = rIdentifier.getLength();
|
fdo#60075 open drawings with connector attached to SVG
This problem arises when there is a connector attached to draw:frame
element with multiple draw:image elements in it. The import code expects
that they are different representations of the same image (I have not
found if this is specified in ODF), so it only selects the most
"suitable" for import. To do that, it imports them all and then removes
all but the selected one. The image import context,
SdXMLGraphicObjectShapeContext, shares the parent frame's attributes,
which means that all the images in a frame have got the same ID. in
SdXMLGraphicObjectShapeContext::AddShape, the created css::draw::XShape
is registered with its ID... That means that anything that refers to the
frame's ID, like a draw:connector, will always get the _first_ image in
the frame.
Solution is to extend comphelper::UnoInterfaceToUniqueIdentifierMapper
to allow reserving an identifier and setting an interface for it later.
That way, SdXMLFrameShapeContext can reserve its own ID before it starts
importing the first draw:image, and then set the selected XShape at the
end.
Change-Id: I2e11cfd38e1e3534df2b3c01d85da0d755a266c3
2013-05-03 06:15:30 +02:00
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
// see if the identifier is 'id' followed by a pure integer value
|
|
|
|
if( nLength < 2 || p[0] != 'i' || p[1] != 'd' )
|
|
|
|
return;
|
fdo#60075 open drawings with connector attached to SVG
This problem arises when there is a connector attached to draw:frame
element with multiple draw:image elements in it. The import code expects
that they are different representations of the same image (I have not
found if this is specified in ODF), so it only selects the most
"suitable" for import. To do that, it imports them all and then removes
all but the selected one. The image import context,
SdXMLGraphicObjectShapeContext, shares the parent frame's attributes,
which means that all the images in a frame have got the same ID. in
SdXMLGraphicObjectShapeContext::AddShape, the created css::draw::XShape
is registered with its ID... That means that anything that refers to the
frame's ID, like a draw:connector, will always get the _first_ image in
the frame.
Solution is to extend comphelper::UnoInterfaceToUniqueIdentifierMapper
to allow reserving an identifier and setting an interface for it later.
That way, SdXMLFrameShapeContext can reserve its own ID before it starts
importing the first draw:image, and then set the selected XShape at the
end.
Change-Id: I2e11cfd38e1e3534df2b3c01d85da0d755a266c3
2013-05-03 06:15:30 +02:00
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
nLength -= 2;
|
|
|
|
p += 2;
|
fdo#60075 open drawings with connector attached to SVG
This problem arises when there is a connector attached to draw:frame
element with multiple draw:image elements in it. The import code expects
that they are different representations of the same image (I have not
found if this is specified in ODF), so it only selects the most
"suitable" for import. To do that, it imports them all and then removes
all but the selected one. The image import context,
SdXMLGraphicObjectShapeContext, shares the parent frame's attributes,
which means that all the images in a frame have got the same ID. in
SdXMLGraphicObjectShapeContext::AddShape, the created css::draw::XShape
is registered with its ID... That means that anything that refers to the
frame's ID, like a draw:connector, will always get the _first_ image in
the frame.
Solution is to extend comphelper::UnoInterfaceToUniqueIdentifierMapper
to allow reserving an identifier and setting an interface for it later.
That way, SdXMLFrameShapeContext can reserve its own ID before it starts
importing the first draw:image, and then set the selected XShape at the
end.
Change-Id: I2e11cfd38e1e3534df2b3c01d85da0d755a266c3
2013-05-03 06:15:30 +02:00
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
while(nLength--)
|
|
|
|
{
|
|
|
|
if( (*p < '0') || (*p > '9') )
|
|
|
|
return; // a custom id, that will never conflict with genereated id's
|
fdo#60075 open drawings with connector attached to SVG
This problem arises when there is a connector attached to draw:frame
element with multiple draw:image elements in it. The import code expects
that they are different representations of the same image (I have not
found if this is specified in ODF), so it only selects the most
"suitable" for import. To do that, it imports them all and then removes
all but the selected one. The image import context,
SdXMLGraphicObjectShapeContext, shares the parent frame's attributes,
which means that all the images in a frame have got the same ID. in
SdXMLGraphicObjectShapeContext::AddShape, the created css::draw::XShape
is registered with its ID... That means that anything that refers to the
frame's ID, like a draw:connector, will always get the _first_ image in
the frame.
Solution is to extend comphelper::UnoInterfaceToUniqueIdentifierMapper
to allow reserving an identifier and setting an interface for it later.
That way, SdXMLFrameShapeContext can reserve its own ID before it starts
importing the first draw:image, and then set the selected XShape at the
end.
Change-Id: I2e11cfd38e1e3534df2b3c01d85da0d755a266c3
2013-05-03 06:15:30 +02:00
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
p++;
|
|
|
|
}
|
fdo#60075 open drawings with connector attached to SVG
This problem arises when there is a connector attached to draw:frame
element with multiple draw:image elements in it. The import code expects
that they are different representations of the same image (I have not
found if this is specified in ODF), so it only selects the most
"suitable" for import. To do that, it imports them all and then removes
all but the selected one. The image import context,
SdXMLGraphicObjectShapeContext, shares the parent frame's attributes,
which means that all the images in a frame have got the same ID. in
SdXMLGraphicObjectShapeContext::AddShape, the created css::draw::XShape
is registered with its ID... That means that anything that refers to the
frame's ID, like a draw:connector, will always get the _first_ image in
the frame.
Solution is to extend comphelper::UnoInterfaceToUniqueIdentifierMapper
to allow reserving an identifier and setting an interface for it later.
That way, SdXMLFrameShapeContext can reserve its own ID before it starts
importing the first draw:image, and then set the selected XShape at the
end.
Change-Id: I2e11cfd38e1e3534df2b3c01d85da0d755a266c3
2013-05-03 06:15:30 +02:00
|
|
|
|
2013-05-15 11:05:45 +02:00
|
|
|
// the identifier is a pure integer value
|
|
|
|
// so we make sure we will never generate
|
|
|
|
// an integer value like this one
|
|
|
|
sal_Int32 nId = rIdentifier.copy(2).toInt32();
|
|
|
|
if( mnNextId <= nId )
|
|
|
|
mnNextId = nId + 1;
|
fdo#60075 open drawings with connector attached to SVG
This problem arises when there is a connector attached to draw:frame
element with multiple draw:image elements in it. The import code expects
that they are different representations of the same image (I have not
found if this is specified in ODF), so it only selects the most
"suitable" for import. To do that, it imports them all and then removes
all but the selected one. The image import context,
SdXMLGraphicObjectShapeContext, shares the parent frame's attributes,
which means that all the images in a frame have got the same ID. in
SdXMLGraphicObjectShapeContext::AddShape, the created css::draw::XShape
is registered with its ID... That means that anything that refers to the
frame's ID, like a draw:connector, will always get the _first_ image in
the frame.
Solution is to extend comphelper::UnoInterfaceToUniqueIdentifierMapper
to allow reserving an identifier and setting an interface for it later.
That way, SdXMLFrameShapeContext can reserve its own ID before it starts
importing the first draw:image, and then set the selected XShape at the
end.
Change-Id: I2e11cfd38e1e3534df2b3c01d85da0d755a266c3
2013-05-03 06:15:30 +02:00
|
|
|
}
|
|
|
|
|
2006-06-19 17:05:53 +00:00
|
|
|
}
|
2004-11-26 18:30:10 +00:00
|
|
|
|
2010-10-12 15:53:47 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|