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