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