summaryrefslogtreecommitdiffstats
path: root/oox
diff options
context:
space:
mode:
authorTamás Zolnai <tamas.zolnai@collabora.com>2017-08-17 21:47:22 +0200
committerTamás Zolnai <tamas.zolnai@collabora.com>2017-08-17 23:11:15 +0200
commitc0cc02e2934aeb12dda44818955e5964496c186a (patch)
tree16f450bbe38e14d336bdbac3220b642b9a302a87 /oox
parentRelated tdf#105500: leaks in PaletteManager and SvxColorToolBoxControl (diff)
downloadcore-c0cc02e2934aeb12dda44818955e5964496c186a.tar.gz
core-c0cc02e2934aeb12dda44818955e5964496c186a.zip
tdf#50097: DOCX: export form controls as MSO ActiveX controls
* Use the same structure for export what MSO uses ** Position and size information are exported as VML shape properties ** Different handling of inline and floating controls (pict or object) ** Do some changes on VML shape export to match how MSO exports these controls ** Write out activeX.xml and activeX.bin to store control properties ** Use persistStorage storage type defined in activeX.xml * Drop grabbaging of activex.XML and activeX.bin * Cleanup control related test code Change-Id: I38bb2b2ffd2676c5459b61ec2549c31348bab41c Signed-off-by: Tamás Zolnai <tamas.zolnai@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/41256 Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/export/preset-definitions-to-shape-types.pl2
-rw-r--r--oox/source/export/vmlexport.cxx93
-rw-r--r--oox/source/ole/olehelper.cxx45
-rw-r--r--oox/source/token/tokens.txt2
4 files changed, 100 insertions, 42 deletions
diff --git a/oox/source/export/preset-definitions-to-shape-types.pl b/oox/source/export/preset-definitions-to-shape-types.pl
index 2fe929705746..b41dd58953e8 100644
--- a/oox/source/export/preset-definitions-to-shape-types.pl
+++ b/oox/source/export/preset-definitions-to-shape-types.pl
@@ -287,7 +287,7 @@ my %shapes_ids = (
198 => 'actionButtonDocument',
199 => 'actionButtonSound',
200 => 'actionButtonMovie',
- 201 => 'hostControl', # should not be used
+ 201 => 'hostControl',
202 => 'textBox'
);
# An error occurred, we have to ignore this shape
diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
index b91d72e218e9..3ee2711f8e5f 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -59,6 +59,7 @@ VMLExport::VMLExport( ::sax_fastparser::FSHelperPtr const & pSerializer, VMLText
, m_eVOri( 0 )
, m_eHRel( 0 )
, m_eVRel( 0 )
+ , m_bInline( false )
, m_pNdTopLeft( nullptr )
, m_pSdrObject( nullptr )
, m_pShapeAttrList( nullptr )
@@ -66,6 +67,8 @@ VMLExport::VMLExport( ::sax_fastparser::FSHelperPtr const & pSerializer, VMLText
, m_nShapeFlags(0)
, m_ShapeStyle( 200 )
, m_aShapeTypeWritten( ESCHER_ShpInst_COUNT )
+ , m_bSkipwzName( false )
+ , m_bUseHashMarkForType( false )
{
mnGroupLevel = 1;
}
@@ -181,19 +184,21 @@ void VMLExport::AddShape( sal_uInt32 nShapeType, sal_uInt32 nShapeFlags, sal_uIn
{
m_nShapeType = nShapeType;
m_nShapeFlags = nShapeFlags;
+
+ m_sShapeId = ShapeIdString( nShapeId );
// If shape is a watermark object - should keep the original shape's name
// because Microsoft detects if it is a watermark by the actual name
if (!IsWaterMarkShape(m_pSdrObject->GetName()))
{
// Not a watermark object
- m_pShapeAttrList->add( XML_id, ShapeIdString( nShapeId ) );
+ m_pShapeAttrList->add( XML_id, m_sShapeId );
}
else
{
// A watermark object - store the optional shape ID
m_pShapeAttrList->add( XML_id, OUStringToOString(m_pSdrObject->GetName(), RTL_TEXTENCODING_UTF8) );
// also ('o:spid')
- m_pShapeAttrList->addNS( XML_o, XML_spid, ShapeIdString( nShapeId ) );
+ m_pShapeAttrList->addNS( XML_o, XML_spid, m_sShapeId );
}
}
@@ -849,7 +854,7 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
aStream.Seek(0);
OUString idStr = SvxMSDffManager::MSDFFReadZString(aStream, it->nPropSize, true);
aStream.Seek(0);
- if (!IsWaterMarkShape(m_pSdrObject->GetName()))
+ if (!IsWaterMarkShape(m_pSdrObject->GetName()) && !m_bSkipwzName)
m_pShapeAttrList->add(XML_ID, OUStringToOString(idStr, RTL_TEXTENCODING_UTF8).getStr());
bAlreadyWritten[ESCHER_Prop_wzName] = true;
@@ -939,12 +944,18 @@ void VMLExport::AddRectangleDimensions( OStringBuffer& rBuffer, const tools::Rec
if ( !rBuffer.isEmpty() )
rBuffer.append( ";" );
- if (rbAbsolutePos)
+ if (rbAbsolutePos && !m_bInline)
{
rBuffer.append( "position:absolute;" );
}
- if ( mnGroupLevel == 1 )
+ if(m_bInline)
+ {
+ rBuffer.append( "width:" ).append( double( rRectangle.Right() - rRectangle.Left() ) / 20 )
+ .append( "pt;height:" ).append( double( rRectangle.Bottom() - rRectangle.Top() ) / 20 )
+ .append( "pt" );
+ }
+ else if ( mnGroupLevel == 1 )
{
rBuffer.append( "margin-left:" ).append( double( rRectangle.Left() ) / 20 )
.append( "pt;margin-top:" ).append( double( rRectangle.Top() ) / 20 )
@@ -1031,6 +1042,62 @@ sal_Int32 VMLExport::StartShape()
case ESCHER_ShpInst_Ellipse: nShapeElement = XML_oval; break;
case ESCHER_ShpInst_Arc: nShapeElement = XML_arc; break;
case ESCHER_ShpInst_Line: nShapeElement = XML_line; break;
+ case ESCHER_ShpInst_HostControl:
+ {
+ // We don't have a shape definition for host control in presetShapeDefinitions.xml
+ // So use a definition copied from DOCX file created with MSO
+ bReferToShapeType = true;
+ nShapeElement = XML_shape;
+ if ( !m_aShapeTypeWritten[ m_nShapeType ] )
+ {
+ OStringBuffer sShapeType;
+ sShapeType.append("<v:shapetype id=\"shapetype_").append(OString::number(m_nShapeType)).
+ append("\" coordsize=\"21600,21600\" o:spt=\"").append(OString::number(m_nShapeType)).
+ append("\" path=\"m,l,21600l21600,21600l21600,xe\">\n").
+ append("<v:stroke joinstyle=\"miter\"/>\n"
+ "<v:path shadowok=\"f\" o:extrusionok=\"f\" strokeok=\"f\" fillok=\"f\" o:connecttype=\"rect\"/>\n"
+ "<o:lock v:ext=\"edit\" shapetype=\"t\"/>\n"
+ "</v:shapetype>");
+ m_pSerializer->write(sShapeType.makeStringAndClear().getStr());
+ m_aShapeTypeWritten[ m_nShapeType ] = true;
+ }
+ break;
+ }
+ case ESCHER_ShpInst_PictureFrame:
+ {
+ // We don't have a shape definition for picture frame in presetShapeDefinitions.xml
+ // So use a definition copied from DOCX file created with MSO
+ bReferToShapeType = true;
+ nShapeElement = XML_shape;
+ if ( !m_aShapeTypeWritten[ m_nShapeType ] )
+ {
+ OStringBuffer sShapeType;
+ sShapeType.append("<v:shapetype id=\"shapetype_").append(OString::number(m_nShapeType)).
+ append("\" coordsize=\"21600,21600\" o:spt=\"").append(OString::number(m_nShapeType)).
+ append("\" o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@5xe\" filled=\"f\" stroked=\"f\">\n").
+ append("<v:stroke joinstyle=\"miter\"/>\n"
+ "<v:formulas>\n"
+ "<v:f eqn=\"if lineDrawn pixelLineWidth 0\"/>\n"
+ "<v:f eqn=\"sum @0 1 0\"/>\n"
+ "<v:f eqn=\"sum 0 0 @1\"/>\n"
+ "<v:f eqn=\"prod @2 1 2\"/>\n"
+ "<v:f eqn=\"prod @3 21600 pixelWidth\"/>\n"
+ "<v:f eqn=\"prod @3 21600 pixelHeight\"/>\n"
+ "<v:f eqn=\"sum @0 0 1\"/>\n"
+ "<v:f eqn=\"prod @6 1 2\"/>\n"
+ "<v:f eqn=\"prod @7 21600 pixelWidth\"/>\n"
+ "<v:f eqn=\"sum @8 21600 0\"/>\n"
+ "<v:f eqn=\"prod @7 21600 pixelHeight\"/>\n"
+ "<v:f eqn=\"sum @10 21600 0\"/>\n"
+ "</v:formulas>\n"
+ "<v:path o:extrusionok=\"f\" gradientshapeok=\"t\" o:connecttype=\"rect\"/>\n"
+ "<o:lock v:ext=\"edit\" aspectratio=\"t\"/>\n"
+ "</v:shapetype>");
+ m_pSerializer->write(sShapeType.makeStringAndClear().getStr());
+ m_aShapeTypeWritten[ m_nShapeType ] = true;
+ }
+ break;
+ }
default:
if ( m_nShapeType < ESCHER_ShpInst_COUNT )
{
@@ -1137,7 +1204,10 @@ sal_Int32 VMLExport::StartShape()
if ( nShapeElement >= 0 && !m_pShapeAttrList->hasAttribute( XML_type ) && bReferToShapeType )
{
- m_pShapeAttrList->add( XML_type, OStringBuffer( 20 )
+ OStringBuffer sTypeBuffer( 20 );
+ if (m_bUseHashMarkForType)
+ sTypeBuffer.append("#");
+ m_pShapeAttrList->add( XML_type, sTypeBuffer
.append( "shapetype_" ).append( sal_Int32( m_nShapeType ) )
.makeStringAndClear() );
}
@@ -1210,7 +1280,7 @@ void VMLExport::EndShape( sal_Int32 nShapeElement )
}
}
-void VMLExport::AddSdrObject( const SdrObject& rObj, sal_Int16 eHOri, sal_Int16 eVOri, sal_Int16 eHRel, sal_Int16 eVRel, const Point* pNdTopLeft, const bool bOOxmlExport )
+OString VMLExport::AddSdrObject( const SdrObject& rObj, sal_Int16 eHOri, sal_Int16 eVOri, sal_Int16 eHRel, sal_Int16 eVRel, const Point* pNdTopLeft, const bool bOOxmlExport )
{
m_pSdrObject = &rObj;
m_eHOri = eHOri;
@@ -1219,6 +1289,15 @@ void VMLExport::AddSdrObject( const SdrObject& rObj, sal_Int16 eHOri, sal_Int16
m_eVRel = eVRel;
m_pNdTopLeft = pNdTopLeft;
EscherEx::AddSdrObject(rObj, bOOxmlExport);
+ return m_sShapeId;
+}
+
+OString VMLExport::AddInlineSdrObject( const SdrObject& rObj, const bool bOOxmlExport )
+{
+ m_pSdrObject = &rObj;
+ m_bInline = true;
+ EscherEx::AddSdrObject(rObj, bOOxmlExport);
+ return m_sShapeId;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ole/olehelper.cxx b/oox/source/ole/olehelper.cxx
index 1a6e7df17a5e..f2df54a833a0 100644
--- a/oox/source/ole/olehelper.cxx
+++ b/oox/source/ole/olehelper.cxx
@@ -329,35 +329,7 @@ Reference< css::frame::XFrame > lcl_getFrame( const Reference< css::frame::XMod
return xFrame;
}
-class OleFormCtrlExportHelper final
-{
- ::oox::ole::EmbeddedControl maControl;
- ::oox::ole::ControlModelBase* mpModel;
- ::oox::GraphicHelper maGrfHelper;
- Reference< XModel > mxDocModel;
- Reference< XControlModel > mxControlModel;
-
- OUString maName;
- OUString maTypeName;
- OUString maFullName;
- OUString maGUID;
-public:
- OleFormCtrlExportHelper( const Reference< XComponentContext >& rxCtx, const Reference< XModel >& xDocModel, const Reference< XControlModel >& xModel );
- OUString getGUID()
- {
- OUString sResult;
- if ( maGUID.getLength() > 2 )
- sResult = maGUID.copy(1, maGUID.getLength() - 2 );
- return sResult;
- }
- const OUString& getFullName() { return maFullName; }
- const OUString& getTypeName() { return maTypeName; }
- bool isValid() { return mpModel != nullptr; }
- void exportName( const Reference< XOutputStream >& rxOut );
- void exportCompObj( const Reference< XOutputStream >& rxOut );
- void exportControl( const Reference< XOutputStream >& rxOut, const css::awt::Size& rSize );
-};
-OleFormCtrlExportHelper::OleFormCtrlExportHelper( const Reference< XComponentContext >& rxCtx, const Reference< XModel >& rxDocModel, const Reference< XControlModel >& xCntrlModel ) : maControl( "Unknown" ), mpModel( nullptr ), maGrfHelper( rxCtx, lcl_getFrame( rxDocModel ), StorageRef() ), mxDocModel( rxDocModel ), mxControlModel( xCntrlModel )
+OleFormCtrlExportHelper::OleFormCtrlExportHelper( const Reference< XComponentContext >& rxCtx, const Reference< XModel >& rxDocModel, const Reference< XControlModel >& xCntrlModel ) : mpControl(nullptr), mpModel( nullptr ), maGrfHelper( rxCtx, lcl_getFrame( rxDocModel ), StorageRef() ), mxDocModel( rxDocModel ), mxControlModel( xCntrlModel )
{
// try to get the guid
Reference< css::beans::XPropertySet > xProps( xCntrlModel, UNO_QUERY );
@@ -404,14 +376,18 @@ OleFormCtrlExportHelper::OleFormCtrlExportHelper( const Reference< XComponentCo
aPropSet.getProperty(maName, PROP_Name );
maTypeName = OUString::createFromAscii( it->second.sName );
maFullName = "Microsoft Forms 2.0 " + maTypeName;
- maControl = EmbeddedControl( maName );
+ mpControl.reset(new EmbeddedControl( maName ));
maGUID = OUString::createFromAscii( it->second.sGUID );
- mpModel = maControl.createModelFromGuid( maGUID );
+ mpModel = mpControl->createModelFromGuid( maGUID );
}
}
}
}
+OleFormCtrlExportHelper::~OleFormCtrlExportHelper()
+{
+}
+
void OleFormCtrlExportHelper::exportName( const Reference< XOutputStream >& rxOut )
{
oox::BinaryXOutputStream aOut( rxOut, false );
@@ -426,13 +402,14 @@ void OleFormCtrlExportHelper::exportCompObj( const Reference< XOutputStream >& r
mpModel->exportCompObj( aOut );
}
-void OleFormCtrlExportHelper::exportControl( const Reference< XOutputStream >& rxOut, const Size& rSize )
+void OleFormCtrlExportHelper::exportControl( const Reference< XOutputStream >& rxOut, const Size& rSize, bool bAutoClose )
{
- oox::BinaryXOutputStream aOut( rxOut, false );
+ oox::BinaryXOutputStream aOut( rxOut, bAutoClose );
if ( mpModel )
{
::oox::ole::ControlConverter aConv( mxDocModel, maGrfHelper );
- maControl.convertFromProperties( mxControlModel, aConv );
+ if(mpControl)
+ mpControl->convertFromProperties( mxControlModel, aConv );
mpModel->maSize.first = rSize.Width;
mpModel->maSize.second = rSize.Height;
mpModel->exportBinaryModel( aOut );
diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt
index 00577f862890..653050ea9ba2 100644
--- a/oox/source/token/tokens.txt
+++ b/oox/source/token/tokens.txt
@@ -740,6 +740,7 @@ avLst
average
avg
avgSubtotal
+ax
axId
axPos
axis
@@ -5808,6 +5809,7 @@ xmlPr
xmlns
xpath
xrange
+xsc
xscale
xsi
xy