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/source | |
parent | fad50e6a8c95412aeb4a2490ceab0c8d4f402919 (diff) |
use oox filter for *all* control import
Diffstat (limited to 'oox/source')
-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 |
3 files changed, 239 insertions, 0 deletions
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 |