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