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