Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "oox/ole/olehelper.hxx"
21 :
22 : #include <rtl/ustrbuf.hxx>
23 : #include <sot/storage.hxx>
24 : #include <osl/diagnose.h>
25 : #include "oox/helper/binaryinputstream.hxx"
26 : #include "oox/helper/graphichelper.hxx"
27 : #include "oox/token/tokens.hxx"
28 : #include "oox/ole/axcontrol.hxx"
29 : #include "oox/helper/propertymap.hxx"
30 : #include "oox/helper/propertyset.hxx"
31 : #include "oox/ole/olestorage.hxx"
32 :
33 : #include <com/sun/star/beans/XPropertySet.hpp>
34 : #include <com/sun/star/form/FormComponentType.hpp>
35 : #include <com/sun/star/form/XFormsSupplier.hpp>
36 : #include <com/sun/star/form/XForm.hpp>
37 : #include <com/sun/star/lang/XServiceInfo.hpp>
38 : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
39 : #include <com/sun/star/container/XNameContainer.hpp>
40 : #include <com/sun/star/awt/Size.hpp>
41 :
42 : #include <tools/globname.hxx>
43 : #include <unotools/streamwrap.hxx>
44 : #include <comphelper/processfactory.hxx>
45 :
46 : namespace oox {
47 : namespace ole {
48 :
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;
70 :
71 : using namespace ::com::sun::star::form;
72 :
73 : namespace {
74 :
75 : const sal_uInt32 OLE_COLORTYPE_MASK = 0xFF000000;
76 : const sal_uInt32 OLE_COLORTYPE_CLIENT = 0x00000000;
77 : const sal_uInt32 OLE_COLORTYPE_PALETTE = 0x01000000;
78 : const sal_uInt32 OLE_COLORTYPE_BGR = 0x02000000;
79 : const sal_uInt32 OLE_COLORTYPE_SYSCOLOR = 0x80000000;
80 :
81 : const sal_uInt32 OLE_PALETTECOLOR_MASK = 0x0000FFFF;
82 : const sal_uInt32 OLE_SYSTEMCOLOR_MASK = 0x0000FFFF;
83 :
84 : /** Swaps the red and blue component of the passed color. */
85 11 : inline sal_uInt32 lclSwapRedBlue( sal_uInt32 nColor )
86 : {
87 11 : return static_cast< sal_uInt32 >( (nColor & 0xFF00FF00) | ((nColor & 0x0000FF) << 16) | ((nColor & 0xFF0000) >> 16) );
88 : }
89 :
90 : /** Returns the UNO RGB color from the passed encoded OLE BGR color. */
91 10 : inline sal_Int32 lclDecodeBgrColor( sal_uInt32 nOleColor )
92 : {
93 10 : return static_cast< sal_Int32 >( lclSwapRedBlue( nOleColor ) & 0xFFFFFF );
94 : }
95 :
96 : const sal_uInt32 OLE_STDPIC_ID = 0x0000746C;
97 :
98 : struct GUIDCNamePair
99 : {
100 : const char* sGUID;
101 : const char* sName;
102 : };
103 :
104 : struct IdCntrlData
105 : {
106 : sal_Int16 nId;
107 : GUIDCNamePair aData;
108 : };
109 :
110 : const sal_Int16 TOGGLEBUTTON = -1;
111 : const sal_Int16 FORMULAFIELD = -2;
112 :
113 : typedef std::map< sal_Int16, GUIDCNamePair > GUIDCNamePairMap;
114 1 : class classIdToGUIDCNamePairMap
115 : {
116 : GUIDCNamePairMap mnIdToGUIDCNamePairMap;
117 : classIdToGUIDCNamePairMap();
118 : public:
119 : static GUIDCNamePairMap& get();
120 : };
121 :
122 1 : classIdToGUIDCNamePairMap::classIdToGUIDCNamePairMap()
123 : {
124 : IdCntrlData initialCntrlData[] =
125 : {
126 : // Command button MUST be at index 0
127 : { FormComponentType::COMMANDBUTTON,
128 : { AX_GUID_COMMANDBUTTON, "CommandButton"} ,
129 : },
130 : // Toggle button MUST be at index 1
131 : { TOGGLEBUTTON,
132 : { AX_GUID_TOGGLEBUTTON, "ToggleButton"},
133 : },
134 : { FormComponentType::FIXEDTEXT,
135 : { AX_GUID_LABEL, "Label"},
136 : },
137 : { FormComponentType::TEXTFIELD,
138 : { AX_GUID_TEXTBOX, "TextBox"},
139 : },
140 : { FormComponentType::LISTBOX,
141 : { AX_GUID_LISTBOX, "ListBox"},
142 : },
143 : { FormComponentType::COMBOBOX,
144 : { AX_GUID_COMBOBOX, "ComboBox"},
145 : },
146 : { FormComponentType::CHECKBOX,
147 : { AX_GUID_CHECKBOX, "CheckBox"},
148 : },
149 : { FormComponentType::RADIOBUTTON,
150 : { AX_GUID_OPTIONBUTTON, "OptionButton"},
151 : },
152 : { FormComponentType::IMAGECONTROL,
153 : { AX_GUID_IMAGE, "Image"},
154 : },
155 : { FormComponentType::DATEFIELD,
156 : { AX_GUID_TEXTBOX, "TextBox"},
157 : },
158 : { FormComponentType::TIMEFIELD,
159 : { AX_GUID_TEXTBOX, "TextBox"},
160 : },
161 : { FormComponentType::NUMERICFIELD,
162 : { AX_GUID_TEXTBOX, "TextBox"},
163 : },
164 : { FormComponentType::CURRENCYFIELD,
165 : { AX_GUID_TEXTBOX, "TextBox"},
166 : },
167 : { FormComponentType::PATTERNFIELD,
168 : { AX_GUID_TEXTBOX, "TextBox"},
169 : },
170 : { FORMULAFIELD,
171 : { AX_GUID_TEXTBOX, "TextBox"},
172 : },
173 : { FormComponentType::IMAGEBUTTON,
174 : { AX_GUID_COMMANDBUTTON, "CommandButton"},
175 : },
176 : { FormComponentType::SPINBUTTON,
177 : { AX_GUID_SPINBUTTON, "SpinButton"},
178 : },
179 : { FormComponentType::SCROLLBAR,
180 : { AX_GUID_SCROLLBAR, "ScrollBar"},
181 : }
182 1 : };
183 1 : int length = SAL_N_ELEMENTS( initialCntrlData );
184 1 : IdCntrlData* pData = initialCntrlData;
185 19 : for ( int index = 0; index < length; ++index, ++pData )
186 18 : mnIdToGUIDCNamePairMap[ pData->nId ] = pData->aData;
187 1 : };
188 :
189 1 : GUIDCNamePairMap& classIdToGUIDCNamePairMap::get()
190 : {
191 1 : static classIdToGUIDCNamePairMap theInst;
192 1 : return theInst.mnIdToGUIDCNamePairMap;
193 : }
194 :
195 : template< typename Type >
196 550 : void lclAppendHex( OUStringBuffer& orBuffer, Type nValue )
197 : {
198 550 : const sal_Int32 nWidth = 2 * sizeof( Type );
199 : static const sal_Unicode spcHexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
200 550 : orBuffer.setLength( orBuffer.getLength() + nWidth );
201 2150 : for( sal_Int32 nCharIdx = orBuffer.getLength() - 1, nCharEnd = nCharIdx - nWidth; nCharIdx > nCharEnd; --nCharIdx, nValue >>= 4 )
202 1600 : orBuffer[nCharIdx] = spcHexChars[ nValue & 0xF ];
203 550 : }
204 :
205 : } // namespace
206 :
207 0 : StdFontInfo::StdFontInfo() :
208 : mnHeight( 0 ),
209 : mnWeight( OLE_STDFONT_NORMAL ),
210 : mnCharSet( WINDOWS_CHARSET_ANSI ),
211 0 : mnFlags( 0 )
212 : {
213 0 : }
214 :
215 0 : StdFontInfo::StdFontInfo( const OUString& rName, sal_uInt32 nHeight,
216 : sal_uInt16 nWeight, sal_uInt16 nCharSet, sal_uInt8 nFlags ) :
217 : maName( rName ),
218 : mnHeight( nHeight ),
219 : mnWeight( nWeight ),
220 : mnCharSet( nCharSet ),
221 0 : mnFlags( nFlags )
222 : {
223 0 : }
224 :
225 92 : sal_Int32 OleHelper::decodeOleColor(
226 : const GraphicHelper& rGraphicHelper, sal_uInt32 nOleColor, bool bDefaultColorBgr )
227 : {
228 : static const sal_Int32 spnSystemColors[] =
229 : {
230 : XML_scrollBar, XML_background, XML_activeCaption, XML_inactiveCaption,
231 : XML_menu, XML_window, XML_windowFrame, XML_menuText,
232 : XML_windowText, XML_captionText, XML_activeBorder, XML_inactiveBorder,
233 : XML_appWorkspace, XML_highlight, XML_highlightText, XML_btnFace,
234 : XML_btnShadow, XML_grayText, XML_btnText, XML_inactiveCaptionText,
235 : XML_btnHighlight, XML_3dDkShadow, XML_3dLight, XML_infoText,
236 : XML_infoBk
237 : };
238 :
239 92 : switch( nOleColor & OLE_COLORTYPE_MASK )
240 : {
241 : case OLE_COLORTYPE_CLIENT:
242 9 : return bDefaultColorBgr ? lclDecodeBgrColor( nOleColor ) : rGraphicHelper.getPaletteColor( nOleColor & OLE_PALETTECOLOR_MASK );
243 :
244 : case OLE_COLORTYPE_PALETTE:
245 0 : return rGraphicHelper.getPaletteColor( nOleColor & OLE_PALETTECOLOR_MASK );
246 :
247 : case OLE_COLORTYPE_BGR:
248 1 : return lclDecodeBgrColor( nOleColor );
249 :
250 : case OLE_COLORTYPE_SYSCOLOR:
251 82 : return rGraphicHelper.getSystemColor( STATIC_ARRAY_SELECT( spnSystemColors, nOleColor & OLE_SYSTEMCOLOR_MASK, XML_TOKEN_INVALID ), API_RGB_WHITE );
252 : }
253 : OSL_FAIL( "OleHelper::decodeOleColor - unknown color type" );
254 0 : return API_RGB_BLACK;
255 : }
256 :
257 1 : sal_uInt32 OleHelper::encodeOleColor( sal_Int32 nRgbColor )
258 : {
259 1 : return OLE_COLORTYPE_BGR | lclSwapRedBlue( static_cast< sal_uInt32 >( nRgbColor & 0xFFFFFF ) );
260 : }
261 :
262 0 : void OleHelper::exportGuid( BinaryOutputStream& rOStr, const SvGlobalName& rId )
263 : {
264 0 : rOStr.WriteUInt32( rId.GetCLSID().Data1 );
265 0 : rOStr.WriteUInt16( rId.GetCLSID().Data2 );
266 0 : rOStr.WriteUInt16( rId.GetCLSID().Data3 );
267 0 : rOStr.writeArray( rId.GetCLSID().Data4, 8 );
268 0 : }
269 :
270 50 : OUString OleHelper::importGuid( BinaryInputStream& rInStrm )
271 : {
272 50 : OUStringBuffer aBuffer;
273 50 : aBuffer.append( '{' );
274 50 : lclAppendHex( aBuffer, rInStrm.readuInt32() );
275 50 : aBuffer.append( '-' );
276 50 : lclAppendHex( aBuffer, rInStrm.readuInt16() );
277 50 : aBuffer.append( '-' );
278 50 : lclAppendHex( aBuffer, rInStrm.readuInt16() );
279 50 : aBuffer.append( '-' );
280 50 : lclAppendHex( aBuffer, rInStrm.readuInt8() );
281 50 : lclAppendHex( aBuffer, rInStrm.readuInt8() );
282 50 : aBuffer.append( '-' );
283 350 : for( int nIndex = 0; nIndex < 6; ++nIndex )
284 300 : lclAppendHex( aBuffer, rInStrm.readuInt8() );
285 50 : aBuffer.append( '}' );
286 50 : return aBuffer.makeStringAndClear();
287 : }
288 :
289 0 : bool OleHelper::importStdFont( StdFontInfo& orFontInfo, BinaryInputStream& rInStrm, bool bWithGuid )
290 : {
291 0 : if( bWithGuid )
292 : {
293 0 : bool bIsStdFont = importGuid( rInStrm ) == OLE_GUID_STDFONT;
294 : OSL_ENSURE( bIsStdFont, "OleHelper::importStdFont - unexpected header GUID, expected StdFont" );
295 0 : if( !bIsStdFont )
296 0 : return false;
297 : }
298 :
299 : sal_uInt8 nVersion, nNameLen;
300 0 : nVersion = rInStrm.readuChar();
301 0 : orFontInfo.mnCharSet = rInStrm.readuInt16();
302 0 : orFontInfo.mnFlags = rInStrm.readuChar();
303 0 : orFontInfo.mnWeight = rInStrm.readuInt16();
304 0 : orFontInfo.mnHeight = rInStrm.readuInt32();
305 0 : nNameLen = rInStrm.readuChar();
306 : // according to spec the name is ASCII
307 0 : orFontInfo.maName = rInStrm.readCharArrayUC( nNameLen, RTL_TEXTENCODING_ASCII_US );
308 : OSL_ENSURE( nVersion <= 1, "OleHelper::importStdFont - wrong version" );
309 0 : return !rInStrm.isEof() && (nVersion <= 1);
310 : }
311 :
312 0 : bool OleHelper::importStdPic( StreamDataSequence& orGraphicData, BinaryInputStream& rInStrm, bool bWithGuid )
313 : {
314 0 : if( bWithGuid )
315 : {
316 0 : bool bIsStdPic = importGuid( rInStrm ) == OLE_GUID_STDPIC;
317 : OSL_ENSURE( bIsStdPic, "OleHelper::importStdPic - unexpected header GUID, expected StdPic" );
318 0 : if( !bIsStdPic )
319 0 : return false;
320 : }
321 :
322 : sal_uInt32 nStdPicId;
323 : sal_Int32 nBytes;
324 0 : nStdPicId = rInStrm.readuInt32();
325 0 : nBytes = rInStrm.readInt32();
326 : OSL_ENSURE( nStdPicId == OLE_STDPIC_ID, "OleHelper::importStdPic - unexpected header version" );
327 0 : return !rInStrm.isEof() && (nStdPicId == OLE_STDPIC_ID) && (nBytes > 0) && (rInStrm.readData( orGraphicData, nBytes ) == nBytes);
328 : }
329 :
330 : Reference< ::com::sun::star::frame::XFrame >
331 726 : lcl_getFrame( const Reference< ::com::sun::star::frame::XModel >& rxModel )
332 : {
333 726 : Reference< ::com::sun::star::frame::XFrame > xFrame;
334 726 : if ( rxModel.is() )
335 : {
336 726 : Reference< ::com::sun::star::frame::XController > xController = rxModel->getCurrentController();
337 726 : xFrame = xController.is() ? xController->getFrame() : NULL;
338 : }
339 726 : return xFrame;
340 : }
341 :
342 : class OleFormCtrlExportHelper
343 : {
344 : ::oox::ole::EmbeddedControl maControl;
345 : ::oox::ole::ControlModelBase* mpModel;
346 : ::oox::GraphicHelper maGrfHelper;
347 : Reference< XModel > mxDocModel;
348 : Reference< XControlModel > mxControlModel;
349 :
350 : OUString maName;
351 : OUString maTypeName;
352 : OUString maFullName;
353 : OUString maGUID;
354 : public:
355 : OleFormCtrlExportHelper( const Reference< XComponentContext >& rxCtx, const Reference< XModel >& xDocModel, const Reference< XControlModel >& xModel );
356 1 : virtual ~OleFormCtrlExportHelper() { }
357 1 : OUString getGUID()
358 : {
359 1 : OUString sResult;
360 1 : if ( maGUID.getLength() > 2 )
361 1 : sResult = maGUID.copy(1, maGUID.getLength() - 2 );
362 1 : return sResult;
363 : }
364 1 : OUString getFullName() { return maFullName; }
365 1 : OUString getTypeName() { return maTypeName; }
366 1 : bool isValid() { return mpModel != NULL; }
367 : void exportName( const Reference< XOutputStream >& rxOut );
368 : void exportCompObj( const Reference< XOutputStream >& rxOut );
369 : void exportControl( const Reference< XOutputStream >& rxOut, const ::com::sun::star::awt::Size& rSize );
370 : };
371 1 : 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 )
372 : {
373 : // try to get the guid
374 1 : Reference< com::sun::star::beans::XPropertySet > xProps( xCntrlModel, UNO_QUERY );
375 1 : if ( xProps.is() )
376 : {
377 1 : sal_Int16 nClassId = 0;
378 1 : PropertySet aPropSet( mxControlModel );
379 1 : if ( aPropSet.getProperty( nClassId, PROP_ClassId ) )
380 : {
381 : /* pseudo ripped from legacy msocximex:
382 : "There is a truly horrible thing with EditControls and FormattedField
383 : Controls, they both pretend to have an EDITBOX ClassId for compatibility
384 : reasons, at some stage in the future hopefully there will be a proper
385 : FormulaField ClassId rather than this piggybacking two controls onto the
386 : same ClassId, cmc." - when fixed the fake FORMULAFIELD id entry
387 : and definition above can be removed/replaced
388 : */
389 1 : if ( nClassId == FormComponentType::TEXTFIELD)
390 : {
391 : Reference< XServiceInfo > xInfo( xCntrlModel,
392 1 : UNO_QUERY);
393 3 : if (xInfo->
394 2 : supportsService( "com.sun.star.form.component.FormattedField" ) )
395 0 : nClassId = FORMULAFIELD;
396 : }
397 0 : else if ( nClassId == FormComponentType::COMMANDBUTTON )
398 : {
399 0 : bool bToggle = false;
400 0 : if ( aPropSet.getProperty( bToggle, PROP_Toggle ) && bToggle )
401 0 : nClassId = TOGGLEBUTTON;
402 : }
403 0 : else if ( nClassId == FormComponentType::CONTROL )
404 : {
405 : Reference< XServiceInfo > xInfo( xCntrlModel,
406 0 : UNO_QUERY);
407 0 : if (xInfo->supportsService("com.sun.star.form.component.ImageControl" ) )
408 0 : nClassId = FormComponentType::IMAGECONTROL;
409 : }
410 :
411 1 : GUIDCNamePairMap& cntrlMap = classIdToGUIDCNamePairMap::get();
412 1 : GUIDCNamePairMap::iterator it = cntrlMap.find( nClassId );
413 1 : if ( it != cntrlMap.end() )
414 : {
415 1 : aPropSet.getProperty(maName, PROP_Name );
416 1 : maTypeName = OUString::createFromAscii( it->second.sName );
417 1 : maFullName = "Microsoft Forms 2.0 " + maTypeName;
418 1 : maControl = EmbeddedControl( maName );
419 1 : maGUID = OUString::createFromAscii( it->second.sGUID );
420 1 : mpModel = maControl.createModelFromGuid( maGUID );
421 : }
422 1 : }
423 1 : }
424 1 : }
425 :
426 1 : void OleFormCtrlExportHelper::exportName( const Reference< XOutputStream >& rxOut )
427 : {
428 1 : oox::BinaryXOutputStream aOut( rxOut, false );
429 1 : aOut.writeUnicodeArray( maName );
430 1 : aOut.WriteInt32(0);
431 1 : }
432 :
433 1 : void OleFormCtrlExportHelper::exportCompObj( const Reference< XOutputStream >& rxOut )
434 : {
435 1 : oox::BinaryXOutputStream aOut( rxOut, false );
436 1 : if ( mpModel )
437 1 : mpModel->exportCompObj( aOut );
438 1 : }
439 :
440 1 : void OleFormCtrlExportHelper::exportControl( const Reference< XOutputStream >& rxOut, const Size& rSize )
441 : {
442 1 : oox::BinaryXOutputStream aOut( rxOut, false );
443 1 : if ( mpModel )
444 : {
445 1 : ::oox::ole::ControlConverter aConv( mxDocModel, maGrfHelper );
446 1 : maControl.convertFromProperties( mxControlModel, aConv );
447 1 : mpModel->maSize.first = rSize.Width;
448 1 : mpModel->maSize.second = rSize.Height;
449 1 : mpModel->exportBinaryModel( aOut );
450 1 : }
451 1 : }
452 :
453 725 : MSConvertOCXControls::MSConvertOCXControls( const Reference< ::com::sun::star::frame::XModel >& rxModel ) : SvxMSConvertOCXControls( rxModel ), mxCtx( comphelper::getProcessComponentContext() ), maGrfHelper( mxCtx, lcl_getFrame( rxModel ), StorageRef() )
454 : {
455 725 : }
456 :
457 724 : MSConvertOCXControls::~MSConvertOCXControls()
458 : {
459 724 : }
460 :
461 : bool
462 50 : MSConvertOCXControls::importControlFromStream( ::oox::BinaryInputStream& rInStrm, Reference< XFormComponent >& rxFormComp, const OUString& rGuidString )
463 : {
464 50 : ::oox::ole::EmbeddedControl aControl( "Unknown" );
465 50 : if( ::oox::ole::ControlModelBase* pModel = aControl.createModelFromGuid( rGuidString ) )
466 : {
467 34 : pModel->importBinaryModel( rInStrm );
468 34 : rxFormComp.set( mxCtx->getServiceManager()->createInstanceWithContext( pModel->getServiceName(), mxCtx ), UNO_QUERY );
469 34 : Reference< XControlModel > xCtlModel( rxFormComp, UNO_QUERY );
470 68 : ::oox::ole::ControlConverter aConv( mxModel, maGrfHelper );
471 68 : aControl.convertProperties( xCtlModel, aConv );
472 : }
473 50 : return rxFormComp.is();
474 : }
475 :
476 : bool
477 29 : MSConvertOCXControls::ReadOCXCtlsStream( tools::SvRef<SotStorageStream>& rSrc1, Reference< XFormComponent > & rxFormComp,
478 : sal_Int32 nPos,
479 : sal_Int32 nStreamSize)
480 : {
481 29 : if ( rSrc1.Is() )
482 : {
483 29 : BinaryXInputStream aCtlsStrm( Reference< XInputStream >( new utl::OSeekableInputStreamWrapper( *rSrc1 ) ), true );
484 29 : aCtlsStrm.seek( nPos );
485 58 : OUString aStrmClassId = ::oox::ole::OleHelper::importGuid( aCtlsStrm );
486 58 : return importControlFromStream( aCtlsStrm, rxFormComp, aStrmClassId, nStreamSize );
487 : }
488 0 : return false;
489 : }
490 :
491 50 : bool MSConvertOCXControls::importControlFromStream( ::oox::BinaryInputStream& rInStrm, Reference< XFormComponent >& rxFormComp, const OUString& rStrmClassId,
492 : sal_Int32 nStreamSize)
493 : {
494 50 : if ( !rInStrm.isEof() )
495 : {
496 : // Special processing for those html controls
497 50 : bool bOneOfHtmlControls = false;
498 200 : if ( rStrmClassId.toAsciiUpperCase() == HTML_GUID_SELECT
499 200 : || rStrmClassId.toAsciiUpperCase() == HTML_GUID_TEXTBOX )
500 0 : bOneOfHtmlControls = true;
501 :
502 50 : if ( bOneOfHtmlControls )
503 : {
504 : // html controls don't seem have a handy record length following the GUID
505 : // in the binary stream.
506 : // Given the control stream length create a stream of nStreamSize bytes starting from
507 : // nPos ( offset by the guid already read in )
508 0 : if ( !nStreamSize )
509 0 : return false;
510 0 : const int nGuidSize = 0x10;
511 0 : StreamDataSequence aDataSeq;
512 0 : sal_Int32 nBytesToRead = nStreamSize - nGuidSize;
513 0 : while ( nBytesToRead )
514 0 : nBytesToRead -= rInStrm.readData( aDataSeq, nBytesToRead );
515 0 : SequenceInputStream aInSeqStream( aDataSeq );
516 0 : importControlFromStream( aInSeqStream, rxFormComp, rStrmClassId );
517 : }
518 : else
519 : {
520 50 : importControlFromStream( rInStrm, rxFormComp, rStrmClassId );
521 : }
522 : }
523 50 : return rxFormComp.is();
524 : }
525 :
526 21 : bool MSConvertOCXControls::ReadOCXStorage( tools::SvRef<SotStorage>& xOleStg,
527 : Reference< XFormComponent > & rxFormComp )
528 : {
529 21 : if ( xOleStg.Is() )
530 : {
531 21 : tools::SvRef<SotStorageStream> pNameStream = xOleStg->OpenSotStream( OUString("\3OCXNAME"));
532 37 : BinaryXInputStream aNameStream( Reference< XInputStream >( new utl::OSeekableInputStreamWrapper( *pNameStream ) ), true );
533 :
534 37 : tools::SvRef<SotStorageStream> pContents = xOleStg->OpenSotStream( OUString("contents"));
535 37 : BinaryXInputStream aInStrm( Reference< XInputStream >( new utl::OSeekableInputStreamWrapper( *pContents ) ), true );
536 :
537 37 : tools::SvRef<SotStorageStream> pClsStrm = xOleStg->OpenSotStream(OUString("\1CompObj"));
538 37 : BinaryXInputStream aClsStrm( Reference< XInputStream >( new utl::OSeekableInputStreamWrapper(*pClsStrm ) ), true );
539 21 : aClsStrm.skip(12);
540 :
541 37 : OUString aStrmClassId = ::oox::ole::OleHelper::importGuid( aClsStrm );
542 21 : if ( importControlFromStream( aInStrm, rxFormComp, aStrmClassId, aInStrm.size() ) )
543 : {
544 5 : OUString aName = aNameStream.readNulUnicodeArray();
545 10 : Reference< XControlModel > xCtlModel( rxFormComp, UNO_QUERY );
546 5 : if ( !aName.isEmpty() && xCtlModel.is() )
547 : {
548 5 : PropertyMap aPropMap;
549 5 : aPropMap.setProperty( PROP_Name, aName );
550 10 : PropertySet aPropSet( xCtlModel );
551 10 : aPropSet.setProperties( aPropMap );
552 : }
553 10 : return rxFormComp.is();
554 16 : }
555 : }
556 16 : return false;
557 : }
558 :
559 0 : bool MSConvertOCXControls::WriteOCXExcelKludgeStream( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutStrm, const com::sun::star::uno::Reference< com::sun::star::awt::XControlModel > &rxControlModel, const com::sun::star::awt::Size& rSize,OUString &rName )
560 : {
561 0 : OleFormCtrlExportHelper exportHelper( comphelper::getProcessComponentContext(), rxModel, rxControlModel );
562 0 : if ( !exportHelper.isValid() )
563 0 : return false;
564 0 : rName = exportHelper.getTypeName();
565 0 : SvGlobalName aName;
566 0 : OUString sId = exportHelper.getGUID();
567 0 : aName.MakeId(sId);
568 0 : BinaryXOutputStream xOut( xOutStrm, false );
569 0 : OleHelper::exportGuid( xOut, aName );
570 0 : exportHelper.exportControl( xOutStrm, rSize );
571 0 : return true;
572 : }
573 :
574 1 : bool MSConvertOCXControls::WriteOCXStream( const Reference< XModel >& rxModel, tools::SvRef<SotStorage> &xOleStg,
575 : const Reference< XControlModel > &rxControlModel,
576 : const com::sun::star::awt::Size& rSize, OUString &rName)
577 : {
578 1 : SvGlobalName aName;
579 :
580 2 : OleFormCtrlExportHelper exportHelper( comphelper::getProcessComponentContext(), rxModel, rxControlModel );
581 :
582 1 : if ( !exportHelper.isValid() )
583 0 : return false;
584 :
585 2 : OUString sId = exportHelper.getGUID();
586 1 : aName.MakeId(sId);
587 :
588 2 : OUString sFullName = exportHelper.getFullName();
589 1 : rName = exportHelper.getTypeName();
590 1 : xOleStg->SetClass( aName, SotClipboardFormatId::EMBEDDED_OBJ_OLE, sFullName);
591 : {
592 1 : tools::SvRef<SotStorageStream> pNameStream = xOleStg->OpenSotStream(OUString("\3OCXNAME"));
593 2 : Reference< XOutputStream > xOut = new utl::OSeekableOutputStreamWrapper( *pNameStream );
594 2 : exportHelper.exportName( xOut );
595 : }
596 : {
597 1 : tools::SvRef<SotStorageStream> pObjStream = xOleStg->OpenSotStream(OUString("\1CompObj"));
598 2 : Reference< XOutputStream > xOut = new utl::OSeekableOutputStreamWrapper( *pObjStream );
599 2 : exportHelper.exportCompObj( xOut );
600 : }
601 : {
602 1 : tools::SvRef<SotStorageStream> pContents = xOleStg->OpenSotStream(OUString("contents"));
603 2 : Reference< XOutputStream > xOut = new utl::OSeekableOutputStreamWrapper( *pContents );
604 2 : exportHelper.exportControl( xOut, rSize );
605 : }
606 2 : return true;
607 : }
608 :
609 : } // namespace ole
610 246 : } // namespace oox
611 :
612 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|