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