LibreOffice Module oox (master)  1
pptshape.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 <oox/ppt/pptshape.hxx>
22 #include <drawingml/textbody.hxx>
24 #include <drawingml/textfield.hxx>
26 #include <editeng/flditem.hxx>
27 
28 #include <com/sun/star/text/XTextField.hpp>
29 #include <com/sun/star/container/XNamed.hpp>
30 #include <com/sun/star/frame/XModel.hpp>
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/drawing/XDrawPage.hpp>
33 #include <com/sun/star/drawing/XDrawPages.hpp>
34 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
35 #include <com/sun/star/drawing/XShapes.hpp>
36 #include <com/sun/star/text/XText.hpp>
38 #include <sal/log.hxx>
39 #include <oox/ppt/slidepersist.hxx>
40 #include <oox/token/tokens.hxx>
41 
42 using namespace ::oox::core;
43 using namespace ::oox::drawingml;
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::awt;
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::beans;
48 using namespace ::com::sun::star::text;
49 using namespace ::com::sun::star::drawing;
50 
51 namespace oox::ppt {
52 
53 PPTShape::PPTShape( const oox::ppt::ShapeLocation eShapeLocation, const char* pServiceName )
54 : Shape( pServiceName )
55 , meShapeLocation( eShapeLocation )
56 , mbReferenced( false )
57 , mbHasNoninheritedShapeProperties( false )
58 {
59 }
60 
62 {
63 }
64 
65 static const char* lclDebugSubType( sal_Int32 nType )
66 {
67  switch (nType) {
68  case XML_ctrTitle :
69  return "ctrTitle";
70  case XML_title :
71  return "title";
72  case XML_subTitle :
73  return "subTitle";
74  case XML_obj :
75  return "obj";
76  case XML_body :
77  return "body";
78  case XML_dt :
79  return "dt";
80  case XML_hdr :
81  return "hdr";
82  case XML_ftr :
83  return "frt";
84  case XML_sldNum :
85  return "sldNum";
86  case XML_sldImg :
87  return "sldImg";
88  }
89 
90  return "unknown - please extend lclDebugSubType";
91 }
92 
93 namespace
94 {
95 bool ShapeHasNoVisualPropertiesOnImport(const oox::ppt::PPTShape& rPPTShape)
96 {
97  return !rPPTShape.hasNonInheritedShapeProperties()
98  && !rPPTShape.hasShapeStyleRefs()
99  && !rPPTShape.getTextBody()->hasVisualRunProperties()
100  && !rPPTShape.getTextBody()->hasNoninheritedBodyProperties()
101  && !rPPTShape.getTextBody()->hasListStyleOnImport()
102  && !rPPTShape.getTextBody()->hasParagraphProperties();
103 }
104 }
105 
107 {
108  oox::drawingml::TextListStylePtr pTextListStyle;
109 
110  SAL_INFO("oox.ppt", "subtype style: " << lclDebugSubType( nSubType ) );
111 
112  switch( nSubType )
113  {
114  case XML_ctrTitle :
115  case XML_title :
116  pTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
117  break;
118  case XML_subTitle :
119  case XML_obj :
120  case XML_body :
121  if ( rSlidePersist.isNotesPage() )
122  pTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getNotesTextStyle() : rSlidePersist.getNotesTextStyle();
123  else
124  pTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
125  break;
126  }
127 
128  return pTextListStyle;
129 }
130 
131 bool PPTShape::IsPlaceHolderCandidate(const SlidePersist& rSlidePersist) const
132 {
133  if (meShapeLocation != Slide)
134  return false;
135  if (rSlidePersist.isNotesPage())
136  return false;
137  auto pTextBody = getTextBody();
138  if (!pTextBody)
139  return false;
140  auto rParagraphs = pTextBody->getParagraphs();
141  if (rParagraphs.size() != 1)
142  return false;
143  if (rParagraphs.front()->getRuns().size() != 1)
144  return false;
145  return ShapeHasNoVisualPropertiesOnImport(*this);
146 }
147 
149  oox::core::XmlFilterBase& rFilterBase,
150  const SlidePersist& rSlidePersist,
151  const oox::drawingml::Theme* pTheme,
152  const Reference< XShapes >& rxShapes,
153  basegfx::B2DHomMatrix& aTransformation,
154  ::oox::drawingml::ShapeIdMap* pShapeMap )
155 {
156  SAL_INFO("oox.ppt","add shape id: " << msId << " location: " << ((meShapeLocation == Master) ? "master" : ((meShapeLocation == Slide) ? "slide" : ((meShapeLocation == Layout) ? "layout" : "other"))) << " subtype: " << mnSubType << " service: " << msServiceName);
157  // only placeholder from layout are being inserted
158  if ( mnSubType && ( meShapeLocation == Master ) )
159  return;
160 
161  OUString sServiceName( msServiceName );
162  if (sServiceName.isEmpty())
163  return;
164  try
165  {
166  oox::drawingml::TextListStylePtr aMasterTextListStyle;
167  Reference<lang::XMultiServiceFactory> xServiceFact(rFilterBase.getModel(), UNO_QUERY_THROW);
168  bool bClearText = false;
169 
170  if (sServiceName != "com.sun.star.drawing.GraphicObjectShape" &&
171  sServiceName != "com.sun.star.drawing.OLE2Shape")
172  {
173  static const OUStringLiteral sOutlinerShapeService(u"com.sun.star.presentation.OutlinerShape");
174  SAL_INFO("oox.ppt","has master: " << std::hex << rSlidePersist.getMasterPersist().get());
175  switch (mnSubType)
176  {
177  case XML_ctrTitle :
178  case XML_title :
179  {
180  sServiceName = "com.sun.star.presentation.TitleTextShape";
181  aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
182  }
183  break;
184  case XML_subTitle :
185  {
186  if ((meShapeLocation == Master) || (meShapeLocation == Layout))
187  sServiceName = OUString();
188  else {
189  sServiceName = "com.sun.star.presentation.SubtitleShape";
190  aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
191  }
192  }
193  break;
194  case XML_obj :
195  {
196  sServiceName = sOutlinerShapeService;
197  aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
198  }
199  break;
200  case XML_body :
201  {
202  if (rSlidePersist.isNotesPage())
203  {
204  sServiceName = "com.sun.star.presentation.NotesShape";
205  aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getNotesTextStyle() : rSlidePersist.getNotesTextStyle();
206  }
207  else
208  {
209  sServiceName = sOutlinerShapeService;
210  aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
211  }
212  }
213  break;
214  case XML_dt :
215  if (IsPlaceHolderCandidate(rSlidePersist))
216  {
217  TextRunPtr& pTextRun = getTextBody()->getParagraphs().front()->getRuns().front();
218  oox::drawingml::TextField* pTextField = dynamic_cast<oox::drawingml::TextField*>(pTextRun.get());
219  if (pTextField)
220  {
221  OUString aType = pTextField->getType();
222  if ( aType.startsWith("datetime") )
223  {
226  Reference< XPropertySet > xPropertySet( rSlidePersist.getPage(), UNO_QUERY );
227 
228  if( eDateFormat != SvxDateFormat::AppDefault
229  || eTimeFormat != SvxTimeFormat::AppDefault )
230  {
231  // DateTimeFormat property looks for the date in 4 LSBs
232  // and looks for time format in the 4 bits after that
233  sal_Int32 nDateTimeFormat = static_cast<sal_Int32>(eDateFormat) |
234  static_cast<sal_Int32>(eTimeFormat) << 4;
235  xPropertySet->setPropertyValue( "IsDateTimeVisible", Any(true) );
236  xPropertySet->setPropertyValue( "IsDateTimeFixed", Any(false) );
237  xPropertySet->setPropertyValue( "DateTimeFormat", Any(nDateTimeFormat) );
238  return;
239  }
240  }
241  }
242  }
243  sServiceName = "com.sun.star.presentation.DateTimeShape";
244  bClearText = true;
245  break;
246  case XML_hdr :
247  sServiceName = "com.sun.star.presentation.HeaderShape";
248  bClearText = true;
249  break;
250  case XML_ftr :
251  if (IsPlaceHolderCandidate(rSlidePersist))
252  {
253  const OUString& rFooterText = getTextBody()->toString();
254 
255  if( !rFooterText.isEmpty() )
256  {
257  // if it is possible to get the footer as a property the LO way,
258  // get it and discard the shape
259  Reference< XPropertySet > xPropertySet( rSlidePersist.getPage(), UNO_QUERY );
260  xPropertySet->setPropertyValue( "IsFooterVisible", Any( true ) );
261  xPropertySet->setPropertyValue( "FooterText", Any(rFooterText) );
262  return;
263  }
264  }
265  sServiceName = "com.sun.star.presentation.FooterShape";
266  bClearText = true;
267  break;
268  case XML_sldNum :
269  if (IsPlaceHolderCandidate(rSlidePersist))
270  {
271  TextRunPtr& pTextRun
272  = getTextBody()->getParagraphs().front()->getRuns().front();
273  oox::drawingml::TextField* pTextField
274  = dynamic_cast<oox::drawingml::TextField*>(pTextRun.get());
275  if (pTextField && pTextField->getType() == "slidenum")
276  {
277  // if it is possible to get the slidenum placeholder as a property
278  // do that and discard the shape
279  Reference<XPropertySet> xPropertySet(rSlidePersist.getPage(),
280  UNO_QUERY);
281  xPropertySet->setPropertyValue("IsPageNumberVisible", Any(true));
282  return;
283  }
284  }
285  sServiceName = "com.sun.star.presentation.SlideNumberShape";
286  bClearText = true;
287  break;
288  case XML_sldImg :
289  sServiceName = "com.sun.star.presentation.PageShape";
290  break;
291  case XML_chart :
292  if (meShapeLocation == Layout)
293  sServiceName = sOutlinerShapeService;
294  else
295  sServiceName = "com.sun.star.presentation.ChartShape";
296  break;
297  case XML_tbl :
298  if (meShapeLocation == Layout)
299  sServiceName = sOutlinerShapeService;
300  else
301  sServiceName = "com.sun.star.presentation.TableShape";
302  break;
303  case XML_pic :
304  if (meShapeLocation == Layout)
305  sServiceName = sOutlinerShapeService;
306  else
307  sServiceName = "com.sun.star.presentation.GraphicObjectShape";
308  break;
309  case XML_media :
310  if (meShapeLocation == Layout)
311  sServiceName = sOutlinerShapeService;
312  else
313  sServiceName = "com.sun.star.presentation.MediaShape";
314  break;
315  default:
316  if (mnSubType && meShapeLocation == Layout)
317  sServiceName = sOutlinerShapeService;
318  break;
319  }
320  }
321 
322  SAL_INFO("oox.ppt","shape service: " << sServiceName);
323 
324  if (mnSubType && getSubTypeIndex().has() && meShapeLocation == Layout)
325  {
326  oox::drawingml::ShapePtr pPlaceholder = PPTShape::findPlaceholderByIndex( getSubTypeIndex().get(), rSlidePersist.getShapes()->getChildren(), true );
327  if (!pPlaceholder)
328  pPlaceholder = PPTShape::findPlaceholder( mnSubType, 0, getSubTypeIndex(), rSlidePersist.getShapes()->getChildren(), true );
329 
330  if (pPlaceholder) {
331  if (maSize.Width == 0 || maSize.Height == 0) {
332  awt::Size aSize = maSize;
333  if (maSize.Width == 0)
334  aSize.Width = pPlaceholder->getSize().Width;
335  if (maSize.Height == 0)
336  aSize.Height = pPlaceholder->getSize().Height;
337  setSize( aSize );
338  if (maPosition.X == 0 || maPosition.Y == 0) {
339  awt::Point aPosition = maPosition;
340  if (maPosition.X == 0)
341  aPosition.X = pPlaceholder->getPosition().X;
342  if (maPosition.Y == 0)
343  aPosition.Y = pPlaceholder->getPosition().Y;
344  setPosition( aPosition );
345  }
346  }
347  }
348  }
349 
350  // use placeholder index if possible
351  if (mnSubType && getSubTypeIndex().has() && rSlidePersist.getMasterPersist())
352  {
353  oox::drawingml::ShapePtr pPlaceholder = PPTShape::findPlaceholderByIndex(getSubTypeIndex().get(), rSlidePersist.getMasterPersist()->getShapes()->getChildren());
354  // TODO: Check if this is required for non-notes slides as well...
355  if (rSlidePersist.isNotesPage() && pPlaceholder && pPlaceholder->getSubType() != getSubType())
356  pPlaceholder.reset();
357 
358  if (pPlaceholder) {
359  SAL_INFO("oox.ppt","found placeholder with index: " << getSubTypeIndex().get() << " and type: " << lclDebugSubType( mnSubType ));
360  }
361  if (pPlaceholder) {
362  PPTShape* pPPTPlaceholder = dynamic_cast< PPTShape* >( pPlaceholder.get() );
363  TextListStylePtr pNewTextListStyle = std::make_shared<TextListStyle>();
364 
365  if (pPlaceholder->getTextBody()) {
366 
367  pNewTextListStyle->apply( pPlaceholder->getTextBody()->getTextListStyle() );
368  if (pPlaceholder->getMasterTextListStyle())
369  pNewTextListStyle->apply( *pPlaceholder->getMasterTextListStyle() );
370 
371  // SAL_INFO("oox.ppt","placeholder body style");
372  // pPlaceholder->getTextBody()->getTextListStyle().dump();
373  // SAL_INFO("oox.ppt","master text list style");
374  // pPlaceholder->getMasterTextListStyle()->dump();
375 
376  aMasterTextListStyle = pNewTextListStyle;
377  // SAL_INFO("oox.ppt","combined master text list style");
378  // aMasterTextListStyle->dump();
379  }
380  if (pPPTPlaceholder && pPPTPlaceholder->mpPlaceholder) {
381  SAL_INFO("oox.ppt","placeholder has parent placeholder: " << pPPTPlaceholder->mpPlaceholder->getId() << " type: " << lclDebugSubType( pPPTPlaceholder->mpPlaceholder->getSubType() ) << " index: " << pPPTPlaceholder->mpPlaceholder->getSubTypeIndex().get() );
382  SAL_INFO("oox.ppt","has textbody " << (pPPTPlaceholder->mpPlaceholder->getTextBody() != nullptr) );
383  TextListStylePtr pPlaceholderStyle = getSubTypeTextListStyle( rSlidePersist, pPPTPlaceholder->mpPlaceholder->getSubType() );
384  if (pPPTPlaceholder->mpPlaceholder->getTextBody())
385  pNewTextListStyle->apply( pPPTPlaceholder->mpPlaceholder->getTextBody()->getTextListStyle() );
386  if (pPlaceholderStyle) {
387  pNewTextListStyle->apply( *pPlaceholderStyle );
388  //pPlaceholderStyle->dump();
389  }
390  }
391  } else if (!mpPlaceholder) {
392  aMasterTextListStyle.reset();
393  }
394  SAL_INFO("oox.ppt","placeholder id: " << (pPlaceholder ? pPlaceholder->getId() : "not found"));
395  }
396 
397  if (!sServiceName.isEmpty())
398  {
399  if (!aMasterTextListStyle)
400  {
401  bool isOther = !getTextBody() && sServiceName != "com.sun.star.drawing.GroupShape";
402  TextListStylePtr aSlideStyle = isOther ? rSlidePersist.getOtherTextStyle() : rSlidePersist.getDefaultTextStyle();
403  // Combine from MasterSlide details as well.
404  if (rSlidePersist.getMasterPersist())
405  {
406  aMasterTextListStyle = isOther ? rSlidePersist.getMasterPersist()->getOtherTextStyle() : rSlidePersist.getMasterPersist()->getDefaultTextStyle();
407  if (aSlideStyle)
408  aMasterTextListStyle->apply( *aSlideStyle );
409  }
410  else
411  {
412  aMasterTextListStyle = aSlideStyle;
413  }
414  }
415 
416  if( aMasterTextListStyle && getTextBody() ) {
417  TextListStylePtr aCombinedTextListStyle = std::make_shared<TextListStyle>();
418 
419  aCombinedTextListStyle->apply( *aMasterTextListStyle );
420 
421  if( mpPlaceholder && mpPlaceholder->getTextBody() )
422  aCombinedTextListStyle->apply( mpPlaceholder->getTextBody()->getTextListStyle() );
423  aCombinedTextListStyle->apply( getTextBody()->getTextListStyle() );
424 
425  setMasterTextListStyle( aCombinedTextListStyle );
426  } else
427  setMasterTextListStyle( aMasterTextListStyle );
428 
429  Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, bClearText, bool(mpPlaceholder), aTransformation, getFillProperties() ) );
430  // if exists and not duplicated, try to use the title text as slide name to help its re-use on UI
431  if (!rSlidePersist.isMasterPage() && rSlidePersist.getPage().is() && mnSubType == XML_title)
432  {
433  try
434  {
435  sal_Int32 nCount = 1;
436  OUString aTitleText;
437  Reference<XTextRange> xText(xShape, UNO_QUERY_THROW);
438  aTitleText = xText->getString();
439  Reference<drawing::XDrawPagesSupplier> xDPS(rFilterBase.getModel(), uno::UNO_QUERY_THROW);
440  Reference<drawing::XDrawPages> xDrawPages(xDPS->getDrawPages(), uno::UNO_SET_THROW);
441  sal_uInt32 nMaxPages = xDrawPages->getCount();
442  // just a magic value but we don't want to drop out slide names which are too long
443  if (aTitleText.getLength() > 63)
444  aTitleText = aTitleText.copy(0, 63);
445  bool bUseTitleAsSlideName = !aTitleText.isEmpty();
446  // check duplicated title name
447  if (bUseTitleAsSlideName)
448  {
449  for (sal_uInt32 nPage = 0; nPage < nMaxPages; ++nPage)
450  {
451  Reference<XDrawPage> xDrawPage(xDrawPages->getByIndex(nPage), uno::UNO_QUERY);
452  Reference<container::XNamed> xNamed(xDrawPage, UNO_QUERY_THROW);
453  OUString sRest;
454  if (xNamed->getName().startsWith(aTitleText, &sRest)
455  && (sRest.isEmpty()
456  || (sRest.startsWith(" (") && sRest.endsWith(")")
457  && sRest.copy(2, sRest.getLength() - 3).toInt32() > 0)))
458  nCount++;
459  }
460  Reference<container::XNamed> xName(rSlidePersist.getPage(), UNO_QUERY_THROW);
461  xName->setName(
462  aTitleText
463  + (nCount == 1 ? OUString("") : " (" + OUString::number(nCount) + ")"));
464  }
465  }
466  catch (uno::Exception&)
467  {
468 
469  }
470  }
471 
472  // Apply text properties on placeholder text inside this placeholder shape
473  if (meShapeLocation == Slide && mpPlaceholder && getTextBody() && getTextBody()->isEmpty())
474  {
475  Reference < XText > xText(mxShape, UNO_QUERY);
476  if (xText.is())
477  {
478  TextCharacterProperties aCharStyleProperties;
479  getTextBody()->ApplyStyleEmpty(rFilterBase, xText, aCharStyleProperties, mpMasterTextListStyle);
480  }
481  }
482  if (pShapeMap)
483  {
484  // bnc#705982 - if optional model id reference is
485  // there, use that to obtain target shape
486  if (!msModelId.isEmpty())
487  {
488  (*pShapeMap)[ msModelId ] = shared_from_this();
489  }
490  else if (!msId.isEmpty())
491  {
492  (*pShapeMap)[ msId ] = shared_from_this();
493  }
494  }
495 
496  // we will be losing whatever information there is in the footer placeholder on master/layout slides
497  // since they should have the "<footer>" textfield in them in order to make LibreOffice process them as expected
498  // likewise DateTime placeholder data on master/layout slides will be lost and replaced
499  if( (mnSubType == XML_ftr || mnSubType == XML_dt) && meShapeLocation != Slide )
500  {
501  OUString aFieldType;
502  if( mnSubType == XML_ftr )
503  aFieldType = "com.sun.star.presentation.TextField.Footer";
504  else
505  aFieldType = "com.sun.star.presentation.TextField.DateTime";
506  Reference < XTextField > xField( xServiceFact->createInstance( aFieldType ), UNO_QUERY );
507  Reference < XText > xText(mxShape, UNO_QUERY);
508  if(xText.is())
509  {
510  xText->setString("");
511  Reference < XTextCursor > xTextCursor = xText->createTextCursor();
512  xText->insertTextContent( xTextCursor, xField, false);
513  }
514  }
515 
516  // if this is a group shape, we have to add also each child shape
517  Reference<XShapes> xShapes(xShape, UNO_QUERY);
518  if (xShapes.is())
519  {
521  {
523  }
524  addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aTransformation );
526  {
527  rFilterBase.setDiagramFontHeights(nullptr);
528  }
529  }
530 
532  {
535  }
536  }
537  }
538  catch (const Exception&)
539  {
540  }
541 }
542 
543 namespace
544 {
545  bool ShapeLocationIsMaster(oox::drawingml::Shape *pInShape)
546  {
547  PPTShape* pShape = dynamic_cast<PPTShape*>(pInShape);
548  return pShape && pShape->getShapeLocation() == Master;
549  }
550 }
551 
552 // Function to find placeholder (ph) for a shape. No idea how MSO implements this, but
553 // this order seems to work quite well (probably it's unnecessary complicated / wrong):
554 // 1. ph with nFirstSubType and the same oSubTypeIndex
555 // 2. ph with nFirstSubType
556 // 3. ph with nSecondSubType and the same oSubTypeIndex
557 // 4. ph with nSecondSubType
558 // 5. ph with the same oSubTypeIndex
559 
560 oox::drawingml::ShapePtr PPTShape::findPlaceholder( sal_Int32 nFirstSubType, sal_Int32 nSecondSubType,
561  const OptValue< sal_Int32 >& oSubTypeIndex, std::vector< oox::drawingml::ShapePtr >& rShapes, bool bMasterOnly )
562 {
563  class Placeholders
564  {
565  public:
566  Placeholders()
567  : aChoice(5) // resize to 5
568  {
569  }
570 
571  void add(const oox::drawingml::ShapePtr& aShape, sal_Int32 nFirstSubType, sal_Int32 nSecondSubType, const OptValue< sal_Int32 >& oSubTypeIndex)
572  {
573  if (!aShape)
574  return;
575 
576  // get flags
577  const bool bSameFirstSubType = aShape->getSubType() == nFirstSubType;
578  const bool bSameSecondSubType = aShape->getSubType() == nSecondSubType;
579  const bool bSameIndex = aShape->getSubTypeIndex() == oSubTypeIndex;
580 
581  // get prio
582  int aPrioIndex = -1;
583  if (bSameIndex && bSameFirstSubType)
584  aPrioIndex = 0;
585  else if (!bSameIndex && bSameFirstSubType)
586  aPrioIndex = 1;
587  else if (bSameIndex && bSameSecondSubType)
588  aPrioIndex = 2;
589  else if (!bSameIndex && bSameSecondSubType)
590  aPrioIndex = 3;
591  else if (bSameIndex)
592  aPrioIndex = 4;
593 
594  // add
595  if (aPrioIndex != -1)
596  {
597  if (!aChoice.at(aPrioIndex))
598  {
599  aChoice.at(aPrioIndex) = aShape;
600  }
601  }
602  }
603 
604  // return according to prio
605  oox::drawingml::ShapePtr getByPrio() const
606  {
607  for (const oox::drawingml::ShapePtr& aShape : aChoice)
608  {
609  if (aShape)
610  {
611  return aShape;
612  }
613  }
614 
615  return oox::drawingml::ShapePtr();
616  }
617 
618  bool hasByPrio(size_t aIndex) const
619  {
620  return bool(aChoice.at(aIndex));
621  }
622 
623  private:
624  std::vector< oox::drawingml::ShapePtr > aChoice;
625 
626  } aPlaceholders;
627 
628  // check all shapes
629  std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
630  for (; aRevIter != rShapes.rend(); ++aRevIter)
631  {
632  // check shape
633  if (!bMasterOnly || ShapeLocationIsMaster((*aRevIter).get()))
634  {
635  const oox::drawingml::ShapePtr& aShape = *aRevIter;
636  aPlaceholders.add(aShape, nFirstSubType, nSecondSubType, oSubTypeIndex);
637  }
638 
639  // check children
640  std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
641  if (!rChildren.empty())
642  {
643  const oox::drawingml::ShapePtr aShape = findPlaceholder( nFirstSubType, nSecondSubType, oSubTypeIndex, rChildren, bMasterOnly );
644  if (aShape)
645  {
646  aPlaceholders.add(aShape, nFirstSubType, nSecondSubType, oSubTypeIndex);
647  }
648  }
649 
650  if (aPlaceholders.hasByPrio(0))
651  {
652  break;
653  }
654  }
655 
656  // return something according to prio
657  return aPlaceholders.getByPrio();
658 }
659 
660 oox::drawingml::ShapePtr PPTShape::findPlaceholderByIndex( const sal_Int32 nIdx, std::vector< oox::drawingml::ShapePtr >& rShapes, bool bMasterOnly )
661 {
662  oox::drawingml::ShapePtr aShapePtr;
663 
664  std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
665  while( aRevIter != rShapes.rend() )
666  {
667  if ( (*aRevIter)->getSubTypeIndex().has() && (*aRevIter)->getSubTypeIndex().get() == nIdx &&
668  ( !bMasterOnly || ShapeLocationIsMaster((*aRevIter).get()) ) )
669  {
670  aShapePtr = *aRevIter;
671  break;
672  }
673  std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
674  aShapePtr = findPlaceholderByIndex( nIdx, rChildren, bMasterOnly );
675  if ( aShapePtr )
676  break;
677  ++aRevIter;
678  }
679  return aShapePtr;
680 }
681 
682 }
683 
684 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void setPosition(css::awt::Point nPosition)
Definition: shape.hxx:138
sal_Int32 getSubType() const
Definition: shape.hxx:162
FrameType meFrameType
Type for graphic frame shapes.
Definition: shape.hxx:342
void setDiagramFontHeights(NamedShapePairs *pDiagramFontHeights)
OUString msServiceName
Definition: shape.hxx:327
void addChildren(::oox::core::XmlFilterBase &rFilterBase, Shape &rMaster, const Theme *pTheme, const css::uno::Reference< css::drawing::XShapes > &rxShapes, ShapeIdMap *pShapeMap, const basegfx::B2DHomMatrix &aTransformation)
Definition: shape.cxx:389
bool isNotesPage() const
sal_Int32 mnSubType
Definition: shape.hxx:332
sal_Int32 toInt32(OUString const &rStr)
void setMasterTextListStyle(const TextListStylePtr &pMasterTextListStyle)
Definition: shape.cxx:1843
oox::core::NamedShapePairs & getDiagramFontHeights()
Definition: shape.hxx:246
std::shared_ptr< TextRun > TextRunPtr
Definition: textrun.hxx:65
void syncDiagramFontHeights()
Definition: shape.cxx:1706
static SvxDateFormat getLODateFormat(std::u16string_view rDateTimeType)
Gets the corresponding LO Date format for given OOXML datetime field type.
Definition: textfield.cxx:209
constexpr OUStringLiteral sServiceName
int nCount
Shape
css::awt::Point maPosition
Definition: shape.hxx:338
bool hasNonInheritedShapeProperties() const
Returns whether or not the shape had a non-empty spPr tag.
Definition: pptshape.hxx:83
css::uno::Reference< css::drawing::XShape > mxShape
Definition: shape.hxx:325
const css::uno::Reference< css::drawing::XDrawPage > & getPage() const
ShapeLocation getShapeLocation() const
Definition: pptshape.hxx:75
const oox::drawingml::TextListStylePtr & getOtherTextStyle() const
static oox::drawingml::ShapePtr findPlaceholder(const sal_Int32 nFirstSubType, const sal_Int32 nSecondSubType, const OptValue< sal_Int32 > &oSubTypeIndex, std::vector< oox::drawingml::ShapePtr > &rShapes, bool bMasterOnly=false)
Definition: pptshape.cxx:560
const OptValue< sal_Int32 > & getSubTypeIndex() const
Definition: shape.hxx:164
css::awt::Size maSize
Definition: shape.hxx:337
static const char * lclDebugSubType(sal_Int32 nType)
Definition: pptshape.cxx:65
bool isMasterPage() const
static oox::drawingml::TextListStylePtr getSubTypeTextListStyle(const SlidePersist &rSlidePersist, sal_Int32 nSubType)
Definition: pptshape.cxx:106
const oox::drawingml::TextListStylePtr & getTitleTextStyle() const
float u
SvxDateFormat
void setSize(css::awt::Size aSize)
Definition: shape.hxx:141
const oox::drawingml::TextListStylePtr & getBodyTextStyle() const
static SvxTimeFormat getLOTimeFormat(std::u16string_view rDateTimeType)
Gets the corresponding LO Time format for given OOXML datetime field type.
Definition: textfield.cxx:242
const css::uno::Reference< css::frame::XModel > & getModel() const
Returns the document model (always existing).
Definition: filterbase.cxx:217
virtual ~PPTShape() override
Definition: pptshape.cxx:61
const TextBodyPtr & getTextBody() const
Definition: shape.hxx:175
std::shared_ptr< TextListStyle > TextListStylePtr
static oox::drawingml::ShapePtr findPlaceholderByIndex(const sal_Int32 nIdx, std::vector< oox::drawingml::ShapePtr > &rShapes, bool bMasterOnly=false)
Definition: pptshape.cxx:660
std::deque< AttacherIndex_Impl > aIndex
OUString msModelId
Definition: pptshape.hxx:49
TextListStylePtr mpMasterTextListStyle
Definition: shape.hxx:324
#define SAL_INFO(area, stream)
::std::map< OUString, ShapePtr > ShapeIdMap
Definition: shape.hxx:72
css::uno::Reference< css::drawing::XShape > const & createAndInsert(::oox::core::XmlFilterBase &rFilterBase, const OUString &rServiceName, const Theme *pTheme, const css::uno::Reference< css::drawing::XShapes > &rxShapes, bool bClearText, bool bDoNotInsertEmptyTextBody, basegfx::B2DHomMatrix &aTransformation, FillProperties &rShapeOrParentShapeFillProps, oox::drawingml::ShapePtr pParentGroupShape=nullptr)
Definition: shape.cxx:672
const OUString & getType() const
Definition: textfield.hxx:43
void keepDiagramCompatibilityInfo()
Definition: shape.cxx:1669
const oox::drawingml::TextListStylePtr & getNotesTextStyle() const
bool hasShapeStyleRefs() const
Definition: shape.hxx:182
const oox::drawingml::ShapePtr & getShapes() const
const oox::drawingml::TextListStylePtr & getDefaultTextStyle() const
const SlidePersistPtr & getMasterPersist() const
PPTShape(const oox::ppt::ShapeLocation eShapeLocation, const char *pServiceType)
Definition: pptshape.cxx:53
bool IsPlaceHolderCandidate(const SlidePersist &rSlidePersist) const
Definition: pptshape.cxx:131
std::shared_ptr< Shape > ShapePtr
SvxTimeFormat
ShapeLocation meShapeLocation
Definition: pptshape.hxx:50
FillProperties & getFillProperties()
Definition: shape.hxx:120
Complex diagram drawing shape.
Definition: shape.hxx:255
void addShape(oox::core::XmlFilterBase &rFilterBase, const SlidePersist &rPersist, const oox::drawingml::Theme *pTheme, const css::uno::Reference< css::drawing::XShapes > &rxShapes, basegfx::B2DHomMatrix &aTransformation,::oox::drawingml::ShapeIdMap *pShapeMap)
Definition: pptshape.cxx:148
oox::drawingml::ShapePtr mpPlaceholder
Definition: pptshape.hxx:53