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