[Libreoffice-commits] .: filter/inc filter/source oox/inc oox/Package_inc.mk oox/source

Noel Power noelp at kemper.freedesktop.org
Tue Jul 12 02:46:27 PDT 2011


 filter/inc/filter/msfilter/msocximex.hxx |   10 --
 filter/inc/filter/msfilter/svdfppt.hxx   |   14 ++-
 filter/source/msfilter/msocximex.cxx     |   89 --------------------
 filter/source/msfilter/svdfppt.cxx       |   24 ++++-
 oox/Package_inc.mk                       |    1 
 oox/inc/oox/ole/axcontrol.hxx            |   21 ++++
 oox/inc/oox/ole/olehelper.hxx            |   40 ++++++++-
 oox/source/ole/axcontrol.cxx             |  100 ++++++++++++++++++++++
 oox/source/ole/olehelper.cxx             |  137 +++++++++++++++++++++++++++++++
 oox/source/token/properties.txt          |    2 
 10 files changed, 335 insertions(+), 103 deletions(-)

New commits:
commit c8191e866b100d06ae7d0316fb15ba97cf00b234
Author: Noel Power <noel.power at novell.com>
Date:   Tue Jul 12 10:07:52 2011 +0100

    use oox filter for *all* control import

diff --git a/filter/inc/filter/msfilter/msocximex.hxx b/filter/inc/filter/msfilter/msocximex.hxx
index 5e1915d..31b3732 100644
--- a/filter/inc/filter/msfilter/msocximex.hxx
+++ b/filter/inc/filter/msfilter/msocximex.hxx
@@ -96,18 +96,12 @@ public:
     virtual ~SvxMSConvertOCXControls();
 
     //Reads a control from the given storage, constructed shape in pShapeRef
-    sal_Bool ReadOCXStream( SotStorageRef& rSrc1,
+    virtual sal_Bool ReadOCXStream( SotStorageRef& rSrc1,
         com::sun::star::uno::Reference<
         com::sun::star::drawing::XShape > *pShapeRef=0,
-        sal_Bool bFloatingCtrl=sal_False );
+        sal_Bool bFloatingCtrl=sal_False ) = 0;
 
 
-    //Excel has a nasty kludged mechanism for this, read
-    //the comments in the source to follow it
-    sal_Bool ReadOCXExcelKludgeStream(SotStorageStreamRef& rSrc1,
-        com::sun::star::uno::Reference <
-        com::sun::star::drawing::XShape > *pShapeRef,sal_Bool bFloatingCtrl);
-
 
     //Writes the given Uno Control into the given storage
 
diff --git a/filter/inc/filter/msfilter/svdfppt.hxx b/filter/inc/filter/msfilter/svdfppt.hxx
index d9f5243..57ab915 100644
--- a/filter/inc/filter/msfilter/svdfppt.hxx
+++ b/filter/inc/filter/msfilter/svdfppt.hxx
@@ -633,6 +633,7 @@ public:
                                 sal_uInt32* pTableArry,
                                 SvxMSDffSolverContainer*
                             );
+    virtual bool ReadFormControl( com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& rxInStrm, com::sun::star::uno::Reference< com::sun::star::form::XFormComponent > & rFormComp ) const = 0;
 };
 
 struct PPTTextCharacterStyleAtomInterpreter
@@ -1258,13 +1259,20 @@ class PPTConvertOCXControls : public SvxMSConvertOCXControls
 {
     virtual const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > & GetDrawPage();
     PptPageKind     ePageKind;
+    const SdrPowerPointImport* mpPPTImporter;
+    com::sun::star::uno::Reference< com::sun::star::io::XInputStream > mxInStrm;
 public :
 
-    PPTConvertOCXControls( SfxObjectShell* pDSh, PptPageKind ePKind ) :
+    PPTConvertOCXControls( const SdrPowerPointImport* pPPTImporter, com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& rxInStrm, SfxObjectShell* pDSh, PptPageKind ePKind ) :
         SvxMSConvertOCXControls ( pDSh, NULL ),
-        ePageKind               ( ePKind )
+        ePageKind               ( ePKind ),
+        mpPPTImporter           ( pPPTImporter ),
+        mxInStrm                ( rxInStrm )
     {};
-
+    virtual sal_Bool ReadOCXStream( SotStorageRef& rSrc1,
+        com::sun::star::uno::Reference<
+        com::sun::star::drawing::XShape > *pShapeRef=0,
+        sal_Bool bFloatingCtrl=sal_False );
     virtual sal_Bool InsertControl(
         const com::sun::star::uno::Reference< com::sun::star::form::XFormComponent > &rFComp,
         const com::sun::star::awt::Size& rSize,
diff --git a/filter/source/msfilter/msocximex.cxx b/filter/source/msfilter/msocximex.cxx
index 9d18728..d646b86 100644
--- a/filter/source/msfilter/msocximex.cxx
+++ b/filter/source/msfilter/msocximex.cxx
@@ -4371,95 +4371,6 @@ OCX_Control * SvxMSConvertOCXControls::OCX_Factory(
 }
 
 
-sal_Bool SvxMSConvertOCXControls::ReadOCXStream( SvStorageRef& rSrc1,
-        uno::Reference < drawing::XShape > *pShapeRef,sal_Bool bFloatingCtrl)
-{
-
-    SvStorageStreamRef xCrash = rSrc1->OpenSotStream( WW8_ASCII2STR("contents") );
-    sal_Bool bRet=sal_False;
-
-    SvStorageStreamRef xSrc2 = rSrc1->OpenSotStream( WW8_ASCII2STR("\3OCXNAME") );
-    SvStorageStream* pSt = xSrc2;
-    pSt->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
-
-    /* #117832# import control name */
-    OUString controlName;
-    bool hasCName = readOCXNAME( controlName, pSt );
-
-    xSrc2 = rSrc1->OpenSotStream( WW8_ASCII2STR("contents") );
-    pSt = xSrc2;
-    pSt->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
-
-    /*Get Class Id of this object, see if it is one of the types
-     *that this importer can handle, call the appropiate handler
-     to read that control, and call the appropiate handler to
-     insert that control
-     */
-
-    SvGlobalName aTest = rSrc1->GetClassName();
-    OCX_Control *pObj = OCX_Factory(aTest.GetHexName());
-    if (pObj)
-    {
-        pObj->pDocSh = pDocSh;
-        /* #117832# set imported control name */
-        if ( hasCName )
-        {
-            pObj->sName = controlName;
-        }
-        com::sun::star::awt::Size aSz;
-        uno::Reference< form::XFormComponent >  xFComp;
-        const uno::Reference< lang::XMultiServiceFactory > & rServiceFactory =
-            GetServiceFactory();
-        if(!rServiceFactory.is())
-            return(sal_False);
-        bRet = pObj->FullRead(pSt);
-        if(bRet)
-            if (pObj->Import(rServiceFactory,xFComp,aSz))
-                bRet = InsertControl( xFComp, aSz,pShapeRef,bFloatingCtrl);
-        delete pObj;
-    }
-    return bRet;
-}
-
-
-sal_Bool SvxMSConvertOCXControls::ReadOCXExcelKludgeStream(
-    SvStorageStreamRef& rSrc1, uno::Reference < drawing::XShape > *
-    pShapeRef,sal_Bool bFloatingCtrl)
-{
-    sal_Bool bRet=sal_False;
-    /*Get Class Id of this object, see if it is one of the types
-     *that this importer can handle, call the appropiate handler
-     to read that control, and call the appropiate handler to
-     insert that control
-     */
-    /*The Excel Kludge is to concatenate a class id with a contents
-     * stream, and then concatenate all the controls together,
-     * This means that you should have the cnts stream wound to the
-     * correct location before passing the control stream in here*/
-    SvStream *pSt = rSrc1;
-    pSt->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
-    SvGlobalName aTest;
-    *pSt >> aTest;
-    OCX_Control *pObj = OCX_Factory(aTest.GetHexName());
-    if (pObj)
-    {
-
-        com::sun::star::awt::Size aSz;
-        uno::Reference< form::XFormComponent >  xFComp;
-        const uno::Reference< lang::XMultiServiceFactory > & rServiceFactory =
-            GetServiceFactory();
-        if(!rServiceFactory.is())
-            return(sal_False);
-        bRet = pObj->FullRead(rSrc1);
-        if(bRet)
-            if (pObj->Import(rServiceFactory,xFComp,aSz))
-                bRet = InsertControl( xFComp, aSz,pShapeRef,bFloatingCtrl);
-        delete pObj;
-    }
-    return bRet;
-}
-
-
 sal_Bool SvxMSConvertOCXControls::WriteOCXStream( SvStorageRef& rSrc1,
     const uno::Reference< awt::XControlModel > &rControlModel,
     const awt::Size &rSize, String &rName)
diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx
index 9b63539..2d812f1 100644
--- a/filter/source/msfilter/svdfppt.cxx
+++ b/filter/source/msfilter/svdfppt.cxx
@@ -127,6 +127,7 @@
 #include <vcl/virdev.hxx>
 #include <algorithm>
 #include <set>
+#include <unotools/streamwrap.hxx>
 
 // PPT ColorScheme Slots
 #define PPT_COLSCHEME                       (0x08000000)
@@ -1676,6 +1677,24 @@ SdrPowerPointImport::~SdrPowerPointImport()
     delete[] pPersistPtr;
 }
 
+sal_Bool PPTConvertOCXControls::ReadOCXStream( SotStorageRef& /*rSrc1*/,
+        com::sun::star::uno::Reference<
+        com::sun::star::drawing::XShape > *pShapeRef,
+        sal_Bool bFloatingCtrl )
+{
+    bool bRes = false;
+    uno::Reference< form::XFormComponent > xFComp;
+    if ( mpPPTImporter && mpPPTImporter->ReadFormControl( mxInStrm, xFComp ) )
+    {
+        if ( xFComp.is() )
+        {
+            com::sun::star::awt::Size aSz;  // not used in import
+            bRes = InsertControl( xFComp, aSz,pShapeRef,bFloatingCtrl);
+        }
+    }
+    return bRes;
+}
+
 sal_Bool PPTConvertOCXControls::InsertControl(
         const com::sun::star::uno::Reference<
         com::sun::star::form::XFormComponent > &rFComp,
@@ -1731,7 +1750,6 @@ sal_Bool PPTConvertOCXControls::InsertControl(
     }
     return bRetValue;
 };
-
 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& PPTConvertOCXControls::GetDrawPage()
 {
     if( !xDrawPage.is() && pDocSh )
@@ -1890,10 +1908,12 @@ SdrObject* SdrPowerPointImport::ImportOLE( long nOLEId,
                                 }
                                 if ( !pRet && ( pOe->nType == PPT_PST_ExControl ) )
                                 {
-                                    PPTConvertOCXControls aPPTConvertOCXControls( pOe->pShell, eAktPageKind );
+                                    uno::Reference< io::XInputStream > xIStrm = new utl::OSeekableInputStreamWrapper(*pDest );
+                                    PPTConvertOCXControls aPPTConvertOCXControls( this, xIStrm, pOe->pShell, eAktPageKind );
                                     ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape;
                                     if ( aPPTConvertOCXControls.ReadOCXStream( xObjStor, &xShape, sal_False ) )
                                         pRet = GetSdrObjectFromXShape( xShape );
+
                                 }
                                 if ( !pRet )
                                 {
diff --git a/oox/Package_inc.mk b/oox/Package_inc.mk
index d9b23db..b51b51b 100644
--- a/oox/Package_inc.mk
+++ b/oox/Package_inc.mk
@@ -48,6 +48,7 @@ $(eval $(call gb_Package_add_file,oox_inc,inc/oox/helper/refmap.hxx,oox/helper/r
 $(eval $(call gb_Package_add_file,oox_inc,inc/oox/helper/refvector.hxx,oox/helper/refvector.hxx))
 $(eval $(call gb_Package_add_file,oox_inc,inc/oox/helper/storagebase.hxx,oox/helper/storagebase.hxx))
 $(eval $(call gb_Package_add_file,oox_inc,inc/oox/helper/zipstorage.hxx,oox/helper/zipstorage.hxx))
+$(eval $(call gb_Package_add_file,oox_inc,inc/oox/ole/olehelper.hxx,oox/ole/olehelper.hxx))
 $(eval $(call gb_Package_add_file,oox_inc,inc/oox/ole/oleobjecthelper.hxx,oox/ole/oleobjecthelper.hxx))
 $(eval $(call gb_Package_add_file,oox_inc,inc/oox/ole/olestorage.hxx,oox/ole/olestorage.hxx))
 $(eval $(call gb_Package_add_file,oox_inc,inc/oox/ole/vbaproject.hxx,oox/ole/vbaproject.hxx))
diff --git a/oox/inc/oox/ole/axcontrol.hxx b/oox/inc/oox/ole/axcontrol.hxx
index 22300cb..21e8e72 100644
--- a/oox/inc/oox/ole/axcontrol.hxx
+++ b/oox/inc/oox/ole/axcontrol.hxx
@@ -77,6 +77,11 @@ const sal_uInt16 COMCTL_VERSION_60          = 6;
 #define AX_GUID_SCROLLBAR     "{DFD181E0-5E2F-11CE-A449-00AA004A803D}"
 #define AX_GUID_FRAME         "{6E182020-F460-11CE-9BCD-00AA00608E01}"
 
+// Html control GUID(s)
+
+#define HTML_GUID_SELECT      "{5512D122-5CC6-11CF-8D67-00AA00BDCE1D}"
+#define HTML_GUID_TEXTBOX     "{5512D124-5CC6-11CF-8D67-00AA00BDCE1D}"
+
 const sal_uInt32 AX_SYSCOLOR_WINDOWBACK     = 0x80000005;
 const sal_uInt32 AX_SYSCOLOR_WINDOWFRAME    = 0x80000006;
 const sal_uInt32 AX_SYSCOLOR_WINDOWTEXT     = 0x80000008;
@@ -853,6 +858,22 @@ public:
     virtual void        convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
 };
 
+class HtmlSelectModel : public AxListBoxModel
+{
+    com::sun::star::uno::Sequence< rtl::OUString > msListData;
+    com::sun::star::uno::Sequence< sal_Int16 > msIndices;
+public:
+    HtmlSelectModel();
+    virtual bool        importBinaryModel( BinaryInputStream& rInStrm );
+    virtual void        convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+class HtmlTextBoxModel : public AxTextBoxModel
+{
+public:
+    explicit            HtmlTextBoxModel();
+    virtual bool        importBinaryModel( BinaryInputStream& rInStrm );
+};
 // ============================================================================
 
 /** A form control embedded in a document draw page. Contains a specific model
diff --git a/oox/inc/oox/ole/olehelper.hxx b/oox/inc/oox/ole/olehelper.hxx
index a7e3318..8c0d28f 100644
--- a/oox/inc/oox/ole/olehelper.hxx
+++ b/oox/inc/oox/ole/olehelper.hxx
@@ -31,15 +31,29 @@
 
 #include <rtl/ustring.hxx>
 #include "oox/helper/binarystreambase.hxx"
+#include "oox/helper/storagebase.hxx"
+#include "oox/helper/graphichelper.hxx"
+#include "com/sun/star/form/XFormComponent.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/frame/XModel.hpp"
+#include "com/sun/star/frame/XFrame.hpp"
+#include "com/sun/star/awt/XControl.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "oox/dllapi.h"
 
 namespace oox {
     class BinaryInputStream;
+    class BinaryXInputStream;
     class GraphicHelper;
 }
 
 namespace oox {
+
+typedef ::boost::shared_ptr< oox::BinaryXInputStream > BinaryXInputStreamRef;
+
 namespace ole {
 
+
 // ============================================================================
 
 #define OLE_GUID_STDFONT "{0BE35203-8F91-11CE-9DE3-00AA004BB851}"
@@ -87,7 +101,7 @@ struct StdHlinkInfo
 // ============================================================================
 
 /** Static helper functions for OLE import/export. */
-class OleHelper
+class OOX_DLLPUBLIC OleHelper
 {
 public:
     /** Returns the UNO RGB color from the passed encoded OLE color.
@@ -139,6 +153,30 @@ private:
                         ~OleHelper();       // not implemented
 };
 
+class OOX_DLLPUBLIC OleFormCtrlImportHelper
+{
+    ::oox::StorageRef mpRoot;
+    ::oox::StorageRef mpPoolStrg;
+    ::oox::BinaryXInputStreamRef mpCtlsStrm;
+    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxCtx;
+    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxModel;
+    ::oox::GraphicHelper maGrfHelper;
+    bool importControlFromStream( ::oox::BinaryInputStream& rInStrm,
+                                  ::com::sun::star::uno::Reference< com::sun::star::form::XFormComponent > & rxFormComp,
+                                  const ::rtl::OUString& rGuidString );
+    bool importControlFromStorage( ::oox::StorageRef rxObjStrg,
+                                  ::com::sun::star::uno::Reference< com::sun::star::form::XFormComponent > & rxFormComp );
+public:
+    OleFormCtrlImportHelper( const ::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > & xInStrm,
+                             const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxCtx,
+                             const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel );
+    ~OleFormCtrlImportHelper();
+    bool importFormControlFromObjStorage( ::com::sun::star::uno::Reference< com::sun::star::form::XFormComponent > & rxFormComp);
+    bool importFormControlFromCtls( ::com::sun::star::uno::Reference< com::sun::star::form::XFormComponent > & rxFormComp,
+                                   sal_Int32 nPos, sal_Int32 nSize );
+    bool importFormControlFromObjPool( ::com::sun::star::uno::Reference< com::sun::star::form::XFormComponent > & rxFormComp,
+                                   const ::rtl::OUString& rPoolName );
+};
 // ============================================================================
 
 } // namespace ole
diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx
index 4381fa2..4dd3554 100644
--- a/oox/source/ole/axcontrol.cxx
+++ b/oox/source/ole/axcontrol.cxx
@@ -61,6 +61,7 @@
 #include "oox/helper/containerhelper.hxx"
 #include "oox/helper/graphichelper.hxx"
 #include "oox/helper/propertymap.hxx"
+#include "tools/string.hxx"
 
 namespace oox {
 namespace ole {
@@ -1748,6 +1749,103 @@ void AxUserFormModel::convertProperties( PropertyMap& rPropMap, const ControlCon
     AxContainerModelBase::convertProperties( rPropMap, rConv );
 }
 
+HtmlSelectModel::HtmlSelectModel()
+{
+}
+
+bool
+HtmlSelectModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+    static OUString sTerm( RTL_CONSTASCII_USTRINGPARAM("</SELECT") );
+    static String sMultiple( RTL_CONSTASCII_USTRINGPARAM("<SELECT MULTIPLE") );
+    static String sSelected( RTL_CONSTASCII_USTRINGPARAM("OPTION SELECTED") );
+
+    OUString sStringContents = rInStrm.readUnicodeArray( rInStrm.size() );
+
+    String data = sStringContents;
+
+    // replace crlf with lf
+    data.SearchAndReplaceAll( String( RTL_CONSTASCII_USTRINGPARAM( "\x0D\x0A" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "\x0A" ) ) );
+    std::vector< rtl::OUString > listValues;
+    std::vector< sal_Int16 > selectedIndices;
+
+    // Ultra hacky parser for the info
+    sal_Int32 nTokenCount = data.GetTokenCount( '\n' );
+
+    for ( sal_Int32 nToken = 0; nToken < nTokenCount; ++nToken )
+    {
+        String sLine( data.GetToken( nToken, '\n' ) );
+        if ( !nToken ) // first line will tell us if multiselect is enabled
+        {
+            if ( sLine.CompareTo( sMultiple, sMultiple.Len() ) == COMPARE_EQUAL )
+                mnMultiSelect = true;
+        }
+        // skip first and last lines, no data there
+        else if ( nToken < nTokenCount - 1)
+        {
+            if ( sLine.GetTokenCount( '>' ) )
+            {
+                String displayValue  = sLine.GetToken( 1, '>' );
+                if ( displayValue.Len() )
+                {
+                    // Really we should be using a proper html parser
+                    // escaping some common bits to be escaped
+                    displayValue.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "&lt;" ) ), String( RTL_CONSTASCII_USTRINGPARAM("<") ) );
+                    displayValue.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "&gt;" ) ), String( RTL_CONSTASCII_USTRINGPARAM(">") ) );
+                    displayValue.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "&quot;" ) ), String( RTL_CONSTASCII_USTRINGPARAM("\"") ) );
+                    displayValue.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "&amp;" ) ), String( RTL_CONSTASCII_USTRINGPARAM("&") ) );
+                    listValues.push_back( displayValue );
+                    if( sLine.Search( sSelected ) != STRING_NOTFOUND )
+                        selectedIndices.push_back( static_cast< sal_Int16 >( listValues.size() ) - 1 );
+                }
+            }
+        }
+    }
+    if ( listValues.size() )
+    {
+        msListData.realloc( listValues.size() );
+        sal_Int32 index = 0;
+        for( std::vector< rtl::OUString >::iterator it = listValues.begin(); it != listValues.end(); ++it, ++index )
+             msListData[ index ] = *it;
+    }
+    if ( selectedIndices.size() )
+    {
+        msIndices.realloc( selectedIndices.size() );
+        sal_Int32 index = 0;
+        for( std::vector< sal_Int16 >::iterator it = selectedIndices.begin(); it != selectedIndices.end(); ++it, ++index )
+             msIndices[ index ] = *it;
+    }
+    return sal_True;
+}
+
+
+void
+HtmlSelectModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+   rPropMap.setProperty( PROP_StringItemList, msListData );
+   rPropMap.setProperty( PROP_SelectedItems, msIndices );
+   rPropMap.setProperty( PROP_Dropdown, true );
+   AxListBoxModel::convertProperties( rPropMap, rConv );
+}
+
+HtmlTextBoxModel::HtmlTextBoxModel()
+{
+}
+
+bool
+HtmlTextBoxModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+    OUString sStringContents = rInStrm.readUnicodeArray( rInStrm.size() );
+#ifdef DEBUG
+    // in msocximex ( where this is ported from, it appears *nothing* is read
+    // from the control stream ), surely there is some useful info there ?
+    OSL_TRACE("HtmlTextBoxModel::importBinaryModel - string contents of stream :");
+    OSL_TRACE("%s", rtl::OUStringToOString( sStringContents, RTL_TEXTENCODING_UTF8 ).getStr() );
+#else
+    (void) rInStrm;
+#endif
+    return true;
+}
 // ============================================================================
 
 EmbeddedControl::EmbeddedControl( const OUString& rName ) :
@@ -1776,6 +1874,8 @@ ControlModelBase* EmbeddedControl::createModelFromGuid( const OUString& rClassId
     if( aClassId.equalsAscii( AX_GUID_SCROLLBAR ) )         return &createModel< AxScrollBarModel >();
     if( aClassId.equalsAscii( AX_GUID_FRAME ) )             return &createModel< AxFrameModel >();
     if( aClassId.equalsAscii( COMCTL_GUID_SCROLLBAR_60 ) )  return &createModel< ComCtlScrollBarModel >( COMCTL_VERSION_60 );
+    if( aClassId.equalsAscii( HTML_GUID_SELECT ) )  return &createModel< HtmlSelectModel >();
+    if( aClassId.equalsAscii( HTML_GUID_TEXTBOX ) ) return &createModel< HtmlTextBoxModel >();
 
     mxModel.reset();
     return 0;
diff --git a/oox/source/ole/olehelper.cxx b/oox/source/ole/olehelper.cxx
index 08af544..72ae55d 100644
--- a/oox/source/ole/olehelper.cxx
+++ b/oox/source/ole/olehelper.cxx
@@ -32,6 +32,11 @@
 #include "oox/helper/binaryinputstream.hxx"
 #include "oox/helper/graphichelper.hxx"
 #include "oox/token/tokens.hxx"
+#include "oox/ole/axcontrol.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "oox/helper/propertymap.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/ole/olestorage.hxx"
 
 namespace oox {
 namespace ole {
@@ -41,6 +46,12 @@ namespace ole {
 using ::rtl::OUString;
 using ::rtl::OUStringBuffer;
 
+using ::com::sun::star::form::XFormComponent;
+using ::com::sun::star::awt::XControlModel;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+
 // ============================================================================
 
 namespace {
@@ -308,6 +319,132 @@ StdFontInfo::StdFontInfo( const ::rtl::OUString& rName, sal_uInt32 nHeight,
     return !rInStrm.isEof();
 }
 
+Reference< ::com::sun::star::frame::XFrame >
+lcl_getFrame( const  Reference< ::com::sun::star::frame::XModel >& rxModel )
+{
+    Reference< ::com::sun::star::frame::XFrame > xFrame;
+    if ( rxModel.is() )
+    {
+        Reference< ::com::sun::star::frame::XController > xController =  rxModel->getCurrentController();
+        xFrame =  xController.is() ? xController->getFrame() : NULL;
+    }
+    return xFrame;
+}
+
+OleFormCtrlImportHelper::OleFormCtrlImportHelper( const Reference< com::sun::star::io::XInputStream > & rxInStrm, const Reference< ::com::sun::star::uno::XComponentContext >& rxCtx, const Reference< ::com::sun::star::frame::XModel >& rxModel ) : mpRoot(  new ::oox::ole::OleStorage( rxCtx, rxInStrm, true ) ), mxCtx( rxCtx ), mxModel( rxModel ), maGrfHelper( rxCtx, lcl_getFrame( rxModel ), mpRoot )
+{
+}
+
+OleFormCtrlImportHelper::~OleFormCtrlImportHelper()
+{
+}
+
+bool
+OleFormCtrlImportHelper::importControlFromStream( ::oox::BinaryInputStream& rInStrm, Reference< XFormComponent >& rxFormComp, const ::rtl::OUString& rGuidString )
+{
+    ::oox::ole::EmbeddedControl aControl( CREATE_OUSTRING( "Unknown" ) );
+    if( ::oox::ole::ControlModelBase* pModel = aControl.createModelFromGuid( rGuidString  ) )
+    {
+        pModel->importBinaryModel( rInStrm );
+        rxFormComp.set( mxCtx->getServiceManager()->createInstanceWithContext( pModel->getServiceName(), mxCtx ), UNO_QUERY );
+        Reference< XControlModel > xCtlModel( rxFormComp, UNO_QUERY );
+        ::oox::ole::ControlConverter aConv(  mxModel, maGrfHelper );
+        aControl.convertProperties( xCtlModel, aConv );
+    }
+    return rxFormComp.is();
+}
+
+bool
+OleFormCtrlImportHelper::importFormControlFromCtls( Reference< XFormComponent > & rxFormComp,
+                                   sal_Int32 nPos,
+                                   sal_Int32 nStreamSize)
+{
+    if ( mpRoot.get() && mpRoot->isStorage() )
+    {
+        if ( !mpCtlsStrm.get() )
+            mpCtlsStrm.reset( new BinaryXInputStream( mpRoot->openInputStream( CREATE_OUSTRING( "Ctls" ) ), true ) );
+        mpCtlsStrm->seek( nPos );
+        OUString aStrmClassId = ::oox::ole::OleHelper::importGuid( *mpCtlsStrm );
+
+        bool bOneOfHtmlControls = false;
+        if ( aStrmClassId.toAsciiUpperCase().equalsAscii( HTML_GUID_SELECT )
+          || aStrmClassId.toAsciiUpperCase().equalsAscii( HTML_GUID_TEXTBOX ) )
+            bOneOfHtmlControls = false;
+
+        if ( bOneOfHtmlControls )
+        {
+            // html controls don't seem have a handy record length following the GUID
+            // in the binary stream.
+            // Given the control stream length create a stream of nStreamSize bytes starting from
+            // nPos ( offset by the guid already read in )
+            const int nGuidSize = 0x10;
+            StreamDataSequence aDataSeq;
+            sal_Int32 nBytesToRead = nStreamSize - nGuidSize;
+            while ( nBytesToRead )
+                nBytesToRead -= mpCtlsStrm->readData( aDataSeq, nBytesToRead );
+            SequenceInputStream aInSeqStream( aDataSeq );
+            importControlFromStream( aInSeqStream, rxFormComp, aStrmClassId );
+        }
+        else
+        {
+            importControlFromStream( *mpCtlsStrm, rxFormComp, aStrmClassId );
+        }
+    }
+    return rxFormComp.is();
+}
+
+bool OleFormCtrlImportHelper::importControlFromStorage( ::oox::StorageRef xObjStrg,
+                                  Reference< XFormComponent > & rxFormComp )
+{
+    if ( xObjStrg.get() && xObjStrg->isStorage() )
+    {
+        BinaryXInputStream aNameStream( xObjStrg->openInputStream( CREATE_OUSTRING("\3OCXNAME") ), true );
+        BinaryXInputStream aInStrm( xObjStrg->openInputStream( CREATE_OUSTRING("contents") ), true );
+        BinaryXInputStream aClsStrm( xObjStrg->openInputStream( CREATE_OUSTRING("\1CompObj") ), true );
+        aClsStrm.skip(12);
+        OUString aStrmClassId = ::oox::ole::OleHelper::importGuid( aClsStrm );
+        if ( importControlFromStream(  aInStrm,  rxFormComp, aStrmClassId ) )
+        {
+            OUString aName = aNameStream.readNulUnicodeArray();
+            Reference< XControlModel > xCtlModel( rxFormComp, UNO_QUERY );
+            if ( aName.getLength() && xCtlModel.is() )
+            {
+                PropertyMap aPropMap;
+                aPropMap.setProperty( PROP_Name, aName );
+                PropertySet aPropSet( xCtlModel );
+                aPropSet.setProperties( aPropMap );
+            }
+        }
+    }
+    return rxFormComp.is();
+}
+
+bool
+OleFormCtrlImportHelper::importFormControlFromObjStorage( Reference< XFormComponent > & rxFormComp )
+{
+    return importControlFromStorage( mpRoot, rxFormComp );
+}
+
+bool
+OleFormCtrlImportHelper::importFormControlFromObjPool( Reference< XFormComponent > & rxFormComp,
+                                   const ::rtl::OUString& rPoolName )
+{
+    bool bRet = false;
+    if ( mpRoot.get() )
+    {
+        if ( !mpPoolStrg.get() )
+            mpPoolStrg = mpRoot->openSubStorage( CREATE_OUSTRING( "ObjectPool" ), false );
+        if ( !mpPoolStrg.get() )
+            return false;
+        if ( mpPoolStrg->isStorage() )
+        {
+            StorageRef xObjStrg = mpPoolStrg->openSubStorage( rPoolName, false );
+            bRet = importControlFromStorage( xObjStrg,  rxFormComp );
+        }
+    }
+    return bRet;
+}
+
 // ============================================================================
 
 } // namespace ole
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index d3bf0b7..a4b270a 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -383,6 +383,7 @@ ScrollValue
 ScrollValueMax
 ScrollValueMin
 Segments
+SelectedItems
 SelectedPage
 Show
 ShowBorder
@@ -426,6 +427,7 @@ StartPosition
 StartWith
 StartingAngle
 State
+StringItemList
 Subtotals
 Suffix
 SwapXAndYAxis


More information about the Libreoffice-commits mailing list