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