Updated core
[LibreOffice.git] / oox / source / ole / olehelper.cxx
blobe87f2cde88a7278ab944683dcd108b50d2238d40
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "oox/ole/olehelper.hxx"
22 #include <rtl/ustrbuf.hxx>
23 #include "oox/helper/binaryinputstream.hxx"
24 #include "oox/helper/graphichelper.hxx"
25 #include "oox/token/tokens.hxx"
26 #include "oox/ole/axcontrol.hxx"
27 #include "oox/helper/propertymap.hxx"
28 #include "oox/helper/propertyset.hxx"
29 #include "oox/ole/olestorage.hxx"
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/form/FormComponentType.hpp>
33 #include <com/sun/star/form/XFormsSupplier.hpp>
34 #include <com/sun/star/form/XForm.hpp>
35 #include <com/sun/star/lang/XServiceInfo.hpp>
36 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
37 #include <com/sun/star/container/XNameContainer.hpp>
38 #include <com/sun/star/awt/Size.hpp>
40 #include <tools/globname.hxx>
41 #include <unotools/streamwrap.hxx>
42 #include <comphelper/processfactory.hxx>
44 namespace oox {
45 namespace ole {
47 // ============================================================================
49 using ::com::sun::star::form::XFormComponent;
50 using ::com::sun::star::form::XForm;
51 using ::com::sun::star::awt::XControlModel;
52 using ::com::sun::star::awt::Size;
53 using ::com::sun::star::frame::XModel;
54 using ::com::sun::star::form::XFormsSupplier;
55 using ::com::sun::star::drawing::XDrawPage;
56 using ::com::sun::star::drawing::XDrawPageSupplier;
57 using ::com::sun::star::drawing::XShapes;
58 using ::com::sun::star::io::XOutputStream;
59 using ::com::sun::star::io::XInputStream;
60 using ::com::sun::star::beans::XPropertySet;
61 using ::com::sun::star::uno::Reference;
62 using ::com::sun::star::uno::XInterface;
63 using ::com::sun::star::uno::UNO_QUERY;
64 using ::com::sun::star::uno::Any;
65 using ::com::sun::star::uno::XComponentContext;
66 using ::com::sun::star::container::XIndexContainer;
67 using ::com::sun::star::container::XNameContainer;
68 using ::com::sun::star::lang::XMultiServiceFactory;
69 using ::com::sun::star::lang::XServiceInfo;
71 using namespace ::com::sun::star::form;
73 // ============================================================================
75 namespace {
77 const sal_uInt32 OLE_COLORTYPE_MASK = 0xFF000000;
78 const sal_uInt32 OLE_COLORTYPE_CLIENT = 0x00000000;
79 const sal_uInt32 OLE_COLORTYPE_PALETTE = 0x01000000;
80 const sal_uInt32 OLE_COLORTYPE_BGR = 0x02000000;
81 const sal_uInt32 OLE_COLORTYPE_SYSCOLOR = 0x80000000;
83 const sal_uInt32 OLE_PALETTECOLOR_MASK = 0x0000FFFF;
84 const sal_uInt32 OLE_BGRCOLOR_MASK = 0x00FFFFFF;
85 const sal_uInt32 OLE_SYSTEMCOLOR_MASK = 0x0000FFFF;
88 /** Swaps the red and blue component of the passed color. */
89 inline sal_uInt32 lclSwapRedBlue( sal_uInt32 nColor )
91 return static_cast< sal_uInt32 >( (nColor & 0xFF00FF00) | ((nColor & 0x0000FF) << 16) | ((nColor & 0xFF0000) >> 16) );
94 /** Returns the UNO RGB color from the passed encoded OLE BGR color. */
95 inline sal_Int32 lclDecodeBgrColor( sal_uInt32 nOleColor )
97 return static_cast< sal_Int32 >( lclSwapRedBlue( nOleColor ) & 0xFFFFFF );
100 // ----------------------------------------------------------------------------
102 const sal_Char OLE_GUID_URLMONIKER[] = "{79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}";
103 const sal_Char OLE_GUID_FILEMONIKER[] = "{00000303-0000-0000-C000-000000000046}";
105 const sal_uInt32 OLE_STDPIC_ID = 0x0000746C;
107 const sal_uInt32 OLE_STDHLINK_VERSION = 2;
108 const sal_uInt32 OLE_STDHLINK_HASTARGET = 0x00000001; /// Has hyperlink moniker.
109 const sal_uInt32 OLE_STDHLINK_ABSOLUTE = 0x00000002; /// Absolute path.
110 const sal_uInt32 OLE_STDHLINK_HASLOCATION = 0x00000008; /// Has target location.
111 const sal_uInt32 OLE_STDHLINK_HASDISPLAY = 0x00000010; /// Has display string.
112 const sal_uInt32 OLE_STDHLINK_HASGUID = 0x00000020; /// Has identification GUID.
113 const sal_uInt32 OLE_STDHLINK_HASTIME = 0x00000040; /// Has creation time.
114 const sal_uInt32 OLE_STDHLINK_HASFRAME = 0x00000080; /// Has frame.
115 const sal_uInt32 OLE_STDHLINK_ASSTRING = 0x00000100; /// Hyperlink as simple string.
117 struct GUIDCNamePair
119 const char* sGUID;
120 const char* sName;
123 struct IdCntrlData
125 sal_Int16 nId;
126 GUIDCNamePair aData;
129 const sal_Int16 TOGGLEBUTTON = -1;
130 const sal_Int16 FORMULAFIELD = -2;
132 typedef std::map< sal_Int16, GUIDCNamePair > GUIDCNamePairMap;
133 class classIdToGUIDCNamePairMap
135 GUIDCNamePairMap mnIdToGUIDCNamePairMap;
136 classIdToGUIDCNamePairMap();
137 public:
138 static GUIDCNamePairMap& get();
141 classIdToGUIDCNamePairMap::classIdToGUIDCNamePairMap()
143 IdCntrlData initialCntrlData[] =
145 // Command button MUST be at index 0
146 { FormComponentType::COMMANDBUTTON,
147 { AX_GUID_COMMANDBUTTON, "CommandButton"} ,
149 // Toggle button MUST be at index 1
150 { TOGGLEBUTTON,
151 { AX_GUID_TOGGLEBUTTON, "ToggleButton"},
153 { FormComponentType::FIXEDTEXT,
154 { AX_GUID_LABEL, "Label"},
156 { FormComponentType::TEXTFIELD,
157 { AX_GUID_TEXTBOX, "TextBox"},
159 { FormComponentType::LISTBOX,
160 { AX_GUID_LISTBOX, "ListBox"},
162 { FormComponentType::COMBOBOX,
163 { AX_GUID_COMBOBOX, "ComboBox"},
165 { FormComponentType::CHECKBOX,
166 { AX_GUID_CHECKBOX, "CheckBox"},
168 { FormComponentType::RADIOBUTTON,
169 { AX_GUID_OPTIONBUTTON, "OptionButton"},
171 { FormComponentType::IMAGECONTROL,
172 { AX_GUID_IMAGE, "Image"},
174 { FormComponentType::DATEFIELD,
175 { AX_GUID_TEXTBOX, "TextBox"},
177 { FormComponentType::TIMEFIELD,
178 { AX_GUID_TEXTBOX, "TextBox"},
180 { FormComponentType::NUMERICFIELD,
181 { AX_GUID_TEXTBOX, "TextBox"},
183 { FormComponentType::CURRENCYFIELD,
184 { AX_GUID_TEXTBOX, "TextBox"},
186 { FormComponentType::PATTERNFIELD,
187 { AX_GUID_TEXTBOX, "TextBox"},
189 { FORMULAFIELD,
190 { AX_GUID_TEXTBOX, "TextBox"},
192 { FormComponentType::IMAGEBUTTON,
193 { AX_GUID_COMMANDBUTTON, "CommandButton"},
195 { FormComponentType::SPINBUTTON,
196 { AX_GUID_SPINBUTTON, "SpinButton"},
198 { FormComponentType::SCROLLBAR,
199 { AX_GUID_SCROLLBAR, "ScrollBar"},
202 int length = SAL_N_ELEMENTS( initialCntrlData );
203 IdCntrlData* pData = initialCntrlData;
204 for ( int index = 0; index < length; ++index, ++pData )
205 mnIdToGUIDCNamePairMap[ pData->nId ] = pData->aData;
208 GUIDCNamePairMap& classIdToGUIDCNamePairMap::get()
210 static classIdToGUIDCNamePairMap theInst;
211 return theInst.mnIdToGUIDCNamePairMap;
214 // ----------------------------------------------------------------------------
216 template< typename Type >
217 void lclAppendHex( OUStringBuffer& orBuffer, Type nValue )
219 const sal_Int32 nWidth = 2 * sizeof( Type );
220 static const sal_Unicode spcHexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
221 orBuffer.setLength( orBuffer.getLength() + nWidth );
222 for( sal_Int32 nCharIdx = orBuffer.getLength() - 1, nCharEnd = nCharIdx - nWidth; nCharIdx > nCharEnd; --nCharIdx, nValue >>= 4 )
223 orBuffer[nCharIdx] = spcHexChars[ nValue & 0xF ];
226 } // namespace
228 // ============================================================================
230 StdFontInfo::StdFontInfo() :
231 mnHeight( 0 ),
232 mnWeight( OLE_STDFONT_NORMAL ),
233 mnCharSet( WINDOWS_CHARSET_ANSI ),
234 mnFlags( 0 )
238 StdFontInfo::StdFontInfo( const OUString& rName, sal_uInt32 nHeight,
239 sal_uInt16 nWeight, sal_uInt16 nCharSet, sal_uInt8 nFlags ) :
240 maName( rName ),
241 mnHeight( nHeight ),
242 mnWeight( nWeight ),
243 mnCharSet( nCharSet ),
244 mnFlags( nFlags )
248 // ============================================================================
250 sal_Int32 OleHelper::decodeOleColor(
251 const GraphicHelper& rGraphicHelper, sal_uInt32 nOleColor, bool bDefaultColorBgr )
253 static const sal_Int32 spnSystemColors[] =
255 XML_scrollBar, XML_background, XML_activeCaption, XML_inactiveCaption,
256 XML_menu, XML_window, XML_windowFrame, XML_menuText,
257 XML_windowText, XML_captionText, XML_activeBorder, XML_inactiveBorder,
258 XML_appWorkspace, XML_highlight, XML_highlightText, XML_btnFace,
259 XML_btnShadow, XML_grayText, XML_btnText, XML_inactiveCaptionText,
260 XML_btnHighlight, XML_3dDkShadow, XML_3dLight, XML_infoText,
261 XML_infoBk
264 switch( nOleColor & OLE_COLORTYPE_MASK )
266 case OLE_COLORTYPE_CLIENT:
267 return bDefaultColorBgr ? lclDecodeBgrColor( nOleColor ) : rGraphicHelper.getPaletteColor( nOleColor & OLE_PALETTECOLOR_MASK );
269 case OLE_COLORTYPE_PALETTE:
270 return rGraphicHelper.getPaletteColor( nOleColor & OLE_PALETTECOLOR_MASK );
272 case OLE_COLORTYPE_BGR:
273 return lclDecodeBgrColor( nOleColor );
275 case OLE_COLORTYPE_SYSCOLOR:
276 return rGraphicHelper.getSystemColor( STATIC_ARRAY_SELECT( spnSystemColors, nOleColor & OLE_SYSTEMCOLOR_MASK, XML_TOKEN_INVALID ), API_RGB_WHITE );
278 OSL_FAIL( "OleHelper::decodeOleColor - unknown color type" );
279 return API_RGB_BLACK;
282 sal_uInt32 OleHelper::encodeOleColor( sal_Int32 nRgbColor )
284 return OLE_COLORTYPE_BGR | lclSwapRedBlue( static_cast< sal_uInt32 >( nRgbColor & 0xFFFFFF ) );
287 OUString OleHelper::importGuid( BinaryInputStream& rInStrm )
289 OUStringBuffer aBuffer;
290 aBuffer.append( sal_Unicode( '{' ) );
291 lclAppendHex( aBuffer, rInStrm.readuInt32() );
292 aBuffer.append( sal_Unicode( '-' ) );
293 lclAppendHex( aBuffer, rInStrm.readuInt16() );
294 aBuffer.append( sal_Unicode( '-' ) );
295 lclAppendHex( aBuffer, rInStrm.readuInt16() );
296 aBuffer.append( sal_Unicode( '-' ) );
297 lclAppendHex( aBuffer, rInStrm.readuInt8() );
298 lclAppendHex( aBuffer, rInStrm.readuInt8() );
299 aBuffer.append( sal_Unicode( '-' ) );
300 for( int nIndex = 0; nIndex < 6; ++nIndex )
301 lclAppendHex( aBuffer, rInStrm.readuInt8() );
302 aBuffer.append( sal_Unicode( '}' ) );
303 return aBuffer.makeStringAndClear();
306 bool OleHelper::importStdFont( StdFontInfo& orFontInfo, BinaryInputStream& rInStrm, bool bWithGuid )
308 if( bWithGuid )
310 bool bIsStdFont = importGuid( rInStrm ) == OLE_GUID_STDFONT;
311 OSL_ENSURE( bIsStdFont, "OleHelper::importStdFont - unexpected header GUID, expected StdFont" );
312 if( !bIsStdFont )
313 return false;
316 sal_uInt8 nVersion, nNameLen;
317 rInStrm >> nVersion >> orFontInfo.mnCharSet >> orFontInfo.mnFlags >> orFontInfo.mnWeight >> orFontInfo.mnHeight >> nNameLen;
318 // according to spec the name is ASCII
319 orFontInfo.maName = rInStrm.readCharArrayUC( nNameLen, RTL_TEXTENCODING_ASCII_US );
320 OSL_ENSURE( nVersion <= 1, "OleHelper::importStdFont - wrong version" );
321 return !rInStrm.isEof() && (nVersion <= 1);
324 bool OleHelper::importStdPic( StreamDataSequence& orGraphicData, BinaryInputStream& rInStrm, bool bWithGuid )
326 if( bWithGuid )
328 bool bIsStdPic = importGuid( rInStrm ) == OLE_GUID_STDPIC;
329 OSL_ENSURE( bIsStdPic, "OleHelper::importStdPic - unexpected header GUID, expected StdPic" );
330 if( !bIsStdPic )
331 return false;
334 sal_uInt32 nStdPicId;
335 sal_Int32 nBytes;
336 rInStrm >> nStdPicId >> nBytes;
337 OSL_ENSURE( nStdPicId == OLE_STDPIC_ID, "OleHelper::importStdPic - unexpected header version" );
338 return !rInStrm.isEof() && (nStdPicId == OLE_STDPIC_ID) && (nBytes > 0) && (rInStrm.readData( orGraphicData, nBytes ) == nBytes);
341 Reference< ::com::sun::star::frame::XFrame >
342 lcl_getFrame( const Reference< ::com::sun::star::frame::XModel >& rxModel )
344 Reference< ::com::sun::star::frame::XFrame > xFrame;
345 if ( rxModel.is() )
347 Reference< ::com::sun::star::frame::XController > xController = rxModel->getCurrentController();
348 xFrame = xController.is() ? xController->getFrame() : NULL;
350 return xFrame;
353 class OleFormCtrlExportHelper
355 ::oox::ole::EmbeddedControl maControl;
356 ::oox::ole::ControlModelBase* mpModel;
357 ::oox::GraphicHelper maGrfHelper;
358 Reference< XModel > mxDocModel;
359 Reference< XControlModel > mxControlModel;
361 OUString maName;
362 OUString maTypeName;
363 OUString maFullName;
364 OUString maGUID;
365 public:
366 OleFormCtrlExportHelper( const Reference< XComponentContext >& rxCtx, const Reference< XModel >& xDocModel, const Reference< XControlModel >& xModel );
367 virtual ~OleFormCtrlExportHelper() { }
368 virtual OUString getGUID()
370 OUString sResult;
371 if ( maGUID.getLength() > 2 )
372 sResult = maGUID.copy(1, maGUID.getLength() - 2 );
373 return sResult;
375 OUString getFullName() { return maFullName; }
376 OUString getTypeName() { return maTypeName; }
377 bool isValid() { return mpModel != NULL; }
378 void exportName( const Reference< XOutputStream >& rxOut );
379 void exportCompObj( const Reference< XOutputStream >& rxOut );
380 void exportControl( const Reference< XOutputStream >& rxOut, const ::com::sun::star::awt::Size& rSize );
382 OleFormCtrlExportHelper::OleFormCtrlExportHelper( const Reference< XComponentContext >& rxCtx, const Reference< XModel >& rxDocModel, const Reference< XControlModel >& xCntrlModel ) : maControl( "Unknown" ), mpModel( NULL ), maGrfHelper( rxCtx, lcl_getFrame( rxDocModel ), StorageRef() ), mxDocModel( rxDocModel ), mxControlModel( xCntrlModel )
384 // try to get the guid
385 Reference< com::sun::star::beans::XPropertySet > xProps( xCntrlModel, UNO_QUERY );
386 if ( xProps.is() )
388 sal_Int16 nClassId = 0;
389 PropertySet aPropSet( mxControlModel );
390 if ( aPropSet.getProperty( nClassId, PROP_ClassId ) )
392 /* psuedo ripped from legacy msocximex:
393 "There is a truly horrible thing with EditControls and FormattedField
394 Controls, they both pretend to have an EDITBOX ClassId for compability
395 reasons, at some stage in the future hopefully there will be a proper
396 FormulaField ClassId rather than this piggybacking two controls onto the
397 same ClassId, cmc." - when fixed the fake FORMULAFIELD id entry
398 and definition above can be removed/replaced
400 if ( nClassId == FormComponentType::TEXTFIELD)
402 Reference< XServiceInfo > xInfo( xCntrlModel,
403 UNO_QUERY);
404 if (xInfo->
405 supportsService( "com.sun.star.form.component.FormattedField" ) )
406 nClassId = FORMULAFIELD;
408 else if ( nClassId == FormComponentType::COMMANDBUTTON )
410 bool bToggle = false;
411 aPropSet.getProperty( bToggle, PROP_Toggle );
412 if ( bToggle )
413 nClassId = TOGGLEBUTTON;
415 else if ( nClassId == FormComponentType::CONTROL )
417 Reference< XServiceInfo > xInfo( xCntrlModel,
418 UNO_QUERY);
419 if (xInfo->supportsService("com.sun.star.form.component.ImageControl" ) )
420 nClassId = FormComponentType::IMAGECONTROL;
423 GUIDCNamePairMap& cntrlMap = classIdToGUIDCNamePairMap::get();
424 GUIDCNamePairMap::iterator it = cntrlMap.find( nClassId );
425 if ( it != cntrlMap.end() )
427 aPropSet.getProperty(maName, PROP_Name );
428 maTypeName = OUString::createFromAscii( it->second.sName );
429 maFullName = "Microsoft Forms 2.0 " + maTypeName;
430 maControl = EmbeddedControl( maName );
431 maGUID = OUString::createFromAscii( it->second.sGUID );
432 mpModel = maControl.createModelFromGuid( maGUID );
438 void OleFormCtrlExportHelper::exportName( const Reference< XOutputStream >& rxOut )
440 oox::BinaryXOutputStream aOut( rxOut, false );
441 aOut.writeUnicodeArray( maName );
442 aOut << sal_Int32(0);
445 void OleFormCtrlExportHelper::exportCompObj( const Reference< XOutputStream >& rxOut )
447 oox::BinaryXOutputStream aOut( rxOut, false );
448 if ( mpModel && mpModel->getControlType() == API_CONTROL_BUTTON )
449 mpModel->exportCompObj( aOut );
452 void OleFormCtrlExportHelper::exportControl( const Reference< XOutputStream >& rxOut, const Size& rSize )
454 oox::BinaryXOutputStream aOut( rxOut, false );
455 if ( mpModel )
457 ::oox::ole::ControlConverter aConv( mxDocModel, maGrfHelper );
458 maControl.convertFromProperties( mxControlModel, aConv );
459 mpModel->maSize.first = rSize.Width;
460 mpModel->maSize.second = rSize.Height;
461 mpModel->exportBinaryModel( aOut );
465 MSConvertOCXControls::MSConvertOCXControls( const Reference< ::com::sun::star::frame::XModel >& rxModel ) : SvxMSConvertOCXControls( rxModel ), mxCtx( comphelper::getProcessComponentContext() ), maGrfHelper( mxCtx, lcl_getFrame( rxModel ), StorageRef() )
469 MSConvertOCXControls::~MSConvertOCXControls()
473 bool
474 MSConvertOCXControls::importControlFromStream( ::oox::BinaryInputStream& rInStrm, Reference< XFormComponent >& rxFormComp, const OUString& rGuidString )
476 ::oox::ole::EmbeddedControl aControl( "Unknown" );
477 if( ::oox::ole::ControlModelBase* pModel = aControl.createModelFromGuid( rGuidString ) )
479 pModel->importBinaryModel( rInStrm );
480 rxFormComp.set( mxCtx->getServiceManager()->createInstanceWithContext( pModel->getServiceName(), mxCtx ), UNO_QUERY );
481 Reference< XControlModel > xCtlModel( rxFormComp, UNO_QUERY );
482 ::oox::ole::ControlConverter aConv( mxModel, maGrfHelper );
483 aControl.convertProperties( xCtlModel, aConv );
485 return rxFormComp.is();
488 sal_Bool
489 MSConvertOCXControls::ReadOCXCtlsStream( SotStorageStreamRef& rSrc1, Reference< XFormComponent > & rxFormComp,
490 sal_Int32 nPos,
491 sal_Int32 nStreamSize)
493 if ( rSrc1.Is() )
495 BinaryXInputStream aCtlsStrm( Reference< XInputStream >( new utl::OSeekableInputStreamWrapper( *rSrc1 ) ), true );
496 aCtlsStrm.seek( nPos );
497 OUString aStrmClassId = ::oox::ole::OleHelper::importGuid( aCtlsStrm );
498 return importControlFromStream( aCtlsStrm, rxFormComp, aStrmClassId, nStreamSize );
500 return sal_False;
503 bool MSConvertOCXControls::importControlFromStream( ::oox::BinaryInputStream& rInStrm, Reference< XFormComponent >& rxFormComp, const OUString& rStrmClassId,
504 sal_Int32 nStreamSize)
506 if ( !rInStrm.isEof() )
508 // Special processing for those html controls
509 bool bOneOfHtmlControls = false;
510 if ( rStrmClassId.toAsciiUpperCase().equalsAscii( HTML_GUID_SELECT )
511 || rStrmClassId.toAsciiUpperCase().equalsAscii( HTML_GUID_TEXTBOX ) )
512 bOneOfHtmlControls = false;
514 if ( bOneOfHtmlControls )
516 // html controls don't seem have a handy record length following the GUID
517 // in the binary stream.
518 // Given the control stream length create a stream of nStreamSize bytes starting from
519 // nPos ( offset by the guid already read in )
520 if ( !nStreamSize )
521 return false;
522 const int nGuidSize = 0x10;
523 StreamDataSequence aDataSeq;
524 sal_Int32 nBytesToRead = nStreamSize - nGuidSize;
525 while ( nBytesToRead )
526 nBytesToRead -= rInStrm.readData( aDataSeq, nBytesToRead );
527 SequenceInputStream aInSeqStream( aDataSeq );
528 importControlFromStream( aInSeqStream, rxFormComp, rStrmClassId );
530 else
532 importControlFromStream( rInStrm, rxFormComp, rStrmClassId );
535 return rxFormComp.is();
538 sal_Bool MSConvertOCXControls::ReadOCXStorage( SotStorageRef& xOleStg,
539 Reference< XFormComponent > & rxFormComp )
541 if ( xOleStg.Is() )
543 SvStorageStreamRef pNameStream = xOleStg->OpenSotStream( OUString("\3OCXNAME"));
544 BinaryXInputStream aNameStream( Reference< XInputStream >( new utl::OSeekableInputStreamWrapper( *pNameStream ) ), true );
546 SvStorageStreamRef pContents = xOleStg->OpenSotStream( OUString("contents"));
547 BinaryXInputStream aInStrm( Reference< XInputStream >( new utl::OSeekableInputStreamWrapper( *pContents ) ), true );
550 SvStorageStreamRef pClsStrm = xOleStg->OpenSotStream(OUString("\1CompObj"));
551 BinaryXInputStream aClsStrm( Reference< XInputStream >( new utl::OSeekableInputStreamWrapper(*pClsStrm ) ), true );
552 aClsStrm.skip(12);
554 OUString aStrmClassId = ::oox::ole::OleHelper::importGuid( aClsStrm );
555 if ( importControlFromStream( aInStrm, rxFormComp, aStrmClassId, aInStrm.size() ) )
557 OUString aName = aNameStream.readNulUnicodeArray();
558 Reference< XControlModel > xCtlModel( rxFormComp, UNO_QUERY );
559 if ( !aName.isEmpty() && xCtlModel.is() )
561 PropertyMap aPropMap;
562 aPropMap.setProperty( PROP_Name, aName );
563 PropertySet aPropSet( xCtlModel );
564 aPropSet.setProperties( aPropMap );
566 return rxFormComp.is();
569 return sal_False;
572 sal_Bool MSConvertOCXControls::WriteOCXStream( const Reference< XModel >& rxModel, SotStorageRef &xOleStg,
573 const Reference< XControlModel > &rxControlModel,
574 const com::sun::star::awt::Size& rSize, OUString &rName)
576 SvGlobalName aName;
578 OleFormCtrlExportHelper exportHelper( comphelper::getProcessComponentContext(), rxModel, rxControlModel );
580 if ( !exportHelper.isValid() )
581 return sal_False;
583 OUString sId = exportHelper.getGUID();
584 aName.MakeId(sId);
586 OUString sFullName = exportHelper.getFullName();
587 rName = exportHelper.getTypeName();
588 xOleStg->SetClass( aName,0x5C,sFullName);
590 SvStorageStreamRef pNameStream = xOleStg->OpenSotStream(OUString("\3OCXNAME"));
591 Reference< XOutputStream > xOut = new utl::OSeekableOutputStreamWrapper( *pNameStream );
592 exportHelper.exportName( xOut );
595 SvStorageStreamRef pObjStream = xOleStg->OpenSotStream(OUString("\1CompObj"));
596 Reference< XOutputStream > xOut = new utl::OSeekableOutputStreamWrapper( *pObjStream );
597 exportHelper.exportCompObj( xOut );
600 SvStorageStreamRef pContents = xOleStg->OpenSotStream(OUString("contents"));
601 Reference< XOutputStream > xOut = new utl::OSeekableOutputStreamWrapper( *pContents );
602 exportHelper.exportControl( xOut, rSize );
604 return sal_True;
607 #ifdef SvxMSConvertOCXControlsRemoved
608 const Reference< com::sun::star::lang::XMultiServiceFactory > & MSConvertOCXControls::GetServiceFactory()
610 if ( !mxServiceFactory.is() && mxModel.is() )
611 mxServiceFactory.set( mxModel, UNO_QUERY );
612 return mxServiceFactory;
615 const Reference< XIndexContainer >&
616 MSConvertOCXControls::GetFormComps()
618 if( !mxFormComps.is() )
620 GetDrawPage();
621 if( mxDrawPage.is() )
623 Reference< XFormsSupplier > xFormsSupplier( mxDrawPage,
624 UNO_QUERY );
625 OSL_ENSURE( xFormsSupplier.is(),
626 "not able to get XFormsSupplier from XDrawPage" );
628 Reference< XNameContainer > xNameCont =
629 xFormsSupplier->getForms();
631 OUString sStdName = "WW-Standard";
632 OUString sName( sStdName );
633 sal_uInt16 n = 0;
635 while( xNameCont->hasByName( sName ) )
637 sName = sStdName;
638 sName += OUString::number(++n);
641 const Reference< XMultiServiceFactory > &rServiceFactory
642 = GetServiceFactory();
643 if( !rServiceFactory.is() )
644 return mxFormComps;
646 Reference< XInterface > xCreate =
647 rServiceFactory->createInstance("com.sun.star.form.component.Form");
648 if( xCreate.is() )
650 Reference< XPropertySet > xFormPropSet( xCreate,
651 UNO_QUERY );
653 Any aTmp(&sName,getCppuType((OUString *)0));
654 xFormPropSet->setPropertyValue( "Name", aTmp );
656 Reference< XForm > xForm( xCreate, UNO_QUERY );
657 OSL_ENSURE(xForm.is(), "No Form?");
659 Reference< XIndexContainer > xForms( xNameCont,
660 UNO_QUERY );
661 OSL_ENSURE( xForms.is(), "XForms not available" );
663 aTmp.setValue( &xForm,
664 ::getCppuType((Reference < XForm >*)0));
665 xForms->insertByIndex( xForms->getCount(), aTmp );
667 mxFormComps = Reference< XIndexContainer >
668 (xCreate, UNO_QUERY);
673 return mxFormComps;
675 const Reference< XDrawPage >& MSConvertOCXControls::GetDrawPage()
677 if( !mxDrawPage.is() && mxModel.is() )
679 Reference< XDrawPageSupplier > xTxtDoc(mxModel, UNO_QUERY);
680 OSL_ENSURE( xTxtDoc.is(),"no XDrawPageSupplier from XModel");
681 mxDrawPage = xTxtDoc->getDrawPage();
682 OSL_ENSURE( mxDrawPage.is(), "no XDrawPage" );
684 return mxDrawPage;
687 const Reference< XShapes >& MSConvertOCXControls::GetShapes()
689 if( !mxShapes.is() )
691 GetDrawPage();
692 if( mxDrawPage.is() )
695 mxShapes = Reference< XShapes >(mxDrawPage,
696 UNO_QUERY);
697 OSL_ENSURE( mxShapes.is(), "no XShapes from XDrawPage" );
700 return mxShapes;
702 #endif
703 // ============================================================================
705 } // namespace ole
706 } // namespace oox
708 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */