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 "xeescher.hxx"
21 :
22 : #include <com/sun/star/lang/XServiceInfo.hpp>
23 : #include <com/sun/star/frame/XModel.hpp>
24 : #include <com/sun/star/form/FormComponentType.hpp>
25 : #include <com/sun/star/awt/VisualEffect.hpp>
26 : #include <com/sun/star/awt/ScrollBarOrientation.hpp>
27 : #include <com/sun/star/drawing/XShape.hpp>
28 : #include <com/sun/star/form/binding/XBindableValue.hpp>
29 : #include <com/sun/star/form/binding/XValueBinding.hpp>
30 : #include <com/sun/star/form/binding/XListEntrySink.hpp>
31 : #include <com/sun/star/form/binding/XListEntrySource.hpp>
32 : #include <com/sun/star/script/ScriptEventDescriptor.hpp>
33 : #include <com/sun/star/chart2/XChartDocument.hpp>
34 : #include <com/sun/star/awt/Point.hpp>
35 : #include <com/sun/star/awt/Size.hpp>
36 : #include <com/sun/star/container/XNamed.hpp>
37 :
38 : #include <set>
39 : #include <rtl/ustrbuf.h>
40 : #include <vcl/bmpacc.hxx>
41 : #include <svx/svdoole2.hxx>
42 : #include <svx/svdocapt.hxx>
43 : #include <editeng/outlobj.hxx>
44 : #include <editeng/editobj.hxx>
45 : #include <unotools/tempfile.hxx>
46 : #include <unotools/ucbstreamhelper.hxx>
47 : #include <svtools/embedhlp.hxx>
48 :
49 : #include "editutil.hxx"
50 : #include "unonames.hxx"
51 : #include "convuno.hxx"
52 : #include "postit.hxx"
53 :
54 : #include "fapihelper.hxx"
55 : #include "xechart.hxx"
56 : #include "xeformula.hxx"
57 : #include "xelink.hxx"
58 : #include "xename.hxx"
59 : #include "xestyle.hxx"
60 : #include "userdat.hxx"
61 : #include "drwlayer.hxx"
62 : #include <svx/unoapi.hxx>
63 : #include <svx/algitem.hxx>
64 : #include "scitems.hxx"
65 : #include <editeng/justifyitem.hxx>
66 : #include <svx/sdtaitm.hxx>
67 : #include "attrib.hxx"
68 : #include "document.hxx"
69 : #include <svx/svdattr.hxx>
70 : #include <svx/sdr/properties/properties.hxx>
71 : #include "detfunc.hxx"
72 : #include <svx/xflclit.hxx>
73 : #include <svx/xlnstwit.hxx>
74 : #include <svx/xlnstit.hxx>
75 : #include <svx/sxmspitm.hxx>
76 :
77 : #include <oox/token/tokens.hxx>
78 : #include <oox/export/drawingml.hxx>
79 : #include <oox/export/chartexport.hxx>
80 : #include <oox/export/utils.hxx>
81 : #include <memory>
82 :
83 : using namespace com::sun::star;
84 : using ::com::sun::star::uno::UNO_QUERY;
85 : using ::com::sun::star::uno::Reference;
86 : using ::com::sun::star::uno::Sequence;
87 : using ::com::sun::star::lang::XServiceInfo;
88 : using ::com::sun::star::beans::XPropertySet;
89 : using ::com::sun::star::drawing::XShape;
90 : using ::com::sun::star::drawing::XShapes;
91 : using ::com::sun::star::frame::XModel;
92 : using ::com::sun::star::embed::XEmbeddedObject;
93 : using ::com::sun::star::awt::XControlModel;
94 : using ::com::sun::star::form::binding::XBindableValue;
95 : using ::com::sun::star::form::binding::XValueBinding;
96 : using ::com::sun::star::form::binding::XListEntrySink;
97 : using ::com::sun::star::form::binding::XListEntrySource;
98 : using ::com::sun::star::script::ScriptEventDescriptor;
99 : using ::com::sun::star::table::CellAddress;
100 : using ::com::sun::star::table::CellRangeAddress;
101 : using ::com::sun::star::chart2::XChartDocument;
102 : using ::com::sun::star::container::XNamed;
103 : using ::oox::drawingml::DrawingML;
104 : using ::oox::drawingml::ChartExport;
105 : using namespace oox;
106 :
107 : #define HMM2XL(x) ((x)/26.5)+0.5
108 :
109 : #if 1//def XLSX_OOXML_FUTURE
110 : // these function are only used within that context
111 : // Static Function Helpers
112 0 : static const char *ToHorizAlign( SdrTextHorzAdjust eAdjust )
113 : {
114 0 : switch( eAdjust )
115 : {
116 : case SDRTEXTHORZADJUST_CENTER:
117 0 : return "center";
118 : case SDRTEXTHORZADJUST_RIGHT:
119 0 : return "right";
120 : case SDRTEXTHORZADJUST_BLOCK:
121 0 : return "justify";
122 : case SDRTEXTHORZADJUST_LEFT:
123 : default:
124 0 : return "left";
125 : }
126 : }
127 :
128 0 : static const char *ToVertAlign( SdrTextVertAdjust eAdjust )
129 : {
130 0 : switch( eAdjust )
131 : {
132 : case SDRTEXTVERTADJUST_CENTER:
133 0 : return "center";
134 : case SDRTEXTVERTADJUST_BOTTOM:
135 0 : return "bottom";
136 : case SDRTEXTVERTADJUST_BLOCK:
137 0 : return "justify";
138 : case SDRTEXTVERTADJUST_TOP:
139 : default:
140 0 : return "top";
141 : }
142 : }
143 :
144 0 : static void lcl_WriteAnchorVertex( sax_fastparser::FSHelperPtr rComments, Rectangle &aRect )
145 : {
146 0 : rComments->startElement( FSNS( XML_xdr, XML_col ), FSEND );
147 0 : rComments->writeEscaped( OUString::number( aRect.Left() ) );
148 0 : rComments->endElement( FSNS( XML_xdr, XML_col ) );
149 0 : rComments->startElement( FSNS( XML_xdr, XML_colOff ), FSEND );
150 0 : rComments->writeEscaped( OUString::number( aRect.Top() ) );
151 0 : rComments->endElement( FSNS( XML_xdr, XML_colOff ) );
152 0 : rComments->startElement( FSNS( XML_xdr, XML_row ), FSEND );
153 0 : rComments->writeEscaped( OUString::number( aRect.Right() ) );
154 0 : rComments->endElement( FSNS( XML_xdr, XML_row ) );
155 0 : rComments->startElement( FSNS( XML_xdr, XML_rowOff ), FSEND );
156 0 : rComments->writeEscaped( OUString::number( aRect.Bottom() ) );
157 0 : rComments->endElement( FSNS( XML_xdr, XML_rowOff ) );
158 0 : }
159 : #endif
160 :
161 3 : static void lcl_GetFromTo( const XclExpRoot& rRoot, const Rectangle &aRect, sal_Int32 nTab, Rectangle &aFrom, Rectangle &aTo )
162 : {
163 3 : bool bTo = false;
164 3 : sal_Int32 nCol = 0, nRow = 0;
165 3 : sal_Int32 nColOff = 0, nRowOff= 0;
166 :
167 : while(true)
168 : {
169 9 : Rectangle r = rRoot.GetDocPtr()->GetMMRect( nCol,nRow,nCol,nRow,nTab );
170 9 : if( !bTo )
171 : {
172 9 : if( r.Left() <= aRect.Left() )
173 : {
174 6 : nCol++;
175 6 : nColOff = aRect.Left() - r.Left();
176 : }
177 9 : if( r.Top() <= aRect.Top() )
178 : {
179 3 : nRow++;
180 3 : nRowOff = aRect.Top() - r.Top();
181 : }
182 9 : if( r.Left() > aRect.Left() && r.Top() > aRect.Top() )
183 : {
184 6 : aFrom = Rectangle( nCol-1, static_cast<long>(HMM2XL( nColOff )),
185 9 : nRow-1, static_cast<long>(HMM2XL( nRowOff )) );
186 3 : bTo=true;
187 : }
188 : }
189 9 : if( bTo )
190 : {
191 3 : if( r.Right() < aRect.Right() )
192 0 : nCol++;
193 3 : if( r.Bottom() < aRect.Bottom() )
194 0 : nRow++;
195 3 : if( r.Right() >= aRect.Right() && r.Bottom() >= aRect.Bottom() )
196 : {
197 3 : aTo = Rectangle( nCol, static_cast<long>(HMM2XL( aRect.Right() - r.Left() )),
198 6 : nRow, static_cast<long>(HMM2XL( aRect.Bottom() - r.Top() )));
199 3 : break;
200 : }
201 : }
202 : }
203 3 : return;
204 : }
205 :
206 : // Escher client anchor =======================================================
207 :
208 58 : XclExpDffAnchorBase::XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags ) :
209 : XclExpRoot( rRoot ),
210 58 : mnFlags( nFlags )
211 : {
212 58 : }
213 :
214 29 : void XclExpDffAnchorBase::SetFlags( const SdrObject& rSdrObj )
215 : {
216 29 : ImplSetFlags( rSdrObj );
217 29 : }
218 :
219 26 : void XclExpDffAnchorBase::SetSdrObject( const SdrObject& rSdrObj )
220 : {
221 26 : ImplSetFlags( rSdrObj );
222 26 : ImplCalcAnchorRect( rSdrObj.GetCurrentBoundRect(), MAP_100TH_MM );
223 26 : }
224 :
225 58 : void XclExpDffAnchorBase::WriteDffData( EscherEx& rEscherEx ) const
226 : {
227 58 : rEscherEx.AddAtom( 18, ESCHER_ClientAnchor );
228 58 : rEscherEx.GetStream().WriteUInt16( mnFlags );
229 58 : WriteXclObjAnchor( rEscherEx.GetStream(), maAnchor );
230 58 : }
231 :
232 29 : void XclExpDffAnchorBase::WriteData( EscherEx& rEscherEx, const Rectangle& rRect )
233 : {
234 : // the passed rectangle is in twips
235 29 : ImplCalcAnchorRect( rRect, MAP_TWIP );
236 29 : WriteDffData( rEscherEx );
237 29 : }
238 :
239 0 : void XclExpDffAnchorBase::ImplSetFlags( const SdrObject& )
240 : {
241 : OSL_FAIL( "XclExpDffAnchorBase::ImplSetFlags - not implemented" );
242 0 : }
243 :
244 0 : void XclExpDffAnchorBase::ImplCalcAnchorRect( const Rectangle&, MapUnit )
245 : {
246 : OSL_FAIL( "XclExpDffAnchorBase::ImplCalcAnchorRect - not implemented" );
247 0 : }
248 :
249 55 : XclExpDffSheetAnchor::XclExpDffSheetAnchor( const XclExpRoot& rRoot ) :
250 : XclExpDffAnchorBase( rRoot ),
251 55 : mnScTab( rRoot.GetCurrScTab() )
252 : {
253 55 : }
254 :
255 55 : void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject& rSdrObj )
256 : {
257 : // set flags for cell/page anchoring
258 55 : if ( ScDrawLayer::GetAnchorType( rSdrObj ) == SCA_CELL )
259 34 : mnFlags = 0;
260 : else
261 21 : mnFlags = EXC_ESC_ANCHOR_LOCKED;
262 55 : }
263 :
264 55 : void XclExpDffSheetAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit )
265 : {
266 55 : maAnchor.SetRect( GetRoot(), mnScTab, rRect, eMapUnit );
267 55 : }
268 :
269 0 : XclExpDffEmbeddedAnchor::XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot,
270 : const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) :
271 : XclExpDffAnchorBase( rRoot ),
272 : maPageSize( rPageSize ),
273 : mnScaleX( nScaleX ),
274 0 : mnScaleY( nScaleY )
275 : {
276 0 : }
277 :
278 0 : void XclExpDffEmbeddedAnchor::ImplSetFlags( const SdrObject& /*rSdrObj*/ )
279 : {
280 : // TODO (unsupported feature): fixed size
281 0 : }
282 :
283 0 : void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit )
284 : {
285 0 : maAnchor.SetRect( maPageSize, mnScaleX, mnScaleY, rRect, eMapUnit, true );
286 0 : }
287 :
288 3 : XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ) :
289 3 : XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_SIZELOCKED )
290 : {
291 3 : maAnchor.SetRect( rRoot, rRoot.GetCurrScTab(), rRect, MAP_100TH_MM );
292 3 : }
293 :
294 0 : XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ) :
295 0 : XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_POSLOCKED )
296 : {
297 0 : GetAddressConverter().ConvertAddress( maAnchor.maFirst, rScPos, true );
298 0 : maAnchor.maLast.mnCol = maAnchor.maFirst.mnCol + 1;
299 0 : maAnchor.maLast.mnRow = maAnchor.maFirst.mnRow + 1;
300 0 : maAnchor.mnLX = maAnchor.mnTY = maAnchor.mnRX = maAnchor.mnBY = 0;
301 0 : }
302 :
303 : // MSODRAWING* records ========================================================
304 :
305 219 : XclExpMsoDrawingBase::XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId ) :
306 : XclExpRecord( nRecId ),
307 : mrEscherEx( rEscherEx ),
308 219 : mnFragmentKey( rEscherEx.InitNextDffFragment() )
309 : {
310 219 : }
311 :
312 51 : void XclExpMsoDrawingBase::WriteBody( XclExpStream& rStrm )
313 : {
314 : OSL_ENSURE( mrEscherEx.GetStreamPos() == mrEscherEx.GetDffFragmentPos( mnFragmentKey ),
315 : "XclExpMsoDrawingBase::WriteBody - DFF stream position mismatch" );
316 51 : rStrm.CopyFromStream( mrEscherEx.GetStream(), mrEscherEx.GetDffFragmentSize( mnFragmentKey ) );
317 51 : }
318 :
319 72 : XclExpMsoDrawingGroup::XclExpMsoDrawingGroup( XclEscherEx& rEscherEx ) :
320 72 : XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWINGGROUP )
321 : {
322 72 : SvStream& rDffStrm = mrEscherEx.GetStream();
323 :
324 : // write the DGGCONTAINER with some default settings
325 72 : mrEscherEx.OpenContainer( ESCHER_DggContainer );
326 :
327 : // TODO: stuff the OPT atom with our own document defaults?
328 : static const sal_uInt8 spnDffOpt[] = {
329 : 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01,
330 : 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00,
331 : 0x00, 0x08
332 : };
333 72 : mrEscherEx.AddAtom( sizeof( spnDffOpt ), ESCHER_OPT, 3, 3 );
334 72 : rDffStrm.Write( spnDffOpt, sizeof( spnDffOpt ) );
335 :
336 : // SPLITMENUCOLORS contains colors in toolbar
337 : static const sal_uInt8 spnDffSplitMenuColors[] = {
338 : 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08,
339 : 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10
340 : };
341 72 : mrEscherEx.AddAtom( sizeof( spnDffSplitMenuColors ), ESCHER_SplitMenuColors, 0, 4 );
342 72 : rDffStrm.Write( spnDffSplitMenuColors, sizeof( spnDffSplitMenuColors ) );
343 :
344 : // close the DGGCONTAINER
345 72 : mrEscherEx.CloseContainer();
346 72 : mrEscherEx.UpdateDffFragmentEnd();
347 72 : }
348 :
349 147 : XclExpMsoDrawing::XclExpMsoDrawing( XclEscherEx& rEscherEx ) :
350 147 : XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWING )
351 : {
352 147 : }
353 :
354 0 : XclExpImgData::XclExpImgData( const Graphic& rGraphic, sal_uInt16 nRecId ) :
355 : maGraphic( rGraphic ),
356 0 : mnRecId( nRecId )
357 : {
358 0 : }
359 :
360 0 : void XclExpImgData::Save( XclExpStream& rStrm )
361 : {
362 0 : Bitmap aBmp = maGraphic.GetBitmap();
363 0 : if( aBmp.GetBitCount() != 24 )
364 0 : aBmp.Convert( BMP_CONVERSION_24BIT );
365 :
366 0 : if( BitmapReadAccess* pAccess = aBmp.AcquireReadAccess() )
367 : {
368 0 : sal_Int32 nWidth = ::std::min< sal_Int32 >( pAccess->Width(), 0xFFFF );
369 0 : sal_Int32 nHeight = ::std::min< sal_Int32 >( pAccess->Height(), 0xFFFF );
370 0 : if( (nWidth > 0) && (nHeight > 0) )
371 : {
372 0 : sal_uInt8 nPadding = static_cast< sal_uInt8 >( nWidth & 0x03 );
373 0 : sal_uInt32 nTmpSize = static_cast< sal_uInt32 >( (nWidth * 3 + nPadding) * nHeight + 12 );
374 :
375 0 : rStrm.StartRecord( mnRecId, nTmpSize + 4 );
376 :
377 0 : rStrm << EXC_IMGDATA_BMP // BMP format
378 0 : << EXC_IMGDATA_WIN // Windows
379 0 : << nTmpSize // size after _this_ field
380 0 : << sal_uInt32( 12 ) // BITMAPCOREHEADER size
381 0 : << static_cast< sal_uInt16 >( nWidth ) // width
382 0 : << static_cast< sal_uInt16 >( nHeight ) // height
383 0 : << sal_uInt16( 1 ) // planes
384 0 : << sal_uInt16( 24 ); // bits per pixel
385 :
386 0 : for( sal_Int32 nY = nHeight - 1; nY >= 0; --nY )
387 : {
388 0 : for( sal_Int32 nX = 0; nX < nWidth; ++nX )
389 : {
390 0 : const BitmapColor& rBmpColor = pAccess->GetPixel( nY, nX );
391 0 : rStrm << rBmpColor.GetBlue() << rBmpColor.GetGreen() << rBmpColor.GetRed();
392 0 : }
393 0 : rStrm.WriteZeroBytes( nPadding );
394 : }
395 :
396 0 : rStrm.EndRecord();
397 : }
398 0 : Bitmap::ReleaseAccess( pAccess );
399 0 : }
400 0 : }
401 :
402 0 : void XclExpImgData::SaveXml( XclExpXmlStream& rStrm )
403 : {
404 0 : sax_fastparser::FSHelperPtr pWorksheet = rStrm.GetCurrentStream();
405 :
406 0 : DrawingML aDML( pWorksheet, &rStrm, DrawingML::DOCUMENT_XLSX );
407 0 : OUString rId = aDML.WriteImage( maGraphic );
408 : pWorksheet->singleElement( XML_picture,
409 : FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( rId ).getStr(),
410 0 : FSEND );
411 0 : }
412 :
413 29 : XclExpControlHelper::XclExpControlHelper( const XclExpRoot& rRoot ) :
414 : XclExpRoot( rRoot ),
415 29 : mnEntryCount( 0 )
416 : {
417 29 : }
418 :
419 29 : XclExpControlHelper::~XclExpControlHelper()
420 : {
421 29 : }
422 :
423 0 : void XclExpControlHelper::ConvertSheetLinks( Reference< XShape > xShape )
424 : {
425 0 : mxCellLink.reset();
426 0 : mxSrcRange.reset();
427 0 : mnEntryCount = 0;
428 :
429 : // get control model
430 0 : Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( xShape );
431 0 : if( !xCtrlModel.is() )
432 0 : return;
433 :
434 : // *** cell link *** ------------------------------------------------------
435 :
436 0 : Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY );
437 0 : if( xBindable.is() )
438 : {
439 0 : Reference< XServiceInfo > xServInfo( xBindable->getValueBinding(), UNO_QUERY );
440 0 : if( xServInfo.is() && xServInfo->supportsService( SC_SERVICENAME_VALBIND ) )
441 : {
442 0 : ScfPropertySet aBindProp( xServInfo );
443 0 : CellAddress aApiAddress;
444 0 : if( aBindProp.GetProperty( aApiAddress, SC_UNONAME_BOUNDCELL ) )
445 : {
446 0 : ScAddress aCellLink;
447 0 : ScUnoConversion::FillScAddress( aCellLink, aApiAddress );
448 0 : if( GetTabInfo().IsExportTab( aCellLink.Tab() ) )
449 0 : mxCellLink = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL, aCellLink );
450 0 : }
451 0 : }
452 : }
453 :
454 : // *** source range *** ---------------------------------------------------
455 :
456 0 : Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY );
457 0 : if( xEntrySink.is() )
458 : {
459 0 : Reference< XServiceInfo > xServInfo( xEntrySink->getListEntrySource(), UNO_QUERY );
460 0 : if( xServInfo.is() && xServInfo->supportsService( SC_SERVICENAME_LISTSOURCE ) )
461 : {
462 0 : ScfPropertySet aSinkProp( xServInfo );
463 0 : CellRangeAddress aApiRange;
464 0 : if( aSinkProp.GetProperty( aApiRange, SC_UNONAME_CELLRANGE ) )
465 : {
466 0 : ScRange aSrcRange;
467 0 : ScUnoConversion::FillScRange( aSrcRange, aApiRange );
468 0 : if( (aSrcRange.aStart.Tab() == aSrcRange.aEnd.Tab()) && GetTabInfo().IsExportTab( aSrcRange.aStart.Tab() ) )
469 0 : mxSrcRange = GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL, aSrcRange );
470 0 : mnEntryCount = static_cast< sal_uInt16 >( aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1 );
471 0 : }
472 0 : }
473 0 : }
474 : }
475 :
476 0 : void XclExpControlHelper::WriteFormula( XclExpStream& rStrm, const XclTokenArray& rTokArr )
477 : {
478 0 : sal_uInt16 nFmlaSize = rTokArr.GetSize();
479 0 : rStrm << nFmlaSize << sal_uInt32( 0 );
480 0 : rTokArr.WriteArray( rStrm );
481 0 : if( nFmlaSize & 1 ) // pad to 16-bit
482 0 : rStrm << sal_uInt8( 0 );
483 0 : }
484 :
485 0 : void XclExpControlHelper::WriteFormulaSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId, const XclTokenArray& rTokArr )
486 : {
487 0 : rStrm.StartRecord( nSubRecId, (rTokArr.GetSize() + 5) & ~1 );
488 0 : WriteFormula( rStrm, rTokArr );
489 0 : rStrm.EndRecord();
490 0 : }
491 :
492 : //delete for exporting OCX
493 : //#if EXC_EXP_OCX_CTRL
494 :
495 0 : XclExpOcxControlObj::XclExpOcxControlObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape,
496 : const Rectangle* pChildAnchor, const OUString& rClassName, sal_uInt32 nStrmStart, sal_uInt32 nStrmSize ) :
497 : XclObj( rObjMgr, EXC_OBJTYPE_PICTURE, true ),
498 0 : XclExpControlHelper( rObjMgr.GetRoot() ),
499 : maClassName( rClassName ),
500 : mnStrmStart( nStrmStart ),
501 0 : mnStrmSize( nStrmSize )
502 : {
503 0 : ScfPropertySet aCtrlProp( XclControlHelper::GetControlModel( xShape ) );
504 :
505 : // OBJ record flags
506 0 : SetLocked( true );
507 0 : SetPrintable( aCtrlProp.GetBoolProperty( "Printable" ) );
508 0 : SetAutoFill( false );
509 0 : SetAutoLine( false );
510 :
511 : // fill DFF property set
512 0 : mrEscherEx.OpenContainer( ESCHER_SpContainer );
513 0 : mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE );
514 0 : Rectangle aDummyRect;
515 0 : EscherPropertyContainer aPropOpt( mrEscherEx.GetGraphicProvider(), mrEscherEx.QueryPictureStream(), aDummyRect );
516 0 : aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
517 0 : aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x08000040 );
518 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
519 :
520 : // #i51348# name of the control, may overwrite shape name
521 0 : OUString aCtrlName;
522 0 : if( aCtrlProp.GetProperty( aCtrlName, "Name" ) && !aCtrlName.isEmpty() )
523 0 : aPropOpt.AddOpt( ESCHER_Prop_wzName, aCtrlName );
524 :
525 : // meta file
526 : //TODO - needs check
527 0 : Reference< XPropertySet > xShapePS( xShape, UNO_QUERY );
528 0 : if( xShapePS.is() && aPropOpt.CreateGraphicProperties( xShapePS, OUString( "MetaFile" ), false ) )
529 : {
530 : sal_uInt32 nBlipId;
531 0 : if( aPropOpt.GetOpt( ESCHER_Prop_pib, nBlipId ) )
532 0 : aPropOpt.AddOpt( ESCHER_Prop_pictureId, nBlipId );
533 : }
534 :
535 : // write DFF property set to stream
536 0 : aPropOpt.Commit( mrEscherEx.GetStream() );
537 :
538 : // anchor
539 0 : ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor );
540 :
541 0 : mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
542 0 : mrEscherEx.CloseContainer(); // ESCHER_SpContainer
543 0 : mrEscherEx.UpdateDffFragmentEnd();
544 :
545 : // spreadsheet links
546 0 : ConvertSheetLinks( xShape );
547 0 : }
548 :
549 0 : void XclExpOcxControlObj::WriteSubRecs( XclExpStream& rStrm )
550 : {
551 : // OBJCF - clipboard format
552 0 : rStrm.StartRecord( EXC_ID_OBJCF, 2 );
553 0 : rStrm << sal_uInt16( 2 );
554 0 : rStrm.EndRecord();
555 :
556 : // OBJFLAGS
557 0 : rStrm.StartRecord( EXC_ID_OBJFLAGS, 2 );
558 0 : rStrm << sal_uInt16( 0x0031 );
559 0 : rStrm.EndRecord();
560 :
561 : // OBJPICTFMLA
562 0 : XclExpString aClass( maClassName );
563 0 : sal_uInt16 nClassNameSize = static_cast< sal_uInt16 >( aClass.GetSize() );
564 0 : sal_uInt16 nClassNamePad = nClassNameSize & 1;
565 0 : sal_uInt16 nFirstPartSize = 12 + nClassNameSize + nClassNamePad;
566 :
567 0 : const XclTokenArray* pCellLink = GetCellLinkTokArr();
568 0 : sal_uInt16 nCellLinkSize = pCellLink ? ((pCellLink->GetSize() + 7) & 0xFFFE) : 0;
569 :
570 0 : const XclTokenArray* pSrcRange = GetSourceRangeTokArr();
571 0 : sal_uInt16 nSrcRangeSize = pSrcRange ? ((pSrcRange->GetSize() + 7) & 0xFFFE) : 0;
572 :
573 0 : sal_uInt16 nPictFmlaSize = nFirstPartSize + nCellLinkSize + nSrcRangeSize + 18;
574 0 : rStrm.StartRecord( EXC_ID_OBJPICTFMLA, nPictFmlaSize );
575 :
576 0 : rStrm << sal_uInt16( nFirstPartSize ) // size of first part
577 0 : << sal_uInt16( 5 ) // formula size
578 0 : << sal_uInt32( 0 ) // unknown ID
579 0 : << sal_uInt8( 0x02 ) << sal_uInt32( 0 ) // tTbl token with unknown ID
580 0 : << sal_uInt8( 3 ) // pad to word
581 0 : << aClass; // "Forms.***.1"
582 0 : rStrm.WriteZeroBytes( nClassNamePad ); // pad to word
583 0 : rStrm << mnStrmStart // start in 'Ctls' stream
584 0 : << mnStrmSize // size in 'Ctls' stream
585 0 : << sal_uInt32( 0 ); // class ID size
586 : // cell link
587 0 : rStrm << nCellLinkSize;
588 0 : if( pCellLink )
589 0 : WriteFormula( rStrm, *pCellLink );
590 : // list source range
591 0 : rStrm << nSrcRangeSize;
592 0 : if( pSrcRange )
593 0 : WriteFormula( rStrm, *pSrcRange );
594 :
595 0 : rStrm.EndRecord();
596 0 : }
597 :
598 : //#else
599 :
600 0 : XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager& rRoot, Reference< XShape > xShape , const Rectangle* pChildAnchor ) :
601 : XclObj( rRoot, EXC_OBJTYPE_UNKNOWN, true ),
602 : XclMacroHelper( rRoot ),
603 : meEventType( EXC_TBX_EVENT_ACTION ),
604 : mnHeight( 0 ),
605 : mnState( 0 ),
606 : mnLineCount( 0 ),
607 : mnSelEntry( 0 ),
608 : mnScrollValue( 0 ),
609 : mnScrollMin( 0 ),
610 : mnScrollMax( 100 ),
611 : mnScrollStep( 1 ),
612 : mnScrollPage( 10 ),
613 : mbFlatButton( false ),
614 : mbFlatBorder( false ),
615 : mbMultiSel( false ),
616 0 : mbScrollHor( false )
617 : {
618 : namespace FormCompType = ::com::sun::star::form::FormComponentType;
619 : namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
620 : namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
621 :
622 0 : ScfPropertySet aCtrlProp( XclControlHelper::GetControlModel( xShape ) );
623 0 : if( !xShape.is() || !aCtrlProp.Is() )
624 0 : return;
625 :
626 0 : mnHeight = xShape->getSize().Height;
627 0 : if( mnHeight <= 0 )
628 0 : return;
629 :
630 : // control type
631 0 : sal_Int16 nClassId = 0;
632 0 : if( aCtrlProp.GetProperty( nClassId, "ClassId" ) )
633 : {
634 0 : switch( nClassId )
635 : {
636 0 : case FormCompType::COMMANDBUTTON: mnObjType = EXC_OBJTYPE_BUTTON; meEventType = EXC_TBX_EVENT_ACTION; break;
637 0 : case FormCompType::RADIOBUTTON: mnObjType = EXC_OBJTYPE_OPTIONBUTTON; meEventType = EXC_TBX_EVENT_ACTION; break;
638 0 : case FormCompType::CHECKBOX: mnObjType = EXC_OBJTYPE_CHECKBOX; meEventType = EXC_TBX_EVENT_ACTION; break;
639 0 : case FormCompType::LISTBOX: mnObjType = EXC_OBJTYPE_LISTBOX; meEventType = EXC_TBX_EVENT_CHANGE; break;
640 0 : case FormCompType::COMBOBOX: mnObjType = EXC_OBJTYPE_DROPDOWN; meEventType = EXC_TBX_EVENT_CHANGE; break;
641 0 : case FormCompType::GROUPBOX: mnObjType = EXC_OBJTYPE_GROUPBOX; meEventType = EXC_TBX_EVENT_MOUSE; break;
642 0 : case FormCompType::FIXEDTEXT: mnObjType = EXC_OBJTYPE_LABEL; meEventType = EXC_TBX_EVENT_MOUSE; break;
643 0 : case FormCompType::SCROLLBAR: mnObjType = EXC_OBJTYPE_SCROLLBAR; meEventType = EXC_TBX_EVENT_VALUE; break;
644 0 : case FormCompType::SPINBUTTON: mnObjType = EXC_OBJTYPE_SPIN; meEventType = EXC_TBX_EVENT_VALUE; break;
645 : }
646 : }
647 0 : if( mnObjType == EXC_OBJTYPE_UNKNOWN )
648 0 : return;
649 :
650 : // OBJ record flags
651 0 : SetLocked( true );
652 0 : SetPrintable( aCtrlProp.GetBoolProperty( "Printable" ) );
653 0 : SetAutoFill( false );
654 0 : SetAutoLine( false );
655 :
656 : // fill DFF property set
657 0 : mrEscherEx.OpenContainer( ESCHER_SpContainer );
658 0 : mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
659 0 : EscherPropertyContainer aPropOpt;
660 0 : bool bVisible = aCtrlProp.GetBoolProperty( "EnableVisible" );
661 0 : aPropOpt.AddOpt( ESCHER_Prop_fPrint, bVisible ? 0x00080000 : 0x00080002 ); // visible flag
662 :
663 0 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01000100 ); // bool field
664 0 : aPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 ); // Text ID
665 0 : aPropOpt.AddOpt( ESCHER_Prop_WrapText, 0x00000001 );
666 0 : aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x001A0008 ); // bool field
667 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00100000 ); // bool field
668 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
669 :
670 : // #i51348# name of the control, may overwrite shape name
671 0 : OUString aCtrlName;
672 0 : if( aCtrlProp.GetProperty( aCtrlName, "Name" ) && !aCtrlName.isEmpty() )
673 0 : aPropOpt.AddOpt( ESCHER_Prop_wzName, aCtrlName );
674 :
675 : //Export description as alt text
676 0 : if( SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape ) )
677 : {
678 0 : OUString aAltTxt;
679 0 : OUString aDescrText = pSdrObj->GetDescription();
680 0 : if(!aDescrText.isEmpty())
681 0 : aAltTxt = aDescrText.copy( 0, std::min<sal_Int32>(MSPROP_DESCRIPTION_MAX_LEN, aDescrText.getLength()) );
682 0 : aPropOpt.AddOpt( ESCHER_Prop_wzDescription, aAltTxt );
683 : }
684 :
685 : // write DFF property set to stream
686 0 : aPropOpt.Commit( mrEscherEx.GetStream() );
687 :
688 : // anchor
689 0 : ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor );
690 :
691 0 : mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
692 0 : mrEscherEx.UpdateDffFragmentEnd();
693 :
694 : // control label
695 0 : OUString aString;
696 0 : if( aCtrlProp.GetProperty( aString, "Label" ) )
697 : {
698 : /* Be sure to construct the MSODRAWING record containing the
699 : ClientTextbox atom after the base OBJ's MSODRAWING record data is
700 : completed. */
701 0 : pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
702 0 : mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
703 0 : mrEscherEx.UpdateDffFragmentEnd();
704 :
705 0 : sal_uInt16 nXclFont = EXC_FONT_APP;
706 0 : if( !aString.isEmpty() )
707 : {
708 0 : XclFontData aFontData;
709 0 : GetFontPropSetHelper().ReadFontProperties( aFontData, aCtrlProp, EXC_FONTPROPSET_CONTROL );
710 0 : if( (!aFontData.maName.isEmpty() ) && (aFontData.mnHeight > 0) )
711 0 : nXclFont = GetFontBuffer().Insert( aFontData, EXC_COLOR_CTRLTEXT );
712 : }
713 :
714 0 : pTxo = new XclTxo( aString, nXclFont );
715 0 : pTxo->SetHorAlign( (mnObjType == EXC_OBJTYPE_BUTTON) ? EXC_OBJ_HOR_CENTER : EXC_OBJ_HOR_LEFT );
716 0 : pTxo->SetVerAlign( EXC_OBJ_VER_CENTER );
717 : }
718 :
719 0 : mrEscherEx.CloseContainer(); // ESCHER_SpContainer
720 :
721 : // other properties
722 0 : aCtrlProp.GetProperty( mnLineCount, "LineCount" );
723 :
724 : // border style
725 0 : sal_Int16 nApiButton = AwtVisualEffect::LOOK3D;
726 0 : sal_Int16 nApiBorder = AwtVisualEffect::LOOK3D;
727 0 : switch( nClassId )
728 : {
729 : case FormCompType::LISTBOX:
730 : case FormCompType::COMBOBOX:
731 0 : aCtrlProp.GetProperty( nApiBorder, "Border" );
732 0 : break;
733 : case FormCompType::CHECKBOX:
734 : case FormCompType::RADIOBUTTON:
735 0 : aCtrlProp.GetProperty( nApiButton, "VisualEffect" );
736 0 : nApiBorder = AwtVisualEffect::NONE;
737 0 : break;
738 : // Push button cannot be set to flat in Excel
739 : case FormCompType::COMMANDBUTTON:
740 0 : nApiBorder = AwtVisualEffect::LOOK3D;
741 0 : break;
742 : // Label does not support a border in Excel
743 : case FormCompType::FIXEDTEXT:
744 0 : nApiBorder = AwtVisualEffect::NONE;
745 0 : break;
746 : /* Scroll bar and spin button have a "Border" property, but it is
747 : really used for a border, and not for own 3D/flat look (#i34712#). */
748 : case FormCompType::SCROLLBAR:
749 : case FormCompType::SPINBUTTON:
750 0 : nApiButton = AwtVisualEffect::LOOK3D;
751 0 : nApiBorder = AwtVisualEffect::NONE;
752 0 : break;
753 : // Group box does not support flat style (#i34712#)
754 : case FormCompType::GROUPBOX:
755 0 : nApiBorder = AwtVisualEffect::LOOK3D;
756 0 : break;
757 : }
758 0 : mbFlatButton = nApiButton != AwtVisualEffect::LOOK3D;
759 0 : mbFlatBorder = nApiBorder != AwtVisualEffect::LOOK3D;
760 :
761 : // control state
762 0 : sal_Int16 nApiState = 0;
763 0 : if( aCtrlProp.GetProperty( nApiState, "State" ) )
764 : {
765 0 : switch( nApiState )
766 : {
767 0 : case 0: mnState = EXC_OBJ_CHECKBOX_UNCHECKED; break;
768 0 : case 1: mnState = EXC_OBJ_CHECKBOX_CHECKED; break;
769 0 : case 2: mnState = EXC_OBJ_CHECKBOX_TRISTATE; break;
770 : }
771 : }
772 :
773 : // special control contents
774 0 : switch( nClassId )
775 : {
776 : case FormCompType::LISTBOX:
777 : {
778 0 : mbMultiSel = aCtrlProp.GetBoolProperty( "MultiSelection" );
779 0 : Sequence< sal_Int16 > aSelection;
780 0 : if( aCtrlProp.GetProperty( aSelection, "SelectedItems" ) )
781 : {
782 0 : sal_Int32 nLen = aSelection.getLength();
783 0 : if( nLen > 0 )
784 : {
785 0 : mnSelEntry = aSelection[ 0 ] + 1;
786 0 : maMultiSel.resize( nLen );
787 0 : const sal_Int16* pnBegin = aSelection.getConstArray();
788 0 : ::std::copy( pnBegin, pnBegin + nLen, maMultiSel.begin() );
789 : }
790 : }
791 :
792 : // convert listbox with dropdown button to Excel dropdown
793 0 : if( aCtrlProp.GetBoolProperty( "Dropdown" ) )
794 0 : mnObjType = EXC_OBJTYPE_DROPDOWN;
795 : }
796 0 : break;
797 :
798 : case FormCompType::COMBOBOX:
799 : {
800 0 : Sequence< OUString > aStringList;
801 0 : OUString aDefText;
802 0 : if( aCtrlProp.GetProperty( aStringList, "StringItemList" ) &&
803 0 : aCtrlProp.GetProperty( aDefText, "Text" ) &&
804 0 : aStringList.getLength() && !aDefText.isEmpty() )
805 : {
806 0 : const OUString* pBegin = aStringList.getConstArray();
807 0 : const OUString* pEnd = pBegin + aStringList.getLength();
808 0 : const OUString* pString = ::std::find( pBegin, pEnd, aDefText );
809 0 : if( pString != pEnd )
810 0 : mnSelEntry = static_cast< sal_Int16 >( pString - pBegin + 1 ); // 1-based
811 0 : if( mnSelEntry > 0 )
812 0 : maMultiSel.resize( 1, mnSelEntry - 1 );
813 : }
814 :
815 : // convert combobox without dropdown button to Excel listbox
816 0 : if( !aCtrlProp.GetBoolProperty( "Dropdown" ) )
817 0 : mnObjType = EXC_OBJTYPE_LISTBOX;
818 : }
819 0 : break;
820 :
821 : case FormCompType::SCROLLBAR:
822 : {
823 0 : sal_Int32 nApiValue = 0;
824 0 : if( aCtrlProp.GetProperty( nApiValue, "ScrollValueMin" ) )
825 0 : mnScrollMin = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
826 0 : if( aCtrlProp.GetProperty( nApiValue, "ScrollValueMax" ) )
827 0 : mnScrollMax = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, EXC_OBJ_SCROLLBAR_MIN );
828 0 : if( aCtrlProp.GetProperty( nApiValue, "ScrollValue" ) )
829 0 : mnScrollValue = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, mnScrollMax );
830 0 : if( aCtrlProp.GetProperty( nApiValue, "LineIncrement" ) )
831 0 : mnScrollStep = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
832 0 : if( aCtrlProp.GetProperty( nApiValue, "BlockIncrement" ) )
833 0 : mnScrollPage = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
834 0 : if( aCtrlProp.GetProperty( nApiValue, "Orientation" ) )
835 0 : mbScrollHor = nApiValue == AwtScrollOrient::HORIZONTAL;
836 : }
837 0 : break;
838 :
839 : case FormCompType::SPINBUTTON:
840 : {
841 0 : sal_Int32 nApiValue = 0;
842 0 : if( aCtrlProp.GetProperty( nApiValue, "SpinValueMin" ) )
843 0 : mnScrollMin = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
844 0 : if( aCtrlProp.GetProperty( nApiValue, "SpinValueMax" ) )
845 0 : mnScrollMax = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, EXC_OBJ_SCROLLBAR_MAX );
846 0 : if( aCtrlProp.GetProperty( nApiValue, "SpinValue" ) )
847 0 : mnScrollValue = limit_cast< sal_uInt16 >( nApiValue, mnScrollMin, mnScrollMax );
848 0 : if( aCtrlProp.GetProperty( nApiValue, "SpinIncrement" ) )
849 0 : mnScrollStep = limit_cast< sal_uInt16 >( nApiValue, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
850 0 : if( aCtrlProp.GetProperty( nApiValue, "Orientation" ) )
851 0 : mbScrollHor = nApiValue == AwtScrollOrient::HORIZONTAL;
852 : }
853 0 : break;
854 : }
855 :
856 : // spreadsheet links
857 0 : ConvertSheetLinks( xShape );
858 : }
859 :
860 0 : bool XclExpTbxControlObj::SetMacroLink( const ScriptEventDescriptor& rEvent )
861 : {
862 0 : return XclMacroHelper::SetMacroLink( rEvent, meEventType );
863 : }
864 :
865 0 : void XclExpTbxControlObj::WriteSubRecs( XclExpStream& rStrm )
866 : {
867 0 : switch( mnObjType )
868 : {
869 : // *** Push buttons, labels ***
870 :
871 : case EXC_OBJTYPE_BUTTON:
872 : case EXC_OBJTYPE_LABEL:
873 : // ftMacro - macro link
874 0 : WriteMacroSubRec( rStrm );
875 0 : break;
876 :
877 : // *** Check boxes, option buttons ***
878 :
879 : case EXC_OBJTYPE_CHECKBOX:
880 : case EXC_OBJTYPE_OPTIONBUTTON:
881 : {
882 : // ftCbls - box properties
883 0 : sal_uInt16 nStyle = 0;
884 0 : ::set_flag( nStyle, EXC_OBJ_CHECKBOX_FLAT, mbFlatButton );
885 :
886 0 : rStrm.StartRecord( EXC_ID_OBJCBLS, 12 );
887 0 : rStrm << mnState;
888 0 : rStrm.WriteZeroBytes( 8 );
889 0 : rStrm << nStyle;
890 0 : rStrm.EndRecord();
891 :
892 : // ftMacro - macro link
893 0 : WriteMacroSubRec( rStrm );
894 : // ftCblsFmla subrecord - cell link
895 0 : WriteCellLinkSubRec( rStrm, EXC_ID_OBJCBLSFMLA );
896 :
897 : // ftCblsData subrecord - box properties, again
898 0 : rStrm.StartRecord( EXC_ID_OBJCBLS, 8 );
899 0 : rStrm << mnState;
900 0 : rStrm.WriteZeroBytes( 4 );
901 0 : rStrm << nStyle;
902 0 : rStrm.EndRecord();
903 : }
904 0 : break;
905 :
906 : // *** List boxes, combo boxes ***
907 :
908 : case EXC_OBJTYPE_LISTBOX:
909 : case EXC_OBJTYPE_DROPDOWN:
910 : {
911 0 : sal_uInt16 nEntryCount = GetSourceEntryCount();
912 :
913 : // ftSbs subrecord - Scroll bars
914 0 : sal_Int32 nLineHeight = XclTools::GetHmmFromTwips( 200 ); // always 10pt
915 0 : if( mnObjType == EXC_OBJTYPE_LISTBOX )
916 0 : mnLineCount = static_cast< sal_uInt16 >( mnHeight / nLineHeight );
917 0 : mnScrollValue = 0;
918 0 : mnScrollMin = 0;
919 0 : sal_uInt16 nInvisLines = (nEntryCount >= mnLineCount) ? (nEntryCount - mnLineCount) : 0;
920 0 : mnScrollMax = limit_cast< sal_uInt16 >( nInvisLines, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
921 0 : mnScrollStep = 1;
922 0 : mnScrollPage = limit_cast< sal_uInt16 >( mnLineCount, EXC_OBJ_SCROLLBAR_MIN, EXC_OBJ_SCROLLBAR_MAX );
923 0 : mbScrollHor = false;
924 0 : WriteSbs( rStrm );
925 :
926 : // ftMacro - macro link
927 0 : WriteMacroSubRec( rStrm );
928 : // ftSbsFmla subrecord - cell link
929 0 : WriteCellLinkSubRec( rStrm, EXC_ID_OBJSBSFMLA );
930 :
931 : // ftLbsData - source data range and box properties
932 0 : sal_uInt16 nStyle = 0;
933 0 : ::insert_value( nStyle, mbMultiSel ? EXC_OBJ_LISTBOX_MULTI : EXC_OBJ_LISTBOX_SINGLE, 4, 2 );
934 0 : ::set_flag( nStyle, EXC_OBJ_LISTBOX_FLAT, mbFlatBorder );
935 :
936 0 : rStrm.StartRecord( EXC_ID_OBJLBSDATA, 0 );
937 :
938 0 : if( const XclTokenArray* pSrcRange = GetSourceRangeTokArr() )
939 : {
940 0 : rStrm << static_cast< sal_uInt16 >( (pSrcRange->GetSize() + 7) & 0xFFFE );
941 0 : WriteFormula( rStrm, *pSrcRange );
942 : }
943 : else
944 0 : rStrm << sal_uInt16( 0 );
945 :
946 0 : rStrm << nEntryCount << mnSelEntry << nStyle << sal_uInt16( 0 );
947 0 : if( mnObjType == EXC_OBJTYPE_LISTBOX )
948 : {
949 0 : if( nEntryCount )
950 : {
951 0 : ScfUInt8Vec aSelEx( nEntryCount, 0 );
952 0 : for( ScfInt16Vec::const_iterator aIt = maMultiSel.begin(), aEnd = maMultiSel.end(); aIt != aEnd; ++aIt )
953 0 : if( *aIt < nEntryCount )
954 0 : aSelEx[ *aIt ] = 1;
955 0 : rStrm.Write( &aSelEx[ 0 ], aSelEx.size() );
956 : }
957 : }
958 0 : else if( mnObjType == EXC_OBJTYPE_DROPDOWN )
959 : {
960 0 : rStrm << sal_uInt16( 0 ) << mnLineCount << sal_uInt16( 0 ) << sal_uInt16( 0 );
961 : }
962 :
963 0 : rStrm.EndRecord();
964 : }
965 0 : break;
966 :
967 : // *** Spin buttons, scrollbars ***
968 :
969 : case EXC_OBJTYPE_SPIN:
970 : case EXC_OBJTYPE_SCROLLBAR:
971 : {
972 : // ftSbs subrecord - scroll bars
973 0 : WriteSbs( rStrm );
974 : // ftMacro - macro link
975 0 : WriteMacroSubRec( rStrm );
976 : // ftSbsFmla subrecord - cell link
977 0 : WriteCellLinkSubRec( rStrm, EXC_ID_OBJSBSFMLA );
978 : }
979 0 : break;
980 :
981 : // *** Group boxes ***
982 :
983 : case EXC_OBJTYPE_GROUPBOX:
984 : {
985 : // ftMacro - macro link
986 0 : WriteMacroSubRec( rStrm );
987 :
988 : // ftGboData subrecord - group box properties
989 0 : sal_uInt16 nStyle = 0;
990 0 : ::set_flag( nStyle, EXC_OBJ_GROUPBOX_FLAT, mbFlatBorder );
991 :
992 0 : rStrm.StartRecord( EXC_ID_OBJGBODATA, 6 );
993 0 : rStrm << sal_uInt32( 0 )
994 0 : << nStyle;
995 0 : rStrm.EndRecord();
996 : }
997 0 : break;
998 : }
999 0 : }
1000 :
1001 0 : void XclExpTbxControlObj::WriteCellLinkSubRec( XclExpStream& rStrm, sal_uInt16 nSubRecId )
1002 : {
1003 0 : if( const XclTokenArray* pCellLink = GetCellLinkTokArr() )
1004 0 : WriteFormulaSubRec( rStrm, nSubRecId, *pCellLink );
1005 0 : }
1006 :
1007 0 : void XclExpTbxControlObj::WriteSbs( XclExpStream& rStrm )
1008 : {
1009 0 : sal_uInt16 nOrient = 0;
1010 0 : ::set_flag( nOrient, EXC_OBJ_SCROLLBAR_HOR, mbScrollHor );
1011 0 : sal_uInt16 nStyle = EXC_OBJ_SCROLLBAR_DEFFLAGS;
1012 0 : ::set_flag( nStyle, EXC_OBJ_SCROLLBAR_FLAT, mbFlatButton );
1013 :
1014 0 : rStrm.StartRecord( EXC_ID_OBJSBS, 20 );
1015 0 : rStrm << sal_uInt32( 0 ) // reserved
1016 0 : << mnScrollValue // thumb position
1017 0 : << mnScrollMin // thumb min pos
1018 0 : << mnScrollMax // thumb max pos
1019 0 : << mnScrollStep // line increment
1020 0 : << mnScrollPage // page increment
1021 0 : << nOrient // 0 = vertical, 1 = horizontal
1022 0 : << sal_uInt16( 15 ) // thumb width
1023 0 : << nStyle; // flags/style
1024 0 : rStrm.EndRecord();
1025 0 : }
1026 :
1027 : //#endif
1028 :
1029 26 : XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, const Rectangle* pChildAnchor ) :
1030 : XclObj( rObjMgr, EXC_OBJTYPE_CHART ),
1031 26 : XclExpRoot( rObjMgr.GetRoot() ), mxShape( xShape )
1032 : {
1033 : // create the MSODRAWING record contents for the chart object
1034 26 : mrEscherEx.OpenContainer( ESCHER_SpContainer );
1035 26 : mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
1036 26 : EscherPropertyContainer aPropOpt;
1037 26 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 );
1038 26 : aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 );
1039 26 : aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x0800004E );
1040 26 : aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x0800004D );
1041 26 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 );
1042 26 : aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x0800004D );
1043 26 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080008 );
1044 26 : aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00020000 );
1045 26 : aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080000 );
1046 26 : aPropOpt.Commit( mrEscherEx.GetStream() );
1047 :
1048 : // anchor
1049 26 : SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape );
1050 26 : ImplWriteAnchor( GetRoot(), pSdrObj, pChildAnchor );
1051 :
1052 : // client data (the following OBJ record)
1053 26 : mrEscherEx.AddAtom( 0, ESCHER_ClientData );
1054 26 : mrEscherEx.CloseContainer(); // ESCHER_SpContainer
1055 26 : mrEscherEx.UpdateDffFragmentEnd();
1056 :
1057 : // load the chart OLE object
1058 26 : if( SdrOle2Obj* pSdrOleObj = dynamic_cast< SdrOle2Obj* >( pSdrObj ) )
1059 26 : svt::EmbeddedObjectRef::TryRunningState( pSdrOleObj->GetObjRef() );
1060 :
1061 : // create the chart substream object
1062 52 : ScfPropertySet aShapeProp( xShape );
1063 52 : Reference< XModel > xModel;
1064 26 : aShapeProp.GetProperty( xModel, "Model" );
1065 26 : mxChartDoc.set( xModel,UNO_QUERY );
1066 26 : ::com::sun::star::awt::Rectangle aBoundRect;
1067 26 : aShapeProp.GetProperty( aBoundRect, "BoundRect" );
1068 26 : Rectangle aChartRect( Point( aBoundRect.X, aBoundRect.Y ), Size( aBoundRect.Width, aBoundRect.Height ) );
1069 52 : mxChart.reset( new XclExpChart( GetRoot(), xModel, aChartRect ) );
1070 26 : }
1071 :
1072 52 : XclExpChartObj::~XclExpChartObj()
1073 : {
1074 52 : }
1075 :
1076 2 : void XclExpChartObj::Save( XclExpStream& rStrm )
1077 : {
1078 : // content of OBJ record
1079 2 : XclObj::Save( rStrm );
1080 : // chart substream
1081 2 : mxChart->Save( rStrm );
1082 2 : }
1083 :
1084 24 : void XclExpChartObj::SaveXml( XclExpXmlStream& rStrm )
1085 : {
1086 : OSL_TRACE("XclExpChartObj::SaveXml -- Entry point to export chart");
1087 24 : sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
1088 :
1089 : // FIXME: two cell? it seems the two cell anchor is incorrect.
1090 : pDrawing->startElement( FSNS( XML_xdr, XML_twoCellAnchor ), // OOXTODO: oneCellAnchor, absoluteAnchor
1091 : XML_editAs, "oneCell",
1092 24 : FSEND );
1093 48 : Reference< XPropertySet > xPropSet( mxShape, UNO_QUERY );
1094 24 : if (xPropSet.is())
1095 : {
1096 24 : XclObjAny::WriteFromTo( rStrm, mxShape, GetTab() );
1097 24 : Reference< XModel > xModel( mxChartDoc, UNO_QUERY );
1098 48 : ChartExport aChartExport( XML_xdr, pDrawing, xModel, &rStrm, DrawingML::DOCUMENT_XLSX );
1099 : static sal_Int32 nChartCount = 0;
1100 24 : nChartCount++;
1101 48 : aChartExport.WriteChartObj( mxShape, nChartCount );
1102 : // TODO: get the correcto chart number
1103 : }
1104 :
1105 : pDrawing->singleElement( FSNS( XML_xdr, XML_clientData),
1106 : // OOXTODO: XML_fLocksWithSheet
1107 : // OOXTODO: XML_fPrintsWithSheet
1108 24 : FSEND );
1109 48 : pDrawing->endElement( FSNS( XML_xdr, XML_twoCellAnchor ) );
1110 24 : }
1111 :
1112 24 : const css::uno::Reference<css::chart::XChartDocument>& XclExpChartObj::GetChartDoc() const
1113 : {
1114 24 : return mxChartDoc;
1115 : }
1116 :
1117 3 : XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos,
1118 : const ScPostIt* pScNote, const OUString& rAddText ) :
1119 : XclExpRecord( EXC_ID_NOTE ),
1120 : maScPos( rScPos ),
1121 : mnObjId( EXC_OBJ_INVALID_ID ),
1122 3 : mbVisible( pScNote && pScNote->IsCaptionShown() )
1123 : {
1124 : // get the main note text
1125 3 : OUString aNoteText;
1126 3 : if( pScNote )
1127 : {
1128 3 : aNoteText = pScNote->GetText();
1129 3 : const EditTextObject *pEditObj = pScNote->GetEditTextObject();
1130 3 : if( pEditObj )
1131 3 : mpNoteContents = XclExpStringHelper::CreateString( rRoot, *pEditObj );
1132 : }
1133 : // append additional text
1134 3 : aNoteText = ScGlobal::addToken( aNoteText, rAddText, '\n', 2 );
1135 3 : maOrigNoteText = aNoteText;
1136 :
1137 : // initialize record dependent on BIFF type
1138 3 : switch( rRoot.GetBiff() )
1139 : {
1140 : case EXC_BIFF5:
1141 0 : maNoteText = OUStringToOString(aNoteText, rRoot.GetTextEncoding());
1142 0 : break;
1143 :
1144 : case EXC_BIFF8:
1145 : {
1146 : // TODO: additional text
1147 3 : if( pScNote )
1148 3 : if( SdrCaptionObj* pCaption = pScNote->GetOrCreateCaption( maScPos ) )
1149 : {
1150 3 : lcl_GetFromTo( rRoot, pCaption->GetLogicRect(), maScPos.Tab(), maCommentFrom, maCommentTo );
1151 3 : if( const OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() )
1152 3 : mnObjId = rRoot.GetObjectManager().AddObj( new XclObjComment( rRoot.GetObjectManager(), pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible, maScPos, maCommentFrom, maCommentTo ) );
1153 :
1154 3 : SfxItemSet aItemSet = pCaption->GetMergedItemSet();
1155 3 : meTVA = pCaption->GetTextVerticalAdjust();
1156 3 : meTHA = pCaption->GetTextHorizontalAdjust();
1157 3 : mbAutoScale = pCaption->GetFitToSize() != SDRTEXTFIT_NONE;
1158 3 : mbLocked = pCaption->IsMoveProtect() || pCaption->IsResizeProtect();
1159 :
1160 : // AutoFill style would change if Postit.cxx object creation values are changed
1161 6 : OUString aCol(((XFillColorItem &)GETITEM(aItemSet, XFillColorItem , XATTR_FILLCOLOR)).GetValue());
1162 3 : mbAutoFill = aCol.isEmpty() && (GETITEMVALUE(aItemSet, XFillStyleItem, XATTR_FILLSTYLE, sal_uLong) == drawing::FillStyle_SOLID);
1163 3 : mbAutoLine = true;
1164 3 : mbRowHidden = (rRoot.GetDoc().RowHidden(maScPos.Row(),maScPos.Tab()));
1165 6 : mbColHidden = (rRoot.GetDoc().ColHidden(maScPos.Col(),maScPos.Tab()));
1166 : }
1167 :
1168 3 : SetRecSize( 9 + maAuthor.GetSize() );
1169 : }
1170 3 : break;
1171 :
1172 : default: DBG_ERROR_BIFF();
1173 3 : }
1174 3 : }
1175 :
1176 3 : void XclExpNote::Save( XclExpStream& rStrm )
1177 : {
1178 3 : switch( rStrm.GetRoot().GetBiff() )
1179 : {
1180 : case EXC_BIFF5:
1181 : {
1182 : // write the NOTE record directly, there may be the need to create more than one
1183 0 : const sal_Char* pcBuffer = maNoteText.getStr();
1184 0 : sal_uInt16 nCharsLeft = static_cast< sal_uInt16 >( maNoteText.getLength() );
1185 :
1186 0 : while( nCharsLeft )
1187 : {
1188 0 : sal_uInt16 nWriteChars = ::std::min( nCharsLeft, EXC_NOTE5_MAXLEN );
1189 :
1190 0 : rStrm.StartRecord( EXC_ID_NOTE, 6 + nWriteChars );
1191 0 : if( pcBuffer == maNoteText.getStr() )
1192 : {
1193 : // first record: row, col, length of complete text
1194 0 : rStrm << static_cast< sal_uInt16 >( maScPos.Row() )
1195 0 : << static_cast< sal_uInt16 >( maScPos.Col() )
1196 0 : << nCharsLeft; // still contains full length
1197 : }
1198 : else
1199 : {
1200 : // next records: -1, 0, length of current text segment
1201 0 : rStrm << sal_uInt16( 0xFFFF )
1202 0 : << sal_uInt16( 0 )
1203 0 : << nWriteChars;
1204 : }
1205 0 : rStrm.Write( pcBuffer, nWriteChars );
1206 0 : rStrm.EndRecord();
1207 :
1208 0 : pcBuffer += nWriteChars;
1209 0 : nCharsLeft = nCharsLeft - nWriteChars;
1210 : }
1211 : }
1212 0 : break;
1213 :
1214 : case EXC_BIFF8:
1215 3 : if( mnObjId != EXC_OBJ_INVALID_ID )
1216 3 : XclExpRecord::Save( rStrm );
1217 3 : break;
1218 :
1219 : default: DBG_ERROR_BIFF();
1220 : }
1221 3 : }
1222 :
1223 3 : void XclExpNote::WriteBody( XclExpStream& rStrm )
1224 : {
1225 : // BIFF5/BIFF7 is written separately
1226 : OSL_ENSURE_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
1227 :
1228 3 : sal_uInt16 nFlags = 0;
1229 3 : ::set_flag( nFlags, EXC_NOTE_VISIBLE, mbVisible );
1230 :
1231 3 : rStrm << static_cast< sal_uInt16 >( maScPos.Row() )
1232 6 : << static_cast< sal_uInt16 >( maScPos.Col() )
1233 6 : << nFlags
1234 6 : << mnObjId
1235 6 : << maAuthor
1236 3 : << sal_uInt8( 0 );
1237 3 : }
1238 :
1239 0 : void XclExpNote::WriteXml( sal_Int32 nAuthorId, XclExpXmlStream& rStrm )
1240 : {
1241 0 : sax_fastparser::FSHelperPtr rComments = rStrm.GetCurrentStream();
1242 :
1243 : rComments->startElement( XML_comment,
1244 : XML_ref, XclXmlUtils::ToOString( maScPos ).getStr(),
1245 : XML_authorId, OString::number( nAuthorId ).getStr(),
1246 : // OOXTODO: XML_guid,
1247 0 : FSEND );
1248 0 : rComments->startElement( XML_text, FSEND );
1249 : // OOXTODO: phoneticPr, rPh, r
1250 0 : if( mpNoteContents )
1251 0 : mpNoteContents->WriteXml( rStrm );
1252 0 : rComments->endElement( XML_text );
1253 :
1254 : /*
1255 : Export of commentPr is disabled, since the current (Oct 2010)
1256 : version of MSO 2010 doesn't yet support commentPr
1257 : */
1258 : #if 1//def XLSX_OOXML_FUTURE
1259 0 : if( rStrm.getVersion() == oox::core::ISOIEC_29500_2008 )
1260 : {
1261 0 : rComments->startElement( FSNS( XML_mc, XML_AlternateContent ), FSEND );
1262 0 : rComments->startElement( FSNS( XML_mc, XML_Choice ), XML_Requires, "v2", FSEND );
1263 : rComments->startElement( XML_commentPr,
1264 : XML_autoFill, XclXmlUtils::ToPsz( mbAutoFill ),
1265 : XML_autoScale, XclXmlUtils::ToPsz( mbAutoScale ),
1266 : XML_colHidden, XclXmlUtils::ToPsz( mbColHidden ),
1267 : XML_locked, XclXmlUtils::ToPsz( mbLocked ),
1268 : XML_rowHidden, XclXmlUtils::ToPsz( mbRowHidden ),
1269 : XML_textHAlign, ToHorizAlign( meTHA ),
1270 : XML_textVAlign, ToVertAlign( meTVA ) ,
1271 0 : FSEND );
1272 : rComments->startElement( XML_anchor,
1273 : XML_moveWithCells, "false",
1274 : XML_sizeWithCells, "false",
1275 0 : FSEND );
1276 0 : rComments->startElement( FSNS( XML_xdr, XML_from ), FSEND );
1277 0 : lcl_WriteAnchorVertex( rComments, maCommentFrom );
1278 0 : rComments->endElement( FSNS( XML_xdr, XML_from ) );
1279 0 : rComments->startElement( FSNS( XML_xdr, XML_to ), FSEND );
1280 0 : lcl_WriteAnchorVertex( rComments, maCommentTo );
1281 0 : rComments->endElement( FSNS( XML_xdr, XML_to ) );
1282 0 : rComments->endElement( XML_anchor );
1283 0 : rComments->endElement( XML_commentPr );
1284 :
1285 0 : rComments->endElement( FSNS( XML_mc, XML_Choice ) );
1286 0 : rComments->startElement( FSNS( XML_mc, XML_Fallback ), FSEND );
1287 : // Any fallback code ?
1288 0 : rComments->endElement( FSNS( XML_mc, XML_Fallback ) );
1289 0 : rComments->endElement( FSNS( XML_mc, XML_AlternateContent ) );
1290 : }
1291 : #endif
1292 0 : rComments->endElement( XML_comment );
1293 0 : }
1294 :
1295 29 : XclMacroHelper::XclMacroHelper( const XclExpRoot& rRoot ) :
1296 29 : XclExpControlHelper( rRoot )
1297 : {
1298 29 : }
1299 :
1300 29 : XclMacroHelper::~XclMacroHelper()
1301 : {
1302 29 : }
1303 :
1304 7 : void XclMacroHelper::WriteMacroSubRec( XclExpStream& rStrm )
1305 : {
1306 7 : if( mxMacroLink )
1307 0 : WriteFormulaSubRec( rStrm, EXC_ID_OBJMACRO, *mxMacroLink );
1308 7 : }
1309 :
1310 : bool
1311 0 : XclMacroHelper::SetMacroLink( const ScriptEventDescriptor& rEvent, const XclTbxEventType& nEventType )
1312 : {
1313 0 : OUString aMacroName = XclControlHelper::ExtractFromMacroDescriptor( rEvent, nEventType, GetDocShell() );
1314 0 : if( !aMacroName.isEmpty() )
1315 : {
1316 0 : return SetMacroLink( aMacroName );
1317 : }
1318 0 : return false;
1319 : }
1320 :
1321 : bool
1322 0 : XclMacroHelper::SetMacroLink( const OUString& rMacroName )
1323 : {
1324 : OSL_TRACE("SetMacroLink( macroname:=%s )", OUStringToOString( rMacroName, RTL_TEXTENCODING_UTF8 ).getStr() );
1325 0 : if( !rMacroName.isEmpty() )
1326 : {
1327 0 : sal_uInt16 nExtSheet = GetLocalLinkManager().FindExtSheet( EXC_EXTSH_OWNDOC );
1328 0 : sal_uInt16 nNameIdx = GetNameManager().InsertMacroCall( rMacroName, true, false );
1329 0 : mxMacroLink = GetFormulaCompiler().CreateNameXFormula( nExtSheet, nNameIdx );
1330 0 : return true;
1331 : }
1332 0 : return false;
1333 : }
1334 :
1335 29 : XclExpShapeObj::XclExpShapeObj( XclExpObjectManager& rRoot, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, ScDocument* pDoc ) :
1336 : XclObjAny( rRoot, xShape, pDoc ),
1337 29 : XclMacroHelper( rRoot )
1338 : {
1339 29 : if( SdrObject* pSdrObj = ::GetSdrObjectFromXShape( xShape ) )
1340 : {
1341 29 : ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pSdrObj );
1342 29 : if ( pInfo && !pInfo->GetMacro().isEmpty() )
1343 : // FIXME ooo330-m2: XclControlHelper::GetXclMacroName was removed in upstream sources; they started to call XclTools::GetXclMacroName instead; is this enough? it has only one parameter
1344 : // SetMacroLink( XclControlHelper::GetXclMacroName( pInfo->GetMacro(), rRoot.GetDocShell() ) );
1345 0 : SetMacroLink( XclTools::GetXclMacroName( pInfo->GetMacro() ) );
1346 : }
1347 29 : }
1348 :
1349 58 : XclExpShapeObj::~XclExpShapeObj()
1350 : {
1351 58 : }
1352 :
1353 7 : void XclExpShapeObj::WriteSubRecs( XclExpStream& rStrm )
1354 : {
1355 7 : XclObjAny::WriteSubRecs( rStrm );
1356 7 : WriteMacroSubRec( rStrm );
1357 7 : }
1358 :
1359 0 : XclExpComments::XclExpComments( SCTAB nTab, XclExpRecordList< XclExpNote >& rNotes )
1360 0 : : mnTab( nTab ), mrNotes( rNotes )
1361 : {
1362 0 : }
1363 :
1364 : struct OUStringLess : public std::binary_function<OUString, OUString, bool>
1365 : {
1366 0 : bool operator()(const OUString& x, const OUString& y) const
1367 : {
1368 0 : return x.compareTo( y ) < 0;
1369 : }
1370 : };
1371 :
1372 0 : void XclExpComments::SaveXml( XclExpXmlStream& rStrm )
1373 : {
1374 0 : if( mrNotes.IsEmpty() )
1375 0 : return;
1376 :
1377 : sax_fastparser::FSHelperPtr rComments = rStrm.CreateOutputStream(
1378 : XclXmlUtils::GetStreamName( "xl/", "comments", mnTab + 1 ),
1379 : XclXmlUtils::GetStreamName( "../", "comments", mnTab + 1 ),
1380 0 : rStrm.GetCurrentStream()->getOutputStream(),
1381 : "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
1382 0 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" );
1383 0 : rStrm.PushStream( rComments );
1384 :
1385 0 : if( rStrm.getVersion() == oox::core::ISOIEC_29500_2008 )
1386 : rComments->startElement( XML_comments,
1387 : XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1388 : FSNS( XML_xmlns, XML_mc ), "http://schemas.openxmlformats.org/markup-compatibility/2006",
1389 : FSNS( XML_xmlns, XML_xdr ), "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
1390 : FSNS( XML_xmlns, XML_v2 ), "http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2",
1391 : FSNS( XML_mc, XML_Ignorable ), "v2",
1392 0 : FSEND );
1393 : else
1394 : rComments->startElement( XML_comments,
1395 : XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1396 : FSNS( XML_xmlns, XML_xdr ), "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
1397 0 : FSEND );
1398 :
1399 0 : rComments->startElement( XML_authors, FSEND );
1400 :
1401 : typedef std::set< OUString, OUStringLess > Authors;
1402 0 : Authors aAuthors;
1403 :
1404 0 : size_t nNotes = mrNotes.GetSize();
1405 0 : for( size_t i = 0; i < nNotes; ++i )
1406 : {
1407 0 : aAuthors.insert( XclXmlUtils::ToOUString( mrNotes.GetRecord( i )->GetAuthor() ) );
1408 : }
1409 :
1410 0 : for( Authors::const_iterator b = aAuthors.begin(), e = aAuthors.end(); b != e; ++b )
1411 : {
1412 0 : rComments->startElement( XML_author, FSEND );
1413 0 : rComments->writeEscaped( *b );
1414 0 : rComments->endElement( XML_author );
1415 : }
1416 :
1417 0 : rComments->endElement( XML_authors );
1418 0 : rComments->startElement( XML_commentList, FSEND );
1419 :
1420 0 : Authors::const_iterator aAuthorsBegin = aAuthors.begin();
1421 0 : for( size_t i = 0; i < nNotes; ++i )
1422 : {
1423 0 : XclExpNoteList::RecordRefType xNote = mrNotes.GetRecord( i );
1424 : Authors::const_iterator aAuthor = aAuthors.find(
1425 0 : XclXmlUtils::ToOUString( xNote->GetAuthor() ) );
1426 0 : sal_Int32 nAuthorId = distance( aAuthorsBegin, aAuthor );
1427 0 : xNote->WriteXml( nAuthorId, rStrm );
1428 0 : }
1429 :
1430 0 : rComments->endElement( XML_commentList );
1431 0 : rComments->endElement( XML_comments );
1432 :
1433 0 : rStrm.PopStream();
1434 : }
1435 :
1436 : // object manager =============================================================
1437 :
1438 72 : XclExpObjectManager::XclExpObjectManager( const XclExpRoot& rRoot ) :
1439 72 : XclExpRoot( rRoot )
1440 : {
1441 72 : InitStream( true );
1442 72 : mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm ) );
1443 72 : }
1444 :
1445 0 : XclExpObjectManager::XclExpObjectManager( const XclExpObjectManager& rParent ) :
1446 0 : XclExpRoot( rParent.GetRoot() )
1447 : {
1448 0 : InitStream( false );
1449 0 : mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm, rParent.mxEscherEx.get() ) );
1450 0 : }
1451 :
1452 144 : XclExpObjectManager::~XclExpObjectManager()
1453 : {
1454 144 : }
1455 :
1456 55 : XclExpDffAnchorBase* XclExpObjectManager::CreateDffAnchor() const
1457 : {
1458 55 : return new XclExpDffSheetAnchor( GetRoot() );
1459 : }
1460 :
1461 72 : std::shared_ptr< XclExpRecordBase > XclExpObjectManager::CreateDrawingGroup()
1462 : {
1463 72 : return std::shared_ptr< XclExpRecordBase >( new XclExpMsoDrawingGroup( *mxEscherEx ) );
1464 : }
1465 :
1466 129 : void XclExpObjectManager::StartSheet()
1467 : {
1468 129 : mxObjList.reset( new XclExpObjList( GetRoot(), *mxEscherEx ) );
1469 129 : }
1470 :
1471 129 : std::shared_ptr< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( SdrPage* pSdrPage )
1472 : {
1473 129 : if( pSdrPage )
1474 127 : mxEscherEx->AddSdrPage( *pSdrPage );
1475 : // the first dummy object may still be open
1476 : OSL_ENSURE( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1477 260 : while( mxEscherEx->GetGroupLevel() )
1478 2 : mxEscherEx->LeaveGroup();
1479 129 : mxObjList->EndSheet();
1480 129 : return mxObjList;
1481 : }
1482 :
1483 0 : std::shared_ptr< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( const Reference< XShapes >& rxShapes )
1484 : {
1485 0 : if( rxShapes.is() )
1486 0 : mxEscherEx->AddUnoShapes( rxShapes );
1487 : // the first dummy object may still be open
1488 : OSL_ENSURE( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1489 0 : while( mxEscherEx->GetGroupLevel() )
1490 0 : mxEscherEx->LeaveGroup();
1491 0 : mxObjList->EndSheet();
1492 0 : return mxObjList;
1493 : }
1494 :
1495 72 : void XclExpObjectManager::EndDocument()
1496 : {
1497 72 : mxEscherEx->EndDocument();
1498 72 : }
1499 :
1500 52 : XclExpMsoDrawing* XclExpObjectManager::GetMsodrawingPerSheet()
1501 : {
1502 52 : return mxObjList->GetMsodrawingPerSheet();
1503 : }
1504 :
1505 58 : bool XclExpObjectManager::HasObj() const
1506 : {
1507 58 : return !mxObjList->empty();
1508 : }
1509 :
1510 58 : sal_uInt16 XclExpObjectManager::AddObj( XclObj* pObjRec )
1511 : {
1512 58 : return mxObjList->Add( pObjRec );
1513 : }
1514 :
1515 0 : XclObj* XclExpObjectManager::RemoveLastObj()
1516 : {
1517 0 : XclObj* pLastObj = mxObjList->back();
1518 0 : mxObjList->pop_back();
1519 0 : return pLastObj;
1520 : }
1521 :
1522 72 : void XclExpObjectManager::InitStream( bool bTempFile )
1523 : {
1524 72 : if( bTempFile )
1525 : {
1526 72 : mxTempFile.reset( new ::utl::TempFile );
1527 72 : if( mxTempFile->IsValid() )
1528 : {
1529 72 : mxTempFile->EnableKillingFile();
1530 72 : mxDffStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxTempFile->GetURL(), STREAM_STD_READWRITE ) );
1531 : }
1532 : }
1533 :
1534 72 : if( !mxDffStrm.get() )
1535 0 : mxDffStrm.reset( new SvMemoryStream );
1536 :
1537 72 : mxDffStrm->SetEndian( SvStreamEndian::LITTLE );
1538 72 : }
1539 :
1540 0 : XclExpEmbeddedObjectManager::XclExpEmbeddedObjectManager(
1541 : const XclExpObjectManager& rParent, const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) :
1542 : XclExpObjectManager( rParent ),
1543 : maPageSize( rPageSize ),
1544 : mnScaleX( nScaleX ),
1545 0 : mnScaleY( nScaleY )
1546 : {
1547 0 : }
1548 :
1549 0 : XclExpDffAnchorBase* XclExpEmbeddedObjectManager::CreateDffAnchor() const
1550 : {
1551 0 : return new XclExpDffEmbeddedAnchor( GetRoot(), maPageSize, mnScaleX, mnScaleY );
1552 30 : }
1553 :
1554 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|