LibreOffice Module oox (master)  1
presentationfragmenthandler.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 
23 #include <o3tl/string_view.hxx>
24 #include <sal/log.hxx>
25 #include <tools/multisel.hxx>
26 #include <tools/diagnose_ex.h>
27 
28 #include <com/sun/star/container/XNamed.hpp>
29 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
30 #include <com/sun/star/drawing/XDrawPages.hpp>
31 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
32 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
33 #include <com/sun/star/frame/XModel.hpp>
34 #include <com/sun/star/io/XInputStream.hpp>
35 #include <com/sun/star/text/XTextField.hpp>
36 #include <com/sun/star/xml/dom/XDocument.hpp>
37 #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
38 #include <com/sun/star/presentation/XPresentationPage.hpp>
39 #include <com/sun/star/task/XStatusIndicator.hpp>
40 #include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
41 #include <com/sun/star/container/XIndexContainer.hpp>
42 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
44 #include <com/sun/star/container/XNameContainer.hpp>
45 
46 #include <oox/drawingml/theme.hxx>
51 #include <oox/ole/olestorage.hxx>
52 #include <oox/ole/vbaproject.hxx>
53 #include <oox/ppt/pptshape.hxx>
57 #include <oox/ppt/pptimport.hxx>
58 #include <oox/token/namespaces.hxx>
59 #include <oox/token/tokens.hxx>
60 
61 #include <com/sun/star/office/XAnnotation.hpp>
62 #include <com/sun/star/office/XAnnotationAccess.hpp>
63 
64 using namespace ::com::sun::star;
65 using namespace ::oox::core;
66 using namespace ::oox::drawingml;
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star::beans;
69 using namespace ::com::sun::star::drawing;
70 using namespace ::com::sun::star::presentation;
71 using namespace ::com::sun::star::xml::sax;
72 
73 namespace oox::ppt {
74 
75 static std::map<PredefinedClrSchemeId, sal_Int32> PredefinedClrTokens =
76 {
77  //{ dk1, XML_dk1 },
78  //{ lt1, XML_lt1 },
79  { dk2, XML_dk2 },
80  { lt2, XML_lt2 },
81  { accent1, XML_accent1 },
82  { accent2, XML_accent2 },
83  { accent3, XML_accent3 },
84  { accent4, XML_accent4 },
85  { accent5, XML_accent5 },
86  { accent6, XML_accent6 },
87  { hlink, XML_hlink },
88  { folHlink, XML_folHlink }
89 };
90 
91 PresentationFragmentHandler::PresentationFragmentHandler(XmlFilterBase& rFilter, const OUString& rFragmentPath)
92  : FragmentHandler2( rFilter, rFragmentPath )
93  , mpTextListStyle( std::make_shared<TextListStyle>() )
94  , mbCommentAuthorsRead(false)
95 {
96  TextParagraphPropertiesArray& rParagraphDefaultsVector( mpTextListStyle->getListStyle() );
97  for (auto & elem : rParagraphDefaultsVector)
98  {
99  // ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
100  // so this attribute needs to be set always
101  elem.getParaBottomMargin() = TextSpacing( 0 );
102  }
103 }
104 
106 {
107 }
108 
109 static void ResolveTextFields( XmlFilterBase const & rFilter )
110 {
111  const oox::core::TextFieldStack& rTextFields = rFilter.getTextFieldStack();
112  if ( rTextFields.empty() )
113  return;
114 
115  const Reference< frame::XModel >& xModel( rFilter.getModel() );
116  for (auto const& textField : rTextFields)
117  {
118  static const OUStringLiteral sURL = u"URL";
119  Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
120  Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_SET_THROW );
121 
122  const oox::core::TextField& rTextField( textField );
123  Reference< XPropertySet > xPropSet( rTextField.xTextField, UNO_QUERY );
124  Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
125  if ( xPropSetInfo->hasPropertyByName( sURL ) )
126  {
127  OUString aURL;
128  if ( xPropSet->getPropertyValue( sURL ) >>= aURL )
129  {
130  static const OUStringLiteral sSlide = u"#Slide ";
131  static const OUStringLiteral sNotes = u"#Notes ";
132  bool bNotes = false;
133  sal_Int32 nPageNumber = 0;
134  if ( aURL.match( sSlide ) )
135  nPageNumber = o3tl::toInt32(aURL.subView( sSlide.getLength() ));
136  else if ( aURL.match( sNotes ) )
137  {
138  nPageNumber = o3tl::toInt32(aURL.subView( sNotes.getLength() ));
139  bNotes = true;
140  }
141  if ( nPageNumber )
142  {
143  try
144  {
145  Reference< XDrawPage > xDrawPage;
146  xDrawPages->getByIndex( nPageNumber - 1 ) >>= xDrawPage;
147  if ( bNotes )
148  {
149  Reference< css::presentation::XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
150  xDrawPage = xPresentationPage->getNotesPage();
151  }
152  Reference< container::XNamed > xNamed( xDrawPage, UNO_QUERY_THROW );
153  aURL = "#" + xNamed->getName();
154  xPropSet->setPropertyValue( sURL, Any( aURL ) );
155  Reference< text::XTextContent > xContent( rTextField.xTextField);
156  Reference< text::XTextRange > xTextRange = rTextField.xTextCursor;
157  rTextField.xText->insertTextContent( xTextRange, xContent, true );
158  }
159  catch( uno::Exception& )
160  {
161  }
162  }
163  }
164  }
165  }
166 }
167 
168 void PresentationFragmentHandler::importCustomSlideShow(std::vector<CustomShow>& rCustomShowList)
169 {
170  PowerPointImport& rFilter = dynamic_cast<PowerPointImport&>(getFilter());
172  Reference<XDrawPagesSupplier> xDrawPagesSupplier(xModel, UNO_QUERY_THROW);
173  Reference<XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW);
174 
175  Reference<css::lang::XSingleServiceFactory> mxShowFactory;
176  Reference<css::container::XNameContainer> mxShows;
177  Reference<XCustomPresentationSupplier> xShowsSupplier(xModel, UNO_QUERY);
178  if (xShowsSupplier.is())
179  {
180  mxShows = xShowsSupplier->getCustomPresentations();
181  mxShowFactory.set(mxShows, UNO_QUERY);
182  }
183 
184  for (size_t i = 0; i < rCustomShowList.size(); ++i)
185  {
186  Reference<com::sun::star::container::XIndexContainer> xShow(mxShowFactory->createInstance(),
187  UNO_QUERY);
188  if (xShow.is())
189  {
190  static const OUStringLiteral sSlide = u"slides/slide";
191  for (size_t j = 0; j < rCustomShowList[i].maSldLst.size(); ++j)
192  {
193  OUString sCustomSlide = rCustomShowList[i].maSldLst[j];
194  sal_Int32 nPageNumber = 0;
195  if (sCustomSlide.match(sSlide))
196  nPageNumber = o3tl::toInt32(sCustomSlide.subView(sSlide.getLength()));
197 
198  Reference<XDrawPage> xPage;
199  xDrawPages->getByIndex(nPageNumber - 1) >>= xPage;
200  if (xPage.is())
201  xShow->insertByIndex(xShow->getCount(), Any(xPage));
202  }
203 
204  Any aAny;
205  aAny <<= xShow;
206  mxShows->insertByName(rCustomShowList[i].maCustomShowName, aAny);
207  }
208  }
209 }
210 
212  sal_Int32 nThemeIdx)
213 {
214  if (!pThemePtr)
215  return;
216 
217  try
218  {
219  uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
220  if (xDocProps.is())
221  {
222  uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
223 
224  static const OUStringLiteral aGrabBagPropName = u"InteropGrabBag";
225  if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
226  {
227  // get existing grab bag
228  comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
229 
230  comphelper::SequenceAsHashMap aThemesHashMap;
231 
232  // create current theme
233  uno::Sequence<beans::PropertyValue> aCurrentTheme(PredefinedClrSchemeId::Count);
234  auto pCurrentTheme = aCurrentTheme.getArray();
235 
236  ClrScheme rClrScheme = pThemePtr->getClrScheme();
238  {
239  sal_uInt32 nToken = PredefinedClrTokens[static_cast<PredefinedClrSchemeId>(nId)];
240  const OUString& sName = PredefinedClrNames[static_cast<PredefinedClrSchemeId>(nId)];
241  ::Color nColor;
242 
243  rClrScheme.getColor(nToken, nColor);
244  const uno::Any& rColor = uno::Any(nColor);
245 
246  pCurrentTheme[nId].Name = sName;
247  pCurrentTheme[nId].Value = rColor;
248  }
249 
250 
251  uno::Sequence<beans::PropertyValue> aTheme{
252  // add new theme to the sequence
253  // Export code uses the master slide's index to find the right theme
254  // so use the same index in the grabbag.
256  "ppt/theme/theme" + OUString::number(nThemeIdx) + ".xml", aCurrentTheme),
257  // store DOM fragment for SmartArt re-generation
258  comphelper::makePropertyValue("OOXTheme", pThemePtr->getFragment())
259  };
260 
261  aThemesHashMap << aTheme;
262 
263  // put the new items
264  aGrabBag.update(aThemesHashMap);
265 
266  // put it back to the document
267  xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList()));
268  }
269  }
270  }
271  catch (const uno::Exception&)
272  {
273  SAL_WARN("oox", "oox::ppt::PresentationFragmentHandler::saveThemeToGrabBag, Failed to save grab bag");
274  }
275 }
276 
277 void PresentationFragmentHandler::importSlide(sal_uInt32 nSlide, bool bFirstPage, bool bImportNotesPage)
278 {
279  PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
280 
283 
284  // importing slide pages and its corresponding notes page
285  Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
286  Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_SET_THROW );
287 
288  try {
289 
290  if( bFirstPage )
291  xDrawPages->getByIndex( 0 ) >>= xSlide;
292  else
293  xSlide = xDrawPages->insertNewByIndex( xDrawPages->getCount() );
294 
295  OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] );
296  if( !aSlideFragmentPath.isEmpty() )
297  {
298  SlidePersistPtr pMasterPersistPtr;
299  SlidePersistPtr pSlidePersistPtr = std::make_shared<SlidePersist>( rFilter, false, false, xSlide,
300  std::make_shared<PPTShape>( Slide, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
301 
302  FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( rFilter, aSlideFragmentPath, pSlidePersistPtr, Slide ) );
303 
304  // importing the corresponding masterpage/layout
305  OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideLayout" );
306  OUString aCommentFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"comments" );
307  if ( !aLayoutFragmentPath.isEmpty() )
308  {
309  // importing layout
310  RelationsRef xLayoutRelations = rFilter.importRelations( aLayoutFragmentPath );
311  OUString aMasterFragmentPath = xLayoutRelations->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideMaster" );
312  if( !aMasterFragmentPath.isEmpty() )
313  {
314  // check if the corresponding masterpage+layout has already been imported
315  std::vector< SlidePersistPtr >& rMasterPages( rFilter.getMasterPages() );
316  for (auto const& masterPage : rMasterPages)
317  {
318  if ( ( masterPage->getPath() == aMasterFragmentPath ) && ( masterPage->getLayoutPath() == aLayoutFragmentPath ) )
319  {
320  pMasterPersistPtr = masterPage;
321  break;
322  }
323  }
324 
325  if ( !pMasterPersistPtr )
326  { // masterpersist not found, we have to load it
328  Reference< drawing::XMasterPagesSupplier > xMPS( xModel, uno::UNO_QUERY_THROW );
329  Reference< drawing::XDrawPages > xMasterPages( xMPS->getMasterPages(), uno::UNO_SET_THROW );
330 
331  sal_Int32 nIndex;
332  if( rFilter.getMasterPages().empty() )
333  {
334  nIndex = 0;
335  xMasterPages->getByIndex( nIndex ) >>= xMasterPage;
336  }
337  else
338  {
339  nIndex = xMasterPages->getCount();
340  xMasterPage = xMasterPages->insertNewByIndex( nIndex );
341  }
342 
343  pMasterPersistPtr = std::make_shared<SlidePersist>( rFilter, true, false, xMasterPage,
344  std::make_shared<PPTShape>( Master, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
345  pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
346  rFilter.getMasterPages().push_back( pMasterPersistPtr );
347  rFilter.setActualSlidePersist( pMasterPersistPtr );
348  FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, aMasterFragmentPath, pMasterPersistPtr, Master ) );
349 
350  // set the correct theme
351  OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"theme" );
352  if( !aThemeFragmentPath.isEmpty() )
353  {
354  std::map< OUString, oox::drawingml::ThemePtr >& rThemes( rFilter.getThemes() );
355  std::map< OUString, oox::drawingml::ThemePtr >::iterator aIter2( rThemes.find( aThemeFragmentPath ) );
356  if( aIter2 == rThemes.end() )
357  {
358  oox::drawingml::ThemePtr pThemePtr = std::make_shared<oox::drawingml::Theme>();
359  pMasterPersistPtr->setTheme( pThemePtr );
360  Reference<xml::dom::XDocument> xDoc=
361  rFilter.importFragment(aThemeFragmentPath);
362 
363  rFilter.importFragment(
364  new ThemeFragmentHandler(
365  rFilter, aThemeFragmentPath, *pThemePtr ),
366  Reference<xml::sax::XFastSAXSerializable>(
367  xDoc,
368  UNO_QUERY_THROW));
369  rThemes[ aThemeFragmentPath ] = pThemePtr;
370  pThemePtr->setFragment(xDoc);
371  saveThemeToGrabBag(pThemePtr, nIndex + 1);
372  }
373  else
374  {
375  pMasterPersistPtr->setTheme( (*aIter2).second );
376  }
377  }
378  importSlide( xMasterFragmentHandler, pMasterPersistPtr );
379  rFilter.importFragment( new LayoutFragmentHandler( rFilter, aLayoutFragmentPath, pMasterPersistPtr ) );
380  pMasterPersistPtr->createBackground( rFilter );
381  pMasterPersistPtr->createXShapes( rFilter );
382 
383  oox::drawingml::ThemePtr pTheme = pMasterPersistPtr->getTheme();
384  if (pTheme)
385  {
386  pTheme->addTheme(pMasterPersistPtr->getPage());
387  }
388  }
389  }
390  }
391 
392  // importing slide page
393  if (pMasterPersistPtr) {
394  pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
395  pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
396  Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
397  if( xMasterPageTarget.is() )
398  xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
399  }
400  rFilter.getDrawPages().push_back( pSlidePersistPtr );
401  rFilter.setActualSlidePersist( pSlidePersistPtr );
402  importSlide( xSlideFragmentHandler, pSlidePersistPtr );
403  pSlidePersistPtr->createBackground( rFilter );
404  pSlidePersistPtr->createXShapes( rFilter );
405 
406  if(bImportNotesPage) {
407 
408  // now importing the notes page
409  OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"notesSlide" );
410  if( !aNotesFragmentPath.isEmpty() )
411  {
412  Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
413  if ( xPresentationPage.is() )
414  {
415  Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
416  if ( xNotesPage.is() )
417  {
418  SlidePersistPtr pNotesPersistPtr = std::make_shared<SlidePersist>( rFilter, false, true, xNotesPage,
419  std::make_shared<PPTShape>( Slide, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
420  FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
421  rFilter.getNotesPages().push_back( pNotesPersistPtr );
422  rFilter.setActualSlidePersist( pNotesPersistPtr );
423  importSlide( xNotesFragmentHandler, pNotesPersistPtr );
424  pNotesPersistPtr->createBackground( rFilter );
425  pNotesPersistPtr->createXShapes( rFilter );
426  }
427  }
428  }
429  }
430 
431  if( !mbCommentAuthorsRead && !aCommentFragmentPath.isEmpty() )
432  {
433  // Comments are present and commentAuthors.xml has still not been read
434  mbCommentAuthorsRead = true;
435  Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
436  Reference< XDrawPage > xCommentAuthorsPage( xPresentationPage->getNotesPage() );
437  SlidePersistPtr pCommentAuthorsPersistPtr =
438  std::make_shared<SlidePersist>( rFilter, false, true, xCommentAuthorsPage,
439  std::make_shared<PPTShape>(
440  Slide, "com.sun.star.drawing.GroupShape" ),
441  mpTextListStyle );
442  FragmentHandlerRef xCommentAuthorsFragmentHandler(
443  new SlideFragmentHandler( getFilter(),
444  "ppt/commentAuthors.xml",
445  pCommentAuthorsPersistPtr,
446  Slide ) );
447 
448  getFilter().importFragment( xCommentAuthorsFragmentHandler );
449  maAuthorList.setValues( pCommentAuthorsPersistPtr->getCommentAuthors() );
450  }
451  if( !aCommentFragmentPath.isEmpty() )
452  {
453  Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
454  Reference< XDrawPage > xCommentsPage( xPresentationPage->getNotesPage() );
455  SlidePersistPtr pCommentsPersistPtr =
456  std::make_shared<SlidePersist>(
457  rFilter, false, true, xCommentsPage,
458  std::make_shared<PPTShape>(
459  Slide, "com.sun.star.drawing.GroupShape" ),
460  mpTextListStyle );
461 
462  FragmentHandlerRef xCommentsFragmentHandler(
464  getFilter(),
465  aCommentFragmentPath,
466  pCommentsPersistPtr,
467  Slide ) );
468  pCommentsPersistPtr->getCommentsList().cmLst.clear();
469  getFilter().importFragment( xCommentsFragmentHandler );
470 
471  if (!pCommentsPersistPtr->getCommentsList().cmLst.empty())
472  {
473  //set comment chars for last comment on slide
474  SlideFragmentHandler* comment_handler =
475  dynamic_cast<SlideFragmentHandler*>(xCommentsFragmentHandler.get());
476  assert(comment_handler);
477  // some comments have no text -> set empty string as text to avoid
478  // crash (back() on empty vector is undefined) and losing other
479  // comment data that might be there (author, position, timestamp etc.)
480  pCommentsPersistPtr->getCommentsList().cmLst.back().setText(
481  comment_handler->getCharVector().empty() ? "" :
482  comment_handler->getCharVector().back() );
483  }
484  pCommentsPersistPtr->getCommentAuthors().setValues(maAuthorList);
485 
486  //insert all comments from commentsList
487  for(int i=0; i<pCommentsPersistPtr->getCommentsList().getSize(); i++)
488  {
489  try {
490  Comment aComment = pCommentsPersistPtr->getCommentsList().getCommentAtIndex(i);
491  uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xSlide, UNO_QUERY_THROW );
492  uno::Reference< office::XAnnotation > xAnnotation( xAnnotationAccess->createAndInsertAnnotation() );
493  int nPosX = aComment.getIntX();
494  int nPosY = aComment.getIntY();
495  xAnnotation->setPosition(
496  geometry::RealPoint2D(
497  ::oox::drawingml::convertEmuToHmm( nPosX ) * 15.87,
498  ::oox::drawingml::convertEmuToHmm( nPosY ) * 15.87 ) );
499  xAnnotation->setAuthor( aComment.getAuthor(maAuthorList) );
500  xAnnotation->setDateTime( aComment.getDateTime() );
501  uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
502  xText->setString( aComment.get_text());
503  } catch( css::lang::IllegalArgumentException& ) {}
504  }
505  }
506  }
507  }
508  catch( uno::Exception& )
509  {
510  TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::EndDocument()" );
511  }
512 }
513 
515 {
516  PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
517 
518  sal_Int32 nPageCount = maSlidesVector.size();
519 
520  // we will take the FilterData property "PageRange" if available, otherwise full range is used
521  comphelper::SequenceAsHashMap& rFilterData = rFilter.getFilterData();
522 
523  // writing back the original PageCount of this document, it can be accessed from the XModel
524  // via getArgs after the import.
525  rFilterData["OriginalPageCount"] <<= nPageCount;
526  bool bImportNotesPages = rFilterData.getUnpackedValueOrDefault("ImportNotesPages", true);
527  OUString aPageRange = rFilterData.getUnpackedValueOrDefault("PageRange", OUString());
528 
529  if( !aPageRange.getLength() )
530  {
531  aPageRange = "1-" + OUString::number( nPageCount );
532  }
533 
534  StringRangeEnumerator aRangeEnumerator( aPageRange, 0, nPageCount - 1 );
535  if (aRangeEnumerator.size())
536  {
537  // todo: localized progress bar text
538  const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
539  if ( rxStatusIndicator.is() )
540  rxStatusIndicator->start( OUString(), 10000 );
541 
542  try
543  {
544  int nPagesImported = 0;
545  for (sal_Int32 elem : aRangeEnumerator)
546  {
547  if ( rxStatusIndicator.is() )
548  rxStatusIndicator->setValue((nPagesImported * 10000) / aRangeEnumerator.size());
549 
550  importSlide(elem, !nPagesImported, bImportNotesPages);
551  nPagesImported++;
552  }
553  ResolveTextFields( rFilter );
554  if (!maCustomShowList.empty())
556  }
557  catch( uno::Exception& )
558  {
559  TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::finalizeImport()" );
560  }
561  // todo error handling;
562  if ( rxStatusIndicator.is() )
563  rxStatusIndicator->end();
564  }
565 
566  // open the VBA project storage
567  OUString aVbaFragmentPath = getFragmentPathFromFirstType(CREATE_MSOFFICE_RELATION_TYPE("vbaProject"));
568  if (!aVbaFragmentPath.isEmpty())
569  {
570  uno::Reference<io::XInputStream> xInStrm = getFilter().openInputStream(aVbaFragmentPath);
571  if (xInStrm.is())
572  {
573  StorageRef xPrjStrg = std::make_shared<oox::ole::OleStorage>(getFilter().getComponentContext(), xInStrm, false);
574  getFilter().getVbaProject().importVbaProject(*xPrjStrg);
575  }
576  }
577 }
578 
579 // CT_Presentation
581 {
582  switch( aElementToken )
583  {
584  case PPT_TOKEN( presentation ):
585  case PPT_TOKEN( sldMasterIdLst ):
586  case PPT_TOKEN( notesMasterIdLst ):
587  case PPT_TOKEN( sldIdLst ):
588  return this;
589  case PPT_TOKEN( sldMasterId ):
590  maSlideMasterVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
591  return this;
592  case PPT_TOKEN( sldId ):
593  maSlidesVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
594  return this;
595  case PPT_TOKEN( notesMasterId ):
596  maNotesMasterVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
597  return this;
598  case PPT_TOKEN( sldSz ):
600  return this;
601  case PPT_TOKEN( notesSz ):
603  return this;
604  case PPT_TOKEN( custShowLst ):
605  return new CustomShowListContext( *this, maCustomShowList );
606  case PPT_TOKEN( defaultTextStyle ):
607  return new TextListStyleContext( *this, *mpTextListStyle );
608  case PPT_TOKEN( modifyVerifier ):
609  OUString sAlgorithmClass = rAttribs.getString(XML_cryptAlgorithmClass, OUString());
610  OUString sAlgorithmType = rAttribs.getString(XML_cryptAlgorithmType, OUString());
611  sal_Int32 nAlgorithmSid = rAttribs.getInteger(XML_cryptAlgorithmSid, 0);
612  sal_Int32 nSpinCount = rAttribs.getInteger(XML_spinCount, 0);
613  OUString sSalt = rAttribs.getString(XML_saltData, OUString());
614  OUString sHash = rAttribs.getString(XML_hashData, OUString());
615  if (sAlgorithmClass == "hash" && sAlgorithmType == "typeAny" && nAlgorithmSid != 0
616  && !sSalt.isEmpty() && !sHash.isEmpty())
617  {
618  OUString sAlgorithmName;
619  switch (nAlgorithmSid)
620  {
621  case 1:
622  sAlgorithmName = "MD2";
623  break;
624  case 2:
625  sAlgorithmName = "MD4";
626  break;
627  case 3:
628  sAlgorithmName = "MD5";
629  break;
630  case 4:
631  sAlgorithmName = "SHA-1";
632  break;
633  case 5:
634  sAlgorithmName = "MAC";
635  break;
636  case 6:
637  sAlgorithmName = "RIPEMD";
638  break;
639  case 7:
640  sAlgorithmName = "RIPEMD-160";
641  break;
642  case 9:
643  sAlgorithmName = "HMAC";
644  break;
645  case 12:
646  sAlgorithmName = "SHA-256";
647  break;
648  case 13:
649  sAlgorithmName = "SHA-384";
650  break;
651  case 14:
652  sAlgorithmName = "SHA-512";
653  break;
654  default:; // 8, 10, 11, any other value: Undefined.
655  }
656 
657  if (!sAlgorithmName.isEmpty())
658  {
659  uno::Sequence<beans::PropertyValue> aResult{
660  comphelper::makePropertyValue("algorithm-name", sAlgorithmName),
661  comphelper::makePropertyValue("salt", sSalt),
662  comphelper::makePropertyValue("iteration-count", nSpinCount),
663  comphelper::makePropertyValue("hash", sHash)
664  };
665  try
666  {
667  uno::Reference<beans::XPropertySet> xDocSettings(
668  getFilter().getModelFactory()->createInstance(
669  "com.sun.star.document.Settings"),
670  uno::UNO_QUERY);
671  xDocSettings->setPropertyValue("ModifyPasswordInfo", uno::Any(aResult));
672  }
673  catch (const uno::Exception&)
674  {
675  }
676  }
677  }
678  return this;
679  }
680  return this;
681 }
682 
683 void PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
684  const SlidePersistPtr& rSlidePersistPtr )
685 {
686  Reference< drawing::XDrawPage > xSlide( rSlidePersistPtr->getPage() );
687  SlidePersistPtr pMasterPersistPtr( rSlidePersistPtr->getMasterPersist() );
688  if ( pMasterPersistPtr )
689  {
690  // Setting "Layout" property adds extra title and outliner preset shapes to the master slide
691  Reference< drawing::XDrawPage > xMasterSlide(pMasterPersistPtr->getPage());
692  const int nCount = xMasterSlide->getCount();
693 
694  uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
695  xSet->setPropertyValue( "Layout", Any( pMasterPersistPtr->getLayoutFromValueToken() ) );
696 
697  while( nCount < xMasterSlide->getCount())
698  {
699  Reference< drawing::XShape > xShape;
700  xMasterSlide->getByIndex(xMasterSlide->getCount()-1) >>= xShape;
701  xMasterSlide->remove(xShape);
702  }
703  }
704  while( xSlide->getCount() )
705  {
706  Reference< drawing::XShape > xShape;
707  xSlide->getByIndex(0) >>= xShape;
708  xSlide->remove( xShape );
709  }
710 
711  Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
712  if ( xPropertySet.is() )
713  {
714  awt::Size& rPageSize( rSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
715  xPropertySet->setPropertyValue( "Width", Any( rPageSize.Width ) );
716  xPropertySet->setPropertyValue( "Height", Any( rPageSize.Height ) );
717 
718  oox::ppt::HeaderFooter aHeaderFooter( rSlidePersistPtr->getHeaderFooter() );
719  if ( !rSlidePersistPtr->isMasterPage() )
720  aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = false;
721  try
722  {
723  if ( rSlidePersistPtr->isNotesPage() )
724  xPropertySet->setPropertyValue( "IsHeaderVisible", Any( aHeaderFooter.mbHeader ) );
725  xPropertySet->setPropertyValue( "IsFooterVisible", Any( aHeaderFooter.mbFooter ) );
726  xPropertySet->setPropertyValue( "IsDateTimeVisible", Any( aHeaderFooter.mbDateTime ) );
727  xPropertySet->setPropertyValue( "IsPageNumberVisible", Any( aHeaderFooter.mbSlideNumber ) );
728  }
729  catch( uno::Exception& )
730  {
731  }
732  }
733  rSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
734  getFilter().importFragment( rxSlideFragmentHandler );
735 }
736 
737 }
738 
739 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::shared_ptr< Relations > RelationsRef
Definition: relations.hxx:63
URL aURL
sal_Int32 nIndex
sal_Int32 convertEmuToHmm(sal_Int64 nValue)
Converts the passed 64-bit integer value from EMUs to 1/100 mm.
static std::map< PredefinedClrSchemeId, OUString > PredefinedClrNames
Definition: clrscheme.hxx:52
const OUString & get_text() const
Definition: comments.hxx:83
OptValue< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
Returns the 32-bit signed integer value of the specified attribute (decimal).
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
sal_Int32 getIntY() const
Definition: comments.hxx:95
sal_Int16 nId
Definition: olehelper.cxx:97
OptValue< OUString > getString(sal_Int32 nAttrToken) const
Returns the string value of the specified attribute.
std::shared_ptr< T > make_shared(Args &&...args)
std::shared_ptr< StorageBase > StorageRef
Definition: storagebase.hxx:42
char const sHash[]
sal_Int32 getIntX() const
Definition: comments.hxx:91
virtual ~PresentationFragmentHandler() noexcept override
sal_Int32 size() const
std::array< TextParagraphProperties, NUM_TEXT_LIST_STYLE_ENTRIES > TextParagraphPropertiesArray
int nCount
void saveThemeToGrabBag(const oox::drawingml::ThemePtr &pThemePtr, sal_Int32 nThemeIdx)
void importCustomSlideShow(std::vector< CustomShow > &rCustomShowList)
::comphelper::SequenceAsHashMap & getFilterData() const
Returns the FilterData.
Definition: filterbase.cxx:245
OString sName
Definition: drawingml.cxx:3864
OUString getAuthor(const CommentAuthorList &list)
Definition: comments.cxx:68
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
#define TOOLS_WARN_EXCEPTION(area, stream)
awt::Size GetSize2D(const Reference< XFastAttributeList > &xAttribs)
converts the attributes from a CT_Size2D into an awt Size with 1/100thmm
const ::std::vector< OUString > & getCharVector() const
std::vector< TextField > TextFieldStack
#define CREATE_MSOFFICE_RELATION_TYPE(ascii)
Expands to an OUString containing an MS Office specific relation type created from the passed literal...
Definition: relations.hxx:46
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
float u
::oox::drawingml::TextListStylePtr mpTextListStyle
const css::util::DateTime & getDateTime() const
Definition: comments.hxx:87
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
Provides access to attribute values of an element.
const css::uno::Reference< css::frame::XModel > & getModel() const
Returns the document model (always existing).
Definition: filterbase.cxx:220
void setValues(const CommentAuthorList &list)
Definition: comments.cxx:18
exports com.sun.star. presentation
DefTokenId nToken
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 aElementToken, const AttributeList &rAttribs) override
Will be called to create a context handler for the passed element.
::rtl::Reference< FragmentHandler > FragmentHandlerRef
const css::uno::Reference< css::xml::sax::XFastAttributeList > & getFastAttributeList() const
Returns the wrapped com.sun.star.xml.sax.XFastAttributeList object.
std::shared_ptr< SlidePersist > SlidePersistPtr
void importSlide(const ::oox::core::FragmentHandlerRef &rSlideFragmentHandler, const oox::ppt::SlidePersistPtr &rPersist)
::rtl::Reference< OContentHelper > xContent
#define SAL_WARN(area, stream)
Reference< XModel > xModel
PresentationFragmentHandler(::oox::core::XmlFilterBase &rFilter, const OUString &rFragmentPath)
static std::map< PredefinedClrSchemeId, sal_Int32 > PredefinedClrTokens
std::shared_ptr< Theme > ThemePtr
bool m_bDetectedRangeSegmentation false
static void ResolveTextFields(XmlFilterBase const &rFilter)