diff options
author | Noel Power <noel.power@novell.com> | 2011-07-12 10:07:52 +0100 |
---|---|---|
committer | Noel Power <noel.power@novell.com> | 2011-07-12 10:07:52 +0100 |
commit | 92eafe7218694f16cfe8a66f7fcd3d53187e2665 (patch) | |
tree | 88976c2eb13c555fb2e70408fde726b82f489086 /oox | |
parent | fad50e6a8c95412aeb4a2490ceab0c8d4f402919 (diff) |
use oox filter for *all* control import
Diffstat (limited to 'oox')
-rw-r--r-- | oox/Package_inc.mk | 1 | ||||
-rw-r--r-- | oox/inc/oox/ole/axcontrol.hxx | 21 | ||||
-rw-r--r-- | oox/inc/oox/ole/olehelper.hxx | 40 | ||||
-rw-r--r-- | oox/source/ole/axcontrol.cxx | 100 | ||||
-rw-r--r-- | oox/source/ole/olehelper.cxx | 137 | ||||
-rw-r--r-- | oox/source/token/properties.txt | 2 |
6 files changed, 300 insertions, 1 deletions
diff --git a/oox/Package_inc.mk b/oox/Package_inc.mk index d9b23dbfd266..b51b51b79559 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 273bacd5121a..2f06aca5ee7d 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 9881eebc21dc..efe0b40c2938 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 9e971e602da6..95a791d86b11 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( "<" ) ), String( RTL_CONSTASCII_USTRINGPARAM("<") ) ); + displayValue.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( ">" ) ), String( RTL_CONSTASCII_USTRINGPARAM(">") ) ); + displayValue.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( """ ) ), String( RTL_CONSTASCII_USTRINGPARAM("\"") ) ); + displayValue.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "&" ) ), 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 95678f147cd4..2bcafc9a2882 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 d3bf0b776c25..a4b270ab4124 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 |