/src/libreoffice/xmloff/source/text/XMLTextFrameContext.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 <o3tl/string_view.hxx> |
21 | | #include <osl/diagnose.h> |
22 | | #include <sal/log.hxx> |
23 | | #include <comphelper/diagnose_ex.hxx> |
24 | | #include <comphelper/base64.hxx> |
25 | | #include <comphelper/configuration.hxx> |
26 | | #include <comphelper/mediamimetype.hxx> |
27 | | #include <com/sun/star/frame/XModel.hpp> |
28 | | #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
29 | | #include <com/sun/star/text/TextContentAnchorType.hpp> |
30 | | #include <com/sun/star/beans/XPropertySet.hpp> |
31 | | #include <com/sun/star/text/XTextFrame.hpp> |
32 | | #include <com/sun/star/container/XNamed.hpp> |
33 | | #include <com/sun/star/container/XNameContainer.hpp> |
34 | | #include <com/sun/star/graphic/XGraphic.hpp> |
35 | | #include <com/sun/star/text/SizeType.hpp> |
36 | | #include <com/sun/star/drawing/XShape.hpp> |
37 | | #include <com/sun/star/document/XEventsSupplier.hpp> |
38 | | #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp> |
39 | | #include <com/sun/star/io/XOutputStream.hpp> |
40 | | #include <com/sun/star/text/HoriOrientation.hpp> |
41 | | #include <com/sun/star/text/VertOrientation.hpp> |
42 | | #include <sax/tools/converter.hxx> |
43 | | #include <utility> |
44 | | #include <xmloff/xmlimp.hxx> |
45 | | #include <xmloff/xmltoken.hxx> |
46 | | #include <xmloff/xmlnamespace.hxx> |
47 | | #include <xmloff/xmluconv.hxx> |
48 | | #include "XMLAnchorTypePropHdl.hxx" |
49 | | #include <XMLEmbeddedObjectImportContext.hxx> |
50 | | #include <xmloff/XMLBase64ImportContext.hxx> |
51 | | #include <XMLReplacementImageContext.hxx> |
52 | | #include <xmloff/prstylei.hxx> |
53 | | #include <xmloff/i18nmap.hxx> |
54 | | #include <xexptran.hxx> |
55 | | #include <xmloff/shapeimport.hxx> |
56 | | #include <xmloff/XMLEventsImportContext.hxx> |
57 | | #include <XMLImageMapContext.hxx> |
58 | | #include "XMLTextFrameContext.hxx" |
59 | | #include <basegfx/polygon/b2dpolygon.hxx> |
60 | | #include <basegfx/polygon/b2dpolygontools.hxx> |
61 | | #include <basegfx/polygon/b2dpolypolygon.hxx> |
62 | | #include <basegfx/matrix/b2dhommatrixtools.hxx> |
63 | | #include <basegfx/polygon/b2dpolypolygontools.hxx> |
64 | | #include <basegfx/numeric/ftools.hxx> |
65 | | #include <map> |
66 | | #include <string_view> |
67 | | |
68 | | using namespace ::com::sun::star; |
69 | | using namespace ::com::sun::star::uno; |
70 | | using namespace ::com::sun::star::text; |
71 | | using namespace ::com::sun::star::xml::sax; |
72 | | using namespace ::com::sun::star::beans; |
73 | | using namespace ::com::sun::star::lang; |
74 | | using namespace ::com::sun::star::container; |
75 | | using namespace ::com::sun::star::drawing; |
76 | | using namespace ::com::sun::star::document; |
77 | | using namespace ::xmloff::token; |
78 | | using ::com::sun::star::document::XEventsSupplier; |
79 | | |
80 | 133k | #define XML_TEXT_FRAME_TEXTBOX 1 |
81 | 316k | #define XML_TEXT_FRAME_GRAPHIC 2 |
82 | 129k | #define XML_TEXT_FRAME_OBJECT 3 |
83 | 182k | #define XML_TEXT_FRAME_OBJECT_OLE 4 |
84 | 264k | #define XML_TEXT_FRAME_APPLET 5 |
85 | 223k | #define XML_TEXT_FRAME_PLUGIN 6 |
86 | 65.7k | #define XML_TEXT_FRAME_FLOATING_FRAME 7 |
87 | | |
88 | | typedef ::std::map < const OUString, OUString > ParamMap; |
89 | | |
90 | | class XMLTextFrameContextHyperlink_Impl |
91 | | { |
92 | | OUString sHRef; |
93 | | OUString sName; |
94 | | OUString sTargetFrameName; |
95 | | bool bMap; |
96 | | |
97 | | public: |
98 | | |
99 | | inline XMLTextFrameContextHyperlink_Impl( OUString aHRef, |
100 | | OUString aName, |
101 | | OUString aTargetFrameName, |
102 | | bool bMap ); |
103 | | |
104 | 0 | const OUString& GetHRef() const { return sHRef; } |
105 | 0 | const OUString& GetName() const { return sName; } |
106 | 0 | const OUString& GetTargetFrameName() const { return sTargetFrameName; } |
107 | 0 | bool GetMap() const { return bMap; } |
108 | | }; |
109 | | |
110 | | inline XMLTextFrameContextHyperlink_Impl::XMLTextFrameContextHyperlink_Impl( |
111 | | OUString aHRef, OUString aName, |
112 | | OUString aTargetFrameName, bool bM ) : |
113 | 0 | sHRef(std::move( aHRef )), |
114 | 0 | sName(std::move( aName )), |
115 | 0 | sTargetFrameName(std::move( aTargetFrameName )), |
116 | 0 | bMap( bM ) |
117 | 0 | { |
118 | 0 | } |
119 | | |
120 | | namespace { |
121 | | |
122 | | // Implement Title/Description Elements UI (#i73249#) |
123 | | class XMLTextFrameTitleOrDescContext_Impl : public SvXMLImportContext |
124 | | { |
125 | | OUString& mrTitleOrDesc; |
126 | | |
127 | | public: |
128 | | |
129 | | |
130 | | XMLTextFrameTitleOrDescContext_Impl( SvXMLImport& rImport, |
131 | | OUString& rTitleOrDesc ); |
132 | | |
133 | | virtual void SAL_CALL characters( const OUString& rText ) override; |
134 | | }; |
135 | | |
136 | | } |
137 | | |
138 | | XMLTextFrameTitleOrDescContext_Impl::XMLTextFrameTitleOrDescContext_Impl( |
139 | | SvXMLImport& rImport, |
140 | | OUString& rTitleOrDesc ) |
141 | 0 | : SvXMLImportContext( rImport ) |
142 | 0 | , mrTitleOrDesc( rTitleOrDesc ) |
143 | 0 | { |
144 | 0 | } |
145 | | |
146 | | void XMLTextFrameTitleOrDescContext_Impl::characters( const OUString& rText ) |
147 | 0 | { |
148 | 0 | mrTitleOrDesc += rText; |
149 | 0 | } |
150 | | |
151 | | namespace { |
152 | | |
153 | | class XMLTextFrameParam_Impl : public SvXMLImportContext |
154 | | { |
155 | | public: |
156 | | XMLTextFrameParam_Impl( SvXMLImport& rImport, |
157 | | const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList, |
158 | | ParamMap &rParamMap); |
159 | | }; |
160 | | |
161 | | } |
162 | | |
163 | | XMLTextFrameParam_Impl::XMLTextFrameParam_Impl( |
164 | | SvXMLImport& rImport, |
165 | | const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList, |
166 | | ParamMap &rParamMap): |
167 | 0 | SvXMLImportContext( rImport ) |
168 | 0 | { |
169 | 0 | OUString sName, sValue; |
170 | 0 | bool bFoundValue = false; // to allow empty values |
171 | 0 | for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList )) |
172 | 0 | { |
173 | 0 | switch (aIter.getToken()) |
174 | 0 | { |
175 | 0 | case XML_ELEMENT(DRAW, XML_VALUE): |
176 | 0 | { |
177 | 0 | sValue = aIter.toString(); |
178 | 0 | bFoundValue = true; |
179 | 0 | break; |
180 | 0 | } |
181 | 0 | case XML_ELEMENT(DRAW, XML_NAME): |
182 | 0 | sName = aIter.toString(); |
183 | 0 | break; |
184 | 0 | default: |
185 | 0 | XMLOFF_WARN_UNKNOWN("xmloff", aIter); |
186 | 0 | } |
187 | 0 | } |
188 | 0 | if (!sName.isEmpty() && bFoundValue ) |
189 | 0 | rParamMap[sName] = sValue; |
190 | 0 | } |
191 | | |
192 | | namespace { |
193 | | |
194 | | class XMLTextFrameContourContext_Impl : public SvXMLImportContext |
195 | | { |
196 | | Reference < XPropertySet > xPropSet; |
197 | | |
198 | | public: |
199 | | |
200 | | |
201 | | XMLTextFrameContourContext_Impl( SvXMLImport& rImport, sal_Int32 nElement, |
202 | | const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList, |
203 | | const Reference < XPropertySet >& rPropSet, |
204 | | bool bPath ); |
205 | | }; |
206 | | |
207 | | } |
208 | | |
209 | | XMLTextFrameContourContext_Impl::XMLTextFrameContourContext_Impl( |
210 | | SvXMLImport& rImport, |
211 | | sal_Int32 /*nElement*/, |
212 | | const Reference< XFastAttributeList > & xAttrList, |
213 | | const Reference < XPropertySet >& rPropSet, |
214 | | bool bPath ) : |
215 | 0 | SvXMLImportContext( rImport ), |
216 | 0 | xPropSet( rPropSet ) |
217 | 0 | { |
218 | 0 | OUString sD, sPoints, sViewBox; |
219 | 0 | bool bPixelWidth = false, bPixelHeight = false; |
220 | 0 | bool bAuto = false; |
221 | 0 | sal_Int32 nWidth = 0; |
222 | 0 | sal_Int32 nHeight = 0; |
223 | |
|
224 | 0 | for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) |
225 | 0 | { |
226 | 0 | switch( aIter.getToken() ) |
227 | 0 | { |
228 | 0 | case XML_ELEMENT(SVG, XML_VIEWBOX): |
229 | 0 | case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX): |
230 | 0 | sViewBox = aIter.toString(); |
231 | 0 | break; |
232 | 0 | case XML_ELEMENT(SVG, XML_D): |
233 | 0 | case XML_ELEMENT(SVG_COMPAT, XML_D): |
234 | 0 | if( bPath ) |
235 | 0 | sD = aIter.toString(); |
236 | 0 | break; |
237 | 0 | case XML_ELEMENT(DRAW,XML_POINTS): |
238 | 0 | if( !bPath ) |
239 | 0 | sPoints = aIter.toString(); |
240 | 0 | break; |
241 | 0 | case XML_ELEMENT(SVG, XML_WIDTH): |
242 | 0 | case XML_ELEMENT(SVG_COMPAT, XML_WIDTH): |
243 | 0 | if (::sax::Converter::convertMeasurePx(nWidth, aIter.toView())) |
244 | 0 | bPixelWidth = true; |
245 | 0 | else |
246 | 0 | GetImport().GetMM100UnitConverter().convertMeasureToCore( |
247 | 0 | nWidth, aIter.toView()); |
248 | 0 | break; |
249 | 0 | case XML_ELEMENT(SVG, XML_HEIGHT): |
250 | 0 | case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT): |
251 | 0 | if (::sax::Converter::convertMeasurePx(nHeight, aIter.toView())) |
252 | 0 | bPixelHeight = true; |
253 | 0 | else |
254 | 0 | GetImport().GetMM100UnitConverter().convertMeasureToCore( |
255 | 0 | nHeight, aIter.toView()); |
256 | 0 | break; |
257 | 0 | case XML_ELEMENT(DRAW, XML_RECREATE_ON_EDIT): |
258 | 0 | bAuto = IsXMLToken(aIter, XML_TRUE); |
259 | 0 | break; |
260 | 0 | } |
261 | 0 | } |
262 | | |
263 | 0 | OUString sContourPolyPolygon(u"ContourPolyPolygon"_ustr); |
264 | 0 | Reference < XPropertySetInfo > xPropSetInfo = rPropSet->getPropertySetInfo(); |
265 | |
|
266 | 0 | if(!xPropSetInfo->hasPropertyByName(sContourPolyPolygon) || |
267 | 0 | nWidth <= 0 || nHeight <= 0 || bPixelWidth != bPixelHeight || |
268 | 0 | !(bPath ? sD : sPoints).getLength()) |
269 | 0 | return; |
270 | | |
271 | 0 | const SdXMLImExViewBox aViewBox( sViewBox, GetImport().GetMM100UnitConverter()); |
272 | 0 | basegfx::B2DPolyPolygon aPolyPolygon; |
273 | | |
274 | | // Related tdf#161833: ignore saved polygon for "recreate on edit" contours |
275 | | // tdf#161833 would cause semi-transparent pixels to be treated as fully |
276 | | // transparent pixels when calculating the wrap contour for an image. To |
277 | | // force the correct contour when loading a document, force the contour |
278 | | // to be recalculated by ignoring the saved polygon if the contour is set |
279 | | // to "recreate on edit". |
280 | 0 | if( !bAuto ) |
281 | 0 | { |
282 | 0 | if( bPath ) |
283 | 0 | { |
284 | 0 | basegfx::utils::importFromSvgD(aPolyPolygon, sD, GetImport().needFixPositionAfterZ(), nullptr); |
285 | 0 | } |
286 | 0 | else |
287 | 0 | { |
288 | 0 | basegfx::B2DPolygon aPolygon; |
289 | |
|
290 | 0 | if(basegfx::utils::importFromSvgPoints(aPolygon, sPoints)) |
291 | 0 | { |
292 | 0 | aPolyPolygon = basegfx::B2DPolyPolygon(aPolygon); |
293 | 0 | } |
294 | 0 | } |
295 | 0 | } |
296 | |
|
297 | 0 | if(aPolyPolygon.count()) |
298 | 0 | { |
299 | 0 | const basegfx::B2DRange aSourceRange( |
300 | 0 | aViewBox.GetX(), aViewBox.GetY(), |
301 | 0 | aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight()); |
302 | 0 | const basegfx::B2DRange aTargetRange( |
303 | 0 | 0.0, 0.0, |
304 | 0 | nWidth, nHeight); |
305 | |
|
306 | 0 | if(!aSourceRange.equal(aTargetRange)) |
307 | 0 | { |
308 | 0 | aPolyPolygon.transform( |
309 | 0 | basegfx::utils::createSourceRangeTargetRangeTransform( |
310 | 0 | aSourceRange, |
311 | 0 | aTargetRange)); |
312 | 0 | } |
313 | |
|
314 | 0 | css::drawing::PointSequenceSequence aPointSequenceSequence; |
315 | 0 | basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(aPolyPolygon, aPointSequenceSequence); |
316 | 0 | xPropSet->setPropertyValue( sContourPolyPolygon, Any(aPointSequenceSequence) ); |
317 | 0 | } |
318 | |
|
319 | 0 | static constexpr OUString sIsPixelContour(u"IsPixelContour"_ustr); |
320 | |
|
321 | 0 | if( xPropSetInfo->hasPropertyByName( sIsPixelContour ) ) |
322 | 0 | { |
323 | 0 | xPropSet->setPropertyValue( sIsPixelContour, Any(bPixelWidth) ); |
324 | 0 | } |
325 | |
|
326 | 0 | static constexpr OUString sIsAutomaticContour(u"IsAutomaticContour"_ustr); |
327 | |
|
328 | 0 | if( xPropSetInfo->hasPropertyByName( sIsAutomaticContour ) ) |
329 | 0 | { |
330 | 0 | xPropSet->setPropertyValue( sIsAutomaticContour, Any(bAuto) ); |
331 | 0 | } |
332 | 0 | } |
333 | | |
334 | | namespace { |
335 | | |
336 | | class XMLTextFrameContext_Impl : public SvXMLImportContext |
337 | | { |
338 | | css::uno::Reference < css::text::XTextCursor > xOldTextCursor; |
339 | | css::uno::Reference < css::beans::XPropertySet > xPropSet; |
340 | | css::uno::Reference < css::io::XOutputStream > xBase64Stream; |
341 | | |
342 | | /// old list item and block (#89891#) |
343 | | bool mbListContextPushed; |
344 | | |
345 | | OUString m_sOrigName; |
346 | | OUString sName; |
347 | | OUString sStyleName; |
348 | | OUString sNextName; |
349 | | OUString sHRef; |
350 | | OUString sCode; |
351 | | OUString sMimeType; |
352 | | OUString sFrameName; |
353 | | OUString sAppletName; |
354 | | OUString sFilterService; |
355 | | OUString sBase64CharsLeft; |
356 | | OUString sTblName; |
357 | | OUStringBuffer maUrlBuffer; |
358 | | |
359 | | ParamMap aParamMap; |
360 | | |
361 | | sal_Int32 nX; |
362 | | sal_Int32 nY; |
363 | | sal_Int32 nWidth; |
364 | | sal_Int32 nHeight; |
365 | | sal_Int32 nZIndex; |
366 | | sal_Int16 nPage; |
367 | | sal_Int16 nRotation; |
368 | | sal_Int16 nRelWidth; |
369 | | sal_Int16 nRelHeight; |
370 | | |
371 | | sal_uInt16 nType; |
372 | | css::text::TextContentAnchorType eAnchorType; |
373 | | |
374 | | bool bMayScript : 1; |
375 | | bool bMinWidth : 1; |
376 | | bool bMinHeight : 1; |
377 | | bool bSyncWidth : 1; |
378 | | bool bSyncHeight : 1; |
379 | | bool bCreateFailed : 1; |
380 | | bool bOwnBase64Stream : 1; |
381 | | bool mbMultipleContent : 1; // This context is created based on a multiple content (image) |
382 | | bool m_isDecorative = false; |
383 | | bool m_isSplitAllowed = false; |
384 | | |
385 | | void Create(); |
386 | | |
387 | | public: |
388 | | |
389 | | |
390 | | bool CreateIfNotThere(); |
391 | 11.4k | const OUString& GetHRef() const { return sHRef; } |
392 | | |
393 | | XMLTextFrameContext_Impl( SvXMLImport& rImport, |
394 | | sal_Int32 nElement, |
395 | | const css::uno::Reference<css::xml::sax::XFastAttributeList > & rAttrList, |
396 | | css::text::TextContentAnchorType eAnchorType, |
397 | | sal_uInt16 nType, |
398 | | const css::uno::Reference<css::xml::sax::XFastAttributeList > & rFrameAttrList, |
399 | | bool bMultipleContent = false ); |
400 | | |
401 | | virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; |
402 | | |
403 | | virtual void SAL_CALL characters( const OUString& rChars ) override; |
404 | | |
405 | | virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( |
406 | | sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override; |
407 | | |
408 | | void SetHyperlink( const OUString& rHRef, |
409 | | const OUString& rName, |
410 | | const OUString& rTargetFrameName, |
411 | | bool bMap ); |
412 | | |
413 | | // Implement Title/Description Elements UI (#i73249#) |
414 | | void SetTitle( const OUString& rTitle ); |
415 | | |
416 | | void SetDesc( const OUString& rDesc ); |
417 | | |
418 | | void SetName(); |
419 | | |
420 | 23.6k | const OUString& GetOrigName() const { return m_sOrigName; } |
421 | | |
422 | 5 | css::text::TextContentAnchorType GetAnchorType() const { return eAnchorType; } |
423 | 11.4k | const OUString & GetMimeType() const { return sMimeType; } |
424 | | |
425 | 11.2k | const css::uno::Reference < css::beans::XPropertySet >& GetPropSet() const { return xPropSet; } |
426 | | }; |
427 | | |
428 | | } |
429 | | |
430 | | void XMLTextFrameContext_Impl::Create() |
431 | 65.9k | { |
432 | 65.9k | rtl::Reference < XMLTextImportHelper > xTextImportHelper = |
433 | 65.9k | GetImport().GetTextImport(); |
434 | | |
435 | 65.9k | switch ( nType) |
436 | 65.9k | { |
437 | 45 | case XML_TEXT_FRAME_OBJECT: |
438 | 83 | case XML_TEXT_FRAME_OBJECT_OLE: |
439 | 83 | if( xBase64Stream.is() ) |
440 | 38 | { |
441 | 38 | OUString sURL( GetImport().ResolveEmbeddedObjectURLFromBase64() ); |
442 | 38 | if( !sURL.isEmpty() ) |
443 | 38 | xPropSet = GetImport().GetTextImport() |
444 | 38 | ->createAndInsertOLEObject( GetImport(), sURL, |
445 | 38 | sStyleName, |
446 | 38 | sTblName, |
447 | 38 | nWidth, nHeight ); |
448 | 38 | } |
449 | 45 | else if( !sHRef.isEmpty() ) |
450 | 0 | { |
451 | 0 | OUString sURL( GetImport().ResolveEmbeddedObjectURL( sHRef, |
452 | 0 | std::u16string_view() ) ); |
453 | |
|
454 | 0 | if( GetImport().IsPackageURL( sHRef ) ) |
455 | 0 | { |
456 | 0 | xPropSet = GetImport().GetTextImport() |
457 | 0 | ->createAndInsertOLEObject( GetImport(), sURL, |
458 | 0 | sStyleName, |
459 | 0 | sTblName, |
460 | 0 | nWidth, nHeight ); |
461 | 0 | } |
462 | 0 | else |
463 | 0 | { |
464 | | // it should be an own OOo link that has no storage persistence |
465 | 0 | xPropSet = GetImport().GetTextImport() |
466 | 0 | ->createAndInsertOOoLink( GetImport(), |
467 | 0 | sURL, |
468 | 0 | sStyleName, |
469 | 0 | sTblName, |
470 | 0 | nWidth, nHeight ); |
471 | 0 | } |
472 | 0 | } |
473 | 45 | else |
474 | 45 | { |
475 | 45 | OUString sURL = "vnd.sun.star.ServiceName:" + sFilterService; |
476 | 45 | xPropSet = GetImport().GetTextImport() |
477 | 45 | ->createAndInsertOLEObject( GetImport(), sURL, |
478 | 45 | sStyleName, |
479 | 45 | sTblName, |
480 | 45 | nWidth, nHeight ); |
481 | | |
482 | 45 | } |
483 | 83 | break; |
484 | 0 | case XML_TEXT_FRAME_APPLET: |
485 | 0 | { |
486 | 0 | xPropSet = GetImport().GetTextImport() |
487 | 0 | ->createAndInsertApplet( sAppletName, sCode, |
488 | 0 | bMayScript, sHRef, |
489 | 0 | nWidth, nHeight); |
490 | 0 | break; |
491 | 45 | } |
492 | 0 | case XML_TEXT_FRAME_PLUGIN: |
493 | 0 | { |
494 | 0 | if(!sHRef.isEmpty()) |
495 | 0 | GetImport().GetAbsoluteReference(sHRef); |
496 | 0 | xPropSet = GetImport().GetTextImport() |
497 | 0 | ->createAndInsertPlugin( sMimeType, sHRef, |
498 | 0 | nWidth, nHeight); |
499 | |
|
500 | 0 | break; |
501 | 45 | } |
502 | 0 | case XML_TEXT_FRAME_FLOATING_FRAME: |
503 | 0 | { |
504 | 0 | xPropSet = GetImport().GetTextImport() |
505 | 0 | ->createAndInsertFloatingFrame( sFrameName, sHRef, |
506 | 0 | sStyleName, |
507 | 0 | nWidth, nHeight); |
508 | 0 | break; |
509 | 45 | } |
510 | 65.8k | default: |
511 | 65.8k | { |
512 | 65.8k | Reference<XMultiServiceFactory> xFactory( GetImport().GetModel(), |
513 | 65.8k | UNO_QUERY ); |
514 | 65.8k | if( xFactory.is() ) |
515 | 65.8k | { |
516 | 65.8k | OUString sServiceName; |
517 | 65.8k | switch( nType ) |
518 | 65.8k | { |
519 | 23.0k | case XML_TEXT_FRAME_TEXTBOX: sServiceName = "com.sun.star.text.TextFrame"; break; |
520 | 42.8k | case XML_TEXT_FRAME_GRAPHIC: sServiceName = "com.sun.star.text.GraphicObject"; break; |
521 | 65.8k | } |
522 | 65.8k | Reference<XInterface> xIfc = xFactory->createInstance( sServiceName ); |
523 | 65.8k | SAL_WARN_IF( !xIfc.is(), "xmloff.text", "couldn't create frame" ); |
524 | 65.8k | if( xIfc.is() ) |
525 | 65.7k | xPropSet.set( xIfc, UNO_QUERY ); |
526 | 65.8k | } |
527 | 65.8k | } |
528 | 65.9k | } |
529 | | |
530 | 65.8k | if( !xPropSet.is() ) |
531 | 144 | { |
532 | 144 | bCreateFailed = true; |
533 | 144 | return; |
534 | 144 | } |
535 | | |
536 | 65.7k | Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); |
537 | | |
538 | | // Skip duplicated frames |
539 | 65.7k | if(!mbMultipleContent && // It's allowed to have multiple image for the same frame |
540 | 24.4k | !sName.isEmpty() && |
541 | 9.82k | xTextImportHelper->IsDuplicateFrame(sName, nX, nY, nWidth, nHeight)) |
542 | 1 | { |
543 | 1 | bCreateFailed = true; |
544 | 1 | return; |
545 | 1 | } |
546 | | |
547 | | // set name |
548 | 65.7k | Reference < XNamed > xNamed( xPropSet, UNO_QUERY ); |
549 | 65.7k | if( xNamed.is() ) |
550 | 65.7k | { |
551 | 65.7k | OUString sOrigName( xNamed->getName() ); |
552 | 65.7k | if( sOrigName.isEmpty() || |
553 | 38 | (!sName.isEmpty() && sOrigName != sName) ) |
554 | 65.7k | { |
555 | 65.7k | OUString sOldName( sName ); |
556 | | |
557 | 65.7k | sal_Int32 i = 0; |
558 | 2.32M | while( xTextImportHelper->HasFrameByName( sName ) ) |
559 | 2.25M | { |
560 | 2.25M | sName = sOldName + OUString::number( ++i ); |
561 | 2.25M | } |
562 | 65.7k | xNamed->setName( sName ); |
563 | 65.7k | if( sName != sOldName ) |
564 | 39.0k | { |
565 | 39.0k | xTextImportHelper->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_FRAME, |
566 | 39.0k | sOldName, sName ); |
567 | | |
568 | 39.0k | } |
569 | 65.7k | } |
570 | 65.7k | } |
571 | | |
572 | | // frame style |
573 | 65.7k | XMLPropStyleContext *pStyle = nullptr; |
574 | 65.7k | if( !sStyleName.isEmpty() ) |
575 | 41.0k | { |
576 | 41.0k | pStyle = xTextImportHelper->FindAutoFrameStyle( sStyleName ); |
577 | 41.0k | if( pStyle ) |
578 | 795 | sStyleName = pStyle->GetParentName(); |
579 | 41.0k | } |
580 | | |
581 | 65.7k | Any aAny; |
582 | 65.7k | if( !sStyleName.isEmpty() ) |
583 | 41.0k | { |
584 | 41.0k | OUString sDisplayStyleName( GetImport().GetStyleDisplayName( |
585 | 41.0k | XmlStyleFamily::SD_GRAPHICS_ID, sStyleName ) ); |
586 | 41.0k | const Reference < XNameContainer > & rStyles = |
587 | 41.0k | xTextImportHelper->GetFrameStyles(); |
588 | 41.0k | if( rStyles.is() && |
589 | 41.0k | rStyles->hasByName( sDisplayStyleName ) ) |
590 | 792 | { |
591 | 792 | xPropSet->setPropertyValue( u"FrameStyleName"_ustr, Any(sDisplayStyleName) ); |
592 | 792 | } |
593 | 41.0k | } |
594 | | |
595 | | // anchor type (must be set before any other properties, because |
596 | | // otherwise some orientations cannot be set or will be changed |
597 | | // afterwards) |
598 | 65.7k | xPropSet->setPropertyValue( u"AnchorType"_ustr, Any(eAnchorType) ); |
599 | | |
600 | | // hard properties |
601 | 65.7k | if( pStyle ) |
602 | 795 | pStyle->FillPropertySet( xPropSet ); |
603 | | |
604 | | // x and y |
605 | 65.7k | sal_Int16 nHoriOrient = HoriOrientation::NONE; |
606 | 65.7k | aAny = xPropSet->getPropertyValue( u"HoriOrient"_ustr ); |
607 | 65.7k | aAny >>= nHoriOrient; |
608 | 65.7k | if( HoriOrientation::NONE == nHoriOrient ) |
609 | 244 | { |
610 | 244 | xPropSet->setPropertyValue( u"HoriOrientPosition"_ustr, Any(nX) ); |
611 | 244 | } |
612 | | |
613 | 65.7k | sal_Int16 nVertOrient = VertOrientation::NONE; |
614 | 65.7k | aAny = xPropSet->getPropertyValue( u"VertOrient"_ustr ); |
615 | 65.7k | aAny >>= nVertOrient; |
616 | 65.7k | if( VertOrientation::NONE == nVertOrient ) |
617 | 30 | { |
618 | 30 | xPropSet->setPropertyValue( u"VertOrientPosition"_ustr, Any(nY) ); |
619 | 30 | } |
620 | | |
621 | | // width |
622 | 65.7k | if( nWidth > 0 ) |
623 | 5.98k | { |
624 | 5.98k | xPropSet->setPropertyValue( u"Width"_ustr, Any(nWidth) ); |
625 | 5.98k | } |
626 | 65.7k | if( nRelWidth > 0 || nWidth > 0 ) |
627 | 6.54k | { |
628 | 6.54k | xPropSet->setPropertyValue( u"RelativeWidth"_ustr, Any(nRelWidth) ); |
629 | 6.54k | } |
630 | 65.7k | if( bSyncWidth || nWidth > 0 ) |
631 | 5.98k | { |
632 | 5.98k | xPropSet->setPropertyValue( u"IsSyncWidthToHeight"_ustr, Any(bSyncWidth) ); |
633 | 5.98k | } |
634 | 65.7k | if( xPropSetInfo->hasPropertyByName( u"WidthType"_ustr ) && |
635 | 22.8k | (bMinWidth || nWidth > 0 || nRelWidth > 0 ) ) |
636 | 1.17k | { |
637 | 1.17k | sal_Int16 nSizeType = |
638 | 1.17k | (bMinWidth && XML_TEXT_FRAME_TEXTBOX == nType) ? SizeType::MIN |
639 | 1.17k | : SizeType::FIX; |
640 | 1.17k | xPropSet->setPropertyValue( u"WidthType"_ustr, Any(nSizeType) ); |
641 | 1.17k | } |
642 | | |
643 | 65.7k | if( nHeight > 0 ) |
644 | 6.08k | { |
645 | 6.08k | xPropSet->setPropertyValue( u"Height"_ustr, Any(nHeight) ); |
646 | 6.08k | } |
647 | 65.7k | if( nRelHeight > 0 || nHeight > 0 ) |
648 | 6.08k | { |
649 | 6.08k | xPropSet->setPropertyValue( u"RelativeHeight"_ustr, Any(nRelHeight) ); |
650 | 6.08k | } |
651 | 65.7k | if( bSyncHeight || nHeight > 0 ) |
652 | 6.08k | { |
653 | 6.08k | xPropSet->setPropertyValue( u"IsSyncHeightToWidth"_ustr, Any(bSyncHeight) ); |
654 | 6.08k | } |
655 | 65.7k | if( xPropSetInfo->hasPropertyByName( u"SizeType"_ustr ) && |
656 | 22.8k | (bMinHeight || nHeight > 0 || nRelHeight > 0 ) ) |
657 | 768 | { |
658 | 768 | sal_Int16 nSizeType = |
659 | 768 | (bMinHeight && XML_TEXT_FRAME_TEXTBOX == nType) ? SizeType::MIN |
660 | 768 | : SizeType::FIX; |
661 | 768 | xPropSet->setPropertyValue( u"SizeType"_ustr, Any(nSizeType) ); |
662 | 768 | } |
663 | | |
664 | 65.7k | if( XML_TEXT_FRAME_GRAPHIC == nType ) |
665 | 42.8k | { |
666 | | // URL |
667 | 42.8k | OSL_ENSURE( !sHRef.isEmpty() || xBase64Stream.is(), |
668 | 42.8k | "neither URL nor base64 image data given" ); |
669 | 42.8k | uno::Reference<graphic::XGraphic> xGraphic; |
670 | 42.8k | if (!sHRef.isEmpty()) |
671 | 42.8k | { |
672 | 42.8k | xGraphic = GetImport().loadGraphicByURL(sHRef); |
673 | 42.8k | } |
674 | 0 | else if (xBase64Stream.is()) |
675 | 0 | { |
676 | 0 | xGraphic = GetImport().loadGraphicFromBase64(xBase64Stream); |
677 | 0 | xBase64Stream = nullptr; |
678 | 0 | } |
679 | | |
680 | 42.8k | if (xGraphic.is()) |
681 | 42.8k | xPropSet->setPropertyValue(u"Graphic"_ustr, Any(xGraphic)); |
682 | | |
683 | | // filter name |
684 | 42.8k | xPropSet->setPropertyValue( u"GraphicFilter"_ustr, Any(OUString()) ); |
685 | | |
686 | | // rotation |
687 | 42.8k | xPropSet->setPropertyValue( u"GraphicRotation"_ustr, Any(nRotation) ); |
688 | 42.8k | } |
689 | | |
690 | | // page number (must be set after the frame is inserted, because it |
691 | | // will be overwritten then inserting the frame. |
692 | 65.7k | if( TextContentAnchorType_AT_PAGE == eAnchorType && nPage > 0 ) |
693 | 159 | { |
694 | 159 | xPropSet->setPropertyValue( u"AnchorPageNo"_ustr, Any(nPage) ); |
695 | 159 | } |
696 | | |
697 | 65.7k | if (m_isDecorative && xPropSetInfo->hasPropertyByName(u"Decorative"_ustr)) |
698 | 0 | { |
699 | 0 | xPropSet->setPropertyValue(u"Decorative"_ustr, uno::Any(true)); |
700 | 0 | } |
701 | | |
702 | 65.7k | if (m_isSplitAllowed && xPropSetInfo->hasPropertyByName(u"IsSplitAllowed"_ustr)) |
703 | 0 | { |
704 | 0 | xPropSet->setPropertyValue(u"IsSplitAllowed"_ustr, uno::Any(true)); |
705 | 0 | } |
706 | | |
707 | 65.7k | if( XML_TEXT_FRAME_OBJECT != nType && |
708 | 65.7k | XML_TEXT_FRAME_OBJECT_OLE != nType && |
709 | 65.7k | XML_TEXT_FRAME_APPLET != nType && |
710 | 65.7k | XML_TEXT_FRAME_PLUGIN!= nType && |
711 | 65.7k | XML_TEXT_FRAME_FLOATING_FRAME != nType) |
712 | 65.7k | { |
713 | 65.7k | Reference < XTextContent > xTxtCntnt( xPropSet, UNO_QUERY ); |
714 | 65.7k | try |
715 | 65.7k | { |
716 | 65.7k | xTextImportHelper->InsertTextContent(xTxtCntnt); |
717 | 65.7k | } |
718 | 65.7k | catch (lang::IllegalArgumentException const&) |
719 | 65.7k | { |
720 | 6.01k | TOOLS_WARN_EXCEPTION("xmloff.text", "Cannot import part of the text - probably an image in the text frame?"); |
721 | 6.01k | return; |
722 | 6.01k | } |
723 | 65.7k | } |
724 | | |
725 | | // Make adding the shape to Z-Ordering dependent from if we are |
726 | | // inside an inside_deleted_section (redlining). That is necessary |
727 | | // since the shape will be removed again later. It would lead to |
728 | | // errors if it would stay inside the Z-Ordering. Thus, the |
729 | | // easiest way to solve that conflict is to not add it here. |
730 | 59.7k | if(!GetImport().HasTextImport() |
731 | 59.7k | || !GetImport().GetTextImport()->IsInsideDeleteContext()) |
732 | 59.7k | { |
733 | 59.7k | Reference < XShape > xShape( xPropSet, UNO_QUERY ); |
734 | | |
735 | 59.7k | GetImport().GetShapeImport()->shapeWithZIndexAdded( xShape, nZIndex ); |
736 | 59.7k | } |
737 | | |
738 | 59.7k | if( XML_TEXT_FRAME_TEXTBOX != nType ) |
739 | 36.8k | return; |
740 | | |
741 | 22.8k | xTextImportHelper->ConnectFrameChains( sName, sNextName, xPropSet ); |
742 | 22.8k | Reference < XTextFrame > xTxtFrame( xPropSet, UNO_QUERY ); |
743 | 22.8k | Reference < XText > xTxt = xTxtFrame->getText(); |
744 | 22.8k | xOldTextCursor = xTextImportHelper->GetCursor(); |
745 | 22.8k | xTextImportHelper->SetCursor( xTxt->createTextCursor() ); |
746 | | |
747 | | // remember old list item and block (#89892#) and reset them |
748 | | // for the text frame |
749 | 22.8k | xTextImportHelper->PushListContext(); |
750 | 22.8k | mbListContextPushed = true; |
751 | 22.8k | } |
752 | | |
753 | | void XMLTextFrameContext::removeGraphicFromImportContext(const SvXMLImportContext& rContext) |
754 | 11.2k | { |
755 | 11.2k | const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast< const XMLTextFrameContext_Impl* >(&rContext); |
756 | | |
757 | 11.2k | if(!pXMLTextFrameContext_Impl) |
758 | 0 | return; |
759 | | |
760 | 11.2k | try |
761 | 11.2k | { |
762 | | // just dispose to delete |
763 | 11.2k | uno::Reference< lang::XComponent > xComp(pXMLTextFrameContext_Impl->GetPropSet(), UNO_QUERY); |
764 | | |
765 | | // Inform shape importer about the removal so it can adjust |
766 | | // z-indexes. |
767 | 11.2k | uno::Reference<drawing::XShape> xShape(xComp, uno::UNO_QUERY); |
768 | 11.2k | GetImport().GetShapeImport()->shapeRemoved(xShape); |
769 | | |
770 | 11.2k | if(xComp.is()) |
771 | 10.8k | { |
772 | 10.8k | xComp->dispose(); |
773 | 10.8k | } |
774 | 11.2k | } |
775 | 11.2k | catch( uno::Exception& ) |
776 | 11.2k | { |
777 | 0 | OSL_FAIL( "Error in cleanup of multiple graphic object import (!)" ); |
778 | 0 | } |
779 | 11.2k | } |
780 | | |
781 | | OUString XMLTextFrameContext::getMimeTypeFromImportContext(const SvXMLImportContext& rContext) const |
782 | 11.4k | { |
783 | 11.4k | const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast<const XMLTextFrameContext_Impl*>(&rContext); |
784 | | |
785 | 11.4k | if (pXMLTextFrameContext_Impl) |
786 | 11.4k | return pXMLTextFrameContext_Impl->GetMimeType(); |
787 | | |
788 | 0 | return OUString(); |
789 | 11.4k | } |
790 | | |
791 | | OUString XMLTextFrameContext::getGraphicPackageURLFromImportContext(const SvXMLImportContext& rContext) const |
792 | 11.4k | { |
793 | 11.4k | const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast< const XMLTextFrameContext_Impl* >(&rContext); |
794 | | |
795 | 11.4k | if(pXMLTextFrameContext_Impl) |
796 | 11.4k | { |
797 | 11.4k | return "vnd.sun.star.Package:" + pXMLTextFrameContext_Impl->GetHRef(); |
798 | 11.4k | } |
799 | | |
800 | 0 | return OUString(); |
801 | 11.4k | } |
802 | | |
803 | | css::uno::Reference<css::graphic::XGraphic> XMLTextFrameContext::getGraphicFromImportContext(const SvXMLImportContext& rContext) const |
804 | 0 | { |
805 | 0 | uno::Reference<graphic::XGraphic> xGraphic; |
806 | |
|
807 | 0 | const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast<const XMLTextFrameContext_Impl*>(&rContext); |
808 | |
|
809 | 0 | if (pXMLTextFrameContext_Impl) |
810 | 0 | { |
811 | 0 | try |
812 | 0 | { |
813 | 0 | const uno::Reference<beans::XPropertySet>& xPropertySet = pXMLTextFrameContext_Impl->GetPropSet(); |
814 | |
|
815 | 0 | if (xPropertySet.is()) |
816 | 0 | { |
817 | 0 | xPropertySet->getPropertyValue(u"Graphic"_ustr) >>= xGraphic; |
818 | 0 | } |
819 | 0 | } |
820 | 0 | catch (uno::Exception&) |
821 | 0 | {} |
822 | 0 | } |
823 | 0 | return xGraphic; |
824 | 0 | } |
825 | | |
826 | | bool XMLTextFrameContext_Impl::CreateIfNotThere() |
827 | 90.2k | { |
828 | 90.2k | if( !xPropSet.is() && |
829 | 1.80k | ( XML_TEXT_FRAME_OBJECT_OLE == nType || |
830 | 1.76k | XML_TEXT_FRAME_GRAPHIC == nType ) && |
831 | 1.49k | xBase64Stream.is() && !bCreateFailed ) |
832 | 38 | { |
833 | 38 | if( bOwnBase64Stream ) |
834 | 0 | xBase64Stream->closeOutput(); |
835 | 38 | Create(); |
836 | 38 | } |
837 | | |
838 | 90.2k | return xPropSet.is(); |
839 | 90.2k | } |
840 | | |
841 | | XMLTextFrameContext_Impl::XMLTextFrameContext_Impl( |
842 | | SvXMLImport& rImport, |
843 | | sal_Int32 /*nElement*/, |
844 | | const Reference< XFastAttributeList > & rAttrList, |
845 | | TextContentAnchorType eATyp, |
846 | | sal_uInt16 nNewType, |
847 | | const Reference< XFastAttributeList > & rFrameAttrList, |
848 | | bool bMultipleContent ) |
849 | 67.2k | : SvXMLImportContext( rImport ) |
850 | 67.2k | , mbListContextPushed( false ) |
851 | 67.2k | , nType( nNewType ) |
852 | 67.2k | , eAnchorType( eATyp ) |
853 | 67.2k | { |
854 | 67.2k | nX = 0; |
855 | 67.2k | nY = 0; |
856 | 67.2k | nWidth = 0; |
857 | 67.2k | nHeight = 0; |
858 | 67.2k | nZIndex = -1; |
859 | 67.2k | nPage = 0; |
860 | 67.2k | nRotation = 0; |
861 | 67.2k | nRelWidth = 0; |
862 | 67.2k | nRelHeight = 0; |
863 | 67.2k | bMayScript = false; |
864 | | |
865 | 67.2k | bMinHeight = false; |
866 | 67.2k | bMinWidth = false; |
867 | 67.2k | bSyncWidth = false; |
868 | 67.2k | bSyncHeight = false; |
869 | 67.2k | bCreateFailed = false; |
870 | 67.2k | bOwnBase64Stream = false; |
871 | 67.2k | mbMultipleContent = bMultipleContent; |
872 | | |
873 | 67.2k | auto processAttr = [&](sal_Int32 nElement, const sax_fastparser::FastAttributeList::FastAttributeIter& aIter) -> void |
874 | 331k | { |
875 | 331k | switch( nElement ) |
876 | 331k | { |
877 | 42.1k | case XML_ELEMENT(DRAW, XML_STYLE_NAME): |
878 | 42.1k | sStyleName = aIter.toString(); |
879 | 42.1k | break; |
880 | 49.8k | case XML_ELEMENT(DRAW, XML_NAME): |
881 | 49.8k | m_sOrigName = aIter.toString(); |
882 | 49.8k | sName = m_sOrigName; |
883 | 49.8k | break; |
884 | 0 | case XML_ELEMENT(DRAW, XML_FRAME_NAME): |
885 | 0 | sFrameName = aIter.toString(); |
886 | 0 | break; |
887 | 0 | case XML_ELEMENT(DRAW, XML_APPLET_NAME): |
888 | 0 | sAppletName = aIter.toString(); |
889 | 0 | break; |
890 | 47.5k | case XML_ELEMENT(TEXT, XML_ANCHOR_TYPE): |
891 | 47.5k | if( TextContentAnchorType_AT_PARAGRAPH == eAnchorType || |
892 | 47.5k | TextContentAnchorType_AT_CHARACTER == eAnchorType || |
893 | 47.4k | TextContentAnchorType_AS_CHARACTER == eAnchorType ) |
894 | 46.9k | { |
895 | | |
896 | 46.9k | TextContentAnchorType eNew; |
897 | 46.9k | if( XMLAnchorTypePropHdl::convert( aIter.toView(), eNew ) && |
898 | 39.5k | ( TextContentAnchorType_AT_PARAGRAPH == eNew || |
899 | 39.5k | TextContentAnchorType_AT_CHARACTER == eNew || |
900 | 39.5k | TextContentAnchorType_AS_CHARACTER == eNew || |
901 | 0 | TextContentAnchorType_AT_PAGE == eNew) ) |
902 | 39.5k | eAnchorType = eNew; |
903 | 46.9k | } |
904 | 47.5k | break; |
905 | 159 | case XML_ELEMENT(TEXT, XML_ANCHOR_PAGE_NUMBER): |
906 | 159 | { |
907 | 159 | sal_Int32 nTmp; |
908 | 159 | sal_Int32 nMax = !comphelper::IsFuzzing() ? SHRT_MAX : 100; |
909 | 159 | if (::sax::Converter::convertNumber(nTmp, aIter.toView(), 1, nMax)) |
910 | 159 | nPage = static_cast<sal_Int16>(nTmp); |
911 | 159 | } |
912 | 159 | break; |
913 | 0 | case XML_ELEMENT(SVG, XML_X): |
914 | 30 | case XML_ELEMENT(SVG_COMPAT, XML_X): |
915 | 30 | GetImport().GetMM100UnitConverter().convertMeasureToCore( |
916 | 30 | nX, aIter.toView()); |
917 | 30 | break; |
918 | 0 | case XML_ELEMENT(SVG, XML_Y): |
919 | 30 | case XML_ELEMENT(SVG_COMPAT, XML_Y): |
920 | 30 | GetImport().GetMM100UnitConverter().convertMeasureToCore( |
921 | 30 | nY, aIter.toView() ); |
922 | 30 | break; |
923 | 0 | case XML_ELEMENT(SVG, XML_WIDTH): |
924 | 6.94k | case XML_ELEMENT(SVG_COMPAT, XML_WIDTH): |
925 | | // relative widths are obsolete since SRC617. Remove them some day! |
926 | 6.94k | if( aIter.toView().find( '%' ) != std::string_view::npos ) |
927 | 574 | { |
928 | 574 | sal_Int32 nTmp; |
929 | 574 | if (::sax::Converter::convertPercent(nTmp, aIter.toView())) |
930 | 572 | nRelWidth = static_cast<sal_Int16>(nTmp); |
931 | 574 | } |
932 | 6.37k | else |
933 | 6.37k | { |
934 | 6.37k | GetImport().GetMM100UnitConverter().convertMeasureToCore( |
935 | 6.37k | nWidth, aIter.toView(), 0 ); |
936 | 6.37k | } |
937 | 6.94k | break; |
938 | 0 | case XML_ELEMENT(STYLE, XML_REL_WIDTH): |
939 | 0 | if( IsXMLToken(aIter, XML_SCALE) ) |
940 | 0 | { |
941 | 0 | bSyncWidth = true; |
942 | 0 | } |
943 | 0 | else |
944 | 0 | { |
945 | 0 | sal_Int32 nTmp; |
946 | 0 | if (::sax::Converter::convertPercent( nTmp, aIter.toView() )) |
947 | 0 | nRelWidth = static_cast<sal_Int16>(nTmp); |
948 | 0 | } |
949 | 0 | break; |
950 | 0 | case XML_ELEMENT(FO, XML_MIN_WIDTH): |
951 | 0 | case XML_ELEMENT(FO_COMPAT, XML_MIN_WIDTH): |
952 | 0 | if( aIter.toView().find( '%' ) != std::string_view::npos ) |
953 | 0 | { |
954 | 0 | sal_Int32 nTmp; |
955 | 0 | if (::sax::Converter::convertPercent(nTmp, aIter.toView())) |
956 | 0 | nRelWidth = static_cast<sal_Int16>(nTmp); |
957 | 0 | } |
958 | 0 | else |
959 | 0 | { |
960 | 0 | GetImport().GetMM100UnitConverter().convertMeasureToCore( |
961 | 0 | nWidth, aIter.toView(), 0 ); |
962 | 0 | } |
963 | 0 | bMinWidth = true; |
964 | 0 | break; |
965 | 0 | case XML_ELEMENT(SVG, XML_HEIGHT): |
966 | 6.31k | case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT): |
967 | | // relative heights are obsolete since SRC617. Remove them some day! |
968 | 6.31k | if( aIter.toView().find( '%' ) != std::string_view::npos ) |
969 | 0 | { |
970 | 0 | sal_Int32 nTmp; |
971 | 0 | if (::sax::Converter::convertPercent(nTmp, aIter.toView())) |
972 | 0 | nRelHeight = static_cast<sal_Int16>(nTmp); |
973 | 0 | } |
974 | 6.31k | else |
975 | 6.31k | { |
976 | 6.31k | GetImport().GetMM100UnitConverter().convertMeasureToCore( |
977 | 6.31k | nHeight, aIter.toView(), 0 ); |
978 | 6.31k | } |
979 | 6.31k | break; |
980 | 0 | case XML_ELEMENT(STYLE, XML_REL_HEIGHT): |
981 | 0 | if( IsXMLToken( aIter, XML_SCALE ) ) |
982 | 0 | { |
983 | 0 | bSyncHeight = true; |
984 | 0 | } |
985 | 0 | else if( IsXMLToken( aIter, XML_SCALE_MIN ) ) |
986 | 0 | { |
987 | 0 | bSyncHeight = true; |
988 | 0 | bMinHeight = true; |
989 | 0 | } |
990 | 0 | else |
991 | 0 | { |
992 | 0 | sal_Int32 nTmp; |
993 | 0 | if (::sax::Converter::convertPercent( nTmp, aIter.toView() )) |
994 | 0 | nRelHeight = static_cast<sal_Int16>(nTmp); |
995 | 0 | } |
996 | 0 | break; |
997 | 0 | case XML_ELEMENT(FO, XML_MIN_HEIGHT): |
998 | 178 | case XML_ELEMENT(FO_COMPAT, XML_MIN_HEIGHT): |
999 | 178 | if( aIter.toView().find( '%' ) != std::string_view::npos ) |
1000 | 0 | { |
1001 | 0 | sal_Int32 nTmp; |
1002 | 0 | if (::sax::Converter::convertPercent(nTmp, aIter.toView())) |
1003 | 0 | nRelHeight = static_cast<sal_Int16>(nTmp); |
1004 | 0 | } |
1005 | 178 | else |
1006 | 178 | { |
1007 | 178 | GetImport().GetMM100UnitConverter().convertMeasureToCore( |
1008 | 178 | nHeight, aIter.toView(), 0 ); |
1009 | 178 | } |
1010 | 178 | bMinHeight = true; |
1011 | 178 | break; |
1012 | 54.1k | case XML_ELEMENT(DRAW, XML_ZINDEX): |
1013 | 54.1k | ::sax::Converter::convertNumber( nZIndex, aIter.toView(), -1 ); |
1014 | 54.1k | break; |
1015 | 0 | case XML_ELEMENT(DRAW, XML_CHAIN_NEXT_NAME): |
1016 | 0 | sNextName = aIter.toString(); |
1017 | 0 | break; |
1018 | 42.8k | case XML_ELEMENT(XLINK, XML_HREF): |
1019 | 42.8k | sHRef = aIter.toString(); |
1020 | 42.8k | break; |
1021 | 0 | case XML_ELEMENT(DRAW, XML_TRANSFORM): |
1022 | 0 | { |
1023 | | // RotateFlyFrameFix: im/export full 'draw:transform' using existing tooling |
1024 | | // Currently only rotation is used, but combinations with 'draw:transform' |
1025 | | // may be necessary in the future, so that svg:x/svg:y/svg:width/svg:height |
1026 | | // may be extended/replaced with 'draw:transform' (see draw objects) |
1027 | 0 | SdXMLImExTransform2D aSdXMLImExTransform2D; |
1028 | 0 | basegfx::B2DHomMatrix aFullTransform; |
1029 | | |
1030 | | // Use SdXMLImExTransform2D to convert to transformation |
1031 | | // Note: using GetTwipUnitConverter instead of GetMM100UnitConverter may be needed, |
1032 | | // but is not generally available (as it should be, a 'current' UnitConverter should |
1033 | | // be available at GetExport() - and maybe was once). May have to be addressed as soon |
1034 | | // as translate transformations are used here. |
1035 | 0 | aSdXMLImExTransform2D.SetString(aIter.toString(), GetImport().GetMM100UnitConverter()); |
1036 | 0 | aSdXMLImExTransform2D.GetFullTransform(aFullTransform); |
1037 | |
|
1038 | 0 | if(!aFullTransform.isIdentity()) |
1039 | 0 | { |
1040 | 0 | const basegfx::utils::B2DHomMatrixBufferedDecompose aDecomposedTransform(aFullTransform); |
1041 | | |
1042 | | // currently we *only* use rotation (and translation indirectly), so warn if *any* |
1043 | | // of the other transform parts is used |
1044 | 0 | SAL_WARN_IF(!basegfx::fTools::equal(1.0, aDecomposedTransform.getScale().getX()), "xmloff.text", "draw:transform uses scaleX" ); |
1045 | 0 | SAL_WARN_IF(!basegfx::fTools::equal(1.0, aDecomposedTransform.getScale().getY()), "xmloff.text", "draw:transform uses scaleY" ); |
1046 | 0 | SAL_WARN_IF(!basegfx::fTools::equalZero(aDecomposedTransform.getShearX()), "xmloff.text", "draw:transform uses shearX" ); |
1047 | | |
1048 | | // Translation comes from the translate to RotCenter, rot and BackTranslate. |
1049 | | // This means that it represents the translation between unrotated TopLeft |
1050 | | // and rotated TopLeft. This may be checked here now, but currently we only |
1051 | | // use rotation around center and assume that this *was* a rotation around |
1052 | | // center. The check would compare the object's center with the RotCenter |
1053 | | // that can be extracted from the transformation in aFullTransform. |
1054 | | // The definition contains implicitly the RotationCenter absolute |
1055 | | // to the scaled and translated object, so this may be used if needed (see |
1056 | | // _exportTextGraphic how the -trans/rot/trans is composed) |
1057 | | |
1058 | 0 | if(!basegfx::fTools::equalZero(aDecomposedTransform.getRotate())) |
1059 | 0 | { |
1060 | | // rotation is used, set it. Convert from deg to 10th degree integer |
1061 | | // CAUTION: due to #i78696# (rotation mirrored using API) the rotate |
1062 | | // value is already mirrored, so do not do it again here (to be in sync |
1063 | | // with XMLTextParagraphExport::_exportTextGraphic normally it would need |
1064 | | // to me mirrored using * -1.0, see conversion there) |
1065 | | // CAUTION-II: due to tdf#115782 it is better for current ODF to indeed use it |
1066 | | // with the wrong orientation as in all other cases - ARGH! We will need to |
1067 | | // correct this in future ODF ASAP! For now, mirror the rotation here AGAIN |
1068 | 0 | const double fRotate(-basegfx::rad2deg<10>(aDecomposedTransform.getRotate())); |
1069 | 0 | nRotation = static_cast< sal_Int16 >(basegfx::fround(fRotate) % 3600); |
1070 | | |
1071 | | // tdf#115529 may be negative, with the above modulo maximal -3599, so |
1072 | | // no loop needed here. nRotation is used in setPropertyValue("GraphicRotation") |
1073 | | // and *has* to be in the range [0 .. 3600[ |
1074 | 0 | if(nRotation < 0) |
1075 | 0 | { |
1076 | 0 | nRotation += 3600; |
1077 | 0 | } |
1078 | 0 | } |
1079 | 0 | } |
1080 | 0 | } |
1081 | 0 | break; |
1082 | 0 | case XML_ELEMENT(DRAW, XML_CODE): |
1083 | 0 | sCode = aIter.toString(); |
1084 | 0 | break; |
1085 | 0 | case XML_ELEMENT(DRAW, XML_OBJECT): |
1086 | 0 | break; |
1087 | 0 | case XML_ELEMENT(DRAW, XML_ARCHIVE): |
1088 | 0 | break; |
1089 | 0 | case XML_ELEMENT(DRAW, XML_MAY_SCRIPT): |
1090 | 0 | bMayScript = IsXMLToken( aIter, XML_TRUE ); |
1091 | 0 | break; |
1092 | 0 | case XML_ELEMENT(DRAW, XML_MIME_TYPE): |
1093 | 0 | case XML_ELEMENT(LO_EXT, XML_MIME_TYPE): |
1094 | 0 | sMimeType = aIter.toString(); |
1095 | 0 | break; |
1096 | 0 | case XML_ELEMENT(DRAW, XML_NOTIFY_ON_UPDATE_OF_RANGES): |
1097 | 0 | case XML_ELEMENT(DRAW, XML_NOTIFY_ON_UPDATE_OF_TABLE): |
1098 | 0 | sTblName = aIter.toString(); |
1099 | 0 | break; |
1100 | 0 | case XML_ELEMENT(LO_EXT, XML_DECORATIVE): |
1101 | 0 | case XML_ELEMENT(DRAW, XML_DECORATIVE): |
1102 | 0 | ::sax::Converter::convertBool(m_isDecorative, aIter.toString()); |
1103 | 0 | break; |
1104 | 0 | case XML_ELEMENT(LO_EXT, XML_MAY_BREAK_BETWEEN_PAGES): |
1105 | 0 | case XML_ELEMENT(DRAW, XML_MAY_BREAK_BETWEEN_PAGES): |
1106 | 0 | sax::Converter::convertBool(m_isSplitAllowed, aIter.toString()); |
1107 | 0 | break; |
1108 | 81.2k | default: |
1109 | 81.2k | SAL_INFO("xmloff", "unknown attribute " << SvXMLImport::getPrefixAndNameFromToken(aIter.getToken()) << " value=" << aIter.toString()); |
1110 | 331k | } |
1111 | 331k | }; |
1112 | | |
1113 | 67.2k | for( auto& aIter : sax_fastparser::castToFastAttributeList(rAttrList) ) |
1114 | 124k | processAttr(aIter.getToken(), aIter); |
1115 | 67.2k | for( auto& aIter : sax_fastparser::castToFastAttributeList(rFrameAttrList) ) |
1116 | 207k | processAttr(aIter.getToken(), aIter); |
1117 | | |
1118 | 67.2k | if( ( (XML_TEXT_FRAME_GRAPHIC == nType || |
1119 | 23.1k | XML_TEXT_FRAME_OBJECT == nType || |
1120 | 23.0k | XML_TEXT_FRAME_OBJECT_OLE == nType) && |
1121 | 44.1k | sHRef.isEmpty() ) || |
1122 | 65.8k | ( XML_TEXT_FRAME_APPLET == nType && sCode.isEmpty() ) || |
1123 | 65.8k | ( XML_TEXT_FRAME_PLUGIN == nType && |
1124 | 0 | sHRef.isEmpty() && sMimeType.isEmpty() ) ) |
1125 | 1.32k | return; // no URL: no image or OLE object |
1126 | | |
1127 | 65.8k | Create(); |
1128 | 65.8k | } |
1129 | | |
1130 | | void XMLTextFrameContext_Impl::endFastElement(sal_Int32 ) |
1131 | 66.4k | { |
1132 | 66.4k | if( ( XML_TEXT_FRAME_OBJECT_OLE == nType || |
1133 | 66.4k | XML_TEXT_FRAME_GRAPHIC == nType) && |
1134 | 44.0k | !xPropSet.is() && !bCreateFailed ) |
1135 | 1.26k | { |
1136 | 1.26k | std::u16string_view sTrimmedChars = o3tl::trim(maUrlBuffer); |
1137 | 1.26k | if( !sTrimmedChars.empty() ) |
1138 | 0 | { |
1139 | 0 | if( !xBase64Stream.is() ) |
1140 | 0 | { |
1141 | 0 | if( XML_TEXT_FRAME_GRAPHIC == nType ) |
1142 | 0 | { |
1143 | 0 | xBase64Stream = |
1144 | 0 | GetImport().GetStreamForGraphicObjectURLFromBase64(); |
1145 | 0 | } |
1146 | 0 | else |
1147 | 0 | { |
1148 | 0 | xBase64Stream = |
1149 | 0 | GetImport().GetStreamForEmbeddedObjectURLFromBase64(); |
1150 | 0 | } |
1151 | 0 | if( xBase64Stream.is() ) |
1152 | 0 | bOwnBase64Stream = true; |
1153 | 0 | } |
1154 | 0 | if( bOwnBase64Stream && xBase64Stream.is() ) |
1155 | 0 | { |
1156 | 0 | OUString sChars; |
1157 | 0 | if( !sBase64CharsLeft.isEmpty() ) |
1158 | 0 | { |
1159 | 0 | sChars = sBase64CharsLeft + sTrimmedChars; |
1160 | 0 | sBase64CharsLeft.clear(); |
1161 | 0 | } |
1162 | 0 | else |
1163 | 0 | { |
1164 | 0 | sChars = sTrimmedChars; |
1165 | 0 | } |
1166 | 0 | Sequence< sal_Int8 > aBuffer( (sChars.getLength() / 4) * 3 ); |
1167 | 0 | sal_Int32 nCharsDecoded = |
1168 | 0 | ::comphelper::Base64::decodeSomeChars( aBuffer, sChars ); |
1169 | 0 | xBase64Stream->writeBytes( aBuffer ); |
1170 | 0 | if( nCharsDecoded != sChars.getLength() ) |
1171 | 0 | sBase64CharsLeft = sChars.copy( nCharsDecoded ); |
1172 | 0 | } |
1173 | 0 | } |
1174 | 1.26k | maUrlBuffer.setLength(0); |
1175 | 1.26k | } |
1176 | | |
1177 | 66.4k | CreateIfNotThere(); |
1178 | | |
1179 | 66.4k | if( xOldTextCursor.is() ) |
1180 | 22.2k | { |
1181 | 22.2k | GetImport().GetTextImport()->DeleteParagraph(); |
1182 | 22.2k | GetImport().GetTextImport()->SetCursor( xOldTextCursor ); |
1183 | 22.2k | } |
1184 | | |
1185 | | // reinstall old list item (if necessary) #89892# |
1186 | 66.4k | if (mbListContextPushed) { |
1187 | 22.2k | GetImport().GetTextImport()->PopListContext(); |
1188 | 22.2k | } |
1189 | | |
1190 | 66.4k | if (( nType == XML_TEXT_FRAME_APPLET || nType == XML_TEXT_FRAME_PLUGIN ) && xPropSet.is()) |
1191 | 0 | GetImport().GetTextImport()->endAppletOrPlugin( xPropSet, aParamMap); |
1192 | 66.4k | } |
1193 | | |
1194 | | css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTextFrameContext_Impl::createFastChildContext( |
1195 | | sal_Int32 nElement, |
1196 | | const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) |
1197 | 15.6k | { |
1198 | 15.6k | if( nElement == XML_ELEMENT(DRAW, XML_PARAM) ) |
1199 | 0 | { |
1200 | 0 | if ( nType == XML_TEXT_FRAME_APPLET || nType == XML_TEXT_FRAME_PLUGIN ) |
1201 | 0 | return new XMLTextFrameParam_Impl( GetImport(), |
1202 | 0 | xAttrList, aParamMap ); |
1203 | 0 | } |
1204 | 15.6k | else if( nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA) ) |
1205 | 55 | { |
1206 | 55 | if( !xPropSet.is() && !xBase64Stream.is() && !bCreateFailed ) |
1207 | 55 | { |
1208 | 55 | switch( nType ) |
1209 | 55 | { |
1210 | 0 | case XML_TEXT_FRAME_GRAPHIC: |
1211 | 0 | xBase64Stream = |
1212 | 0 | GetImport().GetStreamForGraphicObjectURLFromBase64(); |
1213 | 0 | break; |
1214 | 55 | case XML_TEXT_FRAME_OBJECT_OLE: |
1215 | 55 | xBase64Stream = |
1216 | 55 | GetImport().GetStreamForEmbeddedObjectURLFromBase64(); |
1217 | 55 | break; |
1218 | 55 | } |
1219 | 55 | if( xBase64Stream.is() ) |
1220 | 55 | return new XMLBase64ImportContext( GetImport(), xBase64Stream ); |
1221 | 55 | } |
1222 | 55 | } |
1223 | | // Correction of condition which also avoids warnings. (#i100480#) |
1224 | 15.6k | if( XML_TEXT_FRAME_OBJECT == nType && |
1225 | 45 | ( nElement == XML_ELEMENT(OFFICE, XML_DOCUMENT) || |
1226 | 45 | nElement == XML_ELEMENT(MATH, XML_MATH) ) ) |
1227 | 45 | { |
1228 | 45 | if( !xPropSet.is() && !bCreateFailed ) |
1229 | 45 | { |
1230 | 45 | XMLEmbeddedObjectImportContext *pEContext = |
1231 | 45 | new XMLEmbeddedObjectImportContext( GetImport(), nElement, xAttrList ); |
1232 | 45 | sFilterService = pEContext->GetFilterServiceName(); |
1233 | 45 | if( !sFilterService.isEmpty() ) |
1234 | 45 | { |
1235 | 45 | Create(); |
1236 | 45 | if( xPropSet.is() ) |
1237 | 0 | { |
1238 | 0 | Reference < XEmbeddedObjectSupplier > xEOS( xPropSet, |
1239 | 0 | UNO_QUERY ); |
1240 | 0 | OSL_ENSURE( xEOS.is(), |
1241 | 0 | "no embedded object supplier for own object" ); |
1242 | 0 | Reference<css::lang::XComponent> aXComponent(xEOS->getEmbeddedObject()); |
1243 | 0 | pEContext->SetComponent( aXComponent ); |
1244 | 0 | } |
1245 | 45 | } |
1246 | 45 | return pEContext; |
1247 | 45 | } |
1248 | 45 | } |
1249 | | |
1250 | 15.5k | if( xOldTextCursor.is() ) // text-box |
1251 | 15.0k | { |
1252 | 15.0k | auto p = GetImport().GetTextImport()->CreateTextChildContext( |
1253 | 15.0k | GetImport(), nElement, xAttrList, |
1254 | 15.0k | XMLTextType::TextBox ); |
1255 | 15.0k | if (p) |
1256 | 15.0k | return p; |
1257 | 15.0k | } |
1258 | | |
1259 | 540 | XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement); |
1260 | | |
1261 | 540 | return nullptr; |
1262 | 540 | } |
1263 | | |
1264 | | void XMLTextFrameContext_Impl::characters( const OUString& rChars ) |
1265 | 35.5k | { |
1266 | 35.5k | maUrlBuffer.append(rChars); |
1267 | 35.5k | } |
1268 | | |
1269 | | void XMLTextFrameContext_Impl::SetHyperlink( const OUString& rHRef, |
1270 | | const OUString& rName, |
1271 | | const OUString& rTargetFrameName, |
1272 | | bool bMap ) |
1273 | 0 | { |
1274 | 0 | static constexpr OUString s_HyperLinkURL = u"HyperLinkURL"_ustr; |
1275 | 0 | static constexpr OUString s_HyperLinkName = u"HyperLinkName"_ustr; |
1276 | 0 | static constexpr OUString s_HyperLinkTarget = u"HyperLinkTarget"_ustr; |
1277 | 0 | static constexpr OUString s_ServerMap = u"ServerMap"_ustr; |
1278 | 0 | if( !xPropSet.is() ) |
1279 | 0 | return; |
1280 | | |
1281 | 0 | Reference < XPropertySetInfo > xPropSetInfo = |
1282 | 0 | xPropSet->getPropertySetInfo(); |
1283 | 0 | if( !xPropSetInfo.is() || |
1284 | 0 | !xPropSetInfo->hasPropertyByName(s_HyperLinkURL)) |
1285 | 0 | return; |
1286 | | |
1287 | 0 | xPropSet->setPropertyValue( s_HyperLinkURL, Any(rHRef) ); |
1288 | |
|
1289 | 0 | if (xPropSetInfo->hasPropertyByName(s_HyperLinkName)) |
1290 | 0 | { |
1291 | 0 | xPropSet->setPropertyValue(s_HyperLinkName, Any(rName)); |
1292 | 0 | } |
1293 | |
|
1294 | 0 | if (xPropSetInfo->hasPropertyByName(s_HyperLinkTarget)) |
1295 | 0 | { |
1296 | 0 | xPropSet->setPropertyValue( s_HyperLinkTarget, Any(rTargetFrameName) ); |
1297 | 0 | } |
1298 | |
|
1299 | 0 | if (xPropSetInfo->hasPropertyByName(s_ServerMap)) |
1300 | 0 | { |
1301 | 0 | xPropSet->setPropertyValue(s_ServerMap, Any(bMap)); |
1302 | 0 | } |
1303 | 0 | } |
1304 | | |
1305 | | void XMLTextFrameContext_Impl::SetName() |
1306 | 1.30k | { |
1307 | 1.30k | Reference<XNamed> xNamed(xPropSet, UNO_QUERY); |
1308 | 1.30k | if (m_sOrigName.isEmpty() || !xNamed.is()) |
1309 | 924 | return; |
1310 | | |
1311 | 379 | OUString const name(xNamed->getName()); |
1312 | 379 | if (name != m_sOrigName) |
1313 | 135 | { |
1314 | 135 | try |
1315 | 135 | { |
1316 | 135 | xNamed->setName(m_sOrigName); |
1317 | 135 | } |
1318 | 135 | catch (uno::Exception const&) |
1319 | 135 | { // fdo#71698 document contains 2 frames with same draw:name |
1320 | 134 | TOOLS_INFO_EXCEPTION("xmloff.text", "SetName(): exception setting \"" |
1321 | 134 | << m_sOrigName << "\""); |
1322 | 134 | } |
1323 | 135 | } |
1324 | 379 | } |
1325 | | |
1326 | | // Implement Title/Description Elements UI (#i73249#) |
1327 | | void XMLTextFrameContext_Impl::SetTitle( const OUString& rTitle ) |
1328 | 0 | { |
1329 | 0 | if ( xPropSet.is() ) |
1330 | 0 | { |
1331 | 0 | Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); |
1332 | 0 | if( xPropSetInfo->hasPropertyByName( u"Title"_ustr ) ) |
1333 | 0 | { |
1334 | 0 | xPropSet->setPropertyValue( u"Title"_ustr, Any( rTitle ) ); |
1335 | 0 | } |
1336 | 0 | } |
1337 | 0 | } |
1338 | | |
1339 | | void XMLTextFrameContext_Impl::SetDesc( const OUString& rDesc ) |
1340 | 0 | { |
1341 | 0 | if ( xPropSet.is() ) |
1342 | 0 | { |
1343 | 0 | Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); |
1344 | 0 | if( xPropSetInfo->hasPropertyByName( u"Description"_ustr ) ) |
1345 | 0 | { |
1346 | 0 | xPropSet->setPropertyValue( u"Description"_ustr, Any( rDesc ) ); |
1347 | 0 | } |
1348 | 0 | } |
1349 | 0 | } |
1350 | | |
1351 | | |
1352 | | bool XMLTextFrameContext::CreateIfNotThere( css::uno::Reference < css::beans::XPropertySet >& rPropSet ) |
1353 | 81 | { |
1354 | 81 | SvXMLImportContext *pContext = m_xImplContext.get(); |
1355 | 81 | XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl*>( pContext ); |
1356 | 81 | if( pImpl && pImpl->CreateIfNotThere() ) |
1357 | 38 | rPropSet = pImpl->GetPropSet(); |
1358 | | |
1359 | 81 | return rPropSet.is(); |
1360 | 81 | } |
1361 | | |
1362 | | XMLTextFrameContext::XMLTextFrameContext( |
1363 | | SvXMLImport& rImport, |
1364 | | const Reference< XFastAttributeList > & xAttrList, |
1365 | | TextContentAnchorType eATyp ) |
1366 | 26.3k | : SvXMLImportContext( rImport ) |
1367 | 26.3k | , m_xAttrList( new sax_fastparser::FastAttributeList( xAttrList ) ) |
1368 | | // Implement Title/Description Elements UI (#i73249#) |
1369 | 26.3k | , m_eDefaultAnchorType( eATyp ) |
1370 | | // Shapes in Writer cannot be named via context menu (#i51726#) |
1371 | 26.3k | , m_HasAutomaticStyleWithoutParentStyle( false ) |
1372 | 26.3k | , m_bSupportsReplacement( false ) |
1373 | 26.3k | { |
1374 | 26.3k | for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) |
1375 | 62.2k | { |
1376 | | // New distinguish attribute between Writer objects and Draw objects is: |
1377 | | // Draw objects have an automatic style without a parent style (#i51726#) |
1378 | 62.2k | switch (aIter.getToken()) |
1379 | 62.2k | { |
1380 | 11.3k | case XML_ELEMENT(DRAW, XML_STYLE_NAME): |
1381 | 11.3k | { |
1382 | 11.3k | OUString aStyleName = aIter.toString(); |
1383 | 11.3k | if( !aStyleName.isEmpty() ) |
1384 | 11.3k | { |
1385 | 11.3k | rtl::Reference < XMLTextImportHelper > xTxtImport = |
1386 | 11.3k | GetImport().GetTextImport(); |
1387 | 11.3k | XMLPropStyleContext* pStyle = xTxtImport->FindAutoFrameStyle( aStyleName ); |
1388 | 11.3k | if ( pStyle && pStyle->GetParentName().isEmpty() ) |
1389 | 1.25k | { |
1390 | 1.25k | m_HasAutomaticStyleWithoutParentStyle = true; |
1391 | 1.25k | } |
1392 | 11.3k | } |
1393 | 11.3k | break; |
1394 | 0 | } |
1395 | 12.9k | case XML_ELEMENT(TEXT, XML_ANCHOR_TYPE): |
1396 | 12.9k | { |
1397 | 12.9k | TextContentAnchorType eNew; |
1398 | 12.9k | if( XMLAnchorTypePropHdl::convert( aIter.toView(), eNew ) && |
1399 | 12.2k | ( TextContentAnchorType_AT_PARAGRAPH == eNew || |
1400 | 12.2k | TextContentAnchorType_AT_CHARACTER == eNew || |
1401 | 12.2k | TextContentAnchorType_AS_CHARACTER == eNew || |
1402 | 172 | TextContentAnchorType_AT_PAGE == eNew) ) |
1403 | 12.2k | m_eDefaultAnchorType = eNew; |
1404 | 12.9k | break; |
1405 | 0 | } |
1406 | 62.2k | } |
1407 | 62.2k | } |
1408 | 26.3k | } |
1409 | | |
1410 | | void XMLTextFrameContext::endFastElement(sal_Int32 ) |
1411 | 24.7k | { |
1412 | | /// solve if multiple image child contexts were imported |
1413 | 24.7k | SvXMLImportContextRef const pMultiContext(solveMultipleImages()); |
1414 | | |
1415 | 24.7k | SvXMLImportContext const*const pContext = |
1416 | 24.7k | (pMultiContext.is()) ? pMultiContext.get() : m_xImplContext.get(); |
1417 | 24.7k | XMLTextFrameContext_Impl *pImpl = const_cast<XMLTextFrameContext_Impl*>(dynamic_cast< const XMLTextFrameContext_Impl*>( pContext )); |
1418 | 24.7k | assert(!pMultiContext.is() || pImpl); |
1419 | | |
1420 | | // When we are dealing with a textbox, pImpl will be null; |
1421 | | // we need to set the hyperlink to the shape instead |
1422 | 24.7k | Reference<XShape> xShape = GetShape(); |
1423 | 24.7k | if (xShape.is() && m_pHyperlink) |
1424 | 0 | { |
1425 | 0 | Reference<XPropertySet> xProps(xShape, UNO_QUERY); |
1426 | 0 | if (xProps.is()) |
1427 | 0 | xProps->setPropertyValue(u"Hyperlink"_ustr, Any(m_pHyperlink->GetHRef())); |
1428 | 0 | } |
1429 | | |
1430 | 24.7k | if( !pImpl ) |
1431 | 1.12k | return; |
1432 | | |
1433 | 23.6k | pImpl->CreateIfNotThere(); |
1434 | | |
1435 | | // fdo#68839: in case the surviving image was not the first one, |
1436 | | // it will have a counter added to its name - set the original name |
1437 | 23.6k | if (pMultiContext.is()) // do this only when necessary; esp. not for text |
1438 | 1.30k | { // frames that may have entries in GetRenameMap()! |
1439 | 1.30k | pImpl->SetName(); |
1440 | 1.30k | } |
1441 | | |
1442 | 23.6k | if( !m_sTitle.isEmpty() ) |
1443 | 0 | { |
1444 | 0 | pImpl->SetTitle( m_sTitle ); |
1445 | 0 | } |
1446 | 23.6k | if( !m_sDesc.isEmpty() ) |
1447 | 0 | { |
1448 | 0 | pImpl->SetDesc( m_sDesc ); |
1449 | 0 | } |
1450 | | |
1451 | 23.6k | if( m_pHyperlink ) |
1452 | 0 | { |
1453 | 0 | pImpl->SetHyperlink( m_pHyperlink->GetHRef(), m_pHyperlink->GetName(), |
1454 | 0 | m_pHyperlink->GetTargetFrameName(), m_pHyperlink->GetMap() ); |
1455 | 0 | m_pHyperlink.reset(); |
1456 | 0 | } |
1457 | | |
1458 | 23.6k | GetImport().GetTextImport()->StoreLastImportedFrameName(pImpl->GetOrigName()); |
1459 | 23.6k | } |
1460 | | |
1461 | | css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTextFrameContext::createFastChildContext( |
1462 | | sal_Int32 nElement, |
1463 | | const uno::Reference< xml::sax::XFastAttributeList>& xAttrList ) |
1464 | 80.5k | { |
1465 | 80.5k | SvXMLImportContextRef xContext; |
1466 | | |
1467 | 80.5k | if( !m_xImplContext.is() ) |
1468 | 36.9k | { |
1469 | | // no child exists |
1470 | 36.9k | if( IsTokenInNamespace(nElement, XML_NAMESPACE_DRAW) ) |
1471 | 26.2k | { |
1472 | 26.2k | sal_uInt16 nFrameType = USHRT_MAX; |
1473 | 26.2k | switch (nElement & TOKEN_MASK) |
1474 | 26.2k | { |
1475 | 24.0k | case XML_TEXT_BOX: |
1476 | 24.0k | nFrameType = XML_TEXT_FRAME_TEXTBOX; |
1477 | 24.0k | break; |
1478 | 1.97k | case XML_IMAGE: |
1479 | 1.97k | nFrameType = XML_TEXT_FRAME_GRAPHIC; |
1480 | 1.97k | break; |
1481 | 45 | case XML_OBJECT: |
1482 | 45 | nFrameType = XML_TEXT_FRAME_OBJECT; |
1483 | 45 | break; |
1484 | 55 | case XML_OBJECT_OLE: |
1485 | 55 | nFrameType = XML_TEXT_FRAME_OBJECT_OLE; |
1486 | 55 | break; |
1487 | 0 | case XML_APPLET: |
1488 | 0 | nFrameType = XML_TEXT_FRAME_APPLET; |
1489 | 0 | break; |
1490 | 0 | case XML_PLUGIN: |
1491 | 0 | nFrameType = XML_TEXT_FRAME_PLUGIN; |
1492 | 0 | break; |
1493 | 0 | case XML_FLOATING_FRAME: |
1494 | 0 | nFrameType = XML_TEXT_FRAME_FLOATING_FRAME; |
1495 | 0 | break; |
1496 | 26.2k | } |
1497 | | |
1498 | 26.2k | if( USHRT_MAX != nFrameType ) |
1499 | 26.1k | { |
1500 | | // Shapes in Writer cannot be named via context menu (#i51726#) |
1501 | 26.1k | if ( ( XML_TEXT_FRAME_TEXTBOX == nFrameType || |
1502 | 2.07k | XML_TEXT_FRAME_GRAPHIC == nFrameType ) && |
1503 | 26.0k | m_HasAutomaticStyleWithoutParentStyle ) |
1504 | 1.19k | { |
1505 | 1.19k | Reference < XShapes > xShapes; |
1506 | 1.19k | xContext = XMLShapeImportHelper::CreateFrameChildContext( |
1507 | 1.19k | GetImport(), nElement, xAttrList, xShapes, m_xAttrList ); |
1508 | 1.19k | } |
1509 | 24.9k | else if( XML_TEXT_FRAME_PLUGIN == nFrameType ) |
1510 | 0 | { |
1511 | 0 | bool bMedia = false; |
1512 | | |
1513 | | // check, if we have a media object |
1514 | 0 | for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) |
1515 | 0 | { |
1516 | 0 | if( aIter.getToken() == XML_ELEMENT(DRAW, XML_MIME_TYPE) ) |
1517 | 0 | { |
1518 | 0 | if (::comphelper::IsMediaMimeType(aIter.toView())) |
1519 | 0 | bMedia = true; |
1520 | | |
1521 | | // leave this loop |
1522 | 0 | break; |
1523 | 0 | } |
1524 | 0 | } |
1525 | |
|
1526 | 0 | if( bMedia ) |
1527 | 0 | { |
1528 | 0 | Reference < XShapes > xShapes; |
1529 | 0 | xContext = XMLShapeImportHelper::CreateFrameChildContext( |
1530 | 0 | GetImport(), nElement, xAttrList, xShapes, m_xAttrList ); |
1531 | 0 | } |
1532 | 0 | } |
1533 | 24.9k | else if( XML_TEXT_FRAME_OBJECT == nFrameType || |
1534 | 24.8k | XML_TEXT_FRAME_OBJECT_OLE == nFrameType ) |
1535 | 100 | { |
1536 | 100 | m_bSupportsReplacement = true; |
1537 | 100 | } |
1538 | 24.8k | else if(XML_TEXT_FRAME_GRAPHIC == nFrameType) |
1539 | 1.79k | { |
1540 | 1.79k | setSupportsMultipleContents( (nElement & TOKEN_MASK) == XML_IMAGE ); |
1541 | 1.79k | } |
1542 | | |
1543 | 26.1k | if (!xContext) |
1544 | 24.9k | { |
1545 | 24.9k | xContext = new XMLTextFrameContext_Impl( GetImport(), nElement, |
1546 | 24.9k | xAttrList, |
1547 | 24.9k | m_eDefaultAnchorType, |
1548 | 24.9k | nFrameType, |
1549 | 24.9k | m_xAttrList ); |
1550 | 24.9k | } |
1551 | | |
1552 | 26.1k | m_xImplContext = xContext; |
1553 | | |
1554 | 26.1k | if(getSupportsMultipleContents() && XML_TEXT_FRAME_GRAPHIC == nFrameType) |
1555 | 1.79k | { |
1556 | 1.79k | addContent(*m_xImplContext); |
1557 | 1.79k | } |
1558 | 26.1k | } |
1559 | 26.2k | } |
1560 | 36.9k | } |
1561 | 43.5k | else if(getSupportsMultipleContents() && nElement == XML_ELEMENT(DRAW, XML_IMAGE)) |
1562 | 42.2k | { |
1563 | | // read another image |
1564 | 42.2k | xContext = new XMLTextFrameContext_Impl( |
1565 | 42.2k | GetImport(), nElement, xAttrList, |
1566 | 42.2k | m_eDefaultAnchorType, XML_TEXT_FRAME_GRAPHIC, m_xAttrList, true); |
1567 | | |
1568 | 42.2k | m_xImplContext = xContext; |
1569 | 42.2k | addContent(*m_xImplContext); |
1570 | 42.2k | } |
1571 | 1.28k | else if( m_bSupportsReplacement && !m_xReplImplContext.is() && |
1572 | 81 | nElement == XML_ELEMENT(DRAW, XML_IMAGE) ) |
1573 | 81 | { |
1574 | | // read replacement image |
1575 | 81 | Reference < XPropertySet > xPropSet; |
1576 | 81 | if( CreateIfNotThere( xPropSet ) ) |
1577 | 38 | { |
1578 | 38 | xContext = new XMLReplacementImageContext( GetImport(), |
1579 | 38 | nElement, xAttrList, xPropSet ); |
1580 | 38 | m_xReplImplContext = xContext; |
1581 | 38 | } |
1582 | 81 | } |
1583 | 1.20k | else if( nullptr != dynamic_cast< const XMLTextFrameContext_Impl*>( m_xImplContext.get() )) |
1584 | 1.11k | { |
1585 | | // the child is a writer frame |
1586 | 1.11k | if( IsTokenInNamespace(nElement, XML_NAMESPACE_SVG) || |
1587 | 1.11k | IsTokenInNamespace(nElement, XML_NAMESPACE_SVG_COMPAT) ) |
1588 | 0 | { |
1589 | | // Implement Title/Description Elements UI (#i73249#) |
1590 | 0 | const bool bOld = SvXMLImport::OOo_2x >= GetImport().getGeneratorVersion(); |
1591 | 0 | if ( bOld ) |
1592 | 0 | { |
1593 | 0 | if ( (nElement & TOKEN_MASK) == XML_DESC ) |
1594 | 0 | { |
1595 | 0 | xContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(), |
1596 | 0 | m_sTitle ); |
1597 | 0 | } |
1598 | 0 | } |
1599 | 0 | else |
1600 | 0 | { |
1601 | 0 | if( (nElement & TOKEN_MASK) == XML_TITLE ) |
1602 | 0 | { |
1603 | 0 | if (getSupportsMultipleContents()) |
1604 | 0 | { // tdf#103567 ensure props are set on surviving shape |
1605 | 0 | m_xImplContext = solveMultipleImages(); |
1606 | 0 | } |
1607 | 0 | xContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(), |
1608 | 0 | m_sTitle ); |
1609 | 0 | } |
1610 | 0 | else if ( (nElement & TOKEN_MASK) == XML_DESC ) |
1611 | 0 | { |
1612 | 0 | if (getSupportsMultipleContents()) |
1613 | 0 | { // tdf#103567 ensure props are set on surviving shape |
1614 | 0 | m_xImplContext = solveMultipleImages(); |
1615 | 0 | } |
1616 | 0 | xContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(), |
1617 | 0 | m_sDesc ); |
1618 | 0 | } |
1619 | 0 | } |
1620 | 0 | } |
1621 | 1.11k | else if( IsTokenInNamespace(nElement, XML_NAMESPACE_DRAW) ) |
1622 | 854 | { |
1623 | 854 | Reference < XPropertySet > xPropSet; |
1624 | 854 | if( (nElement & TOKEN_MASK) == XML_CONTOUR_POLYGON ) |
1625 | 0 | { |
1626 | 0 | if (getSupportsMultipleContents()) |
1627 | 0 | { // tdf#103567 ensure props are set on surviving shape |
1628 | 0 | m_xImplContext = solveMultipleImages(); |
1629 | 0 | } |
1630 | 0 | if( CreateIfNotThere( xPropSet ) ) |
1631 | 0 | xContext = new XMLTextFrameContourContext_Impl( GetImport(), nElement, |
1632 | 0 | xAttrList, xPropSet, false ); |
1633 | 0 | } |
1634 | 854 | else if( (nElement & TOKEN_MASK) == XML_CONTOUR_PATH ) |
1635 | 0 | { |
1636 | 0 | if (getSupportsMultipleContents()) |
1637 | 0 | { // tdf#103567 ensure props are set on surviving shape |
1638 | 0 | m_xImplContext = solveMultipleImages(); |
1639 | 0 | } |
1640 | 0 | if( CreateIfNotThere( xPropSet ) ) |
1641 | 0 | xContext = new XMLTextFrameContourContext_Impl( GetImport(), nElement, |
1642 | 0 | xAttrList, xPropSet, true ); |
1643 | 0 | } |
1644 | 854 | else if( (nElement & TOKEN_MASK) == XML_IMAGE_MAP ) |
1645 | 0 | { |
1646 | 0 | if (getSupportsMultipleContents()) |
1647 | 0 | { // tdf#103567 ensure props are set on surviving shape |
1648 | 0 | m_xImplContext = solveMultipleImages(); |
1649 | 0 | } |
1650 | 0 | if( CreateIfNotThere( xPropSet ) ) |
1651 | 0 | xContext = new XMLImageMapContext( GetImport(), xPropSet ); |
1652 | 0 | } |
1653 | 854 | } |
1654 | 264 | else if( nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) ) |
1655 | 0 | { |
1656 | 0 | if (getSupportsMultipleContents()) |
1657 | 0 | { // tdf#103567 ensure props are set on surviving shape |
1658 | 0 | m_xImplContext = solveMultipleImages(); |
1659 | 0 | } |
1660 | | // do we still have the frame object? |
1661 | 0 | Reference < XPropertySet > xPropSet; |
1662 | 0 | if( CreateIfNotThere( xPropSet ) ) |
1663 | 0 | { |
1664 | | // is it an event supplier? |
1665 | 0 | Reference<XEventsSupplier> xEventsSupplier(xPropSet, UNO_QUERY); |
1666 | 0 | if (xEventsSupplier.is()) |
1667 | 0 | { |
1668 | | // OK, we have the events, so create the context |
1669 | 0 | xContext = new XMLEventsImportContext(GetImport(), xEventsSupplier); |
1670 | 0 | } |
1671 | 0 | } |
1672 | 0 | } |
1673 | 1.11k | } |
1674 | | // #i68101# |
1675 | 90 | else if( nElement == XML_ELEMENT(SVG, XML_TITLE) || nElement == XML_ELEMENT(SVG, XML_DESC ) || |
1676 | 90 | nElement == XML_ELEMENT(SVG_COMPAT, XML_TITLE) || nElement == XML_ELEMENT(SVG_COMPAT, XML_DESC ) ) |
1677 | 0 | { |
1678 | 0 | if (getSupportsMultipleContents()) |
1679 | 0 | { // tdf#103567 ensure props are set on surviving shape |
1680 | | // note: no more draw:image can be added once we get here |
1681 | 0 | m_xImplContext = solveMultipleImages(); |
1682 | 0 | } |
1683 | 0 | xContext = static_cast<SvXMLImportContext*>(m_xImplContext->createFastChildContext( nElement, xAttrList ).get()); |
1684 | 0 | } |
1685 | 90 | else if (nElement == XML_ELEMENT(LO_EXT, XML_SIGNATURELINE)) |
1686 | 0 | { |
1687 | 0 | if (getSupportsMultipleContents()) |
1688 | 0 | { // tdf#103567 ensure props are set on surviving shape |
1689 | | // note: no more draw:image can be added once we get here |
1690 | 0 | m_xImplContext = solveMultipleImages(); |
1691 | 0 | } |
1692 | 0 | xContext = static_cast<SvXMLImportContext*>(m_xImplContext->createFastChildContext(nElement, xAttrList).get()); |
1693 | 0 | } |
1694 | 90 | else if (nElement == XML_ELEMENT(LO_EXT, XML_QRCODE)) |
1695 | 0 | { |
1696 | 0 | if (getSupportsMultipleContents()) |
1697 | 0 | { // tdf#103567 ensure props are set on surviving shape |
1698 | | // note: no more draw:image can be added once we get here |
1699 | 0 | m_xImplContext = solveMultipleImages(); |
1700 | 0 | } |
1701 | 0 | xContext = static_cast<SvXMLImportContext*>(m_xImplContext->createFastChildContext(nElement, xAttrList).get()); |
1702 | 0 | } |
1703 | 90 | else if (nElement == XML_ELEMENT(DRAW, XML_A)) |
1704 | 0 | { |
1705 | 0 | xContext = static_cast<SvXMLImportContext*>(m_xImplContext->createFastChildContext(nElement, xAttrList).get()); |
1706 | 0 | } |
1707 | 90 | else |
1708 | 90 | { |
1709 | | // the child is a drawing shape |
1710 | 90 | return XMLShapeImportHelper::CreateFrameChildContext( |
1711 | 90 | m_xImplContext.get(), nElement, xAttrList ); |
1712 | 90 | } |
1713 | | |
1714 | 80.4k | return xContext; |
1715 | 80.5k | } |
1716 | | |
1717 | | void XMLTextFrameContext::SetHyperlink( const OUString& rHRef, |
1718 | | const OUString& rName, |
1719 | | const OUString& rTargetFrameName, |
1720 | | bool bMap ) |
1721 | 0 | { |
1722 | 0 | OSL_ENSURE( !m_pHyperlink, "recursive SetHyperlink call" ); |
1723 | 0 | m_pHyperlink = std::make_unique<XMLTextFrameContextHyperlink_Impl>( |
1724 | 0 | rHRef, rName, rTargetFrameName, bMap ); |
1725 | 0 | } |
1726 | | |
1727 | | TextContentAnchorType XMLTextFrameContext::GetAnchorType() const |
1728 | 17.6k | { |
1729 | 17.6k | SvXMLImportContext *pContext = m_xImplContext.get(); |
1730 | 17.6k | XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl*>( pContext ); |
1731 | 17.6k | if( pImpl ) |
1732 | 5 | return pImpl->GetAnchorType(); |
1733 | 17.6k | else |
1734 | 17.6k | return m_eDefaultAnchorType; |
1735 | 17.6k | } |
1736 | | |
1737 | | Reference < XTextContent > XMLTextFrameContext::GetTextContent() const |
1738 | 5 | { |
1739 | 5 | Reference < XTextContent > xTxtCntnt; |
1740 | 5 | SvXMLImportContext *pContext = m_xImplContext.get(); |
1741 | 5 | XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl* >( pContext ); |
1742 | 5 | if( pImpl ) |
1743 | 5 | xTxtCntnt.set( pImpl->GetPropSet(), UNO_QUERY ); |
1744 | | |
1745 | 5 | return xTxtCntnt; |
1746 | 5 | } |
1747 | | |
1748 | | Reference < XShape > XMLTextFrameContext::GetShape() const |
1749 | 24.7k | { |
1750 | 24.7k | Reference < XShape > xShape; |
1751 | 24.7k | SvXMLImportContext* pContext = m_xImplContext.get(); |
1752 | 24.7k | SvXMLShapeContext* pImpl = dynamic_cast<SvXMLShapeContext*>( pContext ); |
1753 | 24.7k | if ( pImpl ) |
1754 | 973 | { |
1755 | 973 | xShape = pImpl->getShape(); |
1756 | 973 | } |
1757 | | |
1758 | 24.7k | return xShape; |
1759 | 24.7k | } |
1760 | | |
1761 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |