summaryrefslogtreecommitdiff
path: root/oox/source
diff options
context:
space:
mode:
authorNoel Power <noel.power@novell.com>2011-07-12 10:07:52 +0100
committerNoel Power <noel.power@novell.com>2011-07-12 10:07:52 +0100
commit92eafe7218694f16cfe8a66f7fcd3d53187e2665 (patch)
tree88976c2eb13c555fb2e70408fde726b82f489086 /oox/source
parentfad50e6a8c95412aeb4a2490ceab0c8d4f402919 (diff)
use oox filter for *all* control import
Diffstat (limited to 'oox/source')
-rw-r--r--oox/source/ole/axcontrol.cxx100
-rw-r--r--oox/source/ole/olehelper.cxx137
-rw-r--r--oox/source/token/properties.txt2
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( "&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 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