summaryrefslogtreecommitdiff
path: root/oox/source/vml
diff options
context:
space:
mode:
authorIvo Hinkelmann <ihi@openoffice.org>2009-07-15 14:57:49 +0000
committerIvo Hinkelmann <ihi@openoffice.org>2009-07-15 14:57:49 +0000
commit0851da4d8a0a557f1e9a31af652a530c615c2989 (patch)
tree4c630979f4764c52e84314e9bb16d22416a447b2 /oox/source/vml
parente49ca2777ba38f75b24a49d30f59c2f0d2be79e6 (diff)
CWS-TOOLING: integrate CWS dr68
2009-06-19 17:43:48 +0200 oc r273175 : #i102946# some lines for new dialog added 2009-06-19 14:17:45 +0200 oc r273158 : #i102946# three lines added 2009-05-19 11:56:14 +0200 dr r272065 : #i99677# wrong attribute name 2009-05-18 18:37:05 +0200 dr r272045 : #i10000# suncc warning 2009-05-05 16:46:13 +0200 dr r271536 : #i10000# adoptions after rebase to master containing dr67 2009-05-05 16:01:19 +0200 dr r271530 : #i10000# adoptions after rebase to master containing dr67 2009-05-04 14:20:39 +0200 dr r271453 : CWS-TOOLING: rebase CWS dr68 to trunk@271427 (milestone: DEV300:m47) 2009-04-28 17:01:14 +0200 dr r271332 : CWS-TOOLING: rebase CWS dr68 to trunk@270723 (milestone: DEV300:m46) 2009-04-23 12:21:40 +0200 dr r271149 : #i100688# missing checkins 2009-04-23 12:18:16 +0200 dr r271147 : #i100978# relations path handling 2009-04-22 19:25:45 +0200 nn r271136 : #i49491# show navigator for double click on document position status bar control 2009-04-22 11:28:36 +0200 nn r271085 : #i60401# small text change 2009-04-21 16:53:23 +0200 dr r271044 : #i10000# missing dtor 2009-04-20 13:39:25 +0200 nn r270977 : #i60401# add dialog to extend sort range (patch from maoyg) 2009-04-08 12:11:08 +0200 dr r270630 : #i100943# prevent assertion when loading chart with empty category ranges 2009-04-07 19:03:00 +0200 dr r270609 : #i100688# missing bits for OLE 2009-04-07 17:14:06 +0200 dr r270605 : ported fix for #i100710# 2009-04-07 17:12:50 +0200 dr r270604 : #i10000# wae 2009-04-07 15:31:55 +0200 dr r270598 : import system colors moved to FilterBase class, more rework on fill and color contexts 2009-04-06 15:00:03 +0200 dr r270552 : #i99677# prevent recursive loading of the current document 2009-04-03 18:28:42 +0200 dr r270515 : added import of brightness/contrast and mono/grayscale color effects for image shapes 2009-04-03 17:36:03 +0200 dr r270509 : cache already imported embedded graphics 2009-04-03 16:46:34 +0200 dr r270500 : more rework on bitmap fill and graphic object handling 2009-03-31 12:28:10 +0200 dr r270271 : #i10000# unxlngi6 wae 2009-03-31 09:04:10 +0200 dr r270261 : CWS-TOOLING: rebase CWS dr68 to trunk@270033 (milestone: DEV300:m45) 2009-03-30 17:42:05 +0200 dr r270249 : #i91122# add missing doc 2009-03-30 17:37:08 +0200 dr r270248 : #i91122# add missing doc 2009-03-30 16:59:15 +0200 dr r270241 : #i99677# add import of ActiveX scrollbar controls 2009-03-30 14:30:36 +0200 dr r270230 : #i91122# missing/wrong documentation 2009-03-30 13:03:38 +0200 dr r270220 : #i99677# add import of ActiveX combobox and spinbutton controls 2009-03-27 11:46:59 +0100 dr r270144 : #i99677# import ActiveX listbox controls (Forms.ListBox.1) 2009-03-26 19:58:00 +0100 dr r270104 : #i99677# move more OLE import code into ole submodule 2009-03-26 15:15:02 +0100 dr r270082 : #i100546# add import of chart bitmap fills, add import of X/Y offset in tiled bitmap fills of all shapes 2009-03-25 12:54:59 +0100 dr r270018 : #i99677# import ActiveX edit text control (Forms.TextBox.1) 2009-03-24 10:59:29 +0100 dr r269921 : #i99677# moved import of OLE StdHlink to 'ole' submodule, added string import helpers to BinaryStreamBase class, removed implementation of ST_XString import from docprop in favour of the implementation in class AttributeList 2009-03-24 10:40:18 +0100 dr r269919 : #i100502# implicit precedence of '&&' was intended 2009-03-24 10:18:29 +0100 dr r269917 : #i100502# missing parentheses 2009-03-23 15:17:48 +0100 dr r269876 : #i99677# more code reorg, added graphic helper and OLE helper object per filter, added OLE/control import to PPTX/XLSX filter, moved helpers from XmlFilterBase to FilterBase 2009-03-19 12:45:20 +0100 dr r269740 : #i99677# interface changes in oox 2009-03-18 15:51:50 +0100 dr r269683 : #i99677# improved relation handling (internal/external), added preprocessor for VML streams to eat MS specific instructions, added OCX ToggleButton/OptionButton import, added DIB import for BIFF (page background picture, lots of other minor improvements 2009-03-16 15:25:30 +0100 dr r269551 : #i99677# import excel form control client data (printable, cell link) 2009-03-13 18:37:17 +0100 dr r269494 : #i99677# import image controls and check boxes 2009-03-12 15:08:18 +0100 dr r269420 : #i10000# rebase problems 2009-03-12 14:43:09 +0100 dr r269418 : #i10000# rebase problems 2009-03-12 14:42:41 +0100 dr r269417 : #i10000# missing delivered header 2009-03-12 13:57:06 +0100 dr r269405 : #i10000# typos 2009-03-12 12:58:52 +0100 dr r269391 : CWS-TOOLING: rebase CWS dr68 to trunk@269297 (milestone: DEV300:m43) 2009-03-12 11:11:46 +0100 dr r269374 : #i99677# first step to import BIFF8 page background 2009-03-12 10:21:53 +0100 dr r269364 : #i99677# rework of graphic import in entire filter, added import of AX Label controls 2009-03-09 16:44:50 +0100 dr r269202 : #i99677# import some formatting attributes of command buttons 2009-03-05 15:31:46 +0100 dr r268911 : #i99677# use VML shape client data to import excel VML shape positions 2009-03-05 11:39:48 +0100 dr r268888 : #i99677# create UNO control shapes from VML control shapes 2009-03-05 11:38:59 +0100 dr r268886 : #i99677# change attribute Shapes to DrawPage for import of embedded form controls 2009-03-05 11:30:40 +0100 dr r268885 : #i99677# change attribute Shapes to DrawPage for import of embedded form controls 2009-03-04 18:46:05 +0100 dr r268860 : adapt namespace ids according to oox 2009-03-04 18:43:49 +0100 dr r268859 : #i99677# more VML import rework 2009-03-03 13:38:36 +0100 dr r268721 : #i99677# more cleanup for VML filter 2009-03-03 13:13:15 +0100 dr r268719 : #i99807# do not iterate beyond end of std::list 2009-03-02 11:55:49 +0100 dr r268644 : add ST_XString support (encoded characters in attribute values) 2009-02-26 17:07:18 +0100 dr r268542 : #i99677# first steps of ax control import: dummy AX base classes, reimplement VML import (hopefully without breaking anything), register embedded AX controls at VML drawing 2009-02-23 17:43:50 +0100 dr r268365 : #i99426# remaining work on scenario import 2009-02-19 16:56:25 +0100 dr r268295 : #i99426# base implementations for scenarios import
Diffstat (limited to 'oox/source/vml')
-rw-r--r--oox/source/vml/makefile.mk11
-rw-r--r--oox/source/vml/vmldrawing.cxx168
-rw-r--r--oox/source/vml/vmldrawingfragment.cxx95
-rw-r--r--oox/source/vml/vmldrawingfragmenthandler.cxx519
-rw-r--r--oox/source/vml/vmlinputstream.cxx94
-rw-r--r--oox/source/vml/vmlshape.cxx650
-rw-r--r--oox/source/vml/vmlshapecontainer.cxx137
-rw-r--r--oox/source/vml/vmlshapecontext.cxx267
8 files changed, 1210 insertions, 731 deletions
diff --git a/oox/source/vml/makefile.mk b/oox/source/vml/makefile.mk
index 6d5c719ac0c3..305353eb8f02 100644
--- a/oox/source/vml/makefile.mk
+++ b/oox/source/vml/makefile.mk
@@ -1,7 +1,7 @@
#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
+#
# Copyright 2008 by Sun Microsystems, Inc.
#
# OpenOffice.org - a multi-platform office productivity suite
@@ -45,9 +45,12 @@ ENABLE_EXCEPTIONS=TRUE
# --- Files --------------------------------------------------------
SLOFILES = \
- $(SLO)$/vmlshape.obj\
- $(SLO)$/vmldrawing.obj\
- $(SLO)$/vmldrawingfragmenthandler.obj
+ $(SLO)$/vmldrawing.obj \
+ $(SLO)$/vmldrawingfragment.obj \
+ $(SLO)$/vmlinputstream.obj \
+ $(SLO)$/vmlshape.obj \
+ $(SLO)$/vmlshapecontainer.obj \
+ $(SLO)$/vmlshapecontext.obj
# --- Targets -------------------------------------------------------
diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx
index 9fc0c2efd88a..42529ea4a351 100644
--- a/oox/source/vml/vmldrawing.cxx
+++ b/oox/source/vml/vmldrawing.cxx
@@ -28,67 +28,141 @@
*
************************************************************************/
-#include "oox/vml/drawing.hxx"
-#include "oox/core/namespaces.hxx"
+#include "oox/vml/vmldrawing.hxx"
+#include <com/sun/star/drawing/XShapes.hpp>
#include "tokens.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/ole/axcontrolhelper.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
-namespace oox { namespace vml {
+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::XShapes;
+using ::oox::core::XmlFilterBase;
-Drawing::Drawing()
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+namespace {
+
+/** Returns the textual representation of a numeric VML shape identifier. */
+OUString lclGetShapeId( sal_Int32 nShapeId )
+{
+ // identifier consists of a literal NUL character, a lowercase 's', and the id
+ return CREATE_OUSTRING( "\0s" ) + OUString::valueOf( nShapeId );
+}
+
+} // namespace
+
+// ============================================================================
+
+OleObjectInfo::OleObjectInfo( bool bDmlShape ) :
+ mbAutoLoad( false ),
+ mbDmlShape( bDmlShape )
+{
+}
+
+void OleObjectInfo::setShapeId( sal_Int32 nShapeId )
{
+ maShapeId = lclGetShapeId( nShapeId );
}
+
+// ============================================================================
+
+ControlInfo::ControlInfo()
+{
+}
+
+void ControlInfo::setShapeId( sal_Int32 nShapeId )
+{
+ maShapeId = lclGetShapeId( nShapeId );
+}
+
+// ============================================================================
+
+Drawing::Drawing( XmlFilterBase& rFilter, const Reference< XDrawPage >& rxDrawPage, DrawingType eType ) :
+ mrFilter( rFilter ),
+ mxDrawPage( rxDrawPage ),
+ mxShapes( new ShapeContainer( *this ) ),
+ meType( eType )
+{
+ OSL_ENSURE( mxDrawPage.is(), "Drawing::Drawing - missing UNO draw page" );
+}
+
Drawing::~Drawing()
{
}
-ShapePtr Drawing::createShapeById( const rtl::OUString sId ) const
+::oox::ole::AxControlHelper& Drawing::getControlHelper() const
{
- ShapePtr pRet, pRef;
- std::vector< ShapePtr >::const_iterator aIter( maShapes.begin() );
- while( aIter != maShapes.end() )
- {
- if ( (*aIter)->msId == sId )
- {
- pRef = (*aIter);
- break;
- }
- aIter++;
- }
- if ( pRef )
+ // create the helper object on demand
+ if( !mxCtrlHelper.get() )
{
- pRet = ShapePtr( new Shape( pRef->msServiceName ) );
- if ( pRef->msType.getLength() )
- {
- std::vector< ShapePtr >::const_iterator aShapeTypeIter( maShapeTypes.begin() );
- while( aShapeTypeIter != maShapeTypes.end() )
- {
- if ( (*aShapeTypeIter)->msType == pRef->msType )
- {
- pRet->applyAttributes( *(*aShapeTypeIter).get() );
- break;
- }
- aShapeTypeIter++;
- }
- }
- pRet->applyAttributes( *pRef.get() );
+ mxCtrlHelper.reset( createControlHelper() );
+ OSL_ENSURE( mxCtrlHelper.get(), "Drawing::getControlHelper - cannot create form controls helper" );
}
- return pRet;
+ return *mxCtrlHelper;
}
-rtl::OUString Drawing::getGraphicUrlById( const rtl::OUString sId ) const
+void Drawing::registerOleObject( const OleObjectInfo& rOleObject )
{
- rtl::OUString sGraphicURL;
- std::vector< ShapePtr >::const_iterator aIter( maShapes.begin() );
- while( aIter != maShapes.end() )
- {
- if ( (*aIter)->msId == sId )
- {
- sGraphicURL = (*aIter)->msGraphicURL;
- break;
- }
- aIter++;
- }
- return sGraphicURL;
+ OSL_ENSURE( rOleObject.maShapeId.getLength() > 0, "Drawing::registerOleObject - missing OLE object shape id" );
+ OSL_ENSURE( maOleObjects.count( rOleObject.maShapeId ) == 0, "Drawing::registerOleObject - OLE object already registered" );
+ maOleObjects.insert( OleObjectInfoMap::value_type( rOleObject.maShapeId, rOleObject ) );
}
-} }
+void Drawing::registerControl( const ControlInfo& rControl )
+{
+ OSL_ENSURE( rControl.maShapeId.getLength() > 0, "Drawing::registerControl - missing form control shape id" );
+ OSL_ENSURE( rControl.maName.getLength() > 0, "Drawing::registerControl - missing form control name" );
+ OSL_ENSURE( maControls.count( rControl.maShapeId ) == 0, "Drawing::registerControl - form control already registered" );
+ maControls.insert( ControlInfoMap::value_type( rControl.maShapeId, rControl ) );
+}
+
+void Drawing::finalizeFragmentImport()
+{
+ mxShapes->finalizeFragmentImport();
+}
+
+void Drawing::convertAndInsert() const
+{
+ Reference< XShapes > xShapes( mxDrawPage, UNO_QUERY );
+ mxShapes->convertAndInsert( xShapes );
+}
+
+const OleObjectInfo* Drawing::getOleObjectInfo( const OUString& rShapeId ) const
+{
+ return ContainerHelper::getMapElement( maOleObjects, rShapeId );
+}
+
+const ControlInfo* Drawing::getControlInfo( const OUString& rShapeId ) const
+{
+ return ContainerHelper::getMapElement( maControls, rShapeId );
+}
+
+bool Drawing::convertShapeClientAnchor( Rectangle& /*orShapeRect*/, const OUString& /*rShapeAnchor*/ ) const
+{
+ return false;
+}
+
+void Drawing::convertControlClientData( const Reference< XControlModel >& /*rxCtrlModel*/, const ShapeClientData& /*rClientData*/ ) const
+{
+}
+
+::oox::ole::AxControlHelper* Drawing::createControlHelper() const
+{
+ return new ::oox::ole::AxEmbeddedControlHelper( mrFilter, mxDrawPage );
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespave oox
+
diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx
new file mode 100644
index 000000000000..b622df39941c
--- /dev/null
+++ b/oox/source/vml/vmldrawingfragment.cxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vmldrawingfragmenthandler.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmldrawingfragment.hxx"
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmlinputstream.hxx"
+#include "oox/vml/vmlshapecontext.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::io::XInputStream;
+using ::oox::core::ContextHandlerRef;
+using ::oox::core::FragmentHandler2;
+using ::oox::core::XmlFilterBase;
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+DrawingFragment::DrawingFragment( XmlFilterBase& rFilter, const OUString& rFragmentPath, Drawing& rDrawing ) :
+ FragmentHandler2( rFilter, rFragmentPath ),
+ mrDrawing( rDrawing )
+{
+}
+
+Reference< XInputStream > DrawingFragment::openFragmentStream() const
+{
+ return new InputStream( FragmentHandler2::openFragmentStream() );
+}
+
+ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( mrDrawing.getType() )
+ {
+ // DOCX filter handles plain shape elements with this fragment handler
+ case VMLDRAWING_WORD:
+ if( isRootElement() )
+ return ShapeContextBase::createContext( *this, nElement, rAttribs, mrDrawing.getShapes() );
+ break;
+
+ // XLSX and PPTX filters load the entire VML fragment
+ case VMLDRAWING_EXCEL:
+ case VMLDRAWING_POWERPOINT:
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XML_xml ) return this;
+ break;
+ case XML_xml:
+ return ShapeContextBase::createContext( *this, nElement, rAttribs, mrDrawing.getShapes() );
+ }
+ break;
+ }
+ return 0;
+}
+
+void DrawingFragment::finalizeImport()
+{
+ // resolve shape template references for all shapes
+ mrDrawing.finalizeFragmentImport();
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
diff --git a/oox/source/vml/vmldrawingfragmenthandler.cxx b/oox/source/vml/vmldrawingfragmenthandler.cxx
deleted file mode 100644
index 28e0eebb5e1c..000000000000
--- a/oox/source/vml/vmldrawingfragmenthandler.cxx
+++ /dev/null
@@ -1,519 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: vmldrawingfragmenthandler.cxx,v $
- * $Revision: 1.6 $
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#include "oox/vml/drawingfragmenthandler.hxx"
-
-#include "comphelper/anytostring.hxx"
-#include "cppuhelper/exc_hlp.hxx"
-#include "oox/helper/attributelist.hxx"
-#include "oox/core/contexthandler.hxx"
-#include <com/sun/star/beans/XMultiPropertySet.hpp>
-#include <com/sun/star/container/XNamed.hpp>
-#include <com/sun/star/drawing/PointSequence.hpp>
-#include <com/sun/star/drawing/PointSequenceSequence.hpp>
-#include "oox/core/namespaces.hxx"
-#include "tokens.hxx"
-
-using ::rtl::OUString;
-using namespace ::com::sun::star;
-using namespace ::oox::core;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::xml::sax;
-using namespace ::com::sun::star::container;
-
-namespace oox { namespace vml {
-
-static sal_Int32 getMeasure( const rtl::OUString& rVal )
-{
- double fVal = rVal.toDouble();
- const sal_Int32 nLen = rVal.getLength();
- if ( nLen >= 2 )
- {
- switch( static_cast< sal_Int8 >( rVal[ nLen - 1 ] ) )
- {
- case 'n' : fVal *= 2540; break;
- case 'm' : rVal[ nLen - 2 ] == 'm' ? fVal *= 100.0 : fVal *= 1000.0; break;
- case 't' : fVal *= 2540.0 / 72.0; break;
- case 'c' : fVal *= ( 2540.0 / 72.0 ) * 12.0; break;
- }
- }
- return static_cast< sal_Int32 >( fVal );
-}
-
-// AG_CoreAttributes
-static void ApplyCoreAttributes( const Reference< XFastAttributeList >& xAttribs, Shape& rShape )
-{
- // AG_Id
- rShape.msId = xAttribs->getOptionalValue( XML_id );
-
- // AG_Style
- if ( xAttribs->hasAttribute( XML_style ) )
- {
- rtl::OUString sStyle( xAttribs->getOptionalValue( XML_style ) );
- sal_Int32 nIndex = 0;
- do
- {
- OUString aStyleToken( sStyle.getToken( 0, ';', nIndex ) );
- if ( aStyleToken.getLength() )
- {
- sal_Int32 nIndex2 = 0;
- OUString aName( aStyleToken.getToken( 0, ':', nIndex2 ) );
- OUString aVal ( aStyleToken.getToken( 0, ':', nIndex2 ) );
- if ( aName.getLength() && aVal.getLength() )
- {
- static const ::rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM( "position" ) );
- static const ::rtl::OUString sLeft( RTL_CONSTASCII_USTRINGPARAM( "left" ) );
- static const ::rtl::OUString sTop( RTL_CONSTASCII_USTRINGPARAM( "top" ) );
- static const ::rtl::OUString sWidth( RTL_CONSTASCII_USTRINGPARAM( "width" ) );
- static const ::rtl::OUString sHeight( RTL_CONSTASCII_USTRINGPARAM( "height" ) );
- static const ::rtl::OUString sMarginLeft( RTL_CONSTASCII_USTRINGPARAM( "margin-left" ) );
- static const ::rtl::OUString sMarginTop( RTL_CONSTASCII_USTRINGPARAM( "margin-top" ) );
- if ( aName == sPosition )
- rShape.msPosition = aVal;
- else if ( aName == sLeft )
- rShape.maPosition.X = getMeasure( aVal );
- else if ( aName == sTop )
- rShape.maPosition.Y = getMeasure( aVal );
- else if ( aName == sWidth )
- rShape.maSize.Width = getMeasure( aVal );
- else if ( aName == sHeight )
- rShape.maSize.Height = getMeasure( aVal );
- else if ( aName == sMarginLeft )
- rShape.maPosition.X = getMeasure( aVal );
- else if ( aName == sMarginTop )
- rShape.maPosition.Y = getMeasure( aVal );
- }
- }
- }
- while ( nIndex >= 0 );
- }
-
- // href
- // target
- // class
- // title
- // alt
-
- // coordsize
- rtl::OUString aCoordSize( xAttribs->getOptionalValue( XML_coordsize ) );
- if ( aCoordSize.getLength() )
- {
- sal_Int32 nIndex = 0;
- rtl::OUString aCoordWidth ( aCoordSize.getToken( 0, ',', nIndex ) );
- rtl::OUString aCoordHeight( aCoordSize.getToken( 0, ',', nIndex ) );
- if ( aCoordWidth.getLength() )
- rShape.mnCoordWidth = aCoordWidth.toInt32();
- if ( aCoordHeight.getLength() )
- rShape.mnCoordHeight = aCoordHeight.toInt32();
- }
-
- // coordorigin
- // wrapcoords
- // print
-}
-
-// AG_ShapeAttributes
-static void ApplyShapeAttributes( const Reference< XFastAttributeList >& xAttribs, Shape& rShape )
-{
- AttributeList aAttributeList( xAttribs );
- rShape.mnStroked = xAttribs->getOptionalValueToken( XML_stroked, 0 );
- if ( xAttribs->hasAttribute( XML_filled ) )
- rShape.moFilled = ::boost::optional< sal_Bool >( aAttributeList.getBool( XML_filled, sal_False ) );
- if ( xAttribs->hasAttribute( XML_fillcolor ) )
- rShape.moFillColor = ::boost::optional< rtl::OUString >( xAttribs->getOptionalValue( XML_fillcolor ) );
-}
-
-//--------------------------------------------------------------------------------------------------------------
-// EG_ShapeElements
-class BasicShapeContext : public ContextHandler
-{
-public:
- BasicShapeContext( ContextHandler& rParent,
- sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, Shape& rShape );
- virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element,
- const Reference< XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, RuntimeException);
-private:
- Shape& mrShape;
-};
-
-BasicShapeContext::BasicShapeContext( ContextHandler& rParent,
- sal_Int32 /* aElement */, const Reference< XFastAttributeList >& xAttribs, Shape& rShape )
-: ContextHandler( rParent )
-, mrShape( rShape )
-{
- mrShape.msType = xAttribs->getOptionalValue( XML_type );
- mrShape.msShapeType = xAttribs->getOptionalValue( NMSP_OFFICE|XML_spt );
-}
-Reference< XFastContextHandler > BasicShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
- throw (SAXException, RuntimeException)
-{
- Reference< XFastContextHandler > xRet;
- switch( aElementToken )
- {
- case NMSP_VML|XML_imagedata:
- {
- OUString aRelId( xAttribs->getOptionalValue( NMSP_OFFICE|XML_relid ) );
- mrShape.msGraphicURL = getFragmentPathFromRelId( aRelId );
- mrShape.msImageTitle = xAttribs->getOptionalValue( NMSP_OFFICE|XML_title );
- }
- break;
- default:
- break;
- }
- if( !xRet.is() )
- xRet.set( this );
- return xRet;
-}
-
-//--------------------------------------------------------------------------------------------------------------
-// CT_Shapetype
-class ShapeTypeContext : public BasicShapeContext
-{
-public:
- ShapeTypeContext( ContextHandler& rParent,
- sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, Shape& rShape );
- virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element,
- const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
-};
-
-ShapeTypeContext::ShapeTypeContext( ContextHandler& rParent,
- sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, Shape& rShape )
-: BasicShapeContext( rParent, aElement, xAttribs, rShape )
-{
-}
-
-Reference< XFastContextHandler > ShapeTypeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
- throw (SAXException, RuntimeException)
-{
- Reference< XFastContextHandler > xRet;
-// switch( aElementToken )
-// {
-// default:
- xRet = BasicShapeContext::createFastChildContext( aElementToken, xAttribs );
-// break;
-// }
- if( !xRet.is() )
- xRet.set( this );
- return xRet;
-}
-//--------------------------------------------------------------------------------------------------------------
-// CT_PolyLine
-class PolyLineContext : public BasicShapeContext
-{
-public:
- PolyLineContext( ContextHandler& rParent,
- sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, Shape& rShape );
- virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element,
- const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
-};
-
-PolyLineContext::PolyLineContext( ContextHandler& rParent,
- sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, Shape& rShape )
-: BasicShapeContext( rParent, aElement, xAttribs, rShape )
-{
- ApplyShapeAttributes( xAttribs, rShape );
- ApplyCoreAttributes( xAttribs, rShape );
-
- rtl::OUString aPoints( xAttribs->getOptionalValue( XML_points ) );
- if ( aPoints.getLength() )
- {
- std::vector< awt::Point > vPoints;
- sal_Int32 nIndex = 0;
- do
- {
- OUString aX( aPoints.getToken( 0, ',', nIndex ) );
- OUString aY( aPoints.getToken( 0, ',', nIndex ) );
- awt::Point aPt( getMeasure( aX ), getMeasure( aY ) );
- vPoints.push_back( aPt );
- }
- while ( nIndex >= 0 );
-
- drawing::PointSequenceSequence aPointSeq( 1 );
- aPointSeq[ 0 ] = drawing::PointSequence( &vPoints.front(), vPoints.size() );
- static const ::rtl::OUString sPolyPolygon( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) );
- rShape.maPath.Name = sPolyPolygon;
- rShape.maPath.Value <<= aPointSeq;
-
-/* not sure if the following is needed
-
- // calculating the bounding box
- sal_Int32 nGlobalLeft = SAL_MAX_INT32;
- sal_Int32 nGlobalRight = SAL_MIN_INT32;
- sal_Int32 nGlobalTop = SAL_MAX_INT32;
- sal_Int32 nGlobalBottom= SAL_MIN_INT32;
- std::vector< awt::Point >::const_iterator aIter( vPoints.begin() );
- while( aIter != vPoints.end() )
- {
- sal_Int32 x = (*aIter).X;
- sal_Int32 y = (*aIter).Y;
- if ( nGlobalLeft > x )
- nGlobalLeft = x;
- if ( nGlobalRight < x )
- nGlobalRight = x;
- if ( nGlobalTop > y )
- nGlobalTop = y;
- if ( nGlobalBottom < y )
- nGlobalBottom = y;
- aIter++;
- }
- rShape.maPosition.X = nGlobalLeft;
- rShape.maPosition.Y = nGlobalTop;
- rShape.maSize.Width = nGlobalRight - nGlobalLeft;
- rShape.maSize.Height = nGlobalBottom - nGlobalTop;
-*/
- }
-}
-
-Reference< XFastContextHandler > PolyLineContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
- throw (SAXException, RuntimeException)
-{
- Reference< XFastContextHandler > xRet;
-// switch( aElementToken )
-// {
-// default:
- xRet = BasicShapeContext::createFastChildContext( aElementToken, xAttribs );
-// break;
-// }
- if( !xRet.is() )
- xRet.set( this );
- return xRet;
-}
-
-//--------------------------------------------------------------------------------------------------------------
-// CT_Shape
-class ShapeContext : public BasicShapeContext
-{
-public:
- ShapeContext( ContextHandler& rParent,
- sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, Shape& rShape );
- virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element,
- const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
-};
-
-ShapeContext::ShapeContext( ContextHandler& rParent,
- sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs, Shape& rShape )
-: BasicShapeContext( rParent, aElement, xAttribs, rShape )
-{
- ApplyShapeAttributes( xAttribs, rShape );
- ApplyCoreAttributes( xAttribs, rShape );
-// rShape.msPath = xAttribs->getOptionalValue( XML_path );
-}
-
-Reference< XFastContextHandler > ShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
- throw (SAXException, RuntimeException)
-{
- Reference< XFastContextHandler > xRet;
-// switch( aElementToken )
-// {
-// default:
- xRet = BasicShapeContext::createFastChildContext( aElementToken, xAttribs );
-// break;
-// }
- if( !xRet.is() )
- xRet.set( this );
- return xRet;
-}
-
-//--------------------------------------------------------------------------------------------------------------
-
-class GroupShapeContext : public BasicShapeContext
-{
-public:
- GroupShapeContext( ContextHandler& rParent, sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs,
- Shape& rShape, std::vector< ShapePtr >& rShapeTypes );
- virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element,
- const Reference< XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, RuntimeException);
-private:
- Shape& mrShape;
- std::vector< ShapePtr >& mrShapeTypes;
-};
-
-GroupShapeContext::GroupShapeContext( ContextHandler& rParent,
- sal_Int32 aElement, const Reference< XFastAttributeList >& xAttribs,
- Shape& rShape, std::vector< ShapePtr >& rShapeTypes )
-: BasicShapeContext( rParent, aElement, xAttribs, rShape )
-, mrShape( rShape )
-, mrShapeTypes( rShapeTypes )
-{
- AttributeList aAttributeList( xAttribs );
- if ( xAttribs->hasAttribute( XML_filled ) )
- rShape.moFilled = ::boost::optional< sal_Bool >( aAttributeList.getBool( XML_filled, sal_False ) );
- if ( xAttribs->hasAttribute( XML_fillcolor ) )
- rShape.moFillColor = ::boost::optional< rtl::OUString >( xAttribs->getOptionalValue( XML_fillcolor ) );
- ApplyCoreAttributes( xAttribs, rShape );
-}
-Reference< XFastContextHandler > GroupShapeContext::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
- throw (SAXException, RuntimeException)
-{
- return DrawingFragmentHandler::StaticCreateContext( *this, aElementToken, xAttribs, mrShape.getChilds(), mrShapeTypes );
-}
-
-//--------------------------------------------------------------------------------------------------------------
-
-DrawingFragmentHandler::DrawingFragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath,
- std::vector< ShapePtr >& rShapes, std::vector< ShapePtr >& rShapeTypes )
- throw()
-: FragmentHandler( rFilter, rFragmentPath )
-, mrShapes( rShapes )
-, mrShapeTypes( rShapeTypes )
-, maFragmentPath( rFragmentPath )
-{
-}
-DrawingFragmentHandler::~DrawingFragmentHandler()
- throw()
-{
-}
-
-::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > DrawingFragmentHandler::StaticCreateContext( oox::core::ContextHandler& rParent,
- sal_Int32 aElementToken, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& xAttribs,
- std::vector< ShapePtr >& rShapes, std::vector< ShapePtr >& rShapeTypes )
- throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
-{
- static const ::rtl::OUString sCustomShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.CustomShape" ) );
-
- Reference< XFastContextHandler > xRet;
- switch( aElementToken )
- {
- case NMSP_VML|XML_group :
- {
- static const ::rtl::OUString sGroupShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GroupShape" ) );
- ShapePtr pShapePtr( new Shape( sGroupShape ) );
- xRet = new GroupShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get(), rShapeTypes );
- rShapes.push_back( pShapePtr );
- }
- break;
- case NMSP_VML|XML_shapetype :
- {
- ShapePtr pShapePtr( new Shape( OUString() ) );
- xRet = new ShapeTypeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapeTypes.push_back( pShapePtr );
- }
- break;
- case NMSP_VML|XML_shape:
- {
- ShapePtr pShapePtr( new Shape( sCustomShape ) );
- xRet = new ShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
- case NMSP_VML|XML_oval:
- {
- static const ::rtl::OUString sEllipseShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.EllipseShape" ) );
- ShapePtr pShapePtr( new Shape( sEllipseShape ) );
- xRet = new ShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
- case NMSP_VML|XML_polyline:
- {
- static const ::rtl::OUString sPolyLineShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.PolyLineShape" ) );
- ShapePtr pShapePtr( new Shape( sPolyLineShape ) );
- xRet = new PolyLineContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
- case NMSP_VML|XML_rect:
- {
- static const ::rtl::OUString sRectangleShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.RectangleShape" ) );
- ShapePtr pShapePtr( new Shape( sRectangleShape ) );
- xRet = new ShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
- case NMSP_VML|XML_roundrect:
- {
- static const ::rtl::OUString sRectangleShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.RectangleShape" ) );
- ShapePtr pShapePtr( new Shape( sRectangleShape ) );
- xRet = new ShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
-
- // TODO:
- case NMSP_VML|XML_arc:
- {
- ShapePtr pShapePtr( new Shape( sCustomShape ) );
- xRet = new ShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
- case NMSP_VML|XML_curve:
- {
- ShapePtr pShapePtr( new Shape( sCustomShape ) );
- xRet = new ShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
- case NMSP_VML|XML_line:
- {
- ShapePtr pShapePtr( new Shape( sCustomShape ) );
- xRet = new ShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
- case NMSP_OFFICE|XML_diagram:
- {
- ShapePtr pShapePtr( new Shape( sCustomShape ) );
- xRet = new ShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
- case NMSP_VML|XML_image:
- {
- ShapePtr pShapePtr( new Shape( sCustomShape ) );
- xRet = new ShapeContext( rParent, aElementToken, xAttribs, *pShapePtr.get() );
- rShapes.push_back( pShapePtr );
- }
- break;
- }
- return xRet;
-}
-
-
-// CT_GROUP
-Reference< XFastContextHandler > DrawingFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs )
- throw (SAXException, RuntimeException)
-{
- return aElementToken == XML_xml
- ? getFastContextHandler()
- : StaticCreateContext( *this, aElementToken, xAttribs, mrShapes, mrShapeTypes );
-}
-
-void SAL_CALL DrawingFragmentHandler::endDocument()
- throw (SAXException, RuntimeException)
-{
-}
-
-//--------------------------------------------------------------------------------------------------------------
-
-
-
-} }
-
diff --git a/oox/source/vml/vmlinputstream.cxx b/oox/source/vml/vmlinputstream.cxx
new file mode 100644
index 000000000000..56964ad4ab19
--- /dev/null
+++ b/oox/source/vml/vmlinputstream.cxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vmldrawing.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmlinputstream.hxx"
+#include <algorithm>
+#include <string.h>
+
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::io::XInputStream;
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInStrm )
+{
+ if( rxInStrm.is() ) try
+ {
+ // read all bytes we can read
+ rxInStrm->readBytes( maDataSeq, SAL_MAX_INT32 );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // parse the data and eat all parser instructions that make expat sad
+ if( maDataSeq.hasElements() )
+ {
+ sal_Char* pcBeg = reinterpret_cast< sal_Char* >( maDataSeq.getArray() );
+ sal_Char* pcEnd = pcBeg + maDataSeq.getLength();
+ sal_Char* pcCurr = pcBeg;
+ while( pcCurr < pcEnd )
+ {
+ pcCurr = ::std::find( pcCurr, pcEnd, '<' );
+ sal_Char* pcClose = ::std::find( pcCurr, pcEnd, '>' );
+ if( (pcCurr < pcEnd) && (pcClose < pcEnd) && (pcClose - pcCurr >= 5) && (pcCurr[ 1 ] == '!') && (pcCurr[ 2 ] == '[') && (pcClose[ -1 ] == ']') )
+ {
+ ++pcClose;
+ memmove( pcCurr, pcClose, pcEnd - pcClose );
+ pcEnd -= (pcClose - pcCurr);
+ }
+ else
+ pcCurr = pcClose;
+ }
+ maDataSeq.realloc( static_cast< sal_Int32 >( pcEnd - pcBeg ) );
+ }
+}
+
+// ============================================================================
+
+InputStream::InputStream( const Reference< XInputStream >& rxInStrm ) :
+ StreamDataContainer( rxInStrm ),
+ ::comphelper::SequenceInputStream( maDataSeq )
+{
+}
+
+InputStream::~InputStream()
+{
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespave oox
+
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 106eb394651f..e583248adcfa 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -28,206 +28,534 @@
*
************************************************************************/
-#include <rtl/ustring.hxx>
-#include "oox/vml/shape.hxx"
-#include "oox/core/xmlfilterbase.hxx"
-#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
+#include "oox/vml/vmlshape.hxx"
+#include <rtl/math.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include "properties.hxx"
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/core/xmlfilterbase.hxx"
+#include "oox/ole/axcontrol.hxx"
+#include "oox/ole/axcontrolfragment.hxx"
+#include "oox/ole/oleobjecthelper.hxx"
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::awt::Point;
+using ::com::sun::star::awt::Rectangle;
+using ::com::sun::star::awt::Size;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::graphic::XGraphic;
+using ::com::sun::star::drawing::PointSequenceSequence;
+using ::com::sun::star::drawing::XControlShape;
+using ::com::sun::star::drawing::XEnhancedCustomShapeDefaulter;
+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;
+// ============================================================================
-namespace oox { namespace vml {
+namespace {
-Shape::Shape( const rtl::OUString& rServiceName )
-: msServiceName( rServiceName )
-, mnCoordWidth( 0 )
-, mnCoordHeight( 0 )
-, mnStroked( 0 )
+sal_Int32 lclGetMeasure( const XmlFilterBase& /*rFilter*/, const OUString& rValue, sal_Int32 nRefValue )
{
+ // default for missing values is 0
+ if( rValue.getLength() == 0 )
+ return 0;
+
+ // TODO: according to spec, value may contain "auto"
+ if( rValue.equalsAscii( "auto" ) )
+ return nRefValue;
+
+ // extract the double value and find start position of unit characters
+ rtl_math_ConversionStatus eConvStatus = rtl_math_ConversionStatus_Ok;
+ sal_Int32 nEndPos = 0;
+ double fValue = ::rtl::math::stringToDouble( rValue, '.', '\0', &eConvStatus, &nEndPos );
+ if( (eConvStatus != rtl_math_ConversionStatus_Ok) || (fValue == 0.0) )
+ return 0;
+
+ // process trailing unit, convert to 1/100 mm
+ static const OUString saPx = CREATE_OUSTRING( "px" );
+ OUString aUnit = ((0 < nEndPos) && (nEndPos < rValue.getLength())) ? rValue.copy( nEndPos ) : saPx;
+ if( aUnit.getLength() == 2 )
+ {
+ sal_Unicode cChar1 = aUnit[ 0 ];
+ sal_Unicode cChar2 = aUnit[ 1 ];
+ if( (cChar1 == 'i') && (cChar2 == 'n') ) // 1 inch = 2540 1/100mm
+ fValue *= 2540.0;
+ else if( (cChar1 == 'c') && (cChar2 == 'm') ) // 1 cm = 1000 1/100mm
+ fValue *= 1000.0;
+ else if( (cChar1 == 'm') && (cChar2 == 'm') ) // 1 mm = 100 1/100mm
+ fValue *= 100.0;
+ else if( (cChar1 == 'p') && (cChar2 == 't') ) // 1 point = 1/72 inch
+ fValue *= 2540.0 / 72.0;
+ else if( (cChar1 == 'p') && (cChar2 == 'c') ) // 1 pica = 1/6 inch
+ fValue *= 2540.0 / 6.0;
+ else if( (cChar1 == 'e') && (cChar2 == 'm') ) // relative to refvalue
+ fValue *= nRefValue;
+ else if( (cChar1 == 'p') && (cChar2 == 'x') ) // 1 pixel, dependent on output device
+ fValue *= 1.0;
+ }
+ else if( (aUnit.getLength() == 1) && (aUnit[ 0 ] == '%') )
+ {
+ fValue *= nRefValue / 100.0;
+ }
+ else
+ {
+ OSL_ENSURE( false, "lclGetMeasure - unknown measure unit" );
+ fValue = nRefValue;
+ }
+ return static_cast< sal_Int32 >( fValue + 0.5 );
}
-Shape::~Shape()
+
+Point lclGetAbsPoint( const Point& rRelPoint, const Rectangle& rShapeRect, const Rectangle& rCoordSys )
{
+ double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
+ double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
+ Point aAbsPoint;
+ aAbsPoint.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelPoint.X - rCoordSys.X) + 0.5 );
+ aAbsPoint.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelPoint.Y - rCoordSys.Y) + 0.5 );
+ return aAbsPoint;
}
-void Shape::applyAttributes( const vml::Shape& rSource )
+Rectangle lclGetAbsRect( const Rectangle& rRelRect, const Rectangle& rShapeRect, const Rectangle& rCoordSys )
{
- if ( rSource.msId.getLength() )
- msId = rSource.msId;
- if ( rSource.msType.getLength() )
- msType = rSource.msType;
- if ( rSource.msShapeType.getLength() )
- msShapeType = rSource.msShapeType;
- if ( rSource.mnCoordWidth )
- mnCoordWidth = rSource.mnCoordWidth;
- if ( rSource.mnCoordHeight )
- mnCoordHeight = rSource.mnCoordHeight;
- if ( rSource.mnStroked )
- mnStroked = rSource.mnStroked;
- if ( rSource.moFilled )
- moFilled = rSource.moFilled;
- if ( rSource.moFillColor )
- moFillColor = rSource.moFillColor;
- if ( rSource.maPath.Name.getLength() )
- maPath = rSource.maPath;
- if ( rSource.msPosition.getLength() )
- msPosition = rSource.msPosition;
- maPosition = rSource.maPosition;
- maSize = rSource.maSize;
+ double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
+ double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
+ Rectangle aAbsRect;
+ aAbsRect.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelRect.X - rCoordSys.X) + 0.5 );
+ aAbsRect.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelRect.Y - rCoordSys.Y) + 0.5 );
+ aAbsRect.Width = static_cast< sal_Int32 >( fWidthRatio * rRelRect.Width + 0.5 );
+ aAbsRect.Height = static_cast< sal_Int32 >( fHeightRatio * rRelRect.Height + 0.5 );
+ return aAbsRect;
}
-::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > Shape::createAndInsert(
- const ::oox::core::XmlFilterBase& rFilterBase, const ::oox::vml::Shape& rShape,
- const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
- const awt::Rectangle* pShapeRect )
+Reference< XShape > lclCreateXShape( const XmlFilterBase& rFilter, const OUString& rService )
{
- uno::Reference< drawing::XShape > xShape;
- if ( rShape.msServiceName )
+ OSL_ENSURE( rService.getLength() > 0, "lclCreateXShape - missing UNO shape service name" );
+ Reference< XShape > xShape;
+ try
{
- try
- {
- uno::Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), uno::UNO_QUERY_THROW );
- xShape.set( xServiceFact->createInstance( rShape.msServiceName ), uno::UNO_QUERY_THROW );
- rxShapes->add( xShape );
- awt::Point aPosition;
- awt::Size aSize;
- if ( pShapeRect )
- {
- aPosition.X = pShapeRect->X;
- aPosition.Y = pShapeRect->Y;
- aSize.Width = pShapeRect->Width;
- aSize.Height = pShapeRect->Height;
- }
- else
- {
- aPosition = maPosition;
- aSize = maSize;
- }
- xShape->setPosition( aPosition );
- xShape->setSize( aSize );
- uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
- try
- {
- if ( maPath.Name.getLength() )
- xPropSet->setPropertyValue( maPath.Name, maPath.Value );
+ Reference< XMultiServiceFactory > xFactory( rFilter.getModel(), UNO_QUERY_THROW );
+ xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW );
+ }
+ catch( Exception& )
+ {
+ }
+ OSL_ENSURE( xShape.is(), "lclCreateXShape - cannot instanciate shape object" );
+ return xShape;
+}
- ::rtl::OUString sFillStyle( rtl::OUString::createFromAscii( "FillStyle" ) );
- if ( moFilled )
- xPropSet->setPropertyValue( sFillStyle, uno::Any( *moFilled ? drawing::FillStyle_SOLID : drawing::FillStyle_NONE ) );
- }
- catch ( uno::Exception& )
- {
- }
- ::rtl::OUString rServiceName( rtl::OUString::createFromAscii( "com.sun.star.drawing.CustomShape" ) );
- if ( rShape.msShapeType.getLength() && ( msServiceName == rServiceName ) )
- {
- uno::Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( xShape, uno::UNO_QUERY );
- if( xDefaulter.is() )
- xDefaulter->createCustomShapeDefaults( rShape.msShapeType );
- }
- mxShape = xShape;
- }
- catch( uno::Exception& )
- {
- }
+void lclInsertXShape( const Reference< XShapes >& rxShapes, const Reference< XShape >& rxShape, const Rectangle& rShapeRect )
+{
+ OSL_ENSURE( rxShapes.is(), "lclInsertXShape - missing XShapes container" );
+ OSL_ENSURE( rxShape.is(), "lclInsertXShape - missing XShape" );
+ if( rxShapes.is() && rxShape.is() ) try
+ {
+ // insert shape into passed shape collection (maybe drawpage or group shape)
+ rxShapes->add( rxShape );
+ // set position/size
+ rxShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) );
+ rxShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+Reference< XShape > lclCreateAndInsertXShape( const XmlFilterBase& rFilter,
+ const Reference< XShapes >& rxShapes, const OUString& rService, const Rectangle& rShapeRect )
+{
+ Reference< XShape > xShape = lclCreateXShape( rFilter, rService );
+ lclInsertXShape( rxShapes, xShape, rShapeRect );
+ return xShape;
+}
+
+} // namespace
+
+// ============================================================================
+
+ShapeTypeModel::ShapeTypeModel()
+{
+}
+
+void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource )
+{
+ monShapeType.assignIfUsed( rSource.monShapeType );
+ monCoordLeft.assignIfUsed( rSource.monCoordLeft );
+ monCoordTop.assignIfUsed( rSource.monCoordTop );
+ monCoordWidth.assignIfUsed( rSource.monCoordWidth );
+ monCoordHeight.assignIfUsed( rSource.monCoordHeight );
+ /* The style properties position, left, top, width, height, margin-left,
+ margin-top are not derived from shape template to shape. */
+ mobStroked.assignIfUsed( rSource.mobStroked );
+ moStrokeColor.assignIfUsed( rSource.moStrokeColor );
+ mobFilled.assignIfUsed( rSource.mobFilled );
+ moFillColor.assignIfUsed( rSource.moFillColor );
+ moGraphicPath.assignIfUsed( rSource.moGraphicPath );
+ moGraphicTitle.assignIfUsed( rSource.moGraphicTitle );
+}
+
+// ----------------------------------------------------------------------------
+
+ShapeType::ShapeType( const Drawing& rDrawing ) :
+ mrDrawing( rDrawing )
+{
+}
+
+ShapeType::~ShapeType()
+{
+}
+
+OUString ShapeType::getGraphicPath() const
+{
+ return maTypeModel.moGraphicPath.get( OUString() );
+}
+
+Rectangle ShapeType::getCoordSystem() const
+{
+ return Rectangle(
+ maTypeModel.monCoordLeft.get( 0 ),
+ maTypeModel.monCoordTop.get( 0 ),
+ maTypeModel.monCoordWidth.get( 1000 ),
+ maTypeModel.monCoordHeight.get( 1000 ) );
+}
+
+Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const
+{
+ return pParentAnchor ?
+ lclGetAbsRect( getRelRectangle(), pParentAnchor->maShapeRect, pParentAnchor->maCoordSys ) :
+ getAbsRectangle();
+}
+
+Rectangle ShapeType::getAbsRectangle() const
+{
+ const XmlFilterBase& rFilter = mrDrawing.getFilter();
+ return Rectangle(
+ lclGetMeasure( rFilter, maTypeModel.maLeft, 0 ) + lclGetMeasure( rFilter, maTypeModel.maMarginLeft, 0 ),
+ lclGetMeasure( rFilter, maTypeModel.maTop, 0 ) + lclGetMeasure( rFilter, maTypeModel.maMarginTop, 0 ),
+ lclGetMeasure( rFilter, maTypeModel.maWidth, 0 ),
+ lclGetMeasure( rFilter, maTypeModel.maHeight, 0 ) );
+}
+
+Rectangle ShapeType::getRelRectangle() const
+{
+ return Rectangle(
+ maTypeModel.maLeft.toInt32(),
+ maTypeModel.maTop.toInt32(),
+ maTypeModel.maWidth.toInt32(),
+ maTypeModel.maHeight.toInt32() );
+}
+
+// ============================================================================
+
+ShapeClientData::ShapeClientData() :
+ mnObjType( XML_TOKEN_INVALID ),
+ mbPrintObject( true )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ShapeModel::ShapeModel()
+{
+}
+
+ShapeClientData& ShapeModel::createClientData()
+{
+ mxClientData.reset( new ShapeClientData );
+ return *mxClientData;
+}
+
+// ----------------------------------------------------------------------------
+
+ShapeBase::ShapeBase( const Drawing& rDrawing ) :
+ ShapeType( rDrawing )
+{
+}
+
+void ShapeBase::finalizeFragmentImport()
+{
+ // resolve shape template reference
+ if( (maShapeModel.maType.getLength() > 1) && (maShapeModel.maType[ 0 ] == '#') )
+ if( const ShapeType* pShapeType = mrDrawing.getShapes().getShapeTypeById( maShapeModel.maType.copy( 1 ), true ) )
+ maTypeModel.assignUsed( pShapeType->getTypeModel() );
+}
+
+const ShapeType* ShapeBase::getChildTypeById( const OUString& ) const
+{
+ return 0;
+}
+
+const ShapeBase* ShapeBase::getChildById( const OUString& ) const
+{
+ return 0;
+}
+
+Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
+{
+ Reference< XShape > xShape;
+ /* Calculate shape rectangle. Applications may do something special
+ according to some imported shape client data (e.g. Excel cell anchor). */
+ Rectangle aShapeRect;
+ if( !maShapeModel.mxClientData.get() || !mrDrawing.convertShapeClientAnchor( aShapeRect, maShapeModel.mxClientData->maAnchor ) )
+ aShapeRect = getRectangle( pParentAnchor );
+ // convert the shape, if the calculated rectangle is not empty
+ if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) && rxShapes.is() )
+ xShape = implConvertAndInsert( rxShapes, aShapeRect );
+ return xShape;
+}
+
+// protected ------------------------------------------------------------------
+
+void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const
+{
+ // shape properties
+ PropertySet aPropSet( rxShape );
+
+ // fill style
+ bool bFilled = maTypeModel.mobFilled.get( true );
+ aPropSet.setProperty( PROP_FillStyle, bFilled ? ::com::sun::star::drawing::FillStyle_SOLID : ::com::sun::star::drawing::FillStyle_NONE );
+}
+
+// ============================================================================
+
+SimpleShape::SimpleShape( const Drawing& rDrawing, const OUString& rService ) :
+ ShapeBase( rDrawing ),
+ maService( rService )
+{
+}
+
+Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ Reference< XShape > xShape = lclCreateAndInsertXShape( mrDrawing.getFilter(), rxShapes, maService, rShapeRect );
+ convertShapeProperties( xShape );
+ return xShape;
+}
+
+// ============================================================================
+
+RectangleShape::RectangleShape( const Drawing& rDrawing ) :
+ SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ) )
+{
+}
+
+// ============================================================================
+
+EllipseShape::EllipseShape( const Drawing& rDrawing ) :
+ SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ) )
+{
+}
+
+// ============================================================================
+
+PolyLineShape::PolyLineShape( const Drawing& rDrawing ) :
+ SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" ) )
+{
+}
+
+Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
+ // polygon path
+ Rectangle aCoordSys = getCoordSystem();
+ if( !maShapeModel.maPoints.empty() && (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
+ {
+ ::std::vector< Point > aAbsPoints;
+ for( ShapeModel::PointVector::const_iterator aIt = maShapeModel.maPoints.begin(), aEnd = maShapeModel.maPoints.end(); aIt != aEnd; ++aIt )
+ aAbsPoints.push_back( lclGetAbsPoint( *aIt, rShapeRect, aCoordSys ) );
+ PointSequenceSequence aPointSeq( 1 );
+ aPointSeq[ 0 ] = ContainerHelper::vectorToSequence( aAbsPoints );
+ PropertySet aPropSet( xShape );
+ aPropSet.setProperty( PROP_PolyPolygon, aPointSeq );
}
return xShape;
}
-void Shape::addChilds( const ::oox::core::XmlFilterBase& rFilterBase, const ::oox::vml::Drawing& rDrawing,
- const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
- const awt::Rectangle& rClientRect )
+// ============================================================================
+
+CustomShape::CustomShape( const Drawing& rDrawing ) :
+ SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.CustomShape" ) )
{
- sal_Int32 nGlobalLeft = SAL_MAX_INT32;
- sal_Int32 nGlobalRight = SAL_MIN_INT32;
- sal_Int32 nGlobalTop = SAL_MAX_INT32;
- sal_Int32 nGlobalBottom= SAL_MIN_INT32;
- std::vector< ShapePtr >::iterator aIter( maChilds.begin() );
- while( aIter != maChilds.end() )
+}
+
+Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ // try to create a custom shape
+ Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
+ if( xShape.is() ) try
{
- sal_Int32 l = (*aIter)->maPosition.X;
- sal_Int32 t = (*aIter)->maPosition.Y;
- sal_Int32 r = l + (*aIter)->maSize.Width;
- sal_Int32 b = t + (*aIter)->maSize.Height;
- if ( nGlobalLeft > l )
- nGlobalLeft = l;
- if ( nGlobalRight < r )
- nGlobalRight = r;
- if ( nGlobalTop > t )
- nGlobalTop = t;
- if ( nGlobalBottom < b )
- nGlobalBottom = b;
- aIter++;
+ // create the custom shape geometry
+ Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW );
+ xDefaulter->createCustomShapeDefaults( OUString::valueOf( maTypeModel.monShapeType.get( 0 ) ) );
+ // convert common properties
+ convertShapeProperties( xShape );
}
- aIter = maChilds.begin();
- while( aIter != maChilds.end() )
+ catch( Exception& )
{
- awt::Rectangle aShapeRect;
- awt::Rectangle* pShapeRect = 0;
- if ( ( nGlobalLeft != SAL_MAX_INT32 ) && ( nGlobalRight != SAL_MIN_INT32 ) && ( nGlobalTop != SAL_MAX_INT32 ) && ( nGlobalBottom != SAL_MIN_INT32 ) )
- {
- sal_Int32 nGlobalWidth = nGlobalRight - nGlobalLeft;
- sal_Int32 nGlobalHeight = nGlobalBottom - nGlobalTop;
- if ( nGlobalWidth && nGlobalHeight )
- {
- double fWidth = (*aIter)->maSize.Width;
- double fHeight= (*aIter)->maSize.Height;
- double fXScale = (double)rClientRect.Width / (double)nGlobalWidth;
- double fYScale = (double)rClientRect.Height / (double)nGlobalHeight;
- aShapeRect.X = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.X - nGlobalLeft ) * fXScale ) + rClientRect.X );
- aShapeRect.Y = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.Y - nGlobalTop ) * fYScale ) + rClientRect.Y );
- fWidth *= fXScale;
- fHeight *= fYScale;
- aShapeRect.Width = static_cast< sal_Int32 >( fWidth );
- aShapeRect.Height = static_cast< sal_Int32 >( fHeight );
- pShapeRect = &aShapeRect;
- }
- }
- (*aIter++)->addShape( rFilterBase, rDrawing, rxShapes, pShapeRect );
}
+ return xShape;
+}
+
+// ============================================================================
+
+ComplexShape::ComplexShape( const Drawing& rDrawing ) :
+ CustomShape( rDrawing )
+{
}
-void Shape::addShape( const ::oox::core::XmlFilterBase& rFilterBase, const ::oox::vml::Drawing& rDrawing,
- const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
- const awt::Rectangle* pShapeRect )
+Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
{
- oox::vml::Shape aShape( msServiceName );
- if ( msType.getLength() )
+ XmlFilterBase& rFilter = mrDrawing.getFilter();
+ OUString aGraphicPath = getGraphicPath();
+
+ // try to find registered OLE object info
+ if( const OleObjectInfo* pOleObjectInfo = mrDrawing.getOleObjectInfo( maTypeModel.maShapeId ) )
{
- std::vector< ShapePtr >& rShapeTypes = const_cast< ::oox::vml::Drawing& >( rDrawing ).getShapeTypes();
- std::vector< ShapePtr >::const_iterator aShapeTypeIter( rShapeTypes.begin() );
- while( aShapeTypeIter != rShapeTypes.end() )
+ // if OLE object is embedded into a DrawingML shape (PPTX), do not create it here
+ if( pOleObjectInfo->mbDmlShape )
+ return Reference< XShape >();
+
+ PropertyMap aOleProps;
+ Size aOleSize( rShapeRect.Width, rShapeRect.Height );
+ if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) )
{
- if ( (*aShapeTypeIter)->msType == aShape.msType )
+ Reference< XShape > xShape = lclCreateAndInsertXShape( rFilter, rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ), rShapeRect );
+ if( xShape.is() )
{
- aShape.applyAttributes( *(*aShapeTypeIter).get() );
- break;
+ // set the replacement graphic
+ if( aGraphicPath.getLength() > 0 )
+ {
+ Reference< XGraphic > xGraphic = rFilter.importEmbeddedGraphic( aGraphicPath );
+ if( xGraphic.is() )
+ aOleProps[ PROP_Graphic ] <<= xGraphic;
+ }
+
+ PropertySet aPropSet( xShape );
+ aPropSet.setProperties( aOleProps );
+
+ return xShape;
}
- aShapeTypeIter++;
}
}
- aShape.applyAttributes( *this );
- // creating XShape
- uno::Reference< drawing::XShape > xShape( createAndInsert( rFilterBase, aShape, rxShapes, pShapeRect ) );
+ // try to find registered form control info
+ const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId );
+ if( pControlInfo && (pControlInfo->maFragmentPath.getLength() > 0) && (maTypeModel.maName.getLength() > 0) )
+ {
+ OSL_ENSURE( maTypeModel.maName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" );
+ ::oox::ole::AxControl aControl( maTypeModel.maName );
+ // load the control properties from fragment
+ if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) ) try
+ {
+ // create control model and insert it into the form of the draw page
+ Reference< XControlModel > xCtrlModel( aControl.convertAndInsert( mrDrawing.getControlHelper() ), UNO_SET_THROW );
+ if( maShapeModel.mxClientData.get() )
+ mrDrawing.convertControlClientData( xCtrlModel, *maShapeModel.mxClientData );
- // creating GroupShape if possible
- uno::Reference< drawing::XShapes > xShapes( xShape, uno::UNO_QUERY );
- if ( xShapes.is() )
+ // create the control shape, set control model at the shape
+ Reference< XShape > xShape = lclCreateAndInsertXShape(
+ rFilter, rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ), rShapeRect );
+ Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY ); // do not throw, but always return the shape
+ if( xCtrlShape.is() )
+ xCtrlShape->setControl( xCtrlModel );
+ return xShape;
+ }
+ catch( Exception& )
+ {
+ }
+ // on error, proceed and try to create picture from replacement image
+ }
+
+ // try to create a picture object
+ if( aGraphicPath.getLength() > 0 )
{
- awt::Rectangle aChildRect;
- if ( pShapeRect )
- aChildRect = *pShapeRect;
- else
+ Reference< XShape > xShape = lclCreateAndInsertXShape( rFilter, rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ), rShapeRect );
+ if( xShape.is() )
{
- aChildRect.X = maPosition.X;
- aChildRect.Y = maPosition.Y;
- aChildRect.Width = maSize.Width;
- aChildRect.Height = maSize.Height;
+ OUString aGraphicUrl = rFilter.importEmbeddedGraphicObject( aGraphicPath );
+ if( aGraphicUrl.getLength() > 0 )
+ {
+ PropertySet aPropSet( xShape );
+ aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
+ }
}
- addChilds( rFilterBase, rDrawing, xShapes, aChildRect );
+ return xShape;
+ }
+
+ // default: try to create a custom shape
+ return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
+}
+
+// ============================================================================
+
+GroupShape::GroupShape( const Drawing& rDrawing ) :
+ ShapeBase( rDrawing ),
+ mxChildren( new ShapeContainer( rDrawing ) )
+{
+}
+
+GroupShape::~GroupShape()
+{
+}
+
+void GroupShape::finalizeFragmentImport()
+{
+ // basic shape processing
+ ShapeBase::finalizeFragmentImport();
+ // finalize all child shapes
+ mxChildren->finalizeFragmentImport();
+}
+
+const ShapeType* GroupShape::getChildTypeById( const OUString& rShapeId ) const
+{
+ return mxChildren->getShapeTypeById( rShapeId, true );
+}
+
+const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const
+{
+ return mxChildren->getShapeById( rShapeId, true );
+}
+
+Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const
+{
+ Reference< XShape > xShape;
+ // check that this shape contains children and a valid coordinate system
+ ShapeParentAnchor aParentAnchor;
+ aParentAnchor.maShapeRect = rShapeRect;
+ aParentAnchor.maCoordSys = getCoordSystem();
+ if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try
+ {
+ xShape = lclCreateAndInsertXShape( mrDrawing.getFilter(), rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rShapeRect );
+ Reference< XShapes > xShapes( xShape, UNO_QUERY_THROW );
+ mxChildren->convertAndInsert( xShapes, &aParentAnchor );
}
+ catch( Exception& )
+ {
+ }
+ return xShape;
}
-} }
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
diff --git a/oox/source/vml/vmlshapecontainer.cxx b/oox/source/vml/vmlshapecontainer.cxx
new file mode 100644
index 000000000000..3b9346f3096a
--- /dev/null
+++ b/oox/source/vml/vmlshapecontainer.cxx
@@ -0,0 +1,137 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vmlshapecontainer.cxx,v $
+ * $Revision: 1.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmlshapecontainer.hxx"
+#include "oox/vml/vmldrawing.hxx"
+#include "oox/vml/vmlshape.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::awt::Rectangle;
+using ::com::sun::star::drawing::XShapes;
+using ::oox::core::XmlFilterBase;
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+namespace {
+
+template< typename ShapeType >
+void lclMapShapesById( RefMap< OUString, ShapeType >& orMap, const RefVector< ShapeType >& rVector )
+{
+ for( typename RefVector< ShapeType >::const_iterator aIt = rVector.begin(), aEnd = rVector.end(); aIt != aEnd; ++aIt )
+ {
+ const OUString& rShapeId = (*aIt)->getShapeId();
+ OSL_ENSURE( rShapeId.getLength() > 0, "lclMapShapesById - missing shape identifier" );
+ if( rShapeId.getLength() > 0 )
+ {
+ OSL_ENSURE( orMap.find( rShapeId ) == orMap.end(), "lclMapShapesById - shape identifier already used" );
+ orMap[ rShapeId ] = *aIt;
+ }
+ }
+}
+
+} // namespace
+
+// ============================================================================
+
+ShapeContainer::ShapeContainer( const Drawing& rDrawing ) :
+ mrDrawing( rDrawing )
+{
+}
+
+ShapeContainer::~ShapeContainer()
+{
+}
+
+ShapeType& ShapeContainer::createShapeType()
+{
+ ::boost::shared_ptr< ShapeType > xShape( new ShapeType( mrDrawing ) );
+ maTypes.push_back( xShape );
+ return *xShape;
+}
+
+void ShapeContainer::finalizeFragmentImport()
+{
+ // map all shape templates by shape identifier
+ lclMapShapesById( maTypesById, maTypes );
+ // map all shapes by shape identifier
+ lclMapShapesById( maShapesById, maShapes );
+ /* process all shapes (map all children templates/shapes in group shapes,
+ resolve template references in all shapes) */
+ maShapes.forEachMem( &ShapeBase::finalizeFragmentImport );
+}
+
+const ShapeType* ShapeContainer::getShapeTypeById( const OUString& rShapeId, bool bDeep ) const
+{
+ // search in own shape template list
+ if( const ShapeType* pType = maTypesById.get( rShapeId ).get() )
+ return pType;
+ // search deep in child shapes
+ if( bDeep )
+ for( ShapeVector::const_iterator aVIt = maShapes.begin(), aVEnd = maShapes.end(); aVIt != aVEnd; ++aVIt )
+ if( const ShapeType* pType = (*aVIt)->getChildTypeById( rShapeId ) )
+ return pType;
+ return 0;
+}
+
+const ShapeBase* ShapeContainer::getShapeById( const OUString& rShapeId, bool bDeep ) const
+{
+ // search in own shape list
+ if( const ShapeBase* pShape = maShapesById.get( rShapeId ).get() )
+ return pShape;
+ // search deep in child shapes
+ if( bDeep )
+ for( ShapeVector::const_iterator aVIt = maShapes.begin(), aVEnd = maShapes.end(); aVIt != aVEnd; ++aVIt )
+ if( const ShapeBase* pShape = (*aVIt)->getChildById( rShapeId ) )
+ return pShape;
+ return 0;
+}
+
+const ShapeBase* ShapeContainer::getFirstShape() const
+{
+ OSL_ENSURE( mrDrawing.getType() == VMLDRAWING_WORD, "ShapeContainer::getFirstShape - illegal call, Word filter only" );
+ OSL_ENSURE( maShapes.size() == 1, "ShapeContainer::getFirstShape - single shape expected" );
+ return maShapes.get( 0 ).get();
+}
+
+void ShapeContainer::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
+{
+ for( ShapeVector::const_iterator aIt = maShapes.begin(), aEnd = maShapes.end(); aIt != aEnd; ++aIt )
+ (*aIt)->convertAndInsert( rxShapes, pParentAnchor );
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+
diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx
new file mode 100644
index 000000000000..dcf842a67a8f
--- /dev/null
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: vmldrawingfragmenthandler.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/vml/vmlshapecontext.hxx"
+#include "oox/vml/vmlshape.hxx"
+#include "oox/vml/vmlshapecontainer.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::awt::Point;
+using ::oox::core::ContextHandler2;
+using ::oox::core::ContextHandler2Helper;
+using ::oox::core::ContextHandlerRef;
+
+namespace oox {
+namespace vml {
+
+// ============================================================================
+
+namespace {
+
+bool lclSeparateValue( OUString& orName, OUString& orValue, const OUString& rAttrib, sal_Unicode cSep = ':' )
+{
+ sal_Int32 nSepPos = rAttrib.indexOf( cSep );
+ if( nSepPos <= 0 ) return false;
+ orName = rAttrib.copy( 0, nSepPos ).trim();
+ orValue = rAttrib.copy( nSepPos + 1 ).trim();
+ return (orName.getLength() > 0) && (orValue.getLength() > 0);
+}
+
+/** Returns the boolean value from the passed string (supported: f, t, False, True).
+ @param bDefaultForEmpty Default value for the empty string.
+ */
+bool lclDecodeBool( const OUString& rValue, bool bDefaultForEmpty )
+{
+ if( rValue.getLength() == 0 ) return bDefaultForEmpty;
+ // anything else than 't' or 'True' is considered to be false, as specified
+ return ((rValue.getLength() == 1) && (rValue[ 0 ] == 't')) || (rValue == CREATE_OUSTRING( "True" ));
+}
+
+} // namespace
+
+// ============================================================================
+
+ShapeClientDataContext::ShapeClientDataContext( ContextHandler2Helper& rParent,
+ const AttributeList& rAttribs, ShapeClientData& rClientData ) :
+ ContextHandler2( rParent ),
+ mrClientData( rClientData )
+{
+ mrClientData.mnObjType = rAttribs.getToken( XML_ObjectType, XML_TOKEN_INVALID );
+}
+
+ContextHandlerRef ShapeClientDataContext::onCreateContext( sal_Int32 /*nElement*/, const AttributeList& /*rAttribs*/ )
+{
+ return isRootElement() ? this : 0;
+}
+
+void ShapeClientDataContext::onEndElement( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ case VMLX_TOKEN( Anchor ): mrClientData.maAnchor = rChars; break;
+ case VMLX_TOKEN( FmlaLink ): mrClientData.maLinkedCell = rChars; break;
+ case VMLX_TOKEN( FmlaPict ): mrClientData.maPictureLink = rChars; break;
+ case VMLX_TOKEN( FmlaRange ): mrClientData.maSourceRange = rChars; break;
+ case VMLX_TOKEN( PrintObject ): mrClientData.mbPrintObject = lclDecodeBool( rChars, true ); break;
+ }
+}
+
+// ============================================================================
+
+ShapeContextBase::ShapeContextBase( ContextHandler2Helper& rParent ) :
+ ContextHandler2( rParent )
+{
+}
+
+/*static*/ ContextHandlerRef ShapeContextBase::createContext( ContextHandler2Helper& rParent,
+ sal_Int32 nElement, const AttributeList& rAttribs, ShapeContainer& rShapes )
+{
+ switch( nElement )
+ {
+ case VML_TOKEN( shapetype ):
+ return new ShapeTypeContext( rParent, rAttribs, rShapes.createShapeType() );
+ case VML_TOKEN( group ):
+ return new GroupShapeContext( rParent, rAttribs, rShapes.createShape< GroupShape >() );
+ case VML_TOKEN( shape ):
+ return new ShapeContext( rParent, rAttribs, rShapes.createShape< ComplexShape >() );
+ case VML_TOKEN( rect ):
+ case VML_TOKEN( roundrect ):
+ return new ShapeContext( rParent, rAttribs, rShapes.createShape< RectangleShape >() );
+ case VML_TOKEN( oval ):
+ return new ShapeContext( rParent, rAttribs, rShapes.createShape< EllipseShape >() );
+ case VML_TOKEN( polyline ):
+ return new ShapeContext( rParent, rAttribs, rShapes.createShape< PolyLineShape >() );
+
+ // TODO:
+ case VML_TOKEN( arc ):
+ case VML_TOKEN( curve ):
+ case VML_TOKEN( line ):
+ case VML_TOKEN( diagram ):
+ case VML_TOKEN( image ):
+ return new ShapeContext( rParent, rAttribs, rShapes.createShape< ComplexShape >() );
+ }
+ return false;
+}
+
+// ============================================================================
+
+ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, ShapeType& rShapeType ) :
+ ShapeContextBase( rParent ),
+ mrTypeModel( rShapeType.getTypeModel() )
+{
+ // shape identifier and shape name
+ bool bHasOspid = rAttribs.hasAttribute( O_TOKEN( spid ) );
+ mrTypeModel.maShapeId = rAttribs.getXString( bHasOspid ? O_TOKEN( spid ) : XML_id, OUString() );
+ OSL_ENSURE( mrTypeModel.maShapeId.getLength() > 0, "ShapeTypeContext::ShapeTypeContext - missing shape identifier" );
+ // if the o:spid attribute exists, the id attribute contains the user-defined shape name
+ if( bHasOspid )
+ mrTypeModel.maName = rAttribs.getXString( XML_id, OUString() );
+ // builtin shape type identifier
+ mrTypeModel.monShapeType = rAttribs.getInteger( O_TOKEN( spt ) );
+ // coordinate system position/size
+ setCoordOrigin( rAttribs.getString( XML_coordorigin, OUString() ) );
+ setCoordSize( rAttribs.getString( XML_coordsize, OUString() ) );
+ // CSS style
+ setStyle( rAttribs.getString( XML_style, OUString() ) );
+ // border line
+ mrTypeModel.mobStroked = rAttribs.getBool( XML_stroked );
+ mrTypeModel.moStrokeColor = rAttribs.getString( XML_strokecolor );
+ // shape fill
+ mrTypeModel.mobFilled = rAttribs.getBool( XML_filled );
+ mrTypeModel.moFillColor = rAttribs.getString( XML_fillcolor );
+}
+
+ContextHandlerRef ShapeTypeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ if( isRootElement() ) switch( nElement )
+ {
+ case VML_TOKEN( imagedata ):
+ OptValue< OUString > oGraphicRelId = rAttribs.getString( O_TOKEN( relid ) );
+ if( oGraphicRelId.has() )
+ mrTypeModel.moGraphicPath = getFragmentPathFromRelId( oGraphicRelId.get() );
+ mrTypeModel.moGraphicTitle = rAttribs.getString( O_TOKEN( title ) );
+ break;
+ }
+ return 0;
+}
+
+void ShapeTypeContext::setCoordOrigin( const OUString& rCoordOrigin )
+{
+ OUString aCoordL, aCoordT;
+ if( lclSeparateValue( aCoordL, aCoordT, rCoordOrigin, ',' ) )
+ {
+ mrTypeModel.monCoordLeft = aCoordL.toInt32();
+ mrTypeModel.monCoordTop = aCoordT.toInt32();
+ }
+}
+
+void ShapeTypeContext::setCoordSize( const OUString& rCoordSize )
+{
+ OUString aCoordW, aCoordH;
+ if( lclSeparateValue( aCoordW, aCoordH, rCoordSize, ',' ) )
+ {
+ mrTypeModel.monCoordWidth = aCoordW.toInt32();
+ mrTypeModel.monCoordHeight = aCoordH.toInt32();
+ }
+}
+
+void ShapeTypeContext::setStyle( const OUString& rStyle )
+{
+ sal_Int32 nIndex = 0;
+ while( nIndex >= 0 )
+ {
+ OUString aName, aValue;
+ if( lclSeparateValue( aName, aValue, rStyle.getToken( 0, ';', nIndex ) ) )
+ {
+ if( aName.equalsAscii( "position" ) ) mrTypeModel.maPosition = aValue;
+ else if( aName.equalsAscii( "left" ) ) mrTypeModel.maLeft = aValue;
+ else if( aName.equalsAscii( "top" ) ) mrTypeModel.maTop = aValue;
+ else if( aName.equalsAscii( "width" ) ) mrTypeModel.maWidth = aValue;
+ else if( aName.equalsAscii( "height" ) ) mrTypeModel.maHeight = aValue;
+ else if( aName.equalsAscii( "margin-left" ) ) mrTypeModel.maMarginLeft = aValue;
+ else if( aName.equalsAscii( "margin-top" ) ) mrTypeModel.maMarginTop = aValue;
+ }
+ }
+}
+
+// ============================================================================
+
+ShapeContext::ShapeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, ShapeBase& rShape ) :
+ ShapeTypeContext( rParent, rAttribs, rShape ),
+ mrShapeModel( rShape.getShapeModel() )
+{
+ // collect shape specific attributes
+ mrShapeModel.maType = rAttribs.getXString( XML_type, OUString() );
+ // polyline path
+ setPoints( rAttribs.getString( XML_points, OUString() ) );
+}
+
+ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ // Excel specific shape client data
+ if( isRootElement() && (nElement == VMLX_TOKEN( ClientData )) )
+ return new ShapeClientDataContext( *this, rAttribs, mrShapeModel.createClientData() );
+ // handle remaining stuff in base class
+ return ShapeTypeContext::onCreateContext( nElement, rAttribs );
+}
+
+void ShapeContext::setPoints( const OUString& rPoints )
+{
+ mrShapeModel.maPoints.clear();
+ sal_Int32 nIndex = 0;
+ while( nIndex >= 0 )
+ {
+ sal_Int32 nX = rPoints.getToken( 0, ',', nIndex ).toInt32();
+ sal_Int32 nY = rPoints.getToken( 0, ',', nIndex ).toInt32();
+ mrShapeModel.maPoints.push_back( Point( nX, nY ) );
+ }
+}
+
+// ============================================================================
+
+GroupShapeContext::GroupShapeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, GroupShape& rShape ) :
+ ShapeContext( rParent, rAttribs, rShape ),
+ mrShapes( rShape.getChildren() )
+{
+}
+
+ContextHandlerRef GroupShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ // try to create a context of an embedded shape
+ ContextHandlerRef xContext = ShapeContextBase::createContext( *this, nElement, rAttribs, mrShapes );
+ // handle remaining stuff of this shape in base class
+ return xContext.get() ? xContext : ShapeContext::onCreateContext( nElement, rAttribs );
+}
+
+// ============================================================================
+
+} // namespace vml
+} // namespace oox
+