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 <sal/config.h>
21 :
22 : #include <config_global.h>
23 : #include <unotools/mediadescriptor.hxx>
24 : #include <filter/msfilter/util.hxx>
25 : #include "oox/core/xmlfilterbase.hxx"
26 : #include "oox/export/shapes.hxx"
27 : #include "oox/export/utils.hxx"
28 : #include <oox/token/tokens.hxx>
29 :
30 : #include <cstdio>
31 : #include <initializer_list>
32 :
33 : #include <com/sun/star/awt/CharSet.hpp>
34 : #include <com/sun/star/awt/FontDescriptor.hpp>
35 : #include <com/sun/star/awt/FontSlant.hpp>
36 : #include <com/sun/star/awt/FontWeight.hpp>
37 : #include <com/sun/star/awt/FontUnderline.hpp>
38 : #include <com/sun/star/awt/Gradient.hpp>
39 : #include <com/sun/star/beans/XPropertySet.hpp>
40 : #include <com/sun/star/beans/XPropertySetInfo.hpp>
41 : #include <com/sun/star/beans/XPropertyState.hpp>
42 : #include <com/sun/star/container/XEnumerationAccess.hpp>
43 : #include <com/sun/star/document/XExporter.hpp>
44 : #include <com/sun/star/drawing/FillStyle.hpp>
45 : #include <com/sun/star/drawing/BitmapMode.hpp>
46 : #include <com/sun/star/drawing/ConnectorType.hpp>
47 : #include <com/sun/star/drawing/LineDash.hpp>
48 : #include <com/sun/star/drawing/LineJoint.hpp>
49 : #include <com/sun/star/drawing/LineStyle.hpp>
50 : #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
51 : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
52 : #include <com/sun/star/graphic/XGraphic.hpp>
53 : #include <com/sun/star/i18n/ScriptType.hpp>
54 : #include <com/sun/star/io/XOutputStream.hpp>
55 : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
56 : #include <com/sun/star/style/ParagraphAdjust.hpp>
57 : #include <com/sun/star/text/XSimpleText.hpp>
58 : #include <com/sun/star/text/XText.hpp>
59 : #include <com/sun/star/text/XTextContent.hpp>
60 : #include <com/sun/star/text/XTextDocument.hpp>
61 : #include <com/sun/star/text/XTextField.hpp>
62 : #include <com/sun/star/text/XTextRange.hpp>
63 : #include <com/sun/star/table/XTable.hpp>
64 : #include <com/sun/star/table/XColumnRowRange.hpp>
65 : #include <com/sun/star/table/XCellRange.hpp>
66 : #include <com/sun/star/table/XMergeableCell.hpp>
67 : #include <com/sun/star/chart2/XChartDocument.hpp>
68 : #include <com/sun/star/frame/XModel.hpp>
69 : #include <com/sun/star/table/BorderLine2.hpp>
70 : #include <tools/stream.hxx>
71 : #include <vcl/cvtgrf.hxx>
72 : #include <unotools/fontcvt.hxx>
73 : #include <vcl/graph.hxx>
74 : #include <vcl/outdev.hxx>
75 : #include <svtools/grfmgr.hxx>
76 : #include <rtl/strbuf.hxx>
77 : #include <sfx2/app.hxx>
78 : #include <svl/languageoptions.hxx>
79 : #include <filter/msfilter/escherex.hxx>
80 : #include <svx/svdoashp.hxx>
81 : #include <svx/svdoole2.hxx>
82 : #include <editeng/svxenum.hxx>
83 : #include <svx/unoapi.hxx>
84 : #include <oox/export/chartexport.hxx>
85 :
86 : using namespace ::css;
87 : using namespace ::css::beans;
88 : using namespace ::css::uno;
89 : using namespace ::css::drawing;
90 : using namespace ::css::i18n;
91 : using namespace ::css::table;
92 : using namespace ::css::container;
93 : using namespace ::css::document;
94 : using namespace ::css::text;
95 :
96 : using ::css::graphic::XGraphic;
97 : using ::css::io::XOutputStream;
98 : using ::css::lang::XComponent;
99 : using ::css::chart2::XChartDocument;
100 : using ::css::frame::XModel;
101 : using ::css::sheet::XSpreadsheetDocument;
102 :
103 : using ::oox::core::XmlFilterBase;
104 : using ::sax_fastparser::FSHelperPtr;
105 :
106 : #define IDS(x) OString(OStringLiteral(#x " ") + OString::number( mnShapeIdMax++ )).getStr()
107 :
108 : namespace oox { namespace drawingml {
109 :
110 1510 : URLTransformer::~URLTransformer()
111 : {
112 1510 : }
113 :
114 0 : OUString URLTransformer::getTransformedString(const OUString& rString) const
115 : {
116 0 : return rString;
117 : }
118 :
119 0 : bool URLTransformer::isExternalURL(const OUString& /*rURL*/) const
120 : {
121 0 : return true;
122 : }
123 :
124 : #define GETA(propName) \
125 : GetProperty( rXPropSet, OUString(#propName))
126 :
127 : #define GETAD(propName) \
128 : ( GetPropertyAndState( rXPropSet, rXPropState, OUString(#propName), eState ) && eState == beans::PropertyState_DIRECT_VALUE )
129 :
130 : #define GET(variable, propName) \
131 : if ( GETA(propName) ) \
132 : mAny >>= variable;
133 :
134 : // not thread safe
135 : int ShapeExport::mnEmbeddeDocumentCounter = 1;
136 :
137 744 : ShapeExport::ShapeExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, ShapeHashMap* pShapeMap, XmlFilterBase* pFB, DocumentType eDocumentType, DMLTextExport* pTextExport )
138 : : DrawingML( pFS, pFB, eDocumentType, pTextExport )
139 : , mnShapeIdMax( 1 )
140 : , mnPictureIdMax( 1 )
141 : , mnXmlNamespace( nXmlNamespace )
142 : , maFraction( 1, 576 )
143 : , maMapModeSrc( MAP_100TH_MM )
144 : , maMapModeDest( MAP_INCH, Point(), maFraction, maFraction )
145 744 : , mpShapeMap( pShapeMap ? pShapeMap : &maShapeMap )
146 : {
147 744 : mpURLTransformer.reset(new URLTransformer);
148 744 : }
149 :
150 22 : void ShapeExport::SetURLTranslator(std::shared_ptr<URLTransformer> pTransformer)
151 : {
152 22 : mpURLTransformer = pTransformer;
153 22 : }
154 :
155 0 : awt::Size ShapeExport::MapSize( const awt::Size& rSize ) const
156 : {
157 0 : Size aRetSize( OutputDevice::LogicToLogic( Size( rSize.Width, rSize.Height ), maMapModeSrc, maMapModeDest ) );
158 :
159 0 : if ( !aRetSize.Width() )
160 0 : aRetSize.Width()++;
161 0 : if ( !aRetSize.Height() )
162 0 : aRetSize.Height()++;
163 0 : return awt::Size( aRetSize.Width(), aRetSize.Height() );
164 : }
165 :
166 2538 : bool ShapeExport::NonEmptyText( Reference< XInterface > xIface )
167 : {
168 2538 : Reference< XPropertySet > xPropSet( xIface, UNO_QUERY );
169 :
170 2538 : if( xPropSet.is() )
171 : {
172 2538 : Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
173 2538 : if ( xPropSetInfo.is() )
174 : {
175 2538 : if ( xPropSetInfo->hasPropertyByName( "IsEmptyPresentationObject" ) )
176 : {
177 2002 : bool bIsEmptyPresObj = false;
178 2002 : if ( xPropSet->getPropertyValue( "IsEmptyPresentationObject" ) >>= bIsEmptyPresObj )
179 : {
180 : SAL_INFO("oox.shape", "empty presentation object " << bIsEmptyPresObj << " , props:");
181 2002 : if( bIsEmptyPresObj )
182 1763 : return true;
183 : }
184 : }
185 :
186 775 : if ( xPropSetInfo->hasPropertyByName( "IsPresentationObject" ) )
187 : {
188 239 : bool bIsPresObj = false;
189 239 : if ( xPropSet->getPropertyValue( "IsPresentationObject" ) >>= bIsPresObj )
190 : {
191 : SAL_INFO("oox.shape", "presentation object " << bIsPresObj << ", props:");
192 239 : if( bIsPresObj )
193 208 : return true;
194 : }
195 : }
196 567 : }
197 : }
198 :
199 1134 : Reference< XSimpleText > xText( xIface, UNO_QUERY );
200 :
201 567 : if( xText.is() )
202 567 : return xText->getString().getLength();
203 :
204 2538 : return false;
205 : }
206 :
207 44 : ShapeExport& ShapeExport::WriteBezierShape( Reference< XShape > xShape, bool bClosed )
208 : {
209 : SAL_INFO("oox.shape", "write open bezier shape");
210 :
211 44 : FSHelperPtr pFS = GetFS();
212 44 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
213 :
214 88 : tools::PolyPolygon aPolyPolygon = EscherPropertyContainer::GetPolyPolygon( xShape );
215 44 : Rectangle aRect( aPolyPolygon.GetBoundRect() );
216 :
217 : #if OSL_DEBUG_LEVEL > 0
218 : awt::Size size = MapSize( awt::Size( aRect.GetWidth(), aRect.GetHeight() ) );
219 : SAL_INFO("oox.shape", "poly count " << aPolyPolygon.Count());
220 : SAL_INFO("oox.shape", "size: " << size.Width << " x " << size.Height);
221 : #endif
222 :
223 : // non visual shape properties
224 44 : if (GetDocumentType() != DOCUMENT_DOCX)
225 : {
226 0 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
227 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
228 : XML_id, I32S( GetNewShapeID( xShape ) ),
229 0 : XML_name, IDS( Freeform ),
230 0 : FSEND );
231 : }
232 44 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
233 44 : if (GetDocumentType() != DOCUMENT_DOCX)
234 : {
235 0 : WriteNonVisualProperties( xShape );
236 0 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
237 : }
238 :
239 : // visual shape properties
240 44 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
241 44 : WriteTransformation( aRect, XML_a );
242 44 : WritePolyPolygon( aPolyPolygon );
243 88 : Reference< XPropertySet > xProps( xShape, UNO_QUERY );
244 44 : if( xProps.is() ) {
245 44 : if( bClosed )
246 43 : WriteFill( xProps );
247 44 : WriteOutline( xProps );
248 : }
249 :
250 44 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
251 :
252 : // write text
253 44 : WriteTextBox( xShape, mnXmlNamespace );
254 :
255 44 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
256 :
257 88 : return *this;
258 : }
259 :
260 43 : ShapeExport& ShapeExport::WriteClosedBezierShape( Reference< XShape > xShape )
261 : {
262 43 : return WriteBezierShape( xShape, true );
263 : }
264 :
265 1 : ShapeExport& ShapeExport::WriteOpenBezierShape( Reference< XShape > xShape )
266 : {
267 1 : return WriteBezierShape( xShape, false );
268 : }
269 :
270 38 : ShapeExport& ShapeExport::WriteGroupShape(uno::Reference<drawing::XShape> xShape)
271 : {
272 38 : FSHelperPtr pFS = GetFS();
273 38 : bool bToplevel = !m_xParent.is();
274 38 : if (!bToplevel)
275 9 : mnXmlNamespace = XML_wpg;
276 38 : pFS->startElementNS(mnXmlNamespace, (bToplevel ? XML_wgp : XML_grpSp), FSEND);
277 :
278 : // non visual properties
279 38 : pFS->singleElementNS(mnXmlNamespace, XML_cNvGrpSpPr, FSEND);
280 :
281 : // visual properties
282 38 : pFS->startElementNS(mnXmlNamespace, XML_grpSpPr, FSEND);
283 38 : WriteShapeTransformation(xShape, XML_a);
284 38 : pFS->endElementNS(mnXmlNamespace, XML_grpSpPr);
285 :
286 76 : uno::Reference<drawing::XShapes> xGroupShape(xShape, uno::UNO_QUERY_THROW);
287 76 : uno::Reference<drawing::XShape> xParent = m_xParent;
288 38 : m_xParent = xShape;
289 496 : for (sal_Int32 i = 0; i < xGroupShape->getCount(); ++i)
290 : {
291 458 : uno::Reference<drawing::XShape> xChild(xGroupShape->getByIndex(i), uno::UNO_QUERY_THROW);
292 458 : sal_Int32 nSavedNamespace = mnXmlNamespace;
293 :
294 916 : uno::Reference<lang::XServiceInfo> xServiceInfo(xChild, uno::UNO_QUERY_THROW);
295 458 : if (xServiceInfo->supportsService("com.sun.star.drawing.GraphicObjectShape"))
296 8 : mnXmlNamespace = XML_pic;
297 : else
298 450 : mnXmlNamespace = XML_wps;
299 458 : WriteShape(xChild);
300 :
301 458 : mnXmlNamespace = nSavedNamespace;
302 458 : }
303 38 : m_xParent = xParent;
304 :
305 38 : pFS->endElementNS(mnXmlNamespace, (bToplevel ? XML_wgp : XML_grpSp));
306 76 : return *this;
307 : }
308 :
309 102 : static bool lcl_IsOnBlacklist(OUString& rShapeType)
310 : {
311 : #if !HAVE_BROKEN_STATIC_INITILIZER_LIST
312 : static
313 : #endif
314 : const std::initializer_list<OUStringLiteral> vBlacklist = {
315 : OUStringLiteral("ellipse"),
316 : OUStringLiteral("ring"),
317 : OUStringLiteral("can"),
318 : OUStringLiteral("cube"),
319 : OUStringLiteral("paper"),
320 : OUStringLiteral("frame"),
321 : OUStringLiteral("smiley"),
322 : OUStringLiteral("sun"),
323 : OUStringLiteral("flower"),
324 : OUStringLiteral("forbidden"),
325 : OUStringLiteral("bracket-pair"),
326 : OUStringLiteral("brace-pair"),
327 : OUStringLiteral("col-60da8460"),
328 : OUStringLiteral("col-502ad400"),
329 : OUStringLiteral("quad-bevel"),
330 : OUStringLiteral("cloud-callout"),
331 : OUStringLiteral("line-callout-1"),
332 : OUStringLiteral("line-callout-2"),
333 : OUStringLiteral("line-callout-3"),
334 : OUStringLiteral("paper"),
335 : OUStringLiteral("vertical-scroll"),
336 : OUStringLiteral("horizontal-scroll"),
337 : OUStringLiteral("mso-spt34"),
338 : OUStringLiteral("mso-spt75"),
339 : OUStringLiteral("mso-spt164"),
340 : OUStringLiteral("mso-spt180"),
341 : OUStringLiteral("flowchart-process"),
342 : OUStringLiteral("flowchart-alternate-process"),
343 : OUStringLiteral("flowchart-decision"),
344 : OUStringLiteral("flowchart-data"),
345 : OUStringLiteral("flowchart-predefined-process"),
346 : OUStringLiteral("flowchart-internal-storage"),
347 : OUStringLiteral("flowchart-document"),
348 : OUStringLiteral("flowchart-multidocument"),
349 : OUStringLiteral("flowchart-terminator"),
350 : OUStringLiteral("flowchart-preparation"),
351 : OUStringLiteral("flowchart-manual-input"),
352 : OUStringLiteral("flowchart-manual-operation"),
353 : OUStringLiteral("flowchart-connector"),
354 : OUStringLiteral("flowchart-off-page-connector"),
355 : OUStringLiteral("flowchart-card"),
356 : OUStringLiteral("flowchart-punched-tape"),
357 : OUStringLiteral("flowchart-summing-junction"),
358 : OUStringLiteral("flowchart-or"),
359 : OUStringLiteral("flowchart-collate"),
360 : OUStringLiteral("flowchart-sort"),
361 : OUStringLiteral("flowchart-extract"),
362 : OUStringLiteral("flowchart-merge"),
363 : OUStringLiteral("flowchart-stored-data"),
364 : OUStringLiteral("flowchart-delay"),
365 : OUStringLiteral("flowchart-sequential-access"),
366 : OUStringLiteral("flowchart-magnetic-disk"),
367 : OUStringLiteral("flowchart-direct-access-storage"),
368 : OUStringLiteral("flowchart-display")
369 102 : };
370 :
371 102 : return std::find(vBlacklist.begin(), vBlacklist.end(), rShapeType) != vBlacklist.end();
372 : }
373 :
374 102 : static bool lcl_IsOnWhitelist(OUString& rShapeType)
375 : {
376 : #if !HAVE_BROKEN_STATIC_INITILIZER_LIST
377 : static
378 : #endif
379 : const std::initializer_list<OUStringLiteral> vWhitelist = {
380 : OUStringLiteral("heart"),
381 : OUStringLiteral("puzzle")
382 102 : };
383 :
384 102 : return std::find(vWhitelist.begin(), vWhitelist.end(), rShapeType) != vWhitelist.end();
385 : }
386 :
387 :
388 413 : ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
389 : {
390 : SAL_INFO("oox.shape", "write custom shape");
391 :
392 413 : Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
393 413 : bool bPredefinedHandlesUsed = true;
394 413 : bool bHasHandles = false;
395 826 : OUString sShapeType;
396 413 : sal_uInt32 nMirrorFlags = 0;
397 413 : MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType( xShape, nMirrorFlags, sShapeType );
398 413 : SdrObjCustomShape* pShape = static_cast<SdrObjCustomShape*>( GetSdrObjectFromXShape( xShape ) );
399 413 : bool bIsDefaultObject = EscherPropertyContainer::IsDefaultObject( pShape, eShapeType );
400 413 : const char* sPresetShape = msfilter::util::GetOOXMLPresetGeometry( USS( sShapeType ) );
401 : SAL_INFO("oox.shape", "custom shape type: " << sShapeType << " ==> " << sPresetShape);
402 826 : Sequence< PropertyValue > aGeometrySeq;
403 413 : sal_Int32 nAdjustmentValuesIndex = -1;
404 :
405 413 : bool bFlipH = false;
406 413 : bool bFlipV = false;
407 :
408 413 : if( GETA( CustomShapeGeometry ) ) {
409 : SAL_INFO("oox.shape", "got custom shape geometry");
410 413 : if( mAny >>= aGeometrySeq ) {
411 :
412 : SAL_INFO("oox.shape", "got custom shape geometry sequence");
413 4134 : for( int i = 0; i < aGeometrySeq.getLength(); i++ ) {
414 3721 : const PropertyValue& rProp = aGeometrySeq[ i ];
415 : SAL_INFO("oox.shape", "geometry property: " << rProp.Name);
416 :
417 3721 : if ( rProp.Name == "MirroredX" )
418 364 : rProp.Value >>= bFlipH;
419 :
420 3721 : if ( rProp.Name == "MirroredY" )
421 366 : rProp.Value >>= bFlipV;
422 3721 : if ( rProp.Name == "AdjustmentValues" )
423 413 : nAdjustmentValuesIndex = i;
424 3308 : else if ( rProp.Name == "Handles" )
425 : {
426 326 : uno::Sequence<beans::PropertyValue> aHandles;
427 326 : rProp.Value >>= aHandles;
428 326 : if ( aHandles.getLength() )
429 0 : bHasHandles = true;
430 326 : if( !bIsDefaultObject )
431 311 : bPredefinedHandlesUsed = false;
432 : // TODO: update nAdjustmentsWhichNeedsToBeConverted here
433 : }
434 2982 : else if ( rProp.Name == "PresetTextWarp" )
435 : {
436 33 : rProp.Value >>= m_presetWarp;
437 : }
438 : }
439 : }
440 : }
441 :
442 826 : FSHelperPtr pFS = GetFS();
443 413 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
444 :
445 : // non visual shape properties
446 413 : if (GetDocumentType() != DOCUMENT_DOCX)
447 : {
448 35 : bool isVisible = true ;
449 35 : if( GETA (Visible))
450 : {
451 35 : mAny >>= isVisible;
452 : }
453 35 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
454 : pFS->startElementNS( mnXmlNamespace, XML_cNvPr,
455 : XML_id, I32S( GetNewShapeID( xShape ) ),
456 70 : XML_name, IDS( CustomShape ),
457 : XML_hidden, isVisible ? NULL : "1",
458 70 : FSEND );
459 :
460 35 : if( GETA( URL ) )
461 : {
462 10 : OUString sURL;
463 10 : mAny >>= sURL;
464 10 : if( !sURL.isEmpty() )
465 : {
466 : OUString sRelId = mpFB->addRelation( mpFS->getOutputStream(),
467 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
468 3 : mpURLTransformer->getTransformedString(sURL),
469 6 : mpURLTransformer->isExternalURL(sURL));
470 :
471 : mpFS->singleElementNS( XML_a, XML_hlinkClick,
472 : FSNS( XML_r,XML_id ), USS( sRelId ),
473 3 : FSEND );
474 10 : }
475 : }
476 35 : pFS->endElementNS(mnXmlNamespace, XML_cNvPr);
477 35 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
478 35 : WriteNonVisualProperties( xShape );
479 35 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
480 : }
481 : else
482 378 : pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr, FSEND);
483 :
484 : // visual shape properties
485 413 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
486 : // moon is flipped in MSO, and mso-spt89 (right up arrow) is mapped to leftUpArrow
487 413 : if ( sShapeType == "moon" || sShapeType == "mso-spt89" )
488 0 : WriteShapeTransformation( xShape, XML_a, !bFlipH, bFlipV, false);
489 : else
490 413 : WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, false);
491 :
492 : // we export non-primitive shapes to custom geometry
493 : // we also export non-ooxml shapes which have handles/equations to custom geometry, because
494 : // we cannot convert ODF equations to DrawingML equations. TODO: see what binary DOC export filter does.
495 : // but our WritePolyPolygon() function is incomplete, therefore we use a blacklist
496 : // we use a whitelist for shapes where mapping to MSO preset shape is not optimal
497 413 : bool bCustGeom = true;
498 413 : if( sShapeType == "ooxml-non-primitive" )
499 26 : bCustGeom = true;
500 387 : else if( sShapeType.startsWith("ooxml") )
501 285 : bCustGeom = false;
502 102 : else if( lcl_IsOnWhitelist(sShapeType) )
503 0 : bCustGeom = true;
504 102 : else if( lcl_IsOnBlacklist(sShapeType) )
505 13 : bCustGeom = false;
506 89 : else if( bHasHandles )
507 0 : bCustGeom = true;
508 :
509 413 : if (bHasHandles && bCustGeom && pShape)
510 : {
511 0 : WritePolyPolygon( tools::PolyPolygon( pShape->GetLineGeometry(true) ) );
512 : }
513 413 : else if (bCustGeom && pShape)
514 : {
515 115 : WriteCustomGeometry( xShape );
516 : }
517 : else // preset geometry
518 : {
519 298 : if( nAdjustmentValuesIndex != -1 )
520 : {
521 298 : sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
522 : WritePresetShape( sPresetShape, eShapeType, bPredefinedHandlesUsed,
523 298 : nAdjustmentsWhichNeedsToBeConverted, aGeometrySeq[ nAdjustmentValuesIndex ] );
524 : }
525 : else
526 0 : WritePresetShape( sPresetShape );
527 : }
528 413 : if( rXPropSet.is() )
529 : {
530 413 : WriteFill( rXPropSet );
531 413 : WriteOutline( rXPropSet );
532 413 : WriteShapeEffects( rXPropSet );
533 413 : WriteShape3DEffects( rXPropSet );
534 : }
535 :
536 413 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
537 :
538 413 : pFS->startElementNS( mnXmlNamespace, XML_style, FSEND );
539 413 : WriteShapeStyle( rXPropSet );
540 413 : pFS->endElementNS( mnXmlNamespace, XML_style );
541 :
542 : // write text
543 413 : WriteTextBox( xShape, mnXmlNamespace );
544 :
545 413 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
546 :
547 826 : return *this;
548 : }
549 :
550 0 : ShapeExport& ShapeExport::WriteEllipseShape( Reference< XShape > xShape )
551 : {
552 : SAL_INFO("oox.shape", "write ellipse shape");
553 :
554 0 : FSHelperPtr pFS = GetFS();
555 :
556 0 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
557 :
558 : // TODO: arc, section, cut, connector
559 :
560 : // non visual shape properties
561 0 : if (GetDocumentType() != DOCUMENT_DOCX)
562 : {
563 0 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
564 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
565 : XML_id, I32S( GetNewShapeID( xShape ) ),
566 0 : XML_name, IDS( Ellipse ),
567 0 : FSEND );
568 0 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
569 0 : WriteNonVisualProperties( xShape );
570 0 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
571 : }
572 : else
573 0 : pFS->singleElementNS(mnXmlNamespace, XML_cNvSpPr, FSEND);
574 :
575 : // visual shape properties
576 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
577 0 : WriteShapeTransformation( xShape, XML_a, false, false, false);
578 0 : WritePresetShape( "ellipse" );
579 0 : Reference< XPropertySet > xProps( xShape, UNO_QUERY );
580 0 : if( xProps.is() )
581 : {
582 0 : WriteFill( xProps );
583 0 : WriteOutline( xProps );
584 : }
585 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
586 :
587 : // write text
588 0 : WriteTextBox( xShape, mnXmlNamespace );
589 :
590 0 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
591 :
592 0 : return *this;
593 : }
594 :
595 110 : ShapeExport& ShapeExport::WriteGraphicObjectShape( Reference< XShape > xShape )
596 : {
597 110 : WriteGraphicObjectShapePart( xShape );
598 :
599 110 : return *this;
600 : }
601 :
602 110 : void ShapeExport::WriteGraphicObjectShapePart( Reference< XShape > xShape, const Graphic* pGraphic )
603 : {
604 : SAL_INFO("oox.shape", "write graphic object shape");
605 :
606 110 : if( NonEmptyText( xShape ) )
607 : {
608 : // avoid treating all 'IsPresentationObject' objects as having text.
609 54 : Reference< XSimpleText > xText( xShape, UNO_QUERY );
610 :
611 54 : if( xText.is() && xText->getString().getLength() )
612 : {
613 : SAL_INFO("oox.shape", "graphicObject: wrote only text");
614 :
615 0 : WriteTextShape( xShape );
616 :
617 : //DBG(dump_pset(mXPropSet));
618 0 : return;
619 54 : }
620 : }
621 :
622 : SAL_INFO("oox.shape", "graphicObject without text");
623 :
624 110 : OUString sGraphicURL;
625 220 : Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
626 110 : if( !pGraphic && ( !xShapeProps.is() || !( xShapeProps->getPropertyValue( "GraphicURL" ) >>= sGraphicURL ) ) )
627 : {
628 : SAL_INFO("oox.shape", "no graphic URL found");
629 0 : return;
630 : }
631 :
632 220 : FSHelperPtr pFS = GetFS();
633 :
634 110 : if (GetDocumentType() != DOCUMENT_DOCX)
635 68 : pFS->startElementNS( mnXmlNamespace, XML_pic, FSEND );
636 : else
637 : pFS->startElementNS( mnXmlNamespace, XML_pic,
638 : FSNS(XML_xmlns, XML_pic), "http://schemas.openxmlformats.org/drawingml/2006/picture",
639 42 : FSEND );
640 :
641 110 : pFS->startElementNS( mnXmlNamespace, XML_nvPicPr, FSEND );
642 :
643 220 : OUString sName, sDescr;
644 : bool bHaveName, bHaveDesc;
645 :
646 110 : if ( ( bHaveName= GetProperty( xShapeProps, "Name" ) ) )
647 110 : mAny >>= sName;
648 110 : if ( ( bHaveDesc = GetProperty( xShapeProps, "Description" ) ) )
649 110 : mAny >>= sDescr;
650 :
651 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
652 : XML_id, I32S( GetNewShapeID( xShape ) ),
653 220 : XML_name, bHaveName ? USS( sName ) : OString( "Picture " + OString::number( mnPictureIdMax++ )).getStr(),
654 330 : XML_descr, bHaveDesc ? USS( sDescr ) : NULL,
655 330 : FSEND );
656 : // OOXTODO: //cNvPr children: XML_extLst, XML_hlinkClick, XML_hlinkHover
657 :
658 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPicPr,
659 : // OOXTODO: XML_preferRelativeSize
660 110 : FSEND );
661 :
662 110 : WriteNonVisualProperties( xShape );
663 :
664 110 : pFS->endElementNS( mnXmlNamespace, XML_nvPicPr );
665 :
666 110 : pFS->startElementNS( mnXmlNamespace, XML_blipFill, FSEND );
667 :
668 110 : WriteBlip( xShapeProps, sGraphicURL, false, pGraphic );
669 :
670 110 : WriteSrcRect( xShapeProps, sGraphicURL );
671 :
672 : // now we stretch always when we get pGraphic (when changing that
673 : // behavior, test n#780830 for regression, where the OLE sheet might get tiled
674 110 : bool bStretch = false;
675 110 : if( !pGraphic && GetProperty( xShapeProps, "FillBitmapStretch" ) )
676 110 : mAny >>= bStretch;
677 :
678 110 : if ( pGraphic || bStretch )
679 110 : pFS->singleElementNS( XML_a, XML_stretch, FSEND );
680 :
681 110 : pFS->endElementNS( mnXmlNamespace, XML_blipFill );
682 :
683 : // visual shape properties
684 110 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
685 110 : WriteShapeTransformation( xShape, XML_a, false, false, false);
686 110 : WritePresetShape( "rect" );
687 : // graphic object can come with the frame (bnc#654525)
688 110 : WriteOutline( xShapeProps );
689 :
690 110 : WriteShapeEffects( xShapeProps );
691 110 : WriteShape3DEffects( xShapeProps );
692 :
693 110 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
694 :
695 220 : pFS->endElementNS( mnXmlNamespace, XML_pic );
696 : }
697 :
698 0 : ShapeExport& ShapeExport::WriteConnectorShape( Reference< XShape > xShape )
699 : {
700 0 : bool bFlipH = false;
701 0 : bool bFlipV = false;
702 :
703 : SAL_INFO("oox.shape", "write connector shape");
704 :
705 0 : FSHelperPtr pFS = GetFS();
706 :
707 0 : const char* sGeometry = "line";
708 0 : Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY );
709 0 : Reference< XPropertyState > rXPropState( xShape, UNO_QUERY );
710 0 : awt::Point aStartPoint, aEndPoint;
711 0 : Reference< XShape > rXShapeA;
712 0 : Reference< XShape > rXShapeB;
713 : PropertyState eState;
714 : ConnectorType eConnectorType;
715 0 : if( GETAD( EdgeKind ) ) {
716 0 : mAny >>= eConnectorType;
717 :
718 0 : switch( eConnectorType ) {
719 : case ConnectorType_CURVE:
720 0 : sGeometry = "curvedConnector3";
721 0 : break;
722 : case ConnectorType_STANDARD:
723 0 : sGeometry = "bentConnector3";
724 0 : break;
725 : default:
726 : case ConnectorType_LINE:
727 : case ConnectorType_LINES:
728 0 : sGeometry = "straightConnector1";
729 0 : break;
730 : }
731 :
732 0 : if( GETAD( EdgeStartPoint ) ) {
733 0 : mAny >>= aStartPoint;
734 0 : if( GETAD( EdgeEndPoint ) ) {
735 0 : mAny >>= aEndPoint;
736 : }
737 : }
738 0 : GET( rXShapeA, EdgeStartConnection );
739 0 : GET( rXShapeB, EdgeEndConnection );
740 : }
741 0 : EscherConnectorListEntry aConnectorEntry( xShape, aStartPoint, rXShapeA, aEndPoint, rXShapeB );
742 :
743 0 : Rectangle aRect( Point( aStartPoint.X, aStartPoint.Y ), Point( aEndPoint.X, aEndPoint.Y ) );
744 0 : if( aRect.getWidth() < 0 ) {
745 0 : bFlipH = true;
746 0 : aRect.setX( aEndPoint.X );
747 0 : aRect.setWidth( aStartPoint.X - aEndPoint.X );
748 : }
749 :
750 0 : if( aRect.getHeight() < 0 ) {
751 0 : bFlipV = true;
752 0 : aRect.setY( aEndPoint.Y );
753 0 : aRect.setHeight( aStartPoint.Y - aEndPoint.Y );
754 : }
755 :
756 0 : pFS->startElementNS( mnXmlNamespace, XML_cxnSp, FSEND );
757 :
758 : // non visual shape properties
759 0 : pFS->startElementNS( mnXmlNamespace, XML_nvCxnSpPr, FSEND );
760 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
761 : XML_id, I32S( GetNewShapeID( xShape ) ),
762 0 : XML_name, IDS( Line ),
763 0 : FSEND );
764 : // non visual connector shape drawing properties
765 0 : pFS->startElementNS( mnXmlNamespace, XML_cNvCxnSpPr, FSEND );
766 0 : WriteConnectorConnections( aConnectorEntry, GetShapeID( rXShapeA ), GetShapeID( rXShapeB ) );
767 0 : pFS->endElementNS( mnXmlNamespace, XML_cNvCxnSpPr );
768 0 : pFS->singleElementNS( mnXmlNamespace, XML_nvPr, FSEND );
769 0 : pFS->endElementNS( mnXmlNamespace, XML_nvCxnSpPr );
770 :
771 : // visual shape properties
772 0 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
773 0 : WriteTransformation( aRect, XML_a, bFlipH, bFlipV );
774 : // TODO: write adjustments (ppt export doesn't work well there either)
775 0 : WritePresetShape( sGeometry );
776 0 : Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
777 0 : if( xShapeProps.is() )
778 0 : WriteOutline( xShapeProps );
779 0 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
780 :
781 : // write text
782 0 : WriteTextBox( xShape, mnXmlNamespace );
783 :
784 0 : pFS->endElementNS( mnXmlNamespace, XML_cxnSp );
785 :
786 0 : return *this;
787 : }
788 :
789 16 : ShapeExport& ShapeExport::WriteLineShape( Reference< XShape > xShape )
790 : {
791 16 : bool bFlipH = false;
792 16 : bool bFlipV = false;
793 :
794 : SAL_INFO("oox.shape", "write line shape");
795 :
796 16 : FSHelperPtr pFS = GetFS();
797 :
798 16 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
799 :
800 32 : tools::PolyPolygon aPolyPolygon = EscherPropertyContainer::GetPolyPolygon( xShape );
801 16 : if( aPolyPolygon.Count() == 1 && aPolyPolygon[ 0 ].GetSize() == 2)
802 : {
803 16 : const Polygon& rPoly = aPolyPolygon[ 0 ];
804 :
805 16 : bFlipH = ( rPoly[ 0 ].X() > rPoly[ 1 ].X() );
806 16 : bFlipV = ( rPoly[ 0 ].Y() > rPoly[ 1 ].Y() );
807 : }
808 :
809 : // non visual shape properties
810 16 : if (GetDocumentType() != DOCUMENT_DOCX)
811 : {
812 1 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
813 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
814 : XML_id, I32S( GetNewShapeID( xShape ) ),
815 2 : XML_name, IDS( Line ),
816 1 : FSEND );
817 : }
818 16 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
819 16 : if (GetDocumentType() != DOCUMENT_DOCX)
820 : {
821 1 : WriteNonVisualProperties( xShape );
822 1 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
823 : }
824 :
825 : // visual shape properties
826 16 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
827 16 : WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, true);
828 16 : WritePresetShape( "line" );
829 32 : Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
830 16 : if( xShapeProps.is() )
831 16 : WriteOutline( xShapeProps );
832 16 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
833 :
834 : //write style
835 16 : pFS->startElementNS( mnXmlNamespace, XML_style, FSEND );
836 16 : WriteShapeStyle( xShapeProps );
837 16 : pFS->endElementNS( mnXmlNamespace, XML_style );
838 :
839 : // write text
840 16 : WriteTextBox( xShape, mnXmlNamespace );
841 :
842 16 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
843 :
844 32 : return *this;
845 : }
846 :
847 968 : ShapeExport& ShapeExport::WriteNonVisualDrawingProperties( Reference< XShape > xShape, const char* pName )
848 : {
849 : GetFS()->singleElementNS( mnXmlNamespace, XML_cNvPr,
850 : XML_id, I32S( GetNewShapeID( xShape ) ),
851 : XML_name, pName,
852 968 : FSEND );
853 :
854 968 : return *this;
855 : }
856 :
857 113 : ShapeExport& ShapeExport::WriteNonVisualProperties( Reference< XShape > )
858 : {
859 : // Override to generate //nvPr elements.
860 113 : return *this;
861 : }
862 :
863 50 : ShapeExport& ShapeExport::WriteRectangleShape( Reference< XShape > xShape )
864 : {
865 : SAL_INFO("oox.shape", "write rectangle shape");
866 :
867 50 : FSHelperPtr pFS = GetFS();
868 :
869 50 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
870 :
871 50 : sal_Int32 nRadius = 0;
872 :
873 100 : Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
874 50 : if( xShapeProps.is() )
875 : {
876 50 : xShapeProps->getPropertyValue( "CornerRadius" ) >>= nRadius;
877 : }
878 :
879 50 : if( nRadius )
880 : {
881 0 : nRadius = MapSize( awt::Size( nRadius, 0 ) ).Width;
882 : }
883 :
884 : // non visual shape properties
885 50 : if (GetDocumentType() == DOCUMENT_DOCX)
886 49 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
887 50 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
888 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
889 : XML_id, I32S( GetNewShapeID( xShape ) ),
890 100 : XML_name, IDS( Rectangle ),
891 50 : FSEND );
892 50 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, FSEND );
893 50 : WriteNonVisualProperties( xShape );
894 50 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
895 :
896 : // visual shape properties
897 50 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
898 50 : WriteShapeTransformation( xShape, XML_a, false, false, false);
899 50 : WritePresetShape( "rect" );
900 100 : Reference< XPropertySet > xProps( xShape, UNO_QUERY );
901 50 : if( xProps.is() )
902 : {
903 50 : WriteFill( xProps );
904 50 : WriteOutline( xProps );
905 : }
906 50 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
907 :
908 : // write text
909 50 : WriteTextBox( xShape, mnXmlNamespace );
910 :
911 50 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
912 :
913 100 : return *this;
914 : }
915 :
916 : typedef ShapeExport& (ShapeExport::*ShapeConverter)( Reference< XShape > );
917 : typedef std::unordered_map< const char*, ShapeConverter, rtl::CStringHash, rtl::CStringEqual> NameToConvertMapType;
918 :
919 3774 : static const NameToConvertMapType& lcl_GetConverters(DrawingML::DocumentType eDocumentType)
920 : {
921 : static bool shape_map_inited = false;
922 3774 : static NameToConvertMapType shape_converters;
923 3774 : if( shape_map_inited )
924 : {
925 3760 : return shape_converters;
926 : }
927 :
928 14 : shape_converters[ "com.sun.star.drawing.ClosedBezierShape" ] = &ShapeExport::WriteClosedBezierShape;
929 14 : shape_converters[ "com.sun.star.drawing.ConnectorShape" ] = &ShapeExport::WriteConnectorShape;
930 14 : shape_converters[ "com.sun.star.drawing.CustomShape" ] = &ShapeExport::WriteCustomShape;
931 14 : shape_converters[ "com.sun.star.drawing.EllipseShape" ] = &ShapeExport::WriteEllipseShape;
932 14 : shape_converters[ "com.sun.star.drawing.GraphicObjectShape" ] = &ShapeExport::WriteGraphicObjectShape;
933 14 : shape_converters[ "com.sun.star.drawing.LineShape" ] = &ShapeExport::WriteLineShape;
934 14 : shape_converters[ "com.sun.star.drawing.OpenBezierShape" ] = &ShapeExport::WriteOpenBezierShape;
935 14 : shape_converters[ "com.sun.star.drawing.RectangleShape" ] = &ShapeExport::WriteRectangleShape;
936 14 : shape_converters[ "com.sun.star.drawing.OLE2Shape" ] = &ShapeExport::WriteOLE2Shape;
937 14 : shape_converters[ "com.sun.star.drawing.TableShape" ] = &ShapeExport::WriteTableShape;
938 14 : shape_converters[ "com.sun.star.drawing.TextShape" ] = &ShapeExport::WriteTextShape;
939 :
940 14 : shape_converters[ "com.sun.star.presentation.GraphicObjectShape" ] = &ShapeExport::WriteGraphicObjectShape;
941 14 : shape_converters[ "com.sun.star.presentation.OLE2Shape" ] = &ShapeExport::WriteOLE2Shape;
942 14 : shape_converters[ "com.sun.star.presentation.TableShape" ] = &ShapeExport::WriteTableShape;
943 14 : shape_converters[ "com.sun.star.presentation.TextShape" ] = &ShapeExport::WriteTextShape;
944 :
945 14 : shape_converters[ "com.sun.star.presentation.DateTimeShape" ] = &ShapeExport::WriteTextShape;
946 14 : shape_converters[ "com.sun.star.presentation.FooterShape" ] = &ShapeExport::WriteTextShape;
947 14 : shape_converters[ "com.sun.star.presentation.HeaderShape" ] = &ShapeExport::WriteTextShape;
948 14 : shape_converters[ "com.sun.star.presentation.NotesShape" ] = &ShapeExport::WriteTextShape;
949 14 : shape_converters[ "com.sun.star.presentation.OutlinerShape" ] = &ShapeExport::WriteTextShape;
950 14 : shape_converters[ "com.sun.star.presentation.SlideNumberShape" ] = &ShapeExport::WriteTextShape;
951 14 : shape_converters[ "com.sun.star.presentation.TitleTextShape" ] = &ShapeExport::WriteTextShape;
952 14 : if (eDocumentType == DrawingML::DOCUMENT_DOCX)
953 11 : shape_converters[ "com.sun.star.drawing.GroupShape" ] = &ShapeExport::WriteGroupShape;
954 14 : shape_map_inited = true;
955 :
956 14 : return shape_converters;
957 : }
958 :
959 1887 : ShapeExport& ShapeExport::WriteShape( Reference< XShape > xShape )
960 : {
961 1887 : OUString sShapeType = xShape->getShapeType();
962 : SAL_INFO("oox.shape", "write shape: " << sShapeType);
963 1887 : NameToConvertMapType::const_iterator aConverter = lcl_GetConverters(GetDocumentType()).find( USS( sShapeType ) );
964 1887 : if( aConverter == lcl_GetConverters(GetDocumentType()).end() )
965 : {
966 : SAL_INFO("oox.shape", "unknown shape");
967 222 : return WriteUnknownShape( xShape );
968 : }
969 1665 : (this->*(aConverter->second))( xShape );
970 :
971 1665 : return *this;
972 : }
973 :
974 1593 : ShapeExport& ShapeExport::WriteTextBox( Reference< XInterface > xIface, sal_Int32 nXmlNamespace )
975 : {
976 : // In case this shape has an associated textbox, then export that, and we're done.
977 1593 : if (GetDocumentType() == DOCUMENT_DOCX && GetTextExport())
978 : {
979 576 : uno::Reference<beans::XPropertySet> xPropertySet(xIface, uno::UNO_QUERY);
980 576 : if (xPropertySet.is())
981 : {
982 576 : uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
983 576 : if (xPropertySetInfo->hasPropertyByName("TextBox") && xPropertySet->getPropertyValue("TextBox").get<bool>())
984 : {
985 116 : GetTextExport()->WriteTextBox(uno::Reference<drawing::XShape>(xIface, uno::UNO_QUERY_THROW));
986 116 : WriteText( xIface, m_presetWarp, /*bBodyPr=*/true, /*bText=*/false, /*nXmlNamespace=*/nXmlNamespace );
987 116 : return *this;
988 460 : }
989 460 : }
990 : }
991 :
992 1477 : if( NonEmptyText( xIface ) )
993 : {
994 1131 : FSHelperPtr pFS = GetFS();
995 :
996 1131 : pFS->startElementNS( nXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_txBody : XML_txbx), FSEND );
997 1131 : WriteText( xIface, m_presetWarp, /*bBodyPr=*/(GetDocumentType() != DOCUMENT_DOCX), /*bText=*/true );
998 1131 : pFS->endElementNS( nXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_txBody : XML_txbx) );
999 1131 : if (GetDocumentType() == DOCUMENT_DOCX)
1000 130 : WriteText( xIface, m_presetWarp, /*bBodyPr=*/true, /*bText=*/false, /*nXmlNamespace=*/nXmlNamespace );
1001 : }
1002 346 : else if (GetDocumentType() == DOCUMENT_DOCX)
1003 330 : mpFS->singleElementNS(nXmlNamespace, XML_bodyPr, FSEND);
1004 :
1005 1477 : return *this;
1006 : }
1007 :
1008 4 : void ShapeExport::WriteTable( Reference< XShape > rXShape )
1009 : {
1010 : OSL_TRACE("write table");
1011 :
1012 4 : Reference< XTable > xTable;
1013 8 : Reference< XPropertySet > xPropSet( rXShape, UNO_QUERY );
1014 :
1015 4 : mpFS->startElementNS( XML_a, XML_graphic, FSEND );
1016 4 : mpFS->startElementNS( XML_a, XML_graphicData, XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/table", FSEND );
1017 :
1018 4 : if ( xPropSet.is() && ( xPropSet->getPropertyValue( "Model" ) >>= xTable ) )
1019 : {
1020 4 : mpFS->startElementNS( XML_a, XML_tbl, FSEND );
1021 4 : mpFS->singleElementNS( XML_a, XML_tblPr, FSEND );
1022 :
1023 4 : Reference< container::XIndexAccess > xColumns( xTable->getColumns(), UNO_QUERY_THROW );
1024 8 : Reference< container::XIndexAccess > xRows( xTable->getRows(), UNO_QUERY_THROW );
1025 4 : sal_uInt16 nRowCount = static_cast< sal_uInt16 >( xRows->getCount() );
1026 4 : sal_uInt16 nColumnCount = static_cast< sal_uInt16 >( xColumns->getCount() );
1027 :
1028 4 : mpFS->startElementNS( XML_a, XML_tblGrid, FSEND );
1029 :
1030 12 : for ( sal_Int32 x = 0; x < nColumnCount; x++ )
1031 : {
1032 8 : Reference< XPropertySet > xColPropSet( xColumns->getByIndex( x ), UNO_QUERY_THROW );
1033 8 : sal_Int32 nWidth(0);
1034 8 : xColPropSet->getPropertyValue( "Width" ) >>= nWidth;
1035 :
1036 8 : mpFS->singleElementNS( XML_a, XML_gridCol, XML_w, I64S(oox::drawingml::convertHmmToEmu(nWidth)), FSEND );
1037 8 : }
1038 :
1039 4 : mpFS->endElementNS( XML_a, XML_tblGrid );
1040 :
1041 : // map for holding the transpose index of the merged cells and pair<parentTransposeIndex, parentCell>
1042 : typedef std::unordered_map<sal_Int32, std::pair<sal_Int32, Reference< XMergeableCell> > > transposeTableMap;
1043 8 : transposeTableMap mergedCellMap;
1044 :
1045 10 : for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
1046 : {
1047 6 : Reference< XPropertySet > xRowPropSet( xRows->getByIndex( nRow ), UNO_QUERY_THROW );
1048 6 : sal_Int32 nRowHeight(0);
1049 :
1050 6 : xRowPropSet->getPropertyValue( "Height" ) >>= nRowHeight;
1051 :
1052 6 : mpFS->startElementNS( XML_a, XML_tr, XML_h, I64S( oox::drawingml::convertHmmToEmu( nRowHeight ) ), FSEND );
1053 18 : for( sal_Int32 nColumn = 0; nColumn < nColumnCount; nColumn++ )
1054 : {
1055 24 : Reference< XMergeableCell > xCell( xTable->getCellByPosition( nColumn, nRow ),
1056 24 : UNO_QUERY_THROW );
1057 12 : sal_Int32 transposedIndexofCell = (nRow * nColumnCount) + nColumn;
1058 :
1059 : //assume we will open a cell, set to false below if we won't
1060 12 : bool bCellOpened = true;
1061 :
1062 12 : if(xCell->getColumnSpan() > 1 && xCell->getRowSpan() > 1)
1063 : {
1064 : // having both : horizontal and vertical merge
1065 : mpFS->startElementNS(XML_a, XML_tc, XML_gridSpan,
1066 0 : I32S(xCell->getColumnSpan()),
1067 0 : XML_rowSpan, I32S(xCell->getRowSpan()),
1068 0 : FSEND);
1069 : // since, XMergeableCell doesn't have the information about
1070 : // cell having hMerge or vMerge.
1071 : // So, Populating the merged cell map in-order to use it to
1072 : // decide the attribute for the individual cell.
1073 0 : for(sal_Int32 columnIndex = nColumn; columnIndex < nColumn+xCell->getColumnSpan(); ++columnIndex)
1074 : {
1075 0 : for(sal_Int32 rowIndex = nRow; rowIndex < nRow+xCell->getRowSpan(); ++rowIndex)
1076 : {
1077 : sal_Int32 transposeIndexForMergeCell =
1078 0 : (rowIndex * nColumnCount) + columnIndex;
1079 0 : mergedCellMap[transposeIndexForMergeCell] =
1080 0 : std::make_pair(transposedIndexofCell, xCell);
1081 : }
1082 : }
1083 :
1084 : }
1085 12 : else if(xCell->getColumnSpan() > 1)
1086 : {
1087 : // having : horizontal merge
1088 : mpFS->startElementNS(XML_a, XML_tc, XML_gridSpan,
1089 0 : I32S(xCell->getColumnSpan()), FSEND);
1090 0 : for(sal_Int32 columnIndex = nColumn; columnIndex < xCell->getColumnSpan(); ++columnIndex) {
1091 0 : sal_Int32 transposeIndexForMergeCell = (nRow*nColumnCount) + columnIndex;
1092 0 : mergedCellMap[transposeIndexForMergeCell] =
1093 0 : std::make_pair(transposedIndexofCell, xCell);
1094 : }
1095 : }
1096 12 : else if(xCell->getRowSpan() > 1)
1097 : {
1098 : // having : vertical merge
1099 : mpFS->startElementNS(XML_a, XML_tc, XML_rowSpan,
1100 0 : I32S(xCell->getRowSpan()), FSEND);
1101 :
1102 0 : for(sal_Int32 rowIndex = nRow; rowIndex < xCell->getRowSpan(); ++rowIndex) {
1103 0 : sal_Int32 transposeIndexForMergeCell = (rowIndex*nColumnCount) + nColumn;
1104 0 : mergedCellMap[transposeIndexForMergeCell] =
1105 0 : std::make_pair(transposedIndexofCell, xCell);
1106 : }
1107 : }
1108 : else
1109 : {
1110 : // now, the cell can be an independent cell or
1111 : // it can be a cell which is been merged to some parent cell
1112 12 : if(!xCell->isMerged())
1113 : {
1114 : // independent cell
1115 12 : mpFS->startElementNS( XML_a, XML_tc, FSEND );
1116 : }
1117 : else
1118 : {
1119 : // it a merged cell to some parent cell
1120 : // find the parent cell for the current cell at hand
1121 0 : transposeTableMap::iterator it = mergedCellMap.find(transposedIndexofCell);
1122 0 : if(it != mergedCellMap.end())
1123 : {
1124 0 : sal_Int32 transposeIndexOfParent = it->second.first;
1125 0 : Reference< XMergeableCell > parentCell = it->second.second;
1126 : // finding the row and column index for the parent cell from transposed index
1127 0 : sal_Int32 parentColumnIndex = transposeIndexOfParent % nColumnCount;
1128 0 : sal_Int32 parentRowIndex = transposeIndexOfParent / nColumnCount;
1129 0 : if(nColumn == parentColumnIndex)
1130 : {
1131 : // the cell is vertical merge and it might have gridspan
1132 0 : if(parentCell->getColumnSpan() > 1)
1133 : {
1134 : // vMerge and has gridSpan
1135 : mpFS->startElementNS( XML_a, XML_tc,
1136 : XML_vMerge, I32S(1),
1137 0 : XML_gridSpan, I32S(xCell->getColumnSpan()),
1138 0 : FSEND );
1139 : }
1140 : else
1141 : {
1142 : // only vMerge
1143 : mpFS->startElementNS( XML_a, XML_tc,
1144 0 : XML_vMerge, I32S(1), FSEND );
1145 : }
1146 : }
1147 0 : else if(nRow == parentRowIndex)
1148 : {
1149 : // the cell is horizontal merge and it might have rowspan
1150 0 : if(parentCell->getRowSpan() > 1)
1151 : {
1152 : // hMerge and has rowspan
1153 : mpFS->startElementNS( XML_a, XML_tc,
1154 : XML_hMerge, I32S(1),
1155 0 : XML_rowSpan, I32S(xCell->getRowSpan()),
1156 0 : FSEND );
1157 : }
1158 : else
1159 : {
1160 : // only hMerge
1161 : mpFS->startElementNS( XML_a, XML_tc,
1162 0 : XML_hMerge, I32S(1), FSEND );
1163 : }
1164 : }
1165 : else
1166 : {
1167 : // has hMerge and vMerge
1168 : mpFS->startElementNS( XML_a, XML_tc,
1169 : XML_vMerge, I32S(1),
1170 : XML_hMerge, I32S(1),
1171 0 : FSEND );
1172 0 : }
1173 : }
1174 : else
1175 0 : bCellOpened = false;
1176 : }
1177 : }
1178 :
1179 12 : if (bCellOpened)
1180 : {
1181 12 : WriteTextBox( xCell, XML_a );
1182 :
1183 12 : Reference< XPropertySet > xCellPropSet(xCell, UNO_QUERY_THROW);
1184 12 : WriteTableCellProperties(xCellPropSet);
1185 :
1186 12 : mpFS->endElementNS( XML_a, XML_tc );
1187 : }
1188 12 : }
1189 :
1190 6 : mpFS->endElementNS( XML_a, XML_tr );
1191 6 : }
1192 :
1193 8 : mpFS->endElementNS( XML_a, XML_tbl );
1194 : }
1195 :
1196 4 : mpFS->endElementNS( XML_a, XML_graphicData );
1197 8 : mpFS->endElementNS( XML_a, XML_graphic );
1198 4 : }
1199 :
1200 12 : void ShapeExport::WriteTableCellProperties(Reference< XPropertySet> xCellPropSet)
1201 : {
1202 12 : sal_Int32 nLeftMargin(0), nRightMargin(0);
1203 :
1204 12 : Any aLeftMargin = xCellPropSet->getPropertyValue("TextLeftDistance");
1205 12 : aLeftMargin >>= nLeftMargin;
1206 :
1207 24 : Any aRightMargin = xCellPropSet->getPropertyValue("TextRightDistance");
1208 12 : aRightMargin >>= nRightMargin;
1209 :
1210 : mpFS->startElementNS( XML_a, XML_tcPr,
1211 36 : XML_marL, nLeftMargin > 0 ? I32S( oox::drawingml::convertHmmToEmu( nLeftMargin ) ) : NULL,
1212 48 : XML_marR, nRightMargin > 0 ? I32S( oox::drawingml::convertHmmToEmu( nRightMargin ) ): NULL,
1213 48 : FSEND );
1214 :
1215 : // Write background fill for table cell.
1216 : // TODO
1217 : // tcW : Table cell width
1218 12 : WriteTableCellBorders(xCellPropSet);
1219 12 : DrawingML::WriteFill(xCellPropSet);
1220 24 : mpFS->endElementNS( XML_a, XML_tcPr );
1221 12 : }
1222 :
1223 12 : void ShapeExport::WriteTableCellBorders(Reference< XPropertySet> xCellPropSet)
1224 : {
1225 12 : BorderLine2 aBorderLine;
1226 :
1227 : // lnL - Left Border Line Properties of table cell
1228 12 : xCellPropSet->getPropertyValue("LeftBorder") >>= aBorderLine;
1229 12 : sal_Int32 nLeftBorder = aBorderLine.LineWidth;
1230 12 : util::Color aLeftBorderColor = aBorderLine.Color;
1231 :
1232 : // While importing the table cell border line width, it converts EMU->Hmm then divided result by 2.
1233 : // To get original value of LineWidth need to multiple by 2.
1234 12 : nLeftBorder = nLeftBorder*2;
1235 12 : nLeftBorder = oox::drawingml::convertHmmToEmu( nLeftBorder );
1236 :
1237 12 : if(nLeftBorder > 0)
1238 : {
1239 8 : mpFS->startElementNS( XML_a, XML_lnL, XML_w, I32S(nLeftBorder), FSEND );
1240 8 : DrawingML::WriteSolidFill(aLeftBorderColor);
1241 8 : mpFS->endElementNS( XML_a, XML_lnL );
1242 : }
1243 :
1244 : // lnR - Right Border Line Properties of table cell
1245 12 : xCellPropSet->getPropertyValue("RightBorder") >>= aBorderLine;
1246 12 : sal_Int32 nRightBorder = aBorderLine.LineWidth;
1247 12 : util::Color aRightBorderColor = aBorderLine.Color;
1248 12 : nRightBorder = nRightBorder * 2 ;
1249 12 : nRightBorder = oox::drawingml::convertHmmToEmu( nRightBorder );
1250 :
1251 12 : if(nRightBorder > 0)
1252 : {
1253 8 : mpFS->startElementNS( XML_a, XML_lnR, XML_w, I32S(nRightBorder), FSEND);
1254 8 : DrawingML::WriteSolidFill(aRightBorderColor);
1255 8 : mpFS->endElementNS( XML_a, XML_lnR);
1256 : }
1257 :
1258 : // lnT - Top Border Line Properties of table cell
1259 12 : xCellPropSet->getPropertyValue("TopBorder") >>= aBorderLine;
1260 12 : sal_Int32 nTopBorder = aBorderLine.LineWidth;
1261 12 : util::Color aTopBorderColor = aBorderLine.Color;
1262 12 : nTopBorder = nTopBorder * 2;
1263 12 : nTopBorder = oox::drawingml::convertHmmToEmu( nTopBorder );
1264 :
1265 12 : if(nTopBorder > 0)
1266 : {
1267 8 : mpFS->startElementNS( XML_a, XML_lnT, XML_w, I32S(nTopBorder), FSEND);
1268 8 : DrawingML::WriteSolidFill(aTopBorderColor);
1269 8 : mpFS->endElementNS( XML_a, XML_lnT);
1270 : }
1271 :
1272 : // lnB - Bottom Border Line Properties of table cell
1273 12 : xCellPropSet->getPropertyValue("BottomBorder") >>= aBorderLine;
1274 12 : sal_Int32 nBottomBorder = aBorderLine.LineWidth;
1275 12 : util::Color aBottomBorderColor = aBorderLine.Color;
1276 12 : nBottomBorder = nBottomBorder * 2;
1277 12 : nBottomBorder = oox::drawingml::convertHmmToEmu( nBottomBorder );
1278 :
1279 12 : if(nBottomBorder > 0)
1280 : {
1281 8 : mpFS->startElementNS( XML_a, XML_lnB, XML_w, I32S(nBottomBorder), FSEND);
1282 8 : DrawingML::WriteSolidFill(aBottomBorderColor);
1283 8 : mpFS->endElementNS( XML_a, XML_lnB);
1284 : }
1285 12 : }
1286 :
1287 4 : ShapeExport& ShapeExport::WriteTableShape( Reference< XShape > xShape )
1288 : {
1289 4 : FSHelperPtr pFS = GetFS();
1290 :
1291 : OSL_TRACE("write table shape");
1292 :
1293 4 : pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
1294 :
1295 4 : pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
1296 :
1297 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
1298 : XML_id, I32S( GetNewShapeID( xShape ) ),
1299 8 : XML_name, IDS(Table),
1300 4 : FSEND );
1301 :
1302 : pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
1303 4 : FSEND );
1304 :
1305 4 : if( GetDocumentType() == DOCUMENT_PPTX )
1306 : pFS->singleElementNS( mnXmlNamespace, XML_nvPr,
1307 4 : FSEND );
1308 4 : pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
1309 :
1310 4 : WriteShapeTransformation( xShape, mnXmlNamespace, false);
1311 4 : WriteTable( xShape );
1312 :
1313 4 : pFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
1314 :
1315 4 : return *this;
1316 : }
1317 :
1318 104 : ShapeExport& ShapeExport::WriteTextShape( Reference< XShape > xShape )
1319 : {
1320 104 : FSHelperPtr pFS = GetFS();
1321 :
1322 104 : pFS->startElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp), FSEND );
1323 :
1324 : // non visual shape properties
1325 104 : if (GetDocumentType() != DOCUMENT_DOCX)
1326 : {
1327 14 : pFS->startElementNS( mnXmlNamespace, XML_nvSpPr, FSEND );
1328 14 : WriteNonVisualDrawingProperties( xShape, IDS( TextShape ) );
1329 : }
1330 104 : pFS->singleElementNS( mnXmlNamespace, XML_cNvSpPr, XML_txBox, "1", FSEND );
1331 104 : if (GetDocumentType() != DOCUMENT_DOCX)
1332 : {
1333 14 : WriteNonVisualProperties( xShape );
1334 14 : pFS->endElementNS( mnXmlNamespace, XML_nvSpPr );
1335 : }
1336 :
1337 : // visual shape properties
1338 104 : pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
1339 104 : WriteShapeTransformation( xShape, XML_a, false, false, false);
1340 104 : WritePresetShape( "rect" );
1341 208 : uno::Reference<beans::XPropertySet> xPropertySet(xShape, UNO_QUERY);
1342 104 : WriteBlipOrNormalFill(xPropertySet, "GraphicURL");
1343 104 : WriteOutline(xPropertySet);
1344 104 : pFS->endElementNS( mnXmlNamespace, XML_spPr );
1345 :
1346 104 : WriteTextBox( xShape, mnXmlNamespace );
1347 :
1348 104 : pFS->endElementNS( mnXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX ? XML_sp : XML_wsp) );
1349 :
1350 208 : return *this;
1351 : }
1352 :
1353 2 : ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape )
1354 : {
1355 2 : Reference< XPropertySet > xPropSet( xShape, UNO_QUERY );
1356 2 : if( xPropSet.is() ) {
1357 2 : if( GetProperty( xPropSet, "Model" ) )
1358 : {
1359 2 : Reference< XChartDocument > xChartDoc;
1360 2 : mAny >>= xChartDoc;
1361 2 : if( xChartDoc.is() )
1362 : {
1363 : //export the chart
1364 0 : Reference< XModel > xModel( xChartDoc, UNO_QUERY );
1365 0 : ChartExport aChartExport( mnXmlNamespace, GetFS(), xModel, GetFB(), GetDocumentType() );
1366 : static sal_Int32 nChartCount = 0;
1367 0 : aChartExport.WriteChartObj( xShape, ++nChartCount );
1368 : }
1369 : else
1370 : {
1371 2 : const bool bSpreadSheet = Reference< XSpreadsheetDocument >( mAny, UNO_QUERY ).is();
1372 2 : const bool bTextDocument = Reference< css::text::XTextDocument >( mAny, UNO_QUERY ).is();
1373 2 : if( ( bSpreadSheet || bTextDocument ) && mpFB)
1374 : {
1375 2 : Reference< XComponent > xDocument( mAny, UNO_QUERY );
1376 2 : if( xDocument.is() )
1377 : {
1378 2 : Reference< XOutputStream > xOutStream;
1379 2 : if( bSpreadSheet )
1380 : {
1381 0 : xOutStream = mpFB->openFragmentStream( OUStringBuffer()
1382 0 : .appendAscii( GetComponentDir() )
1383 0 : .appendAscii( "/embeddings/spreadsheet" )
1384 0 : .append( static_cast<sal_Int32>(mnEmbeddeDocumentCounter) )
1385 0 : .appendAscii( ".xlsx" )
1386 : .makeStringAndClear(),
1387 0 : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
1388 : }
1389 : else
1390 : {
1391 8 : xOutStream = mpFB->openFragmentStream( OUStringBuffer()
1392 4 : .appendAscii( GetComponentDir() )
1393 2 : .appendAscii( "/embeddings/textdocument" )
1394 4 : .append( static_cast<sal_Int32>(mnEmbeddeDocumentCounter) )
1395 2 : .appendAscii( ".docx" )
1396 : .makeStringAndClear(),
1397 2 : "application/vnd.openxmlformats-officedocument.wordprocessingml.document" );
1398 : }
1399 :
1400 : // export the embedded document
1401 4 : Sequence< PropertyValue > rMedia(1);
1402 :
1403 2 : rMedia[0].Name = utl::MediaDescriptor::PROP_STREAMFOROUTPUT();
1404 2 : rMedia[0].Value <<= xOutStream;
1405 :
1406 4 : Reference< XExporter > xExporter;
1407 2 : if( bSpreadSheet )
1408 : {
1409 : xExporter.set(
1410 0 : mpFB->getComponentContext()->getServiceManager()->
1411 : createInstanceWithContext(
1412 : "com.sun.star.comp.oox.xls.ExcelFilter",
1413 0 : mpFB->getComponentContext() ),
1414 0 : UNO_QUERY_THROW );
1415 : }
1416 : else
1417 : {
1418 : xExporter.set(
1419 4 : mpFB->getComponentContext()->getServiceManager()->
1420 : createInstanceWithContext(
1421 : "com.sun.star.comp.Writer.WriterFilter",
1422 2 : mpFB->getComponentContext() ),
1423 2 : UNO_QUERY_THROW );
1424 :
1425 : }
1426 2 : xExporter->setSourceDocument( xDocument );
1427 4 : Reference< XFilter >( xExporter, UNO_QUERY_THROW )->
1428 2 : filter( rMedia );
1429 :
1430 2 : xOutStream->closeOutput();
1431 :
1432 4 : OUString sRelId;
1433 2 : if( bSpreadSheet )
1434 : {
1435 0 : sRelId = mpFB->addRelation( mpFS->getOutputStream(),
1436 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package",
1437 : OUStringBuffer()
1438 0 : .appendAscii( GetRelationCompPrefix() )
1439 0 : .appendAscii( "embeddings/spreadsheet" )
1440 0 : .append( static_cast<sal_Int32>(mnEmbeddeDocumentCounter++) )
1441 0 : .appendAscii( ".xlsx" )
1442 0 : .makeStringAndClear() );
1443 : }
1444 : else
1445 : {
1446 4 : sRelId = mpFB->addRelation( mpFS->getOutputStream(),
1447 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package",
1448 : OUStringBuffer()
1449 4 : .appendAscii( GetRelationCompPrefix() )
1450 2 : .appendAscii( "embeddings/textdocument" )
1451 4 : .append( static_cast<sal_Int32>(mnEmbeddeDocumentCounter++) )
1452 2 : .appendAscii( ".docx" )
1453 2 : .makeStringAndClear() );
1454 : }
1455 :
1456 2 : mpFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
1457 :
1458 2 : mpFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
1459 :
1460 : mpFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
1461 : XML_id, I32S( GetNewShapeID( xShape ) ),
1462 4 : XML_name, IDS(Object),
1463 2 : FSEND );
1464 :
1465 : mpFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
1466 2 : FSEND );
1467 :
1468 2 : if( GetDocumentType() == DOCUMENT_PPTX )
1469 : mpFS->singleElementNS( mnXmlNamespace, XML_nvPr,
1470 2 : FSEND );
1471 2 : mpFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
1472 :
1473 2 : WriteShapeTransformation( xShape, mnXmlNamespace );
1474 :
1475 2 : mpFS->startElementNS( XML_a, XML_graphic, FSEND );
1476 : mpFS->startElementNS( XML_a, XML_graphicData,
1477 : XML_uri, "http://schemas.openxmlformats.org/presentationml/2006/ole",
1478 2 : FSEND );
1479 2 : if( bSpreadSheet )
1480 : {
1481 : mpFS->startElementNS( mnXmlNamespace, XML_oleObj,
1482 : XML_name, "Spreadsheet",
1483 : FSNS(XML_r, XML_id), USS( sRelId ),
1484 0 : FSEND );
1485 : }
1486 : else
1487 : {
1488 : mpFS->startElementNS( mnXmlNamespace, XML_oleObj,
1489 : XML_name, "Document",
1490 : FSNS(XML_r, XML_id), USS( sRelId ),
1491 : // The spec says that this is a required attribute, but PowerPoint can only handle an empty value.
1492 : XML_spid, "",
1493 2 : FSEND );
1494 : }
1495 :
1496 2 : mpFS->singleElementNS( mnXmlNamespace, XML_embed, FSEND );
1497 :
1498 : // pic element
1499 2 : SdrObject* pSdrOLE2( GetSdrObjectFromXShape( xShape ) );
1500 : // The spec doesn't allow <p:pic> here, but PowerPoint requires it.
1501 2 : bool bEcma = mpFB->getVersion() == oox::core::ECMA_DIALECT;
1502 2 : if ( pSdrOLE2 && pSdrOLE2->ISA( SdrOle2Obj ) && bEcma)
1503 : {
1504 0 : const Graphic* pGraphic = static_cast<SdrOle2Obj*>(pSdrOLE2)->GetGraphic();
1505 0 : if ( pGraphic )
1506 0 : WriteGraphicObjectShapePart( xShape, pGraphic );
1507 : }
1508 :
1509 2 : mpFS->endElementNS( mnXmlNamespace, XML_oleObj );
1510 :
1511 2 : mpFS->endElementNS( XML_a, XML_graphicData );
1512 2 : mpFS->endElementNS( XML_a, XML_graphic );
1513 :
1514 4 : mpFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
1515 2 : }
1516 : }
1517 2 : }
1518 : }
1519 : }
1520 2 : return *this;
1521 : }
1522 :
1523 138 : ShapeExport& ShapeExport::WriteUnknownShape( Reference< XShape > )
1524 : {
1525 : // Override this method to do something useful.
1526 138 : return *this;
1527 : }
1528 :
1529 1170 : size_t ShapeExport::ShapeHash::operator()( const Reference < XShape > rXShape ) const
1530 : {
1531 1170 : return rXShape->getShapeType().hashCode();
1532 : }
1533 :
1534 1170 : sal_Int32 ShapeExport::GetNewShapeID( const Reference< XShape > rXShape )
1535 : {
1536 1170 : return GetNewShapeID( rXShape, GetFB() );
1537 : }
1538 :
1539 1170 : sal_Int32 ShapeExport::GetNewShapeID( const Reference< XShape > rXShape, XmlFilterBase* pFB )
1540 : {
1541 1170 : if( !rXShape.is() )
1542 0 : return -1;
1543 :
1544 1170 : sal_Int32 nID = pFB->GetUniqueId();
1545 :
1546 1170 : (*mpShapeMap)[ rXShape ] = nID;
1547 :
1548 1170 : return nID;
1549 : }
1550 :
1551 0 : sal_Int32 ShapeExport::GetShapeID( const Reference< XShape > rXShape )
1552 : {
1553 0 : return GetShapeID( rXShape, mpShapeMap );
1554 : }
1555 :
1556 0 : sal_Int32 ShapeExport::GetShapeID( const Reference< XShape > rXShape, ShapeHashMap* pShapeMap )
1557 : {
1558 0 : if( !rXShape.is() )
1559 0 : return -1;
1560 :
1561 0 : ShapeHashMap::const_iterator aIter = pShapeMap->find( rXShape );
1562 :
1563 0 : if( aIter == pShapeMap->end() )
1564 0 : return -1;
1565 :
1566 0 : return aIter->second;
1567 : }
1568 :
1569 246 : } }
1570 :
1571 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|