summaryrefslogtreecommitdiff
path: root/oox/source/vml/vmldrawing.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'oox/source/vml/vmldrawing.cxx')
-rw-r--r--oox/source/vml/vmldrawing.cxx145
1 files changed, 130 insertions, 15 deletions
diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx
index 61dfd4b6c362..ca2d362d11d8 100644
--- a/oox/source/vml/vmldrawing.cxx
+++ b/oox/source/vml/vmldrawing.cxx
@@ -27,28 +27,32 @@
************************************************************************/
#include "oox/vml/vmldrawing.hxx"
+
+#include <algorithm>
+#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/drawing/XShapes.hpp>
-#include "tokens.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include "oox/core/xmlfilterbase.hxx"
+#include "oox/helper/containerhelper.hxx"
#include "oox/ole/axcontrol.hxx"
#include "oox/vml/vmlshape.hxx"
#include "oox/vml/vmlshapecontainer.hxx"
-using ::rtl::OUString;
-using ::com::sun::star::uno::Reference;
-using ::com::sun::star::uno::UNO_QUERY;
-using ::com::sun::star::awt::Rectangle;
-using ::com::sun::star::awt::XControlModel;
-using ::com::sun::star::drawing::XDrawPage;
-using ::com::sun::star::drawing::XShape;
-using ::com::sun::star::drawing::XShapes;
-using ::oox::core::XmlFilterBase;
-
namespace oox {
namespace vml {
// ============================================================================
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::oox::core::XmlFilterBase;
+using ::rtl::OUString;
+
+// ============================================================================
+
namespace {
/** Returns the textual representation of a numeric VML shape identifier. */
@@ -58,6 +62,13 @@ OUString lclGetShapeId( sal_Int32 nShapeId )
return CREATE_OUSTRING( "\0s" ) + OUString::valueOf( nShapeId );
}
+/** Returns the numeric VML shape identifier from its textual representation. */
+sal_Int32 lclGetShapeId( const OUString& rShapeId )
+{
+ // identifier consists of a literal NUL character, a lowercase 's', and the id
+ return ((rShapeId.getLength() >= 3) && (rShapeId[ 0 ] == '\0') && (rShapeId[ 1 ] == 's')) ? rShapeId.copy( 2 ).toInt32() : -1;
+}
+
} // namespace
// ============================================================================
@@ -107,6 +118,18 @@ Drawing::~Drawing()
return *mxCtrlForm;
}
+void Drawing::registerBlockId( sal_Int32 nBlockId )
+{
+ OSL_ENSURE( nBlockId > 0, "Drawing::registerBlockId - invalid block index" );
+ if( nBlockId > 0 )
+ {
+ // lower_bound() returns iterator pointing to element equal to nBlockId, if existing
+ BlockIdVector::iterator aIt = ::std::lower_bound( maBlockIds.begin(), maBlockIds.end(), nBlockId );
+ if( (aIt == maBlockIds.end()) || (nBlockId != *aIt) )
+ maBlockIds.insert( aIt, nBlockId );
+ }
+}
+
void Drawing::registerOleObject( const OleObjectInfo& rOleObject )
{
OSL_ENSURE( rOleObject.maShapeId.getLength() > 0, "Drawing::registerOleObject - missing OLE object shape id" );
@@ -133,6 +156,47 @@ void Drawing::convertAndInsert() const
mxShapes->convertAndInsert( xShapes );
}
+sal_Int32 Drawing::getLocalShapeIndex( const OUString& rShapeId ) const
+{
+ sal_Int32 nShapeId = lclGetShapeId( rShapeId );
+ if( nShapeId <= 0 ) return -1;
+
+ /* Shapes in a drawing are counted per registered shape identifier blocks
+ as stored in the o:idmap element. The contents of this element have
+ been stored in our member maBlockIds. Each block represents 1024 shape
+ identifiers, starting with identifier 1 for the block #0. This means,
+ block #0 represents the identifiers 1-1024, block #1 represents the
+ identifiers 1025-2048, and so on. The local shape index has to be
+ calculated according to all blocks registered for this drawing.
+
+ Example:
+ Registered for this drawing are blocks #1 and #3 (shape identifiers
+ 1025-2048 and 3073-4096).
+ Shape identifier 1025 -> local shape index 1.
+ Shape identifier 1026 -> local shape index 2.
+ ...
+ Shape identifier 2048 -> local shape index 1024.
+ Shape identifier 3073 -> local shape index 1025.
+ ...
+ Shape identifier 4096 -> local shape index 2048.
+ */
+
+ // get block id from shape id and find its index in the list of used blocks
+ sal_Int32 nBlockId = (nShapeId - 1) / 1024;
+ BlockIdVector::iterator aIt = ::std::lower_bound( maBlockIds.begin(), maBlockIds.end(), nBlockId );
+ sal_Int32 nIndex = static_cast< sal_Int32 >( aIt - maBlockIds.begin() );
+
+ // block id not found in set -> register it now (value of nIndex remains valid)
+ if( (aIt == maBlockIds.end()) || (*aIt != nBlockId) )
+ maBlockIds.insert( aIt, nBlockId );
+
+ // get one-based offset of shape id in its block
+ sal_Int32 nBlockOffset = (nShapeId - 1) % 1024 + 1;
+
+ // calculate the local shape index
+ return 1024 * nIndex + nBlockOffset;
+}
+
const OleObjectInfo* Drawing::getOleObjectInfo( const OUString& rShapeId ) const
{
return ContainerHelper::getMapElement( maOleObjects, rShapeId );
@@ -143,21 +207,72 @@ const ControlInfo* Drawing::getControlInfo( const OUString& rShapeId ) const
return ContainerHelper::getMapElement( maControls, rShapeId );
}
+Reference< XShape > Drawing::createAndInsertXShape( const OUString& rService,
+ const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ OSL_ENSURE( rService.getLength() > 0, "Drawing::createAndInsertXShape - missing UNO shape service name" );
+ OSL_ENSURE( rxShapes.is(), "Drawing::createAndInsertXShape - missing XShapes container" );
+ Reference< XShape > xShape;
+ if( (rService.getLength() > 0) && rxShapes.is() ) try
+ {
+ Reference< XMultiServiceFactory > xFactory( mrFilter.getModelFactory(), UNO_SET_THROW );
+ xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW );
+ // insert shape into passed shape collection (maybe drawpage or group shape)
+ rxShapes->add( xShape );
+ xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) );
+ xShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xShape.is(), "Drawing::createAndInsertXShape - cannot instanciate shape object" );
+ return xShape;
+}
+
+Reference< XShape > Drawing::createAndInsertXControlShape( const ::oox::ole::EmbeddedControl& rControl,
+ const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect, sal_Int32& rnCtrlIndex ) const
+{
+ Reference< XShape > xShape;
+ try
+ {
+ // create control model and insert it into the form of the draw page
+ Reference< XControlModel > xCtrlModel( getControlForm().convertAndInsert( rControl, rnCtrlIndex ), UNO_SET_THROW );
+
+ // create the control shape
+ xShape = createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ), rxShapes, rShapeRect );
+
+ // set the control model at the shape
+ Reference< XControlShape >( xShape, UNO_QUERY_THROW )->setControl( xCtrlModel );
+ }
+ catch( Exception& )
+ {
+ }
+ return xShape;
+}
+
bool Drawing::isShapeSupported( const ShapeBase& /*rShape*/ ) const
{
return true;
}
-bool Drawing::convertShapeClientAnchor( Rectangle& /*orShapeRect*/, const OUString& /*rShapeAnchor*/ ) const
+OUString Drawing::getShapeBaseName( const ShapeBase& /*rShape*/ ) const
+{
+ return OUString();
+}
+
+bool Drawing::convertClientAnchor( Rectangle& /*orShapeRect*/, const OUString& /*rShapeAnchor*/ ) const
{
return false;
}
-void Drawing::convertControlClientData( const Reference< XControlModel >& /*rxCtrlModel*/, const ShapeClientData& /*rClientData*/ ) const
+Reference< XShape > Drawing::createAndInsertClientXShape( const ShapeBase& /*rShape*/,
+ const Reference< XShapes >& /*rxShapes*/, const Rectangle& /*rShapeRect*/ ) const
{
+ return Reference< XShape >();
}
-void Drawing::notifyShapeInserted( const Reference< XShape >& /*rxShape*/, const Rectangle& /*rShapeRect*/ )
+void Drawing::notifyXShapeInserted( const Reference< XShape >& /*rxShape*/,
+ const Rectangle& /*rShapeRect*/, const ShapeBase& /*rShape*/, bool /*bGroupChild*/ )
{
}
@@ -166,4 +281,4 @@ void Drawing::notifyShapeInserted( const Reference< XShape >& /*rxShape*/, const
} // namespace vml
} // namespave oox
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ \ No newline at end of file