summaryrefslogtreecommitdiff
path: root/sw
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 /sw
parent8c0cc5cd7befffc6e8e6361ba67807a799cc997f (diff)
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 'sw')
-rw-r--r--sw/qa/extras/ooxmlexport/data/activex.docxbin40422 -> 0 bytes
-rwxr-xr-xsw/qa/extras/ooxmlexport/data/activex_checkbox.docx (renamed from sw/qa/extras/ooxmlimport/data/activex_checkbox.docx)bin13851 -> 13851 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/data/activexbin.docxbin41606 -> 0 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport2.cxx1
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport3.cxx57
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport5.cxx1
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport6.cxx8
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport7.cxx8
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport9.cxx29
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx1
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx28
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx104
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx5
-rw-r--r--sw/source/filter/ww8/docxexport.cxx149
-rw-r--r--sw/source/filter/ww8/docxexport.hxx6
15 files changed, 203 insertions, 194 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/activex.docx b/sw/qa/extras/ooxmlexport/data/activex.docx
deleted file mode 100644
index eb546d9795ef..000000000000
--- a/sw/qa/extras/ooxmlexport/data/activex.docx
+++ /dev/null
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/data/activex_checkbox.docx b/sw/qa/extras/ooxmlexport/data/activex_checkbox.docx
index d7415ef5a5c6..d7415ef5a5c6 100755
--- a/sw/qa/extras/ooxmlimport/data/activex_checkbox.docx
+++ b/sw/qa/extras/ooxmlexport/data/activex_checkbox.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/data/activexbin.docx b/sw/qa/extras/ooxmlexport/data/activexbin.docx
deleted file mode 100644
index ecf4599ed0e9..000000000000
--- a/sw/qa/extras/ooxmlexport/data/activexbin.docx
+++ /dev/null
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx
index 72062211959d..b5e63cf65a86 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx
@@ -14,7 +14,6 @@
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/LineJoint.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
-#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/awt/Gradient.hpp>
#include <com/sun/star/style/TabStop.hpp>
#include <com/sun/star/view/XViewSettingsSupplier.hpp>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
index 85b1b8fef611..0303237aece2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
@@ -14,7 +14,6 @@
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/LineJoint.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
-#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/awt/Gradient.hpp>
#include <com/sun/star/style/TabStop.hpp>
#include <com/sun/star/view/XViewSettingsSupplier.hpp>
@@ -537,62 +536,6 @@ DECLARE_OOXMLEXPORT_TEST(testCustomXmlGrabBag, "customxml.docx")
CPPUNIT_ASSERT(CustomXml); // Grab Bag has all the expected elements
}
-DECLARE_OOXMLEXPORT_TEST(testActiveXGrabBag, "activex.docx")
-{
- // The problem was that activeX.xml files were missing from docx file after saving file.
- // This test case tests whether activex files grabbagged properly in correct object.
-
- uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
- uno::Reference<beans::XPropertySet> xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY);
- uno::Sequence<beans::PropertyValue> aGrabBag(0);
- xTextDocumentPropertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
- CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
- bool bActiveX = false;
- for(int i = 0; i < aGrabBag.getLength(); ++i)
- {
- if (aGrabBag[i].Name == "OOXActiveX")
- {
- bActiveX = true;
- uno::Reference<xml::dom::XDocument> aActiveXDom;
- uno::Sequence<uno::Reference<xml::dom::XDocument> > aActiveXDomList;
- CPPUNIT_ASSERT(aGrabBag[i].Value >>= aActiveXDomList); // PropertyValue of proper type
- sal_Int32 length = aActiveXDomList.getLength();
- CPPUNIT_ASSERT_EQUAL(sal_Int32(5), length);
- aActiveXDom = aActiveXDomList[0];
- CPPUNIT_ASSERT(aActiveXDom.get()); // Reference not empty
- }
- }
- CPPUNIT_ASSERT(bActiveX); // Grab Bag has all the expected elements
-}
-
-DECLARE_OOXMLEXPORT_TEST(testActiveXBinGrabBag, "activexbin.docx")
-{
- // The problem was that activeX.bin files were missing from docx file after saving file.
- // This test case tests whether activex bin files grabbagged properly in correct object.
-
- uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
- uno::Reference<beans::XPropertySet> xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY);
- uno::Sequence<beans::PropertyValue> aGrabBag(0);
- xTextDocumentPropertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
- CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
- bool bActiveX = false;
- for(int i = 0; i < aGrabBag.getLength(); ++i)
- {
- if (aGrabBag[i].Name == "OOXActiveXBin")
- {
- bActiveX = true;
- uno::Reference<io::XInputStream> aActiveXBin;
- uno::Sequence<uno::Reference<io::XInputStream> > aActiveXBinList;
- CPPUNIT_ASSERT(aGrabBag[i].Value >>= aActiveXBinList); // PropertyValue of proper type
- sal_Int32 length = aActiveXBinList.getLength();
- CPPUNIT_ASSERT_EQUAL(sal_Int32(5), length);
- aActiveXBin = aActiveXBinList[0];
- CPPUNIT_ASSERT(aActiveXBin.get()); // Reference not empty
- }
- }
- CPPUNIT_ASSERT(bActiveX); // Grab Bag has all the expected elements
-}
-
DECLARE_OOXMLEXPORT_TEST(testFdo69644, "fdo69644.docx")
{
// The problem was that the exporter exported the table definition
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index a690c4519ea7..96868a3b6f66 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -14,7 +14,6 @@
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/LineJoint.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
-#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/awt/Gradient.hpp>
#include <com/sun/star/style/TabStop.hpp>
#include <com/sun/star/view/XViewSettingsSupplier.hpp>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
index 2891b3ff162f..a5a28a21d9b7 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
@@ -9,7 +9,7 @@
#include <swmodeltestbase.hxx>
-#if !defined(_WIN32)
+
#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
@@ -455,7 +455,7 @@ DECLARE_OOXMLEXPORT_TEST(testVMLData, "TestVMLData.docx")
xmlDocPtr pXmlDoc = parseExport("word/header2.xml");
if (!pXmlDoc)
return;
- CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:hdr/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "stroked").match("f"));
+ CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:hdr/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:shape", "stroked").match("f"));
}
DECLARE_OOXMLEXPORT_TEST(testImageData, "image_data.docx")
@@ -465,7 +465,7 @@ DECLARE_OOXMLEXPORT_TEST(testImageData, "image_data.docx")
xmlDocPtr pXmlDoc = parseExport("word/header2.xml");
if (!pXmlDoc)
return;
- CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:hdr/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:rect/v:imagedata", "detectmouseclick").match("t"));
+ CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:hdr/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:shape/v:imagedata", "detectmouseclick").match("t"));
}
DECLARE_OOXMLEXPORT_TEST(testFdo70838, "fdo70838.docx")
@@ -929,8 +929,6 @@ DECLARE_OOXMLEXPORT_TEST(testSyncedRelativePercent, "tdf93676-1.odt")
assertXPath(pXmlDoc, "//wp14:pctHeight", 0);
}
-#endif
-
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
index d564e8031b26..8607ff84fca5 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
@@ -9,7 +9,6 @@
#include <swmodeltestbase.hxx>
-#if !defined(_WIN32)
#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
@@ -125,7 +124,7 @@ DECLARE_OOXMLEXPORT_TEST(testPictureWatermark, "pictureWatermark.docx")
return;
// Check the watermark ID
- assertXPath(pXmlHeader1, "/w:hdr[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Fallback[1]/w:pict[1]/v:rect[1]","id","WordPictureWatermark11962361");
+ assertXPath(pXmlHeader1, "/w:hdr[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Fallback[1]/w:pict[1]/v:shape[1]","id","WordPictureWatermark11962361");
}
@@ -1127,6 +1126,8 @@ DECLARE_OOXMLEXPORT_TEST(testTDF93675, "no-numlevel-but-indented.odt")
assertXPath(pXmlDoc, "//w:ind", "start", "1418");
}
+
+
DECLARE_OOXMLEXPORT_TEST(testFlipAndRotateCustomShape, "flip_and_rotate.odt")
{
xmlDocPtr pXmlDoc = parseExport("word/document.xml");
@@ -1141,6 +1142,7 @@ DECLARE_OOXMLEXPORT_TEST(testFlipAndRotateCustomShape, "flip_and_rotate.odt")
#ifndef MACOSX /* Retina-related rounding rountrip error
* hard to smooth out due to the use of string compare
* instead of number */
+#if !defined(_WIN32)
assertXPath(pXmlDoc, "//a:custGeom/a:pathLst/a:path/a:lnTo[1]/a:pt", "x", "2351");
assertXPath(pXmlDoc, "//a:custGeom/a:pathLst/a:path/a:lnTo[1]/a:pt", "y", "3171");
assertXPath(pXmlDoc, "//a:custGeom/a:pathLst/a:path/a:lnTo[2]/a:pt", "x", "1695");
@@ -1148,9 +1150,9 @@ DECLARE_OOXMLEXPORT_TEST(testFlipAndRotateCustomShape, "flip_and_rotate.odt")
assertXPath(pXmlDoc, "//a:custGeom/a:pathLst/a:path/a:lnTo[3]/a:pt", "x", "1695");
assertXPath(pXmlDoc, "//a:custGeom/a:pathLst/a:path/a:lnTo[3]/a:pt", "y", "1701");
#endif
+#endif
}
-#endif
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index caecccfa0681..afdd942eade4 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -10,7 +10,6 @@
#include <swmodeltestbase.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
#include <com/sun/star/text/XFootnote.hpp>
#include <com/sun/star/text/XPageCursor.hpp>
@@ -27,6 +26,7 @@
#include <com/sun/star/view/XViewSettingsSupplier.hpp>
#include <com/sun/star/style/LineSpacing.hpp>
#include <com/sun/star/style/LineSpacingMode.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
#include <ftninfo.hxx>
#include <sfx2/docfile.hxx>
@@ -818,6 +818,33 @@ DECLARE_OOXMLEXPORT_TEST(testTdf105095, "tdf105095.docx")
CPPUNIT_ASSERT(xTextRange->getString().endsWith("\tfootnote"));
}
+DECLARE_OOXMLIMPORT_TEST( testActiveXCheckbox, "activex_checkbox.docx" )
+{
+ uno::Reference<drawing::XControlShape> xControlShape( getShape(1), uno::UNO_QUERY );
+ CPPUNIT_ASSERT( xControlShape.is() );
+
+ // Check control type
+ uno::Reference<beans::XPropertySet> xPropertySet( xControlShape->getControl(), uno::UNO_QUERY );
+ uno::Reference<lang::XServiceInfo> xServiceInfo( xPropertySet, uno::UNO_QUERY );
+ CPPUNIT_ASSERT_EQUAL( true, bool( xServiceInfo->supportsService( "com.sun.star.form.component.CheckBox" ) ) );
+
+ // Check custom label
+ CPPUNIT_ASSERT_EQUAL( OUString( "Custom Caption" ), getProperty<OUString>(xPropertySet, "Label") );
+
+ // Check background color (highlight system color)
+ CPPUNIT_ASSERT_EQUAL( sal_Int32( 0x316AC5 ), getProperty<sal_Int32>(xPropertySet, "BackgroundColor") );
+
+ // Check Text color (active border system color)
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD4D0C8), getProperty<sal_Int32>(xPropertySet, "TextColor"));
+
+ // Check state of the checkbox
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPropertySet, "State"));
+
+ // Check anchor type
+ uno::Reference<beans::XPropertySet> xPropertySet2(xControlShape, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index c3b2af4bc065..7e5373e60241 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -14,7 +14,6 @@
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/LineJoint.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
-#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/awt/Gradient.hpp>
#include <com/sun/star/style/TabStop.hpp>
#include <com/sun/star/view/XViewSettingsSupplier.hpp>
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 2c2da5e9e7f3..e44d41f26d03 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -61,7 +61,6 @@
#include <unotools/streamwrap.hxx>
#include <comphelper/propertysequence.hxx>
#include <com/sun/star/drawing/HomogenMatrix3.hpp>
-#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/awt/CharSet.hpp>
#include <test/mtfxmldump.hxx>
@@ -1464,33 +1463,6 @@ DECLARE_OOXMLIMPORT_TEST(testGroupShapeFontName, "groupshape-fontname.docx")
CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(getRun(getParagraphOfText(1, xText), 1), "CharFontNameAsian"));
}
-DECLARE_OOXMLIMPORT_TEST( testActiveXCheckbox, "activex_checkbox.docx" )
-{
- uno::Reference<drawing::XControlShape> xControlShape( getShape(1), uno::UNO_QUERY );
- CPPUNIT_ASSERT( xControlShape.is() );
-
- // Check control type
- uno::Reference<beans::XPropertySet> xPropertySet( xControlShape->getControl(), uno::UNO_QUERY );
- uno::Reference<lang::XServiceInfo> xServiceInfo( xPropertySet, uno::UNO_QUERY );
- CPPUNIT_ASSERT_EQUAL( true, bool( xServiceInfo->supportsService( "com.sun.star.form.component.CheckBox" ) ) );
-
- // Check custom label
- CPPUNIT_ASSERT_EQUAL( OUString( "Custom Caption" ), getProperty<OUString>(xPropertySet, "Label") );
-
- // Check background color (highlight system color)
- CPPUNIT_ASSERT_EQUAL( sal_Int32( 0x316AC5 ), getProperty<sal_Int32>(xPropertySet, "BackgroundColor") );
-
- // Check Text color (active border system color)
- CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD4D0C8), getProperty<sal_Int32>(xPropertySet, "TextColor"));
-
- // Check state of the checkbox
- CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPropertySet, "State"));
-
- // Check anchor type
- uno::Reference<beans::XPropertySet> xPropertySet2(xControlShape, uno::UNO_QUERY);
- CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
-}
-
DECLARE_OOXMLIMPORT_TEST(testTdf111550, "tdf111550.docx")
{
// The test document has following ill-formed structure:
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 93cd4daba349..3c8bddef0cbf 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -50,6 +50,8 @@
#include <oox/mathml/export.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
#include <oox/token/relationship.hxx>
+#include <oox/export/vmlexport.hxx>
+#include <oox/ole/olehelper.hxx>
#include <editeng/autokernitem.hxx>
#include <editeng/unoprnms.hxx>
@@ -2043,6 +2045,8 @@ void DocxAttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData )
WritePostponedOLE();
+ WritePostponedActiveXControl();
+
// merge the properties _before_ the run text (strictly speaking, just
// after the start of the run)
m_pSerializer->mergeTopMarks(Tag_StartRunProperties, sax_fastparser::MergeMarks::PREPEND);
@@ -4781,6 +4785,101 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject)
}
}
+void DocxAttributeOutput::WritePostponedActiveXControl()
+{
+ for( std::vector<PostponedDrawing>::const_iterator it = m_aPostponedActiveXControls.begin();
+ it != m_aPostponedActiveXControls.end(); ++it )
+ {
+ WriteActiveXControl(it->object, *(it->frame), *(it->point));
+ }
+ m_aPostponedActiveXControls.clear();
+}
+
+
+void DocxAttributeOutput::WriteActiveXControl(const SdrObject* pObject, const SwFrameFormat& rFrameFormat,const Point& rNdTopLeft)
+{
+ SdrUnoObj *pFormObj = const_cast<SdrUnoObj*>(dynamic_cast< const SdrUnoObj*>(pObject));
+ if (!pFormObj)
+ return;
+
+ uno::Reference<awt::XControlModel> xControlModel = pFormObj->GetUnoControlModel();
+ if (!xControlModel.is())
+ return;
+
+ const bool bAnchoredInline = rFrameFormat.GetAnchor().GetAnchorId() == static_cast<RndStdIds>(css::text::TextContentAnchorType_AS_CHARACTER);
+
+ // w:pict for floating embedded control and w:object for inline embedded control
+ if(bAnchoredInline)
+ m_pSerializer->startElementNS(XML_w, XML_object, FSEND);
+ else
+ m_pSerializer->startElementNS(XML_w, XML_pict, FSEND);
+
+ // write ActiveX fragment and ActiveX binary
+ uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pObject)->getUnoShape(), uno::UNO_QUERY);
+ std::pair<OString,OString> sRelIdAndName = m_rExport.WriteActiveXObject(xShape, xControlModel);
+
+ // VML shape definition
+ m_rExport.VMLExporter().SetSkipwzName();
+ m_rExport.VMLExporter().SetHashMarkForType();
+ OString sShapeId;
+ if(bAnchoredInline)
+ {
+ sShapeId = m_rExport.VMLExporter().AddInlineSdrObject(*pObject, true);
+ }
+ else
+ {
+ const SwFormatHoriOrient& rHoriOri = rFrameFormat.GetHoriOrient();
+ const SwFormatVertOrient& rVertOri = rFrameFormat.GetVertOrient();
+ sShapeId = m_rExport.VMLExporter().AddSdrObject(*pObject,
+ rHoriOri.GetHoriOrient(), rVertOri.GetVertOrient(),
+ rHoriOri.GetRelationOrient(),
+ rVertOri.GetRelationOrient(), &rNdTopLeft, true);
+ }
+
+ // control
+ m_pSerializer->singleElementNS(XML_w, XML_control,
+ FSNS(XML_r, XML_id), sRelIdAndName.first.getStr(),
+ FSNS(XML_w, XML_name), sRelIdAndName.second.getStr(),
+ FSNS(XML_w, XML_shapeid), sShapeId.getStr(),
+ FSEND);
+
+ if(bAnchoredInline)
+ m_pSerializer->endElementNS(XML_w, XML_object);
+ else
+ m_pSerializer->endElementNS(XML_w, XML_pict);
+}
+
+bool DocxAttributeOutput::ExportAsActiveXControl(const SdrObject* pObject) const
+{
+ SdrUnoObj *pFormObj = const_cast<SdrUnoObj*>(dynamic_cast< const SdrUnoObj*>(pObject));
+ if (!pFormObj)
+ return false;
+
+ uno::Reference<awt::XControlModel> xControlModel = pFormObj->GetUnoControlModel();
+ if (!xControlModel.is())
+ return false;
+
+ uno::Reference< css::frame::XModel > xModel( m_rExport.m_pDoc->GetDocShell() ? m_rExport.m_pDoc->GetDocShell()->GetModel() : nullptr );
+ if (!xModel.is())
+ return false;
+
+ uno::Reference<lang::XServiceInfo> xInfo(xControlModel, uno::UNO_QUERY);
+ if (!xInfo.is())
+ return false;
+
+ // See WritePostponedFormControl
+ // By now date field and combobox is handled on a different way, so let's not interfere with the other method.
+ if(xInfo->supportsService("com.sun.star.form.component.DateField") ||
+ xInfo->supportsService("com.sun.star.form.component.ComboBox"))
+ return false;
+
+ oox::ole::OleFormCtrlExportHelper exportHelper(comphelper::getProcessComponentContext(), xModel, xControlModel);
+ if(!exportHelper.isValid())
+ return false;
+
+ return true;
+}
+
bool DocxAttributeOutput::PostponeOLE( SwOLENode& rNode, const Size& rSize, const SwFlyFrameFormat* pFlyFrameFormat )
{
if( !m_pPostponedOLEs )
@@ -5066,7 +5165,10 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const ww8::Frame &rFrame, const P
case ww8::Frame::eFormControl:
{
const SdrObject* pObject = rFrame.GetFrameFormat().FindRealSdrObject();
- m_aPostponedFormControls.push_back(pObject);
+ if(ExportAsActiveXControl(pObject))
+ m_aPostponedActiveXControls.push_back(PostponedDrawing(pObject, &(rFrame.GetFrameFormat()), &rNdTopLeft));
+ else
+ m_aPostponedFormControls.push_back(pObject);
m_bPostponedProcessingFly = true ;
}
break;
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 8daa50aea34a..54d67559b35e 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -417,6 +417,9 @@ private:
bool PostponeOLE( SwOLENode& rNode, const Size& rSize, const SwFlyFrameFormat* pFlyFrameFormat );
void WriteOLE( SwOLENode& rNode, const Size& rSize, const SwFlyFrameFormat* rFlyFrameFormat );
+ void WriteActiveXControl(const SdrObject* pObject, const SwFrameFormat& rFrameFormat, const Point& rNdTopLeft);
+ bool ExportAsActiveXControl(const SdrObject* pObject) const;
+
/// checks whether the current component is a diagram
static bool IsDiagram (const SdrObject* sdrObject);
@@ -697,6 +700,7 @@ private:
void WritePostponedGraphic();
void WritePostponedMath(const SwOLENode* pObject);
void WritePostponedFormControl(const SdrObject* pObject);
+ void WritePostponedActiveXControl();
void WritePostponedDiagram();
void WritePostponedChart();
void WritePostponedOLE();
@@ -873,6 +877,7 @@ private:
const SdrObject* m_postponedChart;
Size m_postponedChartSize;
std::vector<const SdrObject*> m_aPostponedFormControls;
+ std::vector<PostponedDrawing> m_aPostponedActiveXControls;
const SwField* pendingPlaceholder;
/// Maps postit fields to ID's, used in commentRangeStart/End, commentReference and comment.xml.
std::vector< std::pair<const SwPostItField*, sal_Int32> > m_postitFields;
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 87de4e11b242..c3df2b0cf18f 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -31,6 +31,7 @@
#include <com/sun/star/xml/dom/XDocument.hpp>
#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
#include <com/sun/star/xml/sax/Writer.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
@@ -40,6 +41,9 @@
#include <oox/export/shapes.hxx>
#include <oox/helper/propertyset.hxx>
#include <oox/token/relationship.hxx>
+#include <oox/helper/binaryoutputstream.hxx>
+#include <oox/ole/olestorage.hxx>
+#include <oox/ole/olehelper.hxx>
#include <map>
#include <algorithm>
@@ -419,6 +423,54 @@ OString DocxExport::WriteOLEObject(SwOLEObj& rObject, OUString & io_rProgID)
return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
}
+std::pair<OString, OString> DocxExport::WriteActiveXObject(const uno::Reference<drawing::XShape>& rxShape,
+ const uno::Reference<awt::XControlModel>& rxControlModel)
+{
+ ++m_nActiveXControls;
+
+ // Write out ActiveX binary
+ const OUString sBinaryFileName = "word/activeX/activeX" + OUString::number(m_nActiveXControls) + ".bin";
+
+ OString sGUID;
+ OString sName;
+ uno::Reference<io::XStream> xOutStorage(m_pFilter->openFragmentStream(sBinaryFileName, "application/vnd.ms-office.activeX"), uno::UNO_QUERY);
+ if(xOutStorage.is())
+ {
+ oox::ole::OleStorage aOleStorage(m_pFilter->getComponentContext(), xOutStorage, false);
+ uno::Reference<io::XOutputStream> xOutputStream(aOleStorage.openOutputStream("contents"), uno::UNO_SET_THROW);
+ uno::Reference< css::frame::XModel > xModel( m_pDoc->GetDocShell() ? m_pDoc->GetDocShell()->GetModel() : nullptr );
+ oox::ole::OleFormCtrlExportHelper exportHelper(comphelper::getProcessComponentContext(), xModel, rxControlModel);
+ if ( !exportHelper.isValid() )
+ return std::make_pair<OString, OString>(OString(), OString());
+ sGUID = OUStringToOString(exportHelper.getGUID(), RTL_TEXTENCODING_UTF8);
+ sName = OUStringToOString(exportHelper.getName(), RTL_TEXTENCODING_UTF8);
+ exportHelper.exportControl(xOutputStream, rxShape->getSize(), true);
+ aOleStorage.commit();
+ }
+
+ // Write out ActiveX fragment
+ const OUString sXMLFileName = "word/activeX/activeX" + OUString::number( m_nActiveXControls ) + ".xml";
+ ::sax_fastparser::FSHelperPtr pActiveXFS = m_pFilter->openFragmentStreamWithSerializer(sXMLFileName, "application/vnd.ms-office.activeX+xml" );
+
+ const OUString sBinaryId = m_pFilter->addRelation( pActiveXFS->getOutputStream(),
+ oox::getRelationship(Relationship::ACTIVEXCONTROLBINARY),
+ sBinaryFileName.copy(sBinaryFileName.lastIndexOf("/") + 1) );
+
+ pActiveXFS->singleElementNS(XML_ax, XML_ocx,
+ FSNS(XML_xmlns, XML_ax), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(ax)), RTL_TEXTENCODING_UTF8).getStr(),
+ FSNS(XML_xmlns, XML_r), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(officeRel)), RTL_TEXTENCODING_UTF8).getStr(),
+ FSNS(XML_ax, XML_classid), OString("{" + sGUID + "}").getStr(),
+ FSNS(XML_ax, XML_persistence), "persistStorage",
+ FSNS(XML_r, XML_id), OUStringToOString(sBinaryId, RTL_TEXTENCODING_UTF8).getStr(), FSEND);
+
+ OString sXMLId = OUStringToOString(m_pFilter->addRelation(m_pDocumentFS->getOutputStream(),
+ oox::getRelationship(Relationship::CONTROL),
+ sXMLFileName.copy(sBinaryFileName.indexOf("/") + 1)),
+ RTL_TEXTENCODING_UTF8);
+
+ return std::pair<OString, OString>(sXMLId, sName);
+}
+
void DocxExport::OutputDML(uno::Reference<drawing::XShape> const & xShape)
{
uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
@@ -462,8 +514,6 @@ void DocxExport::ExportDocument_Impl()
WriteCustomXml();
- WriteActiveX();
-
WriteEmbeddings();
WriteVBA();
@@ -1171,100 +1221,6 @@ void DocxExport::WriteCustomXml()
}
}
-void DocxExport::WriteActiveX()
-{
- uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
-
- uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
- OUString aName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
- if ( !xPropSetInfo->hasPropertyByName( aName ) )
- return;
-
- uno::Sequence<uno::Reference<xml::dom::XDocument> > activeXDomlist;
- uno::Sequence<uno::Reference<io::XInputStream> > activeXBinList;
- uno::Sequence< beans::PropertyValue > propList;
- xPropSet->getPropertyValue( aName ) >>= propList;
- for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
- {
- OUString propName = propList[nProp].Name;
- if ( propName == "OOXActiveX" )
- {
- propList[nProp].Value >>= activeXDomlist;
- break;
- }
- }
-
- for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp )
- {
- OUString propName = propList[nProp].Name;
- if ( propName == "OOXActiveXBin" )
- {
- propList[nProp].Value >>= activeXBinList;
- break;
- }
- }
-
- for (sal_Int32 j = 0; j < activeXDomlist.getLength(); j++)
- {
- uno::Reference<xml::dom::XDocument> activeXDom = activeXDomlist[j];
- uno::Reference<io::XInputStream> activeXBin = activeXBinList[j];
-
- if ( activeXDom.is() )
- {
- m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
- oox::getRelationship(Relationship::CONTROL),
- "activeX/activeX"+OUString::number((j+1))+".xml" );
-
- uno::Reference< xml::sax::XSAXSerializable > serializer( activeXDom, uno::UNO_QUERY );
- uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create( comphelper::getProcessComponentContext() );
- writer->setOutputStream( GetFilter().openFragmentStream( "word/activeX/activeX"+OUString::number((j+1))+".xml",
- "application/vnd.ms-office.activeX+xml" ) );
- serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ),
- uno::Sequence< beans::StringPair >() );
- }
-
- if ( activeXBin.is() )
- {
- uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream("word/activeX/activeX"+OUString::number((j+1))+".bin",
- "application/vnd.ms-office.activeX");
-
- try
- {
- sal_Int32 nBufferSize = 512;
- uno::Sequence< sal_Int8 > aDataBuffer(nBufferSize);
- sal_Int32 nRead;
- do
- {
- nRead = activeXBin->readBytes( aDataBuffer, nBufferSize );
- if( nRead )
- {
- if( nRead < nBufferSize )
- {
- nBufferSize = nRead;
- aDataBuffer.realloc(nRead);
- }
- xOutStream->writeBytes( aDataBuffer );
- }
- }
- while( nRead );
- xOutStream->flush();
- }
- catch(const uno::Exception&)
- {
- SAL_WARN("sw.ww8", "WriteActiveX() ::Failed to copy Inputstream to outputstream exception caught!");
- }
-
- xOutStream->closeOutput();
- // Adding itemprops's relationship entry to item.xml.rels file
- m_pFilter->addRelation( GetFilter().openFragmentStream( "/word/activeX/activeX"+OUString::number((j+1))+".xml",
- "application/vnd.ms-office.activeX+xml" ) ,
- oox::getRelationship(Relationship::ACTIVEXCONTROLBINARY),
- "activeX"+OUString::number((j+1))+".bin" );
-
- }
- }
-}
-
void DocxExport::WriteVBA()
{
uno::Reference<document::XStorageBasedDocument> xStorageBasedDocument(m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
@@ -1528,6 +1484,7 @@ DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCur
m_nHeaders( 0 ),
m_nFooters( 0 ),
m_nOLEObjects( 0 ),
+ m_nActiveXControls( 0 ),
m_nHeadersFootersInSection(0),
m_pVMLExport( nullptr ),
m_pSdrExport( nullptr ),
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index 915f50122bfc..73f690a66198 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -49,6 +49,7 @@ namespace oox {
namespace com { namespace sun { namespace star {
namespace frame { class XModel; }
namespace drawing { class XShape; }
+ namespace awt { class XControlModel; }
} } }
/// Data to be written in the document settings part of the document
@@ -91,6 +92,9 @@ class DocxExport : public MSWordExportBase
/// OLE objects counter.
sal_Int32 m_nOLEObjects;
+ /// ActiveX controls counter
+ sal_Int32 m_nActiveXControls;
+
///Footer and Header counter in Section properties
sal_Int32 m_nHeadersFootersInSection;
@@ -174,6 +178,8 @@ public:
/// Returns the relationd id
OString OutputChart( css::uno::Reference< css::frame::XModel > const & xModel, sal_Int32 nCount, ::sax_fastparser::FSHelperPtr const & m_pSerializer );
OString WriteOLEObject(SwOLEObj& rObject, OUString & io_rProgID);
+ std::pair<OString,OString> WriteActiveXObject(const uno::Reference<css::drawing::XShape>& rxShape,
+ const uno::Reference<awt::XControlModel>& rxControlModel);
/// Writes the shape using drawingML syntax.
void OutputDML( css::uno::Reference< css::drawing::XShape > const & xShape );