/src/libreoffice/oox/source/shape/ShapeContextHandler.cxx
Line | Count | Source |
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 <com/sun/star/beans/XPropertySet.hpp> |
21 | | #include <com/sun/star/drawing/XGluePointsSupplier.hpp> |
22 | | #include <com/sun/star/container/XIdentifierContainer.hpp> |
23 | | #include <com/sun/star/xml/dom/XDocument.hpp> |
24 | | #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp> |
25 | | |
26 | | #include <oox/shape/ShapeContextHandler.hxx> |
27 | | #include <oox/shape/ShapeDrawingFragmentHandler.hxx> |
28 | | #include "LockedCanvasContext.hxx" |
29 | | #include "WordprocessingCanvasContext.hxx" |
30 | | #include "WpsContext.hxx" |
31 | | #include "WpgContext.hxx" |
32 | | #include <basegfx/matrix/b2dhommatrix.hxx> |
33 | | #include <oox/vml/vmldrawing.hxx> |
34 | | #include <oox/vml/vmldrawingfragment.hxx> |
35 | | #include <oox/vml/vmlshape.hxx> |
36 | | #include <oox/vml/vmlshapecontainer.hxx> |
37 | | #include <oox/shape/ShapeFilterBase.hxx> |
38 | | #include <oox/token/namespaces.hxx> |
39 | | #include <oox/token/tokens.hxx> |
40 | | #include <oox/drawingml/theme.hxx> |
41 | | #include <oox/drawingml/themefragmenthandler.hxx> |
42 | | #include <svx/svdogrp.hxx> |
43 | | #include <svx/svdoedge.hxx> |
44 | | #include <svx/svdobj.hxx> |
45 | | |
46 | | #include <drawingml/connectorhelper.hxx> |
47 | | |
48 | | #include <memory> |
49 | | #include <utility> |
50 | | |
51 | | using namespace ::com::sun::star; |
52 | | |
53 | | namespace oox::shape { |
54 | | using namespace core; |
55 | | using namespace drawingml; |
56 | | |
57 | | ShapeContextHandler::ShapeContextHandler(rtl::Reference<ShapeFilterBase> xFilterBase) : |
58 | 2.32k | m_bFullWPGSUpport(false), |
59 | 2.32k | mxShapeFilterBase(std::move(xFilterBase)) |
60 | | |
61 | 2.32k | { |
62 | 2.32k | } |
63 | | |
64 | | ShapeContextHandler::~ShapeContextHandler() |
65 | 2.32k | { |
66 | 2.32k | } |
67 | | |
68 | | uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getLockedCanvasContext(sal_Int32 nElement) |
69 | 432 | { |
70 | 432 | if (!mxLockedCanvasContext.is()) |
71 | 54 | { |
72 | 54 | FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath)); |
73 | | |
74 | 54 | switch (nElement & 0xffff) |
75 | 54 | { |
76 | 54 | case XML_lockedCanvas: |
77 | 54 | mxLockedCanvasContext.set(new LockedCanvasContext(*rFragmentHandler)); |
78 | 54 | break; |
79 | 0 | default: |
80 | 0 | break; |
81 | 54 | } |
82 | 54 | } |
83 | | |
84 | 432 | return static_cast<ContextHandler *>(mxLockedCanvasContext.get()); |
85 | 432 | } |
86 | | |
87 | | /* |
88 | | * This method creates new ChartGraphicDataContext Object. |
89 | | */ |
90 | | uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getChartShapeContext(sal_Int32 nElement) |
91 | 90 | { |
92 | 90 | if (!mxChartShapeContext.is()) |
93 | 18 | { |
94 | 18 | switch (nElement & 0xffff) |
95 | 18 | { |
96 | 18 | case XML_chart: |
97 | 18 | { |
98 | 18 | std::unique_ptr<ContextHandler2Helper> pFragmentHandler( |
99 | 18 | new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath)); |
100 | 18 | mpShape = std::make_shared<Shape>("com.sun.star.drawing.OLE2Shape" ); |
101 | 18 | mxChartShapeContext.set(new ChartGraphicDataContext(*pFragmentHandler, mpShape, true)); |
102 | 18 | break; |
103 | 0 | } |
104 | 0 | default: |
105 | 0 | break; |
106 | 18 | } |
107 | 18 | } |
108 | | |
109 | 90 | return mxChartShapeContext; |
110 | 90 | } |
111 | | |
112 | | uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getWpsContext(sal_Int32 nStartElement, sal_Int32 nElement) |
113 | 5.54k | { |
114 | 5.54k | if (!mxWpsContext.is()) |
115 | 984 | { |
116 | 984 | FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath)); |
117 | | |
118 | 984 | uno::Reference<drawing::XShape> xShape; |
119 | | // No element happens in case of pretty-printed XML, bodyPr is the case when we are called again after <wps:txbx>. |
120 | 984 | if (!nElement || nElement == WPS_TOKEN(bodyPr)) |
121 | | // Assume that this is just a continuation of the previous shape. |
122 | 394 | xShape = mxSavedShape; |
123 | | |
124 | 984 | switch (getBaseToken(nStartElement)) |
125 | 984 | { |
126 | 984 | case XML_wsp: |
127 | 984 | mxWpsContext.set(new WpsContext( |
128 | 984 | *rFragmentHandler, |
129 | 984 | xShape, |
130 | 984 | nullptr, |
131 | 984 | std::make_shared<oox::drawingml::Shape>( |
132 | 984 | "com.sun.star.drawing.CustomShape"))); |
133 | 984 | break; |
134 | 0 | default: |
135 | 0 | break; |
136 | 984 | } |
137 | 984 | } |
138 | | |
139 | 5.54k | return mxWpsContext; |
140 | 5.54k | } |
141 | | |
142 | | uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getWpgContext(sal_Int32 nElement) |
143 | 1.15k | { |
144 | 1.15k | if (!mxWpgContext.is()) |
145 | 128 | { |
146 | 128 | FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath)); |
147 | | |
148 | 128 | switch (getBaseToken(nElement)) |
149 | 128 | { |
150 | 128 | case XML_wgp: |
151 | 128 | { |
152 | 128 | mxWpgContext.set(new WpgContext(*rFragmentHandler, oox::drawingml::ShapePtr())); |
153 | 128 | mxWpgContext->setFullWPGSupport(m_bFullWPGSUpport); |
154 | 128 | break; |
155 | 0 | } |
156 | 0 | default: |
157 | 0 | break; |
158 | 128 | } |
159 | 128 | } |
160 | | |
161 | 1.15k | return static_cast<ContextHandler *>(mxWpgContext.get()); |
162 | 1.15k | } |
163 | | |
164 | | uno::Reference<xml::sax::XFastContextHandler> const & |
165 | | ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element ) |
166 | 5.91k | { |
167 | 5.91k | if (! mxGraphicShapeContext.is()) |
168 | 714 | { |
169 | 714 | auto pFragmentHandler = std::make_shared<ShapeFragmentHandler>(*mxShapeFilterBase, msRelationFragmentPath); |
170 | | |
171 | 714 | switch (Element & 0xffff) |
172 | 714 | { |
173 | 0 | case XML_graphic: |
174 | 0 | mpShape = std::make_shared<Shape>("com.sun.star.drawing.GraphicObjectShape" ); |
175 | 0 | mxGraphicShapeContext.set |
176 | 0 | (new GraphicalObjectFrameContext(*pFragmentHandler, nullptr, mpShape, true)); |
177 | 0 | break; |
178 | 714 | case XML_pic: |
179 | 714 | mpShape = std::make_shared<Shape>("com.sun.star.drawing.GraphicObjectShape" ); |
180 | 714 | mxGraphicShapeContext.set |
181 | 714 | (new GraphicShapeContext(*pFragmentHandler, nullptr, mpShape)); |
182 | 714 | break; |
183 | 0 | default: |
184 | 0 | break; |
185 | 714 | } |
186 | 714 | } |
187 | | |
188 | 5.91k | return mxGraphicShapeContext; |
189 | 5.91k | } |
190 | | |
191 | | uno::Reference<xml::sax::XFastContextHandler> |
192 | | ShapeContextHandler::getDrawingShapeContext() |
193 | 17.0k | { |
194 | 17.0k | if (!mxDrawingFragmentHandler.is()) |
195 | 2.21k | { |
196 | 2.21k | mpDrawing = std::make_shared<oox::vml::Drawing>( *mxShapeFilterBase, mxDrawPage, oox::vml::VMLDRAWING_WORD ); |
197 | 2.21k | mxDrawingFragmentHandler.set |
198 | 2.21k | (new oox::vml::DrawingFragment |
199 | 2.21k | ( *mxShapeFilterBase, msRelationFragmentPath, *mpDrawing )); |
200 | 2.21k | } |
201 | 14.8k | else |
202 | 14.8k | { |
203 | | // Reset the handler if fragment path has changed |
204 | 14.8k | OUString sHandlerFragmentPath = mxDrawingFragmentHandler->getFragmentPath(); |
205 | 14.8k | if ( msRelationFragmentPath != sHandlerFragmentPath ) |
206 | 0 | { |
207 | 0 | mxDrawingFragmentHandler.clear(); |
208 | 0 | mxDrawingFragmentHandler.set |
209 | 0 | (new oox::vml::DrawingFragment |
210 | 0 | ( *mxShapeFilterBase, msRelationFragmentPath, *mpDrawing )); |
211 | 0 | } |
212 | 14.8k | } |
213 | 17.0k | return static_cast<ContextHandler *>(mxDrawingFragmentHandler.get()); |
214 | 17.0k | } |
215 | | |
216 | | uno::Reference<xml::sax::XFastContextHandler> |
217 | | ShapeContextHandler::getDiagramShapeContext() |
218 | 266 | { |
219 | 266 | if (!mxDiagramShapeContext.is()) |
220 | 142 | { |
221 | 142 | auto pFragmentHandler = std::make_shared<ShapeFragmentHandler>(*mxShapeFilterBase, msRelationFragmentPath); |
222 | 142 | mpShape = std::make_shared<Shape>(); |
223 | 142 | mpShape->setSize(maSize); |
224 | 142 | mxDiagramShapeContext.set(new DiagramGraphicDataContext(*pFragmentHandler, mpShape)); |
225 | 142 | } |
226 | | |
227 | 266 | return mxDiagramShapeContext; |
228 | 266 | } |
229 | | |
230 | | uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getWordprocessingCanvasContext(sal_Int32 nElement) |
231 | 0 | { |
232 | 0 | if (!mxWordprocessingCanvasContext.is()) |
233 | 0 | { |
234 | 0 | FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath)); |
235 | |
|
236 | 0 | switch (getBaseToken(nElement)) |
237 | 0 | { |
238 | 0 | case XML_wpc: |
239 | 0 | mxWordprocessingCanvasContext.set(new WordprocessingCanvasContext(*rFragmentHandler, maSize)); |
240 | 0 | break; |
241 | 0 | default: |
242 | 0 | break; |
243 | 0 | } |
244 | 0 | } |
245 | | |
246 | 0 | return static_cast<ContextHandler *>(mxWordprocessingCanvasContext.get()); |
247 | 0 | } |
248 | | |
249 | | uno::Reference<xml::sax::XFastContextHandler> |
250 | | ShapeContextHandler::getContextHandler(sal_Int32 nElement) |
251 | 23.5k | { |
252 | 23.5k | uno::Reference<xml::sax::XFastContextHandler> xResult; |
253 | 23.5k | const sal_uInt32 nStartToken = getStartToken(); |
254 | | |
255 | 23.5k | switch (getNamespace( nStartToken )) |
256 | 23.5k | { |
257 | 10.1k | case NMSP_doc: |
258 | 10.1k | case NMSP_vml: |
259 | 10.1k | xResult.set(getDrawingShapeContext()); |
260 | 10.1k | break; |
261 | 266 | case NMSP_dmlDiagram: |
262 | 266 | xResult.set(getDiagramShapeContext()); |
263 | 266 | break; |
264 | 432 | case NMSP_dmlLockedCanvas: |
265 | 432 | xResult.set(getLockedCanvasContext(nStartToken)); |
266 | 432 | break; |
267 | 90 | case NMSP_dmlChart: |
268 | 90 | xResult.set(getChartShapeContext(nStartToken)); |
269 | 90 | break; |
270 | 5.54k | case NMSP_wps: |
271 | 5.54k | xResult.set(getWpsContext(nStartToken, nElement)); |
272 | 5.54k | break; |
273 | 1.15k | case NMSP_wpg: |
274 | 1.15k | xResult.set(getWpgContext(nStartToken)); |
275 | 1.15k | break; |
276 | 0 | case NMSP_wpc: |
277 | 0 | xResult.set(getWordprocessingCanvasContext(nStartToken)); |
278 | 0 | break; |
279 | 5.91k | default: |
280 | 5.91k | xResult.set(getGraphicShapeContext(nStartToken)); |
281 | 5.91k | break; |
282 | 23.5k | } |
283 | | |
284 | 23.5k | return xResult; |
285 | 23.5k | } |
286 | | |
287 | | // css::xml::sax::XFastContextHandler: |
288 | | void SAL_CALL ShapeContextHandler::startFastElement |
289 | | (::sal_Int32 Element, |
290 | | const uno::Reference< xml::sax::XFastAttributeList > & Attribs) |
291 | 3.57k | { |
292 | 3.57k | mxShapeFilterBase->filter(maMediaDescriptor); |
293 | | |
294 | 3.57k | if (Element == DGM_TOKEN(relIds) || Element == LC_TOKEN(lockedCanvas) || Element == C_TOKEN(chart) || |
295 | 3.57k | Element == WPS_TOKEN(wsp) || Element == WPG_TOKEN(wgp) || Element == OOX_TOKEN(dmlPicture, pic) |
296 | 1.93k | || Element == WPC_TOKEN(wpc)) |
297 | 1.64k | { |
298 | | // Parse the theme relation, if available; the diagram won't have colors without it. |
299 | 1.64k | if (!mpThemePtr && !msRelationFragmentPath.isEmpty()) |
300 | 1.14k | { |
301 | | // Get Target for Type = "officeDocument" from _rels/.rels file |
302 | | // aOfficeDocumentFragmentPath is pointing to "word/document.xml" for docx & to "ppt/presentation.xml" for pptx |
303 | 1.14k | FragmentHandlerRef rFragmentHandlerRef(new ShapeFragmentHandler(*mxShapeFilterBase, u"/"_ustr)); |
304 | 1.14k | OUString aOfficeDocumentFragmentPath = rFragmentHandlerRef->getFragmentPathFromFirstTypeFromOfficeDoc( u"officeDocument" ); |
305 | | |
306 | | // Get the theme DO NOT use msRelationFragmentPath for getting theme as for a document there is a single theme in document.xml.rels |
307 | | // and the same is used by header and footer as well. |
308 | 1.14k | FragmentHandlerRef rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, aOfficeDocumentFragmentPath)); |
309 | 1.14k | OUString aThemeFragmentPath = rFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"theme" ); |
310 | | |
311 | 1.14k | if (!aThemeFragmentPath.isEmpty()) |
312 | 643 | { |
313 | 643 | mpThemePtr = std::make_shared<Theme>(); |
314 | 643 | auto pTheme = std::make_shared<model::Theme>(); |
315 | 643 | mpThemePtr->setTheme(pTheme); |
316 | 643 | mxShapeFilterBase->importFragment(new ThemeFragmentHandler(*mxShapeFilterBase, aThemeFragmentPath, *mpThemePtr, *pTheme)); |
317 | 643 | mxShapeFilterBase->setCurrentTheme(mpThemePtr); |
318 | 643 | } |
319 | 1.14k | } |
320 | 505 | else if (mpThemePtr && !mxShapeFilterBase->getCurrentTheme()) |
321 | 254 | { |
322 | 254 | mxShapeFilterBase->setCurrentTheme(mpThemePtr); |
323 | 254 | } |
324 | | |
325 | 1.64k | createFastChildContext(Element, Attribs); |
326 | 1.64k | } |
327 | | |
328 | | // Entering VML block (startFastElement() is called for the outermost tag), |
329 | | // handle possible recursion. |
330 | 3.57k | if ( getContextHandler() == getDrawingShapeContext() ) |
331 | 1.93k | mpDrawing->getShapes().pushMark(); |
332 | | |
333 | 3.57k | uno::Reference<XFastContextHandler> xContextHandler(getContextHandler()); |
334 | | |
335 | 3.57k | if (xContextHandler.is()) |
336 | 3.46k | xContextHandler->startFastElement(Element, Attribs); |
337 | 3.57k | } |
338 | | |
339 | | void SAL_CALL ShapeContextHandler::startUnknownElement |
340 | | (const OUString & Namespace, const OUString & Name, |
341 | | const uno::Reference< xml::sax::XFastAttributeList > & Attribs) |
342 | 0 | { |
343 | 0 | if ( getContextHandler() == getDrawingShapeContext() ) |
344 | 0 | mpDrawing->getShapes().pushMark(); |
345 | |
|
346 | 0 | uno::Reference<XFastContextHandler> xContextHandler(getContextHandler()); |
347 | |
|
348 | 0 | if (xContextHandler.is()) |
349 | 0 | xContextHandler->startUnknownElement(Namespace, Name, Attribs); |
350 | 0 | } |
351 | | |
352 | | void SAL_CALL ShapeContextHandler::endFastElement(::sal_Int32 Element) |
353 | 3.43k | { |
354 | 3.43k | uno::Reference<XFastContextHandler> xContextHandler(getContextHandler()); |
355 | | |
356 | 3.43k | if (xContextHandler.is()) |
357 | 3.43k | xContextHandler->endFastElement(Element); |
358 | | // In case a textbox is sent, and later we get additional properties for |
359 | | // the textbox, then the wps context is not cleared, so do that here. |
360 | 3.43k | if (Element != (NMSP_wps | XML_wsp)) |
361 | 2.84k | return; |
362 | | |
363 | 590 | uno::Reference<lang::XServiceInfo> xServiceInfo(mxSavedShape, uno::UNO_QUERY); |
364 | 590 | bool bTextFrame = xServiceInfo.is() && xServiceInfo->supportsService(u"com.sun.star.text.TextFrame"_ustr); |
365 | 590 | bool bTextBox = false; |
366 | 590 | if (!bTextFrame) |
367 | 590 | { |
368 | 590 | uno::Reference<beans::XPropertySet> xPropertySet(mxSavedShape, uno::UNO_QUERY); |
369 | 590 | if (xPropertySet.is()) |
370 | 394 | xPropertySet->getPropertyValue(u"TextBox"_ustr) >>= bTextBox; |
371 | 590 | } |
372 | 590 | if (bTextFrame || bTextBox) |
373 | 394 | mxWpsContext.clear(); |
374 | 590 | mxSavedShape.clear(); |
375 | 590 | } |
376 | | |
377 | | void SAL_CALL ShapeContextHandler::endUnknownElement |
378 | | (const OUString & Namespace, |
379 | | const OUString & Name) |
380 | 0 | { |
381 | 0 | uno::Reference<XFastContextHandler> xContextHandler(getContextHandler()); |
382 | |
|
383 | 0 | if (xContextHandler.is()) |
384 | 0 | xContextHandler->endUnknownElement(Namespace, Name); |
385 | 0 | } |
386 | | |
387 | | uno::Reference< xml::sax::XFastContextHandler > SAL_CALL |
388 | | ShapeContextHandler::createFastChildContext |
389 | | (::sal_Int32 Element, |
390 | | const uno::Reference< xml::sax::XFastAttributeList > & Attribs) |
391 | 9.35k | { |
392 | 9.35k | uno::Reference< xml::sax::XFastContextHandler > xResult; |
393 | 9.35k | uno::Reference< xml::sax::XFastContextHandler > xContextHandler(getContextHandler(Element)); |
394 | | |
395 | 9.35k | if (xContextHandler.is()) |
396 | 9.35k | xResult.set(xContextHandler->createFastChildContext |
397 | 9.35k | (Element, Attribs)); |
398 | | |
399 | 9.35k | return xResult; |
400 | 9.35k | } |
401 | | |
402 | | uno::Reference< xml::sax::XFastContextHandler > SAL_CALL |
403 | | ShapeContextHandler::createUnknownChildContext |
404 | | (const OUString & Namespace, |
405 | | const OUString & Name, |
406 | | const uno::Reference< xml::sax::XFastAttributeList > & Attribs) |
407 | 0 | { |
408 | 0 | uno::Reference<XFastContextHandler> xContextHandler(getContextHandler()); |
409 | |
|
410 | 0 | if (xContextHandler.is()) |
411 | 0 | return xContextHandler->createUnknownChildContext |
412 | 0 | (Namespace, Name, Attribs); |
413 | | |
414 | 0 | return uno::Reference< xml::sax::XFastContextHandler >(); |
415 | 0 | } |
416 | | |
417 | | void SAL_CALL ShapeContextHandler::characters(const OUString & aChars) |
418 | 375 | { |
419 | 375 | uno::Reference<XFastContextHandler> xContextHandler(getContextHandler()); |
420 | | |
421 | 375 | if (xContextHandler.is()) |
422 | 375 | xContextHandler->characters(aChars); |
423 | 375 | } |
424 | | |
425 | | namespace // helpers for case mxWordprocessingCanvasContext |
426 | | { |
427 | | void lcl_createShapeMap(oox::drawingml::ShapePtr rShapePtr, |
428 | | oox::drawingml::ShapeIdMap& rShapeMap) |
429 | 0 | { |
430 | 0 | std::vector< ShapePtr >& rChildren = rShapePtr->getChildren(); |
431 | 0 | if (rChildren.empty()) |
432 | 0 | return; |
433 | 0 | for (auto& pIt : rChildren) |
434 | 0 | { |
435 | 0 | rShapeMap[pIt->getId()] = pIt; // add child itself |
436 | 0 | lcl_createShapeMap(pIt, rShapeMap); // and all its descendants |
437 | 0 | } |
438 | 0 | } |
439 | | |
440 | | } // end anonymous namespace |
441 | | |
442 | | uno::Reference< drawing::XShape > |
443 | | ShapeContextHandler::getShape() |
444 | 3.43k | { |
445 | 3.43k | uno::Reference< drawing::XShape > xResult; |
446 | 3.43k | uno::Reference< drawing::XShapes > xShapes = mxDrawPage; |
447 | | |
448 | 3.43k | if (mxShapeFilterBase && xShapes.is()) |
449 | 3.43k | { |
450 | 3.43k | if ( getContextHandler() == getDrawingShapeContext() ) |
451 | 1.90k | { |
452 | 1.90k | mpDrawing->finalizeFragmentImport(); |
453 | 1.90k | if( std::shared_ptr< vml::ShapeBase > pShape = mpDrawing->getShapes().takeLastShape() ) |
454 | 1.81k | xResult = pShape->convertAndInsert( xShapes ); |
455 | | // Only now remove the recursion mark, because getShape() is called in writerfilter |
456 | | // after endFastElement(). |
457 | 1.90k | mpDrawing->getShapes().popMark(); |
458 | 1.90k | } |
459 | 1.53k | else if (mxDiagramShapeContext.is()) |
460 | 31 | { |
461 | 31 | basegfx::B2DHomMatrix aMatrix; |
462 | 31 | static bool bIgnoreExtDrawings(nullptr != std::getenv("DIAGRAM_IGNORE_EXTDRAWINGS")); |
463 | | |
464 | 31 | if (bIgnoreExtDrawings || mpShape->getExtDrawings().empty()) |
465 | 11 | { |
466 | 11 | mpShape->addShape( *mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, mpShape->getFillProperties() ); |
467 | 11 | xResult = mpShape->getXShape(); |
468 | 11 | } |
469 | 20 | else |
470 | 20 | { |
471 | | // Prerendered diagram output is available, then use that, and throw away the original result. |
472 | 20 | for (auto const& extDrawing : mpShape->getExtDrawings()) |
473 | 20 | { |
474 | 20 | OUString aFragmentPath(mxDiagramShapeContext->getFragmentPathFromRelId(extDrawing)); |
475 | 20 | oox::drawingml::ShapePtr pShapePtr = std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" ); |
476 | 20 | pShapePtr->setDiagramType(); |
477 | 20 | mxShapeFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxShapeFilterBase, aFragmentPath, pShapePtr)); |
478 | | |
479 | 20 | if (mpShape->getFontRefColorForNodes().isUsed()) |
480 | 0 | applyFontRefColor(pShapePtr, mpShape->getFontRefColorForNodes()); |
481 | | |
482 | | // migrate DiagramHelper_svx to new oox::Shape (from mpShape which was loaded |
483 | | // to pShapePtr where the geometry is now constructed) |
484 | 20 | mpShape->migrateDiagramHelperToNewShape(pShapePtr); |
485 | | |
486 | | // use now migrated DiagramHelper_oox |
487 | 20 | pShapePtr->keepDiagramDrawing(*mxShapeFilterBase, aFragmentPath); |
488 | | |
489 | 20 | if (!mpShape->getChildren().empty()) |
490 | 20 | { |
491 | | // first child is diagram background - we want to keep it, as drawingML fallback doesn't contain it |
492 | 20 | auto& aChildren = pShapePtr->getChildren(); |
493 | 20 | ShapePtr pBackground = mpShape->getChildren().front(); |
494 | 20 | aChildren.insert(aChildren.begin(), pBackground); |
495 | 20 | } |
496 | | |
497 | 20 | pShapePtr->addShape( *mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShapePtr->getFillProperties() ); |
498 | 20 | xResult = pShapePtr->getXShape(); |
499 | 20 | } |
500 | 20 | mpShape.reset(); |
501 | 20 | } |
502 | 31 | mxDiagramShapeContext.clear(); |
503 | 31 | } |
504 | 1.50k | else if (mxLockedCanvasContext.is()) |
505 | 54 | { |
506 | 54 | ShapePtr pShape = mxLockedCanvasContext->getShape(); |
507 | 54 | if (pShape) |
508 | 54 | { |
509 | 54 | basegfx::B2DHomMatrix aMatrix; |
510 | 54 | pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties()); |
511 | 54 | xResult = pShape->getXShape(); |
512 | 54 | mxLockedCanvasContext.clear(); |
513 | 54 | } |
514 | 54 | } |
515 | 1.45k | else if (mxWordprocessingCanvasContext.is()) |
516 | 0 | { |
517 | | // group which represents the drawing canvas |
518 | 0 | ShapePtr pShape = mxWordprocessingCanvasContext->getShape(); |
519 | 0 | if (pShape) |
520 | 0 | { |
521 | 0 | basegfx::B2DHomMatrix aMatrix; |
522 | 0 | pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties()); |
523 | | |
524 | | // create a flat map of all shapes in the drawing canvas group. |
525 | 0 | oox::drawingml::ShapeIdMap aShapeMap; |
526 | 0 | lcl_createShapeMap(pShape, aShapeMap); |
527 | | |
528 | | // Traverse aShapeMap and generate edge related properties. |
529 | 0 | for (auto& rIt : aShapeMap) |
530 | 0 | { |
531 | 0 | if ((rIt.second)->getServiceName() == "com.sun.star.drawing.ConnectorShape") |
532 | 0 | { |
533 | 0 | ConnectorHelper::applyConnections(rIt.second, aShapeMap); |
534 | |
|
535 | 0 | if (rIt.second->getConnectorName() == u"bentConnector3"_ustr |
536 | 0 | || rIt.second->getConnectorName() == u"bentConnector4"_ustr |
537 | 0 | || rIt.second->getConnectorName() == u"bentConnector5"_ustr) |
538 | 0 | { |
539 | 0 | ConnectorHelper::applyBentHandleAdjustments(rIt.second); |
540 | 0 | } |
541 | 0 | else if (rIt.second->getConnectorName() == u"curvedConnector3"_ustr |
542 | 0 | || rIt.second->getConnectorName() == u"curvedConnector4"_ustr |
543 | 0 | || rIt.second->getConnectorName() == u"curvedConnector5"_ustr) |
544 | 0 | { |
545 | 0 | ConnectorHelper::applyCurvedHandleAdjustments(rIt.second); |
546 | 0 | } |
547 | | // else use the default path of LibreOffice. |
548 | | // curveConnector2 and bentConnector2 do not have handles. |
549 | 0 | } |
550 | 0 | } |
551 | 0 | xResult = pShape->getXShape(); |
552 | 0 | mxWordprocessingCanvasContext.clear(); |
553 | 0 | } |
554 | 0 | } |
555 | | //NMSP_dmlChart == getNamespace( mnStartToken ) check is introduced to make sure that |
556 | | //mnStartToken is set as NMSP_dmlChart in setStartToken. |
557 | | //Only in case it is set then only the below block of code for ChartShapeContext should be executed. |
558 | 1.45k | else if (mxChartShapeContext.is() && (NMSP_dmlChart == getNamespace( getStartToken() ))) |
559 | 18 | { |
560 | 18 | basegfx::B2DHomMatrix aMatrix; |
561 | 18 | oox::drawingml::ShapePtr xShapePtr( mxChartShapeContext->getShape()); |
562 | | // See SwXTextDocument::createInstance(), ODF import uses the same hack. |
563 | 18 | xShapePtr->setServiceName(u"com.sun.star.drawing.temporaryForXMLImportOLE2Shape"_ustr); |
564 | 18 | xShapePtr->addShape( *mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, xShapePtr->getFillProperties() ); |
565 | 18 | xResult = xShapePtr->getXShape(); |
566 | 18 | mxChartShapeContext.clear(); |
567 | 18 | } |
568 | 1.43k | else if (mxWpsContext.is()) |
569 | 590 | { |
570 | 590 | ShapePtr pShape = mxWpsContext->getShape(); |
571 | 590 | if (pShape) |
572 | 590 | { |
573 | 590 | basegfx::B2DHomMatrix aMatrix; |
574 | 590 | pShape->setPosition(maPosition); |
575 | 590 | pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties()); |
576 | 590 | xResult = pShape->getXShape(); |
577 | 590 | mxSavedShape = xResult; |
578 | 590 | mxWpsContext.clear(); |
579 | 590 | } |
580 | 590 | } |
581 | 842 | else if (mxWpgContext.is()) |
582 | 128 | { |
583 | 128 | ShapePtr pShape = mxWpgContext->getShape(); |
584 | 128 | if (pShape) |
585 | 128 | { |
586 | 128 | basegfx::B2DHomMatrix aMatrix; |
587 | 128 | pShape->setPosition(maPosition); |
588 | 128 | pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties()); |
589 | 128 | xResult = pShape->getXShape(); |
590 | 128 | mxSavedShape = xResult; |
591 | 128 | mxWpgContext.clear(); |
592 | 128 | } |
593 | 128 | } |
594 | 714 | else if (mpShape) |
595 | 714 | { |
596 | 714 | basegfx::B2DHomMatrix aTransformation; |
597 | | |
598 | 714 | if (maPosition.X != 0 || maPosition.Y != 0) |
599 | 216 | { |
600 | | // We got a position from writerfilter/, store that in the shape, otherwise the |
601 | | // position won't be set. |
602 | 216 | mpShape->setWps(true); |
603 | 216 | mpShape->setPosition(maPosition); |
604 | 216 | } |
605 | | |
606 | 714 | mpShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aTransformation, mpShape->getFillProperties() ); |
607 | 714 | xResult.set(mpShape->getXShape()); |
608 | 714 | mxGraphicShapeContext.clear( ); |
609 | 714 | } |
610 | 3.43k | } |
611 | | |
612 | 3.43k | if (xResult) |
613 | 3.34k | popStartToken(); |
614 | 3.43k | return xResult; |
615 | 3.43k | } |
616 | | |
617 | | void ShapeContextHandler::setDrawPage(const css::uno::Reference< css::drawing::XDrawPage > & the_value) |
618 | 3.57k | { |
619 | 3.57k | mxDrawPage = the_value; |
620 | 3.57k | } |
621 | | |
622 | | void ShapeContextHandler::setModel(const css::uno::Reference< css::frame::XModel > & the_value) |
623 | 3.57k | { |
624 | 3.57k | if( !mxShapeFilterBase.is() ) |
625 | 0 | throw uno::RuntimeException(); |
626 | 3.57k | uno::Reference<lang::XComponent> xComp(the_value, uno::UNO_QUERY_THROW); |
627 | 3.57k | mxShapeFilterBase->setTargetDocument(xComp); |
628 | 3.57k | } |
629 | | |
630 | | void ShapeContextHandler::setRelationFragmentPath(const OUString & the_value) |
631 | 3.57k | { |
632 | 3.57k | msRelationFragmentPath = the_value; |
633 | 3.57k | } |
634 | | |
635 | | sal_Int32 ShapeContextHandler::getStartToken() const |
636 | 24.0k | { |
637 | 24.0k | assert(mnStartTokenStack.size() && "This stack must not be empty!"); |
638 | 24.0k | return mnStartTokenStack.top(); |
639 | 24.0k | } |
640 | | |
641 | | void ShapeContextHandler::popStartToken() |
642 | 3.34k | { |
643 | 3.34k | if (mnStartTokenStack.size() > 1) |
644 | 1.22k | mnStartTokenStack.pop(); |
645 | 3.34k | } |
646 | | |
647 | | void ShapeContextHandler::pushStartToken( sal_Int32 _starttoken ) |
648 | 3.57k | { |
649 | 3.57k | mnStartTokenStack.push(_starttoken); |
650 | 3.57k | } |
651 | | |
652 | | void ShapeContextHandler::setPosition(const awt::Point& rPosition) |
653 | 3.43k | { |
654 | 3.43k | maPosition = rPosition; |
655 | 3.43k | } |
656 | | |
657 | | void ShapeContextHandler::setSize(const awt::Size& rSize) |
658 | 142 | { |
659 | 142 | maSize = rSize; |
660 | 142 | } |
661 | | |
662 | | void ShapeContextHandler::setDocumentProperties(const uno::Reference<document::XDocumentProperties>& xDocProps) |
663 | 3.57k | { |
664 | 3.57k | mxDocumentProperties = xDocProps; |
665 | 3.57k | mxShapeFilterBase->checkDocumentProperties(mxDocumentProperties); |
666 | 3.57k | } |
667 | | |
668 | | void ShapeContextHandler::setMediaDescriptor(const uno::Sequence<beans::PropertyValue>& rMediaDescriptor) |
669 | 3.57k | { |
670 | 3.57k | maMediaDescriptor = rMediaDescriptor; |
671 | 3.57k | } |
672 | | |
673 | | void ShapeContextHandler::setGraphicMapper(css::uno::Reference<css::graphic::XGraphicMapper> const & rxGraphicMapper) |
674 | 3.57k | { |
675 | 3.57k | mxShapeFilterBase->setGraphicMapper(rxGraphicMapper); |
676 | 3.57k | } |
677 | | |
678 | | void ShapeContextHandler::applyFontRefColor(const oox::drawingml::ShapePtr& pShape, |
679 | | const oox::drawingml::Color& rFontRefColor) |
680 | 0 | { |
681 | 0 | pShape->getShapeStyleRefs()[XML_fontRef].maPhClr = rFontRefColor; |
682 | 0 | std::vector<oox::drawingml::ShapePtr>& vChildren = pShape->getChildren(); |
683 | 0 | for (auto const& child : vChildren) |
684 | 0 | { |
685 | 0 | applyFontRefColor(child, rFontRefColor); |
686 | 0 | } |
687 | 0 | } |
688 | | } |
689 | | |
690 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |