Kaydet (Commit) c0cc02e2 authored tarafından Tamás Zolnai's avatar Tamás Zolnai

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: 's avatarTamás Zolnai <tamas.zolnai@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/41256Tested-by: 's avatarJenkins <ci@libreoffice.org>
üst 8c0cc5cd
......@@ -40,6 +40,7 @@
#include <com/sun/star/drawing/TextAdjust.hpp>
#include <com/sun/star/drawing/LineDash.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/drawing/CircleKind.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
......@@ -419,7 +420,24 @@ sal_uInt32 ImplEESdrWriter::ImplWriteShape( ImplEESdrObject& rObj,
}
else if ( rObj.GetType() == "drawing.Control" )
{
break;
mpEscherEx->OpenContainer( ESCHER_SpContainer );
bool bInline = false;
const Reference< XPropertySet > xPropSet(rObj.mXPropSet, UNO_QUERY);
if(xPropSet.is())
{
text::TextContentAnchorType eAnchorType;
xPropSet->getPropertyValue("AnchorType") >>= eAnchorType;
bInline = eAnchorType == text::TextContentAnchorType_AS_CHARACTER;
}
if(bInline)
{
ADD_SHAPE( ESCHER_ShpInst_PictureFrame, SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR );
}
else
{
ADD_SHAPE( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR );
}
}
else if ( rObj.GetType() == "drawing.Connector" )
{
......
......@@ -82,6 +82,7 @@ class OOX_DLLPUBLIC VMLExport : public EscherEx
/// Anchoring.
sal_Int16 m_eHOri, m_eVOri, m_eHRel, m_eVRel;
bool m_bInline; // css::text::TextContentAnchorType_AS_CHARACTER
/// Parent position.
const Point* m_pNdTopLeft;
......@@ -101,11 +102,20 @@ class OOX_DLLPUBLIC VMLExport : public EscherEx
/// Remember style, the most important shape attribute ;-)
OStringBuffer m_ShapeStyle;
/// Remember the generated shape id.
OString m_sShapeId;
/// Remember which shape types we had already written.
std::vector<bool> m_aShapeTypeWritten;
/// It seems useless to write out an XML_ID attribute next to XML_id which defines the actual shape id
bool m_bSkipwzName;
/// Use '#' mark for type attribute (check Type Attribute of VML shape in OOXML documentation)
bool m_bUseHashMarkForType;
public:
VMLExport( ::sax_fastparser::FSHelperPtr const & pSerializer, VMLTextExport* pTextExport = nullptr );
VMLExport( ::sax_fastparser::FSHelperPtr const & pSerializer, VMLTextExport* pTextExport = nullptr);
virtual ~VMLExport() override;
const ::sax_fastparser::FSHelperPtr&
......@@ -116,11 +126,15 @@ public:
/// Export the sdr object as VML.
///
/// Call this when you need to export the object as VML.
void AddSdrObject( const SdrObject& rObj, sal_Int16 eHOri = -1,
OString AddSdrObject( const SdrObject& rObj, sal_Int16 eHOri = -1,
sal_Int16 eVOri = -1, sal_Int16 eHRel = -1,
sal_Int16 eVRel = -1, const Point* pNdTopLeft = nullptr, const bool bOOxmlExport = false );
OString AddInlineSdrObject( const SdrObject& rObj, const bool bOOxmlExport = false );
virtual void AddSdrObjectVMLObject( const SdrObject& rObj) override;
static bool IsWaterMarkShape(const OUString& rStr);
void SetSkipwzName() { m_bSkipwzName = true; }
void SetHashMarkForType() { m_bUseHashMarkForType = true; }
protected:
/// Add an attribute to the generated <v:shape/> element.
///
......
......@@ -29,6 +29,7 @@
#include <rtl/ustring.hxx>
#include <sal/types.h>
#include <tools/ref.hxx>
#include <memory>
namespace com { namespace sun { namespace star {
namespace awt { class XControlModel; }
......@@ -52,6 +53,8 @@ namespace oox {
namespace ole {
class ControlModelBase;
class EmbeddedControl;
#define OLE_GUID_STDFONT "{0BE35203-8F91-11CE-9DE3-00AA004BB851}"
......@@ -131,6 +134,38 @@ namespace OleHelper
bool bWithGuid );
}
class OOX_DLLPUBLIC OleFormCtrlExportHelper final
{
std::unique_ptr<::oox::ole::EmbeddedControl> mpControl;
::oox::ole::ControlModelBase* mpModel;
::oox::GraphicHelper maGrfHelper;
css::uno::Reference< css::frame::XModel > mxDocModel;
css::uno::Reference< css::awt::XControlModel > mxControlModel;
OUString maName;
OUString maTypeName;
OUString maFullName;
OUString maGUID;
public:
OleFormCtrlExportHelper( const css::uno::Reference< css::uno::XComponentContext >& rxCtx, const css::uno::Reference< css::frame::XModel >& xDocModel, const css::uno::Reference< css::awt::XControlModel >& xModel );
~OleFormCtrlExportHelper();
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; }
const OUString& getName() { return maName; }
bool isValid() { return mpModel != nullptr; }
void exportName( const css::uno::Reference< css::io::XOutputStream >& rxOut );
void exportCompObj( const css::uno::Reference< css::io::XOutputStream >& rxOut );
void exportControl( const css::uno::Reference< css::io::XOutputStream >& rxOut, const css::awt::Size& rSize, bool bAutoClose = false );
};
// ideally it would be great to get rid of SvxMSConvertOCXControls
// however msfilter/source/msfilter/svdfppt.cxx still uses
// SvxMSConvertOCXControls as a base class, unfortunately oox depends on
......
......@@ -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
......
......@@ -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: */
......@@ -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 );
......
......@@ -740,6 +740,7 @@ avLst
average
avg
avgSubtotal
ax
axId
axPos
axis
......@@ -5808,6 +5809,7 @@ xmlPr
xmlns
xpath
xrange
xsc
xscale
xsi
xy
......
......@@ -36,7 +36,6 @@ $(eval $(call gb_Module_add_check_targets,sd,\
CppunitTest_sd_filters_test \
CppunitTest_sd_misc_tests \
CppunitTest_sd_html_export_tests \
CppunitTest_sd_activex_controls_tests \
))
endif
......@@ -56,6 +55,7 @@ $(eval $(call gb_Module_add_screenshot_targets,sd, \
$(eval $(call gb_Module_add_subsequentcheck_targets,sd,\
JunitTest_sd_unoapi \
CppunitTest_sd_activex_controls_tests \
))
# vim: set noet sw=4 ts=4:
......@@ -70,7 +70,6 @@
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/table/XTableRows.hpp>
#include <com/sun/star/style/NumberingType.hpp>
#include <com/sun/star/drawing/XControlShape.hpp>
#include <stlpool.hxx>
#include <comphelper/processfactory.hxx>
......
......@@ -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>
......
......@@ -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
......
......@@ -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>
......
......@@ -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: */
......@@ -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();
......
......@@ -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: */
......@@ -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>
......
......@@ -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);