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 <unotools/mediadescriptor.hxx>
21 : #include <filter/msfilter/util.hxx>
22 : #include "oox/core/xmlfilterbase.hxx"
23 : #include "oox/export/shapes.hxx"
24 : #include "oox/export/utils.hxx"
25 : #include <oox/token/tokens.hxx>
26 :
27 : #include <cstdio>
28 : #include <com/sun/star/awt/CharSet.hpp>
29 : #include <com/sun/star/awt/FontDescriptor.hpp>
30 : #include <com/sun/star/awt/FontSlant.hpp>
31 : #include <com/sun/star/awt/FontWeight.hpp>
32 : #include <com/sun/star/awt/FontUnderline.hpp>
33 : #include <com/sun/star/awt/Gradient.hpp>
34 : #include <com/sun/star/beans/XPropertySet.hpp>
35 : #include <com/sun/star/beans/XPropertySetInfo.hpp>
36 : #include <com/sun/star/beans/XPropertyState.hpp>
37 : #include <com/sun/star/container/XEnumerationAccess.hpp>
38 : #include <com/sun/star/document/XExporter.hpp>
39 : #include <com/sun/star/drawing/FillStyle.hpp>
40 : #include <com/sun/star/drawing/BitmapMode.hpp>
41 : #include <com/sun/star/drawing/ConnectorType.hpp>
42 : #include <com/sun/star/drawing/LineDash.hpp>
43 : #include <com/sun/star/drawing/LineJoint.hpp>
44 : #include <com/sun/star/drawing/LineStyle.hpp>
45 : #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
46 : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
47 : #include <com/sun/star/graphic/XGraphic.hpp>
48 : #include <com/sun/star/i18n/ScriptType.hpp>
49 : #include <com/sun/star/io/XOutputStream.hpp>
50 : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
51 : #include <com/sun/star/style/ParagraphAdjust.hpp>
52 : #include <com/sun/star/text/XSimpleText.hpp>
53 : #include <com/sun/star/text/XText.hpp>
54 : #include <com/sun/star/text/XTextContent.hpp>
55 : #include <com/sun/star/text/XTextField.hpp>
56 : #include <com/sun/star/text/XTextRange.hpp>
57 : #include <com/sun/star/table/XTable.hpp>
58 : #include <com/sun/star/table/XColumnRowRange.hpp>
59 : #include <com/sun/star/table/XCellRange.hpp>
60 : #include <com/sun/star/table/XMergeableCell.hpp>
61 : #include <com/sun/star/chart2/XChartDocument.hpp>
62 : #include <com/sun/star/frame/XModel.hpp>
63 : #include <tools/stream.hxx>
64 : #include <vcl/cvtgrf.hxx>
65 : #include <unotools/fontcvt.hxx>
66 : #include <vcl/graph.hxx>
67 : #include <vcl/outdev.hxx>
68 : #include <svtools/grfmgr.hxx>
69 : #include <rtl/strbuf.hxx>
70 : #include <sfx2/app.hxx>
71 : #include <svl/languageoptions.hxx>
72 : #include <filter/msfilter/escherex.hxx>
73 : #include <svx/svdoashp.hxx>
74 : #include <svx/svdoole2.hxx>
75 : #include <editeng/svxenum.hxx>
76 : #include <svx/unoapi.hxx>
77 : #include <oox/export/chartexport.hxx>
78 :
79 : using namespace ::com::sun::star;
80 : using namespace ::com::sun::star::beans;
81 : using namespace ::com::sun::star::uno;
82 : using namespace ::com::sun::star::drawing;
83 : using namespace ::com::sun::star::i18n;
84 : using namespace ::com::sun::star::table;
85 : using ::com::sun::star::beans::PropertyState;
86 : using ::com::sun::star::beans::PropertyValue;
87 : using ::com::sun::star::beans::XPropertySet;
88 : using ::com::sun::star::beans::XPropertyState;
89 : using ::com::sun::star::container::XEnumeration;
90 : using ::com::sun::star::container::XEnumerationAccess;
91 : using ::com::sun::star::container::XIndexAccess;
92 : using ::com::sun::star::document::XExporter;
93 : using ::com::sun::star::document::XFilter;
94 : using ::com::sun::star::drawing::FillStyle;
95 : using ::com::sun::star::graphic::XGraphic;
96 : using ::com::sun::star::io::XOutputStream;
97 : using ::com::sun::star::lang::XComponent;
98 : using ::com::sun::star::text::XSimpleText;
99 : using ::com::sun::star::text::XText;
100 : using ::com::sun::star::text::XTextContent;
101 : using ::com::sun::star::text::XTextField;
102 : using ::com::sun::star::text::XTextRange;
103 : using ::oox::core::XmlFilterBase;
104 : using ::com::sun::star::chart2::XChartDocument;
105 : using ::com::sun::star::frame::XModel;
106 : using ::com::sun::star::sheet::XSpreadsheetDocument;
107 : using ::sax_fastparser::FSHelperPtr;
108 :
109 : #define IDS(x) OString(OStringLiteral(#x " ") + OString::number( mnShapeIdMax++ )).getStr()
110 :
111 : namespace oox { namespace drawingml {
112 :
113 : #define GETA(propName) \
114 : GetProperty( rXPropSet, OUString(#propName))
115 :
116 : #define GETAD(propName) \
117 : ( GetPropertyAndState( rXPropSet, rXPropState, OUString(#propName), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
118 :
119 : #define GET(variable, propName) \
120 : if ( GETA(propName) ) \
121 : mAny >>= variable;
122 :
123 : // not thread safe
124 : int ShapeExport::mnSpreadsheetCounter = 1;
125 :
126 0 : ShapeExport::ShapeExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, ShapeHashMap* pShapeMap, XmlFilterBase* pFB, DocumentType eDocumentType, DMLTextExport* pTextExport )
127 : : DrawingML( pFS, pFB, eDocumentType, pTextExport )
128 : , mnShapeIdMax( 1 )
129 : , mnPictureIdMax( 1 )
130 : , mnXmlNamespace( nXmlNamespace )
131 : , maFraction( 1, 576 )
132 : , maMapModeSrc( MAP_100TH_MM )
133 : , maMapModeDest( MAP_INCH, Point(), maFraction, maFraction )
134 0 : , mpShapeMap( pShapeMap ? pShapeMap : &maShapeMap )
135 : {
136 0 : }
137 :
138 0 : awt::Size ShapeExport::MapSize( const awt::Size& rSize ) const
139 : {
140 0 : Size aRetSize( OutputDevice::LogicToLogic( Size( rSize.Width, rSize.Height ), maMapModeSrc, maMapModeDest ) );
141 :
142 0 : if ( !aRetSize.Width() )
143 0 : aRetSize.Width()++;
144 0 : if ( !aRetSize.Height() )
145 0 : aRetSize.Height()++;
146 0 : return awt::Size( aRetSize.Width(), aRetSize.Height() );
147 : }
148 :
149 0 : bool ShapeExport::NonEmptyText( Reference< XInterface > xIface )
150 : {
151 0 : Reference< XPropertySet > xPropSet( xIface, UNO_QUERY );
152 :
153 0 : if( xPropSet.is() )
154 : {
155 0 : Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
156 0 : if ( xPropSetInfo.is() )
157 : {
158 0 : if ( xPropSetInfo->hasPropertyByName( "IsEmptyPresentationObject" ) )
159 : {
160 0 : sal_Bool bIsEmptyPresObj = sal_False;
161 0 : if ( xPropSet->getPropertyValue( "IsEmptyPresentationObject" ) >>= bIsEmptyPresObj )
162 : {
163 : DBG(fprintf(stderr, "empty presentation object %d, props:\n", bIsEmptyPresObj));
164 0 : if( bIsEmptyPresObj )
165 0 : return true;
166 : }
167 : }
168 :
169 0 : if ( xPropSetInfo->hasPropertyByName( "IsPresentationObject" ) )
170 : {
171 0 : sal_Bool bIsPresObj = sal_False;
172 0 : if ( xPropSet->getPropertyValue( "IsPresentationObject" ) >>= bIsPresObj )
173 : {
174 : DBG(fprintf(stderr, "presentation object %d, props:\n", bIsPresObj));
175 0 : if( bIsPresObj )
176 0 : return true;
177 : }
178 : }
179 0 : }
180 : }
181 :
182 0 : Reference< XSimpleText > xText( xIface, UNO_QUERY );
183 :
184 0 : if( xText.is() )
185 0 : return xText->getString().getLength();
186 :
187 0 : return false;
188 : }
189 :
190 0 : ShapeExport& ShapeExport::WriteBezierShape( Reference< XShape > xShape, bool bClosed )
191 : {
192 : DBG(fprintf(stderr, "write open bezier shape\n"));
193 :
194 0 : FSHelperPtr pFS = GetFS();
195 0 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
196 :
197 0 : PolyPolygon aPolyPolygon = EscherPropertyContainer::GetPolyPolygon( xShape );
198 0 : Rectangle aRect( aPolyPolygon.GetBoundRect() );
199 :
200 : #if OSL_DEBUG_LEVEL > 0
201 : awt::Size size = MapSize( awt::Size( aRect.GetWidth(), aRect.GetHeight() ) );
202 : DBG(fprintf(stderr, "poly count %d\nsize: %d x %d", aPolyPolygon.Count(), int( size.Width ), int( size.Height )));
203 : #endif
204 :
205 : // non visual shape properties
206 0 : if (GetDocumentType() != DOCUMENT_DOCX)
207 : {
208 0 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
209 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
210 : XML_id, I32S( GetNewShapeID( xShape ) ),
211 0 : XML_name, IDS( Freeform ),
212 0 : FSEND );
213 : }
214 0 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
215 0 : if (GetDocumentType() != DOCUMENT_DOCX)
216 : {
217 0 : WriteNonVisualProperties( xShape );
218 0 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
219 : }
220 :
221 : // visual shape properties
222 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
223 0 : WriteTransformation( aRect, XML_a );
224 0 : WritePolyPolygon( aPolyPolygon );
225 0 : Reference< XPropertySet > xProps( xShape, UNO_QUERY );
226 0 : if( xProps.is() ) {
227 0 : if( bClosed )
228 0 : WriteFill( xProps );
229 0 : WriteOutline( xProps );
230 : }
231 :
232 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
233 :
234 : // write text
235 0 : WriteTextBox( xShape, mnXmlNamespace );
236 :
237 0 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
238 :
239 0 : return *this;
240 : }
241 :
242 0 : ShapeExport& ShapeExport::WriteClosedBezierShape( Reference< XShape > xShape )
243 : {
244 0 : return WriteBezierShape( xShape, true );
245 : }
246 :
247 0 : ShapeExport& ShapeExport::WriteOpenBezierShape( Reference< XShape > xShape )
248 : {
249 0 : return WriteBezierShape( xShape, false );
250 : }
251 :
252 0 : ShapeExport& ShapeExport::WriteGroupShape(uno::Reference<drawing::XShape> xShape)
253 : {
254 0 : FSHelperPtr pFS = GetFS();
255 0 : bool bToplevel = !m_xParent.is();
256 0 : if (!bToplevel)
257 0 : mnXmlNamespace = XML_wpg;
258 0 : pFS->startElementNS(mnXmlNamespace, (bToplevel ? XML_wgp : XML_grpSp), FSEND);
259 :
260 : // non visual properties
261 0 : pFS->singleElementNS(mnXmlNamespace, XML_cNvGrpSpPr, FSEND);
262 :
263 : // visual properties
264 0 : pFS->startElementNS(mnXmlNamespace, XML_grpSpPr, FSEND);
265 0 : WriteShapeTransformation(xShape, XML_a);
266 0 : pFS->endElementNS(mnXmlNamespace, XML_grpSpPr);
267 :
268 0 : uno::Reference<drawing::XShapes> xGroupShape(xShape, uno::UNO_QUERY_THROW);
269 0 : uno::Reference<drawing::XShape> xParent = m_xParent;
270 0 : m_xParent = xShape;
271 0 : for (sal_Int32 i = 0; i < xGroupShape->getCount(); ++i)
272 : {
273 0 : uno::Reference<drawing::XShape> xChild(xGroupShape->getByIndex(i), uno::UNO_QUERY_THROW);
274 0 : sal_Int32 nSavedNamespace = mnXmlNamespace;
275 :
276 0 : uno::Reference<lang::XServiceInfo> xServiceInfo(xChild, uno::UNO_QUERY_THROW);
277 0 : if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
278 0 : mnXmlNamespace = XML_pic;
279 : else
280 0 : mnXmlNamespace = XML_wps;
281 0 : WriteShape(xChild);
282 :
283 0 : mnXmlNamespace = nSavedNamespace;
284 0 : }
285 0 : m_xParent = xParent;
286 :
287 0 : pFS->endElementNS(mnXmlNamespace, (bToplevel ? XML_wgp : XML_grpSp));
288 0 : return *this;
289 : }
290 :
291 0 : ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
292 : {
293 : DBG(fprintf(stderr, "write custom shape\n"));
294 :
295 0 : Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
296 0 : bool bPredefinedHandlesUsed = true;
297 0 : OUString sShapeType;
298 0 : sal_uInt32 nMirrorFlags = 0;
299 0 : MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType( xShape, nMirrorFlags, sShapeType );
300 0 : SdrObjCustomShape* pShape = (SdrObjCustomShape*) GetSdrObjectFromXShape( xShape );
301 0 : bool bIsDefaultObject = EscherPropertyContainer::IsDefaultObject( pShape, eShapeType );
302 0 : const char* sPresetShape = msfilter::util::GetOOXMLPresetGeometry( USS( sShapeType ) );
303 : DBG(fprintf(stderr, "custom shape type: %s ==> %s\n", USS( sShapeType ), sPresetShape));
304 0 : Sequence< PropertyValue > aGeometrySeq;
305 0 : sal_Int32 nAdjustmentValuesIndex = -1;
306 :
307 0 : bool bFlipH = false;
308 0 : bool bFlipV = false;
309 :
310 0 : if( GETA( CustomShapeGeometry ) ) {
311 : DBG(fprintf(stderr, "got custom shape geometry\n"));
312 0 : if( mAny >>= aGeometrySeq ) {
313 :
314 : DBG(fprintf(stderr, "got custom shape geometry sequence\n"));
315 0 : for( int i = 0; i < aGeometrySeq.getLength(); i++ ) {
316 0 : const PropertyValue& rProp = aGeometrySeq[ i ];
317 : DBG(fprintf(stderr, "geometry property: %s\n", USS( rProp.Name )));
318 :
319 0 : if ( rProp.Name == "MirroredX" )
320 0 : rProp.Value >>= bFlipH;
321 :
322 0 : if ( rProp.Name == "MirroredY" )
323 0 : rProp.Value >>= bFlipV;
324 0 : if ( rProp.Name == "AdjustmentValues" )
325 0 : nAdjustmentValuesIndex = i;
326 0 : else if ( rProp.Name == "Handles" ) {
327 0 : if( !bIsDefaultObject )
328 0 : bPredefinedHandlesUsed = false;
329 : // TODO: update nAdjustmentsWhichNeedsToBeConverted here
330 : }
331 : }
332 : }
333 : }
334 :
335 0 : FSHelperPtr pFS = GetFS();
336 0 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
337 :
338 : // non visual shape properties
339 0 : if (GetDocumentType() != DOCUMENT_DOCX)
340 : {
341 0 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
342 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
343 : XML_id, I32S( GetNewShapeID( xShape ) ),
344 0 : XML_name, IDS( CustomShape ),
345 0 : FSEND );
346 0 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
347 0 : WriteNonVisualProperties( xShape );
348 0 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
349 : }
350 : else
351 0 : pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr, FSEND);
352 :
353 : // visual shape properties
354 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
355 0 : WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, false);
356 :
357 0 : if( sShapeType == "ooxml-non-primitive" ) // non-primitiv -> custom geometry
358 : {
359 0 : WritePolyPolygon( EscherPropertyContainer::GetPolyPolygon( xShape ) );
360 : }
361 : else // preset geometry
362 : {
363 0 : if( nAdjustmentValuesIndex != -1 )
364 : {
365 0 : sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
366 : WritePresetShape( sPresetShape, eShapeType, bPredefinedHandlesUsed,
367 0 : nAdjustmentsWhichNeedsToBeConverted, aGeometrySeq[ nAdjustmentValuesIndex ] );
368 : }
369 : else
370 0 : WritePresetShape( sPresetShape );
371 : }
372 0 : if( rXPropSet.is() )
373 : {
374 0 : WriteFill( rXPropSet );
375 0 : WriteOutline( rXPropSet );
376 : }
377 :
378 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
379 :
380 0 : pFS->startElementNS( mnXmlNamespace, XML_style, FSEND );
381 0 : WriteShapeStyle( rXPropSet );
382 0 : pFS->endElementNS( mnXmlNamespace, XML_style );
383 :
384 : // write text
385 0 : WriteTextBox( xShape, mnXmlNamespace );
386 :
387 0 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
388 :
389 0 : return *this;
390 : }
391 :
392 0 : ShapeExport& ShapeExport::WriteEllipseShape( Reference< XShape > xShape )
393 : {
394 : DBG(fprintf(stderr, "write ellipse shape\n"));
395 :
396 0 : FSHelperPtr pFS = GetFS();
397 :
398 0 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
399 :
400 : // TODO: arc, section, cut, connector
401 :
402 : // non visual shape properties
403 0 : if (GetDocumentType() != DOCUMENT_DOCX)
404 : {
405 0 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
406 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
407 : XML_id, I32S( GetNewShapeID( xShape ) ),
408 0 : XML_name, IDS( Ellipse ),
409 0 : FSEND );
410 0 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
411 0 : WriteNonVisualProperties( xShape );
412 0 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
413 : }
414 : else
415 0 : pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr, FSEND);
416 :
417 : // visual shape properties
418 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
419 0 : WriteShapeTransformation( xShape, XML_a, false, false, false);
420 0 : WritePresetShape( "ellipse" );
421 0 : Reference< XPropertySet > xProps( xShape, UNO_QUERY );
422 0 : if( xProps.is() )
423 : {
424 0 : WriteFill( xProps );
425 0 : WriteOutline( xProps );
426 : }
427 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
428 :
429 : // write text
430 0 : WriteTextBox( xShape, mnXmlNamespace );
431 :
432 0 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
433 :
434 0 : return *this;
435 : }
436 :
437 0 : ShapeExport& ShapeExport::WriteGraphicObjectShape( Reference< XShape > xShape )
438 : {
439 0 : WriteGraphicObjectShapePart( xShape );
440 :
441 0 : return *this;
442 : }
443 :
444 0 : void ShapeExport::WriteGraphicObjectShapePart( Reference< XShape > xShape, const Graphic* pGraphic )
445 : {
446 : DBG(fprintf(stderr, "write graphic object shape\n"));
447 :
448 0 : if( NonEmptyText( xShape ) )
449 : {
450 : // avoid treating all 'IsPresentationObject' objects as having text.
451 0 : Reference< XSimpleText > xText( xShape, UNO_QUERY );
452 :
453 0 : if( xText.is() && xText->getString().getLength() )
454 : {
455 : DBG(fprintf(stderr, "graphicObject: wrote only text\n"));
456 :
457 0 : WriteTextShape( xShape );
458 :
459 : //DBG(dump_pset(mXPropSet));
460 0 : return;
461 0 : }
462 : }
463 :
464 : DBG(fprintf(stderr, "graphicObject without text\n"));
465 :
466 0 : OUString sGraphicURL;
467 0 : Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
468 0 : if( !pGraphic && ( !xShapeProps.is() || !( xShapeProps->getPropertyValue( "GraphicURL" ) >>= sGraphicURL ) ) )
469 : {
470 : DBG(fprintf(stderr, "no graphic URL found\n"));
471 0 : return;
472 : }
473 :
474 0 : FSHelperPtr pFS = GetFS();
475 :
476 0 : if (GetDocumentType() != DOCUMENT_DOCX)
477 0 : pFS->startElementNS( mnXmlNamespace, XML_pic, FSEND );
478 : else
479 : pFS->startElementNS( mnXmlNamespace, XML_pic,
480 : FSNS(XML_xmlns, XML_pic), "http://schemas.openxmlformats.org/drawingml/2006/picture",
481 0 : FSEND );
482 :
483 0 : pFS->startElementNS( mnXmlNamespace, XML_nvPicPr, FSEND );
484 :
485 0 : OUString sName, sDescr;
486 : bool bHaveName, bHaveDesc;
487 :
488 0 : if ( ( bHaveName= GetProperty( xShapeProps, "Name" ) ) )
489 0 : mAny >>= sName;
490 0 : if ( ( bHaveDesc = GetProperty( xShapeProps, "Description" ) ) )
491 0 : mAny >>= sDescr;
492 :
493 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
494 : XML_id, I32S( GetNewShapeID( xShape ) ),
495 0 : XML_name, bHaveName ? USS( sName ) : OString( "Picture " + OString::number( mnPictureIdMax++ )).getStr(),
496 0 : XML_descr, bHaveDesc ? USS( sDescr ) : NULL,
497 0 : FSEND );
498 : // OOXTODO: //cNvPr children: XML_extLst, XML_hlinkClick, XML_hlinkHover
499 :
500 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPicPr,
501 : // OOXTODO: XML_preferRelativeSize
502 0 : FSEND );
503 :
504 0 : WriteNonVisualProperties( xShape );
505 :
506 0 : pFS->endElementNS( mnXmlNamespace, XML_nvPicPr );
507 :
508 0 : pFS->startElementNS( mnXmlNamespace, XML_blipFill, FSEND );
509 :
510 0 : WriteBlip( xShapeProps, sGraphicURL, false, pGraphic );
511 :
512 0 : WriteSrcRect( xShapeProps, sGraphicURL );
513 :
514 : // now we stretch always when we get pGraphic (when changing that
515 : // behavior, test n#780830 for regression, where the OLE sheet might get tiled
516 0 : bool bStretch = false;
517 0 : if( !pGraphic && GetProperty( xShapeProps, "FillBitmapStretch" ) )
518 0 : mAny >>= bStretch;
519 :
520 0 : if ( pGraphic || bStretch )
521 0 : pFS->singleElementNS( XML_a, XML_stretch, FSEND );
522 :
523 0 : pFS->endElementNS( mnXmlNamespace, XML_blipFill );
524 :
525 : // visual shape properties
526 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
527 0 : WriteShapeTransformation( xShape, XML_a, false, false, false);
528 0 : WritePresetShape( "rect" );
529 : // graphic object can come with the frame (bnc#654525)
530 0 : WriteOutline( xShapeProps );
531 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
532 :
533 0 : pFS->endElementNS( mnXmlNamespace, XML_pic );
534 : }
535 :
536 0 : ShapeExport& ShapeExport::WriteConnectorShape( Reference< XShape > xShape )
537 : {
538 0 : bool bFlipH = false;
539 0 : bool bFlipV = false;
540 :
541 : DBG(fprintf(stderr, "write connector shape\n"));
542 :
543 0 : FSHelperPtr pFS = GetFS();
544 :
545 0 : const char* sGeometry = "line";
546 0 : Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
547 0 : Reference< XPropertyState > rXPropState( xShape, UNO_QUERY );
548 0 : awt::Point aStartPoint, aEndPoint;
549 0 : Reference< XShape > rXShapeA;
550 0 : Reference< XShape > rXShapeB;
551 : PropertyState eState;
552 : ConnectorType eConnectorType;
553 0 : if( GETAD( EdgeKind ) ) {
554 0 : mAny >>= eConnectorType;
555 :
556 0 : switch( eConnectorType ) {
557 : case ConnectorType_CURVE:
558 0 : sGeometry = "curvedConnector3";
559 0 : break;
560 : case ConnectorType_STANDARD:
561 0 : sGeometry = "bentConnector3";
562 0 : break;
563 : default:
564 : case ConnectorType_LINE:
565 : case ConnectorType_LINES:
566 0 : sGeometry = "straightConnector1";
567 0 : break;
568 : }
569 :
570 0 : if( GETAD( EdgeStartPoint ) ) {
571 0 : mAny >>= aStartPoint;
572 0 : if( GETAD( EdgeEndPoint ) ) {
573 0 : mAny >>= aEndPoint;
574 : }
575 : }
576 0 : GET( rXShapeA, EdgeStartConnection );
577 0 : GET( rXShapeB, EdgeEndConnection );
578 : }
579 0 : EscherConnectorListEntry aConnectorEntry( xShape, aStartPoint, rXShapeA, aEndPoint, rXShapeB );
580 :
581 0 : Rectangle aRect( Point( aStartPoint.X, aStartPoint.Y ), Point( aEndPoint.X, aEndPoint.Y ) );
582 0 : if( aRect.getWidth() < 0 ) {
583 0 : bFlipH = true;
584 0 : aRect.setX( aEndPoint.X );
585 0 : aRect.setWidth( aStartPoint.X - aEndPoint.X );
586 : }
587 :
588 0 : if( aRect.getHeight() < 0 ) {
589 0 : bFlipV = true;
590 0 : aRect.setY( aEndPoint.Y );
591 0 : aRect.setHeight( aStartPoint.Y - aEndPoint.Y );
592 : }
593 :
594 0 : pFS->startElementNS( mnXmlNamespace, XML_cxnSp, FSEND );
595 :
596 : // non visual shape properties
597 0 : pFS->startElementNS( mnXmlNamespace, XML_nvCxnSpPr, FSEND );
598 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
599 : XML_id, I32S( GetNewShapeID( xShape ) ),
600 0 : XML_name, IDS( Line ),
601 0 : FSEND );
602 : // non visual connector shape drawing properties
603 0 : pFS->startElementNS( mnXmlNamespace, XML_cNvCxnSpPr, FSEND );
604 0 : WriteConnectorConnections( aConnectorEntry, GetShapeID( rXShapeA ), GetShapeID( rXShapeB ) );
605 0 : pFS->endElementNS( mnXmlNamespace, XML_cNvCxnSpPr );
606 0 : pFS->singleElementNS( mnXmlNamespace, XML_nvPr, FSEND );
607 0 : pFS->endElementNS( mnXmlNamespace, XML_nvCxnSpPr );
608 :
609 : // visual shape properties
610 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
611 0 : WriteTransformation( aRect, XML_a, bFlipH, bFlipV );
612 : // TODO: write adjustments (ppt export doesn't work well there either)
613 0 : WritePresetShape( sGeometry );
614 0 : Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
615 0 : if( xShapeProps.is() )
616 0 : WriteOutline( xShapeProps );
617 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
618 :
619 : // write text
620 0 : WriteTextBox( xShape, mnXmlNamespace );
621 :
622 0 : pFS->endElementNS( mnXmlNamespace, XML_cxnSp );
623 :
624 0 : return *this;
625 : }
626 :
627 0 : ShapeExport& ShapeExport::WriteLineShape( Reference< XShape > xShape )
628 : {
629 0 : bool bFlipH = false;
630 0 : bool bFlipV = false;
631 :
632 : DBG(fprintf(stderr, "write line shape\n"));
633 :
634 0 : FSHelperPtr pFS = GetFS();
635 :
636 0 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
637 :
638 0 : PolyPolygon aPolyPolygon = EscherPropertyContainer::GetPolyPolygon( xShape );
639 0 : if( aPolyPolygon.Count() == 1 && aPolyPolygon[ 0 ].GetSize() == 2)
640 : {
641 0 : const Polygon& rPoly = aPolyPolygon[ 0 ];
642 :
643 0 : bFlipH = ( rPoly[ 0 ].X() > rPoly[ 1 ].X() );
644 0 : bFlipV = ( rPoly[ 0 ].Y() > rPoly[ 1 ].Y() );
645 : }
646 :
647 : // non visual shape properties
648 0 : if (GetDocumentType() != DOCUMENT_DOCX)
649 : {
650 0 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
651 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
652 : XML_id, I32S( GetNewShapeID( xShape ) ),
653 0 : XML_name, IDS( Line ),
654 0 : FSEND );
655 : }
656 0 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
657 0 : if (GetDocumentType() != DOCUMENT_DOCX)
658 : {
659 0 : WriteNonVisualProperties( xShape );
660 0 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
661 : }
662 :
663 : // visual shape properties
664 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
665 0 : WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, true);
666 0 : WritePresetShape( "line" );
667 0 : Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
668 0 : if( xShapeProps.is() )
669 0 : WriteOutline( xShapeProps );
670 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
671 :
672 : // write text
673 0 : WriteTextBox( xShape, mnXmlNamespace );
674 :
675 0 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
676 :
677 0 : return *this;
678 : }
679 :
680 0 : ShapeExport& ShapeExport::WriteNonVisualDrawingProperties( Reference< XShape > xShape, const char* pName )
681 : {
682 : GetFS()->singleElementNS( mnXmlNamespace, XML_cNvPr,
683 : XML_id, I32S( GetNewShapeID( xShape ) ),
684 : XML_name, pName,
685 0 : FSEND );
686 :
687 0 : return *this;
688 : }
689 :
690 0 : ShapeExport& ShapeExport::WriteNonVisualProperties( Reference< XShape > )
691 : {
692 : // Override to generate //nvPr elements.
693 0 : return *this;
694 : }
695 :
696 0 : ShapeExport& ShapeExport::WriteRectangleShape( Reference< XShape > xShape )
697 : {
698 : DBG(fprintf(stderr, "write rectangle shape\n"));
699 :
700 0 : FSHelperPtr pFS = GetFS();
701 :
702 0 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
703 :
704 0 : sal_Int32 nRadius = 0;
705 :
706 0 : Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
707 0 : if( xShapeProps.is() )
708 : {
709 0 : xShapeProps->getPropertyValue( "CornerRadius" ) >>= nRadius;
710 : }
711 :
712 0 : if( nRadius )
713 : {
714 0 : nRadius = MapSize( awt::Size( nRadius, 0 ) ).Width;
715 : }
716 :
717 : // non visual shape properties
718 0 : if (GetDocumentType() == DOCUMENT_DOCX)
719 0 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
720 0 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
721 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
722 : XML_id, I32S( GetNewShapeID( xShape ) ),
723 0 : XML_name, IDS( Rectangle ),
724 0 : FSEND );
725 0 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
726 0 : WriteNonVisualProperties( xShape );
727 0 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
728 :
729 : // visual shape properties
730 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
731 0 : WriteShapeTransformation( xShape, XML_a, false, false, false);
732 0 : WritePresetShape( "rect" );
733 0 : Reference< XPropertySet > xProps( xShape, UNO_QUERY );
734 0 : if( xProps.is() )
735 : {
736 0 : WriteFill( xProps );
737 0 : WriteOutline( xProps );
738 : }
739 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
740 :
741 : // write text
742 0 : WriteTextBox( xShape, mnXmlNamespace );
743 :
744 0 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
745 :
746 0 : return *this;
747 : }
748 :
749 : typedef ShapeExport& (ShapeExport::*ShapeConverter)( Reference< XShape > );
750 : typedef boost::unordered_map< const char*, ShapeConverter, rtl::CStringHash, rtl::CStringEqual> NameToConvertMapType;
751 :
752 0 : static const NameToConvertMapType& lcl_GetConverters(DrawingML::DocumentType eDocumentType)
753 : {
754 : static bool shape_map_inited = false;
755 0 : static NameToConvertMapType shape_converters;
756 0 : if( shape_map_inited )
757 : {
758 0 : return shape_converters;
759 : }
760 :
761 0 : shape_converters[ "com.sun.star.drawing.ClosedBezierShape" ] = &ShapeExport::WriteClosedBezierShape;
762 0 : shape_converters[ "com.sun.star.drawing.ConnectorShape" ] = &ShapeExport::WriteConnectorShape;
763 0 : shape_converters[ "com.sun.star.drawing.CustomShape" ] = &ShapeExport::WriteCustomShape;
764 0 : shape_converters[ "com.sun.star.drawing.EllipseShape" ] = &ShapeExport::WriteEllipseShape;
765 0 : shape_converters[ "com.sun.star.drawing.GraphicObjectShape" ] = &ShapeExport::WriteGraphicObjectShape;
766 0 : shape_converters[ "com.sun.star.drawing.LineShape" ] = &ShapeExport::WriteLineShape;
767 0 : shape_converters[ "com.sun.star.drawing.OpenBezierShape" ] = &ShapeExport::WriteOpenBezierShape;
768 0 : shape_converters[ "com.sun.star.drawing.RectangleShape" ] = &ShapeExport::WriteRectangleShape;
769 0 : shape_converters[ "com.sun.star.drawing.OLE2Shape" ] = &ShapeExport::WriteOLE2Shape;
770 0 : shape_converters[ "com.sun.star.drawing.TableShape" ] = &ShapeExport::WriteTableShape;
771 0 : shape_converters[ "com.sun.star.drawing.TextShape" ] = &ShapeExport::WriteTextShape;
772 :
773 0 : shape_converters[ "com.sun.star.presentation.GraphicObjectShape" ] = &ShapeExport::WriteGraphicObjectShape;
774 0 : shape_converters[ "com.sun.star.presentation.OLE2Shape" ] = &ShapeExport::WriteOLE2Shape;
775 0 : shape_converters[ "com.sun.star.presentation.TableShape" ] = &ShapeExport::WriteTableShape;
776 0 : shape_converters[ "com.sun.star.presentation.TextShape" ] = &ShapeExport::WriteTextShape;
777 :
778 0 : shape_converters[ "com.sun.star.presentation.DateTimeShape" ] = &ShapeExport::WriteTextShape;
779 0 : shape_converters[ "com.sun.star.presentation.FooterShape" ] = &ShapeExport::WriteTextShape;
780 0 : shape_converters[ "com.sun.star.presentation.HeaderShape" ] = &ShapeExport::WriteTextShape;
781 0 : shape_converters[ "com.sun.star.presentation.NotesShape" ] = &ShapeExport::WriteTextShape;
782 0 : shape_converters[ "com.sun.star.presentation.OutlinerShape" ] = &ShapeExport::WriteTextShape;
783 0 : shape_converters[ "com.sun.star.presentation.SlideNumberShape" ] = &ShapeExport::WriteTextShape;
784 0 : shape_converters[ "com.sun.star.presentation.TitleTextShape" ] = &ShapeExport::WriteTextShape;
785 0 : if (eDocumentType == DrawingML::DOCUMENT_DOCX)
786 0 : shape_converters[ "com.sun.star.drawing.GroupShape" ] = &ShapeExport::WriteGroupShape;
787 0 : shape_map_inited = true;
788 :
789 0 : return shape_converters;
790 : }
791 :
792 0 : ShapeExport& ShapeExport::WriteShape( Reference< XShape > xShape )
793 : {
794 0 : OUString sShapeType = xShape->getShapeType();
795 : DBG( fprintf( stderr, "write shape: %s\n", USS( sShapeType ) ) );
796 0 : NameToConvertMapType::const_iterator aConverter = lcl_GetConverters(GetDocumentType()).find( USS( sShapeType ) );
797 0 : if( aConverter == lcl_GetConverters(GetDocumentType()).end() )
798 : {
799 : DBG( fprintf( stderr, "unknown shape\n" ) );
800 0 : return WriteUnknownShape( xShape );
801 : }
802 0 : (this->*(aConverter->second))( xShape );
803 :
804 0 : return *this;
805 : }
806 :
807 0 : ShapeExport& ShapeExport::WriteTextBox( Reference< XInterface > xIface, sal_Int32 nXmlNamespace )
808 : {
809 0 : if( NonEmptyText( xIface ) )
810 : {
811 0 : FSHelperPtr pFS = GetFS();
812 :
813 0 : pFS->startElementNS( nXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_txBody : XML_txbx), FSEND );
814 0 : WriteText( xIface, /*bBodyPr=*/(GetDocumentType() != DOCUMENT_DOCX), /*bText=*/true );
815 0 : pFS->endElementNS( nXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_txBody : XML_txbx) );
816 0 : if (GetDocumentType() == DOCUMENT_DOCX)
817 0 : WriteText( xIface, /*bBodyPr=*/true, /*bText=*/false, /*nXmlNamespace=*/nXmlNamespace );
818 : }
819 0 : else if (GetDocumentType() == DOCUMENT_DOCX)
820 0 : mpFS->singleElementNS(nXmlNamespace, XML_bodyPr, FSEND);
821 :
822 0 : return *this;
823 : }
824 :
825 0 : void ShapeExport::WriteTable( Reference< XShape > rXShape )
826 : {
827 : OSL_TRACE("write table");
828 :
829 0 : Reference< XTable > xTable;
830 0 : Reference< XPropertySet > xPropSet( rXShape, UNO_QUERY );
831 :
832 0 : mpFS->startElementNS( XML_a, XML_graphic, FSEND );
833 0 : mpFS->startElementNS( XML_a, XML_graphicData, XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/table", FSEND );
834 :
835 0 : if ( xPropSet.is() && ( xPropSet->getPropertyValue( "Model" ) >>= xTable ) )
836 : {
837 0 : mpFS->startElementNS( XML_a, XML_tbl, FSEND );
838 0 : mpFS->singleElementNS( XML_a, XML_tblPr, FSEND );
839 :
840 0 : Reference< container::XIndexAccess > xColumns( xTable->getColumns(), UNO_QUERY_THROW );
841 0 : Reference< container::XIndexAccess > xRows( xTable->getRows(), UNO_QUERY_THROW );
842 0 : sal_uInt16 nRowCount = static_cast< sal_uInt16 >( xRows->getCount() );
843 0 : sal_uInt16 nColumnCount = static_cast< sal_uInt16 >( xColumns->getCount() );
844 :
845 0 : mpFS->startElementNS( XML_a, XML_tblGrid, FSEND );
846 :
847 0 : for ( sal_Int32 x = 0; x < nColumnCount; x++ )
848 : {
849 0 : Reference< XPropertySet > xColPropSet( xColumns->getByIndex( x ), UNO_QUERY_THROW );
850 0 : sal_Int32 nWidth(0);
851 0 : xColPropSet->getPropertyValue( "Width" ) >>= nWidth;
852 :
853 0 : mpFS->singleElementNS( XML_a, XML_gridCol, XML_w, I64S(MM100toEMU(nWidth)), FSEND );
854 0 : }
855 :
856 0 : mpFS->endElementNS( XML_a, XML_tblGrid );
857 :
858 0 : for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
859 : {
860 0 : Reference< XPropertySet > xRowPropSet( xRows->getByIndex( nRow ), UNO_QUERY_THROW );
861 0 : sal_Int32 nRowHeight(0);
862 :
863 0 : xRowPropSet->getPropertyValue( "Height" ) >>= nRowHeight;
864 :
865 0 : mpFS->startElementNS( XML_a, XML_tr, XML_h, I64S( MM100toEMU( nRowHeight ) ), FSEND );
866 :
867 0 : for( sal_Int32 nColumn = 0; nColumn < nColumnCount; nColumn++ )
868 : {
869 0 : Reference< XMergeableCell > xCell( xTable->getCellByPosition( nColumn, nRow ), UNO_QUERY_THROW );
870 0 : if ( !xCell->isMerged() )
871 : {
872 0 : mpFS->startElementNS( XML_a, XML_tc, FSEND );
873 :
874 0 : WriteTextBox( xCell, XML_a );
875 :
876 0 : mpFS->singleElementNS( XML_a, XML_tcPr, FSEND );
877 0 : mpFS->endElementNS( XML_a, XML_tc );
878 : }
879 0 : }
880 :
881 0 : mpFS->endElementNS( XML_a, XML_tr );
882 0 : }
883 :
884 0 : mpFS->endElementNS( XML_a, XML_tbl );
885 : }
886 :
887 0 : mpFS->endElementNS( XML_a, XML_graphicData );
888 0 : mpFS->endElementNS( XML_a, XML_graphic );
889 0 : }
890 :
891 0 : ShapeExport& ShapeExport::WriteTableShape( Reference< XShape > xShape )
892 : {
893 0 : FSHelperPtr pFS = GetFS();
894 :
895 : OSL_TRACE("write table shape");
896 :
897 0 : pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
898 :
899 0 : pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
900 :
901 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
902 : XML_id, I32S( GetNewShapeID( xShape ) ),
903 0 : XML_name, IDS(Table),
904 0 : FSEND );
905 :
906 : pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
907 0 : FSEND );
908 :
909 0 : if( GetDocumentType() == DOCUMENT_PPTX )
910 : pFS->singleElementNS( mnXmlNamespace, XML_nvPr,
911 0 : FSEND );
912 0 : pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
913 :
914 0 : WriteShapeTransformation( xShape, mnXmlNamespace, false);
915 0 : WriteTable( xShape );
916 :
917 0 : pFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
918 :
919 0 : return *this;
920 : }
921 :
922 0 : ShapeExport& ShapeExport::WriteTextShape( Reference< XShape > xShape )
923 : {
924 0 : FSHelperPtr pFS = GetFS();
925 :
926 0 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
927 :
928 : // non visual shape properties
929 0 : if (GetDocumentType() != DOCUMENT_DOCX)
930 : {
931 0 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
932 0 : WriteNonVisualDrawingProperties( xShape, IDS( TextShape ) );
933 : }
934 0 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, XML_txBox, "1", FSEND );
935 0 : if (GetDocumentType() != DOCUMENT_DOCX)
936 : {
937 0 : WriteNonVisualProperties( xShape );
938 0 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
939 : }
940 :
941 : // visual shape properties
942 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
943 0 : WriteShapeTransformation( xShape, XML_a, false, false, false);
944 0 : WritePresetShape( "rect" );
945 0 : uno::Reference<beans::XPropertySet> xPropertySet(xShape, UNO_QUERY);
946 0 : WriteBlipOrNormalFill(xPropertySet, "GraphicURL");
947 0 : WriteOutline(xPropertySet);
948 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
949 :
950 0 : WriteTextBox( xShape, mnXmlNamespace );
951 :
952 0 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
953 :
954 0 : return *this;
955 : }
956 :
957 0 : ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape )
958 : {
959 0 : Reference< XPropertySet > xPropSet( xShape, UNO_QUERY );
960 0 : if( xPropSet.is() ) {
961 0 : if( GetProperty( xPropSet, "Model" ) )
962 : {
963 0 : Reference< XChartDocument > xChartDoc;
964 0 : mAny >>= xChartDoc;
965 0 : if( xChartDoc.is() )
966 : {
967 : //export the chart
968 0 : Reference< XModel > xModel( xChartDoc, UNO_QUERY );
969 0 : ChartExport aChartExport( mnXmlNamespace, GetFS(), xModel, GetFB(), GetDocumentType() );
970 : static sal_Int32 nChartCount = 0;
971 0 : aChartExport.WriteChartObj( xShape, ++nChartCount );
972 : }
973 : else
974 : {
975 : // this part now supports only embedded spreadsheets, it can be extended to support remaining ooxml documents
976 : // only exporter, counter and object filename are specific to spreadsheet
977 0 : Reference< XSpreadsheetDocument > xSheetDoc( mAny, UNO_QUERY );
978 0 : if( xSheetDoc.is() && mpFB)
979 : {
980 0 : Reference< XComponent > xDocument( mAny, UNO_QUERY );
981 0 : if( xDocument.is() )
982 : {
983 : Reference< XOutputStream > xOutStream = mpFB->openFragmentStream( OUStringBuffer()
984 0 : .appendAscii( GetComponentDir() )
985 0 : .appendAscii( "/embeddings/spreadsheet" )
986 0 : .append( (sal_Int32) mnSpreadsheetCounter )
987 0 : .appendAscii( ".xlsx" )
988 : .makeStringAndClear(),
989 0 : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
990 : // export the embedded document
991 0 : Sequence< PropertyValue > rMedia(1);
992 :
993 0 : rMedia[0].Name = utl::MediaDescriptor::PROP_STREAMFOROUTPUT();
994 0 : rMedia[0].Value <<= xOutStream;
995 :
996 : Reference< XExporter > xExporter(
997 0 : mpFB->getComponentContext()->getServiceManager()->
998 : createInstanceWithContext(
999 : "com.sun.star.comp.oox.xls.ExcelFilter",
1000 0 : mpFB->getComponentContext() ),
1001 0 : UNO_QUERY_THROW );
1002 0 : xExporter->setSourceDocument( xDocument );
1003 0 : Reference< XFilter >( xExporter, UNO_QUERY_THROW )->
1004 0 : filter( rMedia );
1005 :
1006 0 : xOutStream->closeOutput();
1007 :
1008 : OUString sRelId = mpFB->addRelation( mpFS->getOutputStream(),
1009 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package",
1010 : OUStringBuffer()
1011 0 : .appendAscii( GetRelationCompPrefix() )
1012 0 : .appendAscii( "embeddings/spreadsheet" )
1013 0 : .append( (sal_Int32) mnSpreadsheetCounter ++ )
1014 0 : .appendAscii( ".xlsx" )
1015 0 : .makeStringAndClear() );
1016 :
1017 0 : mpFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
1018 :
1019 0 : mpFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
1020 :
1021 : mpFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
1022 : XML_id, I32S( GetNewShapeID( xShape ) ),
1023 0 : XML_name, IDS(Object),
1024 0 : FSEND );
1025 :
1026 : mpFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
1027 0 : FSEND );
1028 :
1029 0 : if( GetDocumentType() == DOCUMENT_PPTX )
1030 : mpFS->singleElementNS( mnXmlNamespace, XML_nvPr,
1031 0 : FSEND );
1032 0 : mpFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
1033 :
1034 0 : WriteShapeTransformation( xShape, mnXmlNamespace );
1035 :
1036 0 : mpFS->startElementNS( XML_a, XML_graphic, FSEND );
1037 : mpFS->startElementNS( XML_a, XML_graphicData,
1038 : XML_uri, "http://schemas.openxmlformats.org/presentationml/2006/ole",
1039 0 : FSEND );
1040 : mpFS->startElementNS( mnXmlNamespace, XML_oleObj,
1041 : XML_name, "Spreadsheet",
1042 : FSNS(XML_r, XML_id), USS( sRelId ),
1043 0 : FSEND );
1044 :
1045 0 : mpFS->singleElementNS( mnXmlNamespace, XML_embed, FSEND );
1046 :
1047 : // pic element
1048 0 : SdrObject* pSdrOLE2( GetSdrObjectFromXShape( xShape ) );
1049 0 : if ( pSdrOLE2 && pSdrOLE2->ISA( SdrOle2Obj ) )
1050 : {
1051 0 : const Graphic* pGraphic = ((SdrOle2Obj*)pSdrOLE2)->GetGraphic();
1052 0 : if ( pGraphic )
1053 0 : WriteGraphicObjectShapePart( xShape, pGraphic );
1054 : }
1055 :
1056 0 : mpFS->endElementNS( mnXmlNamespace, XML_oleObj );
1057 :
1058 0 : mpFS->endElementNS( XML_a, XML_graphicData );
1059 0 : mpFS->endElementNS( XML_a, XML_graphic );
1060 :
1061 0 : mpFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
1062 0 : }
1063 0 : }
1064 0 : }
1065 : }
1066 : }
1067 0 : return *this;
1068 : }
1069 :
1070 0 : ShapeExport& ShapeExport::WriteUnknownShape( Reference< XShape > )
1071 : {
1072 : // Override this method to do something useful.
1073 0 : return *this;
1074 : }
1075 :
1076 0 : size_t ShapeExport::ShapeHash::operator()( const Reference < XShape > rXShape ) const
1077 : {
1078 0 : return rXShape->getShapeType().hashCode();
1079 : }
1080 :
1081 0 : sal_Int32 ShapeExport::GetNewShapeID( const Reference< XShape > rXShape )
1082 : {
1083 0 : return GetNewShapeID( rXShape, GetFB() );
1084 : }
1085 :
1086 0 : sal_Int32 ShapeExport::GetNewShapeID( const Reference< XShape > rXShape, XmlFilterBase* pFB )
1087 : {
1088 0 : if( !rXShape.is() )
1089 0 : return -1;
1090 :
1091 0 : sal_Int32 nID = pFB->GetUniqueId();
1092 :
1093 0 : (*mpShapeMap)[ rXShape ] = nID;
1094 :
1095 0 : return nID;
1096 : }
1097 :
1098 0 : sal_Int32 ShapeExport::GetShapeID( const Reference< XShape > rXShape )
1099 : {
1100 0 : return GetShapeID( rXShape, mpShapeMap );
1101 : }
1102 :
1103 0 : sal_Int32 ShapeExport::GetShapeID( const Reference< XShape > rXShape, ShapeHashMap* pShapeMap )
1104 : {
1105 0 : if( !rXShape.is() )
1106 0 : return -1;
1107 :
1108 0 : ShapeHashMap::const_iterator aIter = pShapeMap->find( rXShape );
1109 :
1110 0 : if( aIter == pShapeMap->end() )
1111 0 : return -1;
1112 :
1113 0 : return aIter->second;
1114 : }
1115 :
1116 0 : } }
1117 :
1118 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|