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/XMultiServiceFactory.hpp>
41 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
42 #include <com/sun/star/container/XNameContainer.hpp>
43 
44 #include <oox/drawingml/theme.hxx>
49 #include <oox/ole/olestorage.hxx>
50 #include <oox/ole/vbaproject.hxx>
51 #include <oox/ppt/pptshape.hxx>
55 #include <oox/ppt/pptimport.hxx>
56 #include <oox/token/namespaces.hxx>
57 #include <oox/token/tokens.hxx>
58 
59 #include <com/sun/star/office/XAnnotation.hpp>
60 #include <com/sun/star/office/XAnnotationAccess.hpp>
61 
62 using namespace ::com::sun::star;
63 using namespace ::oox::core;
64 using namespace ::oox::drawingml;
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::beans;
67 using namespace ::com::sun::star::drawing;
68 using namespace ::com::sun::star::presentation;
69 using namespace ::com::sun::star::xml::sax;
70 
71 namespace oox::ppt {
72 
73 static std::map<PredefinedClrSchemeId, sal_Int32> PredefinedClrTokens =
74 {
75  //{ dk1, XML_dk1 },
76  //{ lt1, XML_lt1 },
77  { dk2, XML_dk2 },
78  { lt2, XML_lt2 },
79  { accent1, XML_accent1 },
80  { accent2, XML_accent2 },
81  { accent3, XML_accent3 },
82  { accent4, XML_accent4 },
83  { accent5, XML_accent5 },
84  { accent6, XML_accent6 },
85  { hlink, XML_hlink },
86  { folHlink, XML_folHlink }
87 };
88 
89 PresentationFragmentHandler::PresentationFragmentHandler(XmlFilterBase& rFilter, const OUString& rFragmentPath)
90  : FragmentHandler2( rFilter, rFragmentPath )
91  , mpTextListStyle( std::make_shared<TextListStyle>() )
92  , mbCommentAuthorsRead(false)
93 {
94  TextParagraphPropertiesArray& rParagraphDefaultsVector( mpTextListStyle->getListStyle() );
95  for (auto & elem : rParagraphDefaultsVector)
96  {
97  // ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
98  // so this attribute needs to be set always
99  elem.getParaBottomMargin() = TextSpacing( 0 );
100  }
101 }
102 
104 {
105 }
106 
107 static void ResolveTextFields( XmlFilterBase const & rFilter )
108 {
109  const oox::core::TextFieldStack& rTextFields = rFilter.getTextFieldStack();
110  if ( rTextFields.empty() )
111  return;
112 
113  const Reference< frame::XModel >& xModel( rFilter.getModel() );
114  for (auto const& textField : rTextFields)
115  {
116  static const OUStringLiteral sURL = u"URL";
117  Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
118  Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_SET_THROW );
119 
120  const oox::core::TextField& rTextField( textField );
121  Reference< XPropertySet > xPropSet( rTextField.xTextField, UNO_QUERY );
122  Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
123  if ( xPropSetInfo->hasPropertyByName( sURL ) )
124  {
125  OUString aURL;
126  if ( xPropSet->getPropertyValue( sURL ) >>= aURL )
127  {
128  static const OUStringLiteral sSlide = u"#Slide ";
129  static const OUStringLiteral sNotes = u"#Notes ";
130  bool bNotes = false;
131  sal_Int32 nPageNumber = 0;
132  if ( aURL.match( sSlide ) )
133  nPageNumber = aURL.copy( sSlide.getLength() ).toInt32();
134  else if ( aURL.match( sNotes ) )
135  {
136  nPageNumber = aURL.copy( sNotes.getLength() ).toInt32();
137  bNotes = true;
138  }
139  if ( nPageNumber )
140  {
141  try
142  {
143  Reference< XDrawPage > xDrawPage;
144  xDrawPages->getByIndex( nPageNumber - 1 ) >>= xDrawPage;
145  if ( bNotes )
146  {
147  Reference< css::presentation::XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
148  xDrawPage = xPresentationPage->getNotesPage();
149  }
150  Reference< container::XNamed > xNamed( xDrawPage, UNO_QUERY_THROW );
151  aURL = "#" + xNamed->getName();
152  xPropSet->setPropertyValue( sURL, Any( aURL ) );
153  Reference< text::XTextContent > xContent( rTextField.xTextField);
154  Reference< text::XTextRange > xTextRange = rTextField.xTextCursor;
155  rTextField.xText->insertTextContent( xTextRange, xContent, true );
156  }
157  catch( uno::Exception& )
158  {
159  }
160  }
161  }
162  }
163  }
164 }
165 
166 void PresentationFragmentHandler::importCustomSlideShow(std::vector<CustomShow>& rCustomShowList)
167 {
168  PowerPointImport& rFilter = dynamic_cast<PowerPointImport&>(getFilter());
170  Reference<XDrawPagesSupplier> xDrawPagesSupplier(xModel, UNO_QUERY_THROW);
171  Reference<XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW);
172 
173  Reference<css::lang::XSingleServiceFactory> mxShowFactory;
174  Reference<css::container::XNameContainer> mxShows;
175  Reference<XCustomPresentationSupplier> xShowsSupplier(xModel, UNO_QUERY);
176  if (xShowsSupplier.is())
177  {
178  mxShows = xShowsSupplier->getCustomPresentations();
179  mxShowFactory.set(mxShows, UNO_QUERY);
180  }
181 
182  for (size_t i = 0; i < rCustomShowList.size(); ++i)
183  {
184  Reference<com::sun::star::container::XIndexContainer> xShow(mxShowFactory->createInstance(),
185  UNO_QUERY);
186  if (xShow.is())
187  {
188  static const OUStringLiteral sSlide = u"slides/slide";
189  for (size_t j = 0; j < rCustomShowList[i].maSldLst.size(); ++j)
190  {
191  OUString sCustomSlide = rCustomShowList[i].maSldLst[j];
192  sal_Int32 nPageNumber = 0;
193  if (sCustomSlide.match(sSlide))
194  nPageNumber = sCustomSlide.copy(sSlide.getLength()).toInt32();
195 
196  Reference<XDrawPage> xPage;
197  xDrawPages->getByIndex(nPageNumber - 1) >>= xPage;
198  if (xPage.is())
199  xShow->insertByIndex(xShow->getCount(), Any(xPage));
200  }
201 
202  Any aAny;
203  aAny <<= xShow;
204  mxShows->insertByName(rCustomShowList[i].maCustomShowName, aAny);
205  }
206  }
207 }
208 
210  sal_Int32 nThemeIdx)
211 {
212  if (!pThemePtr)
213  return;
214 
215  try
216  {
217  uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
218  if (xDocProps.is())
219  {
220  uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
221 
222  static const OUStringLiteral aGrabBagPropName = u"InteropGrabBag";
223  if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
224  {
225  // get existing grab bag
226  comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
227 
228  uno::Sequence<beans::PropertyValue> aTheme(2);
229  comphelper::SequenceAsHashMap aThemesHashMap;
230 
231  // create current theme
232  uno::Sequence<beans::PropertyValue> aCurrentTheme(PredefinedClrSchemeId::Count);
233 
234  ClrScheme rClrScheme = pThemePtr->getClrScheme();
236  {
237  sal_uInt32 nToken = PredefinedClrTokens[static_cast<PredefinedClrSchemeId>(nId)];
238  const OUString& sName = PredefinedClrNames[static_cast<PredefinedClrSchemeId>(nId)];
239  ::Color nColor;
240 
241  rClrScheme.getColor(nToken, nColor);
242  const uno::Any& rColor = uno::makeAny(nColor);
243 
244  aCurrentTheme[nId].Name = sName;
245  aCurrentTheme[nId].Value = rColor;
246  }
247 
248 
249  // add new theme to the sequence
250  // Export code uses the master slide's index to find the right theme
251  // so use the same index in the grabbag.
252  aTheme[0].Name = "ppt/theme/theme" + OUString::number(nThemeIdx) + ".xml";
253  const uno::Any& rCurrentTheme = makeAny(aCurrentTheme);
254  aTheme[0].Value = rCurrentTheme;
255 
256  // store DOM fragment for SmartArt re-generation
257  aTheme[1].Name = "OOXTheme";
258  const uno::Any& rOOXTheme = makeAny(pThemePtr->getFragment());
259  aTheme[1].Value = rOOXTheme;
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  }
384  }
385 
386  // importing slide page
387  if (pMasterPersistPtr) {
388  pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
389  pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
390  Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
391  if( xMasterPageTarget.is() )
392  xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
393  }
394  rFilter.getDrawPages().push_back( pSlidePersistPtr );
395  rFilter.setActualSlidePersist( pSlidePersistPtr );
396  importSlide( xSlideFragmentHandler, pSlidePersistPtr );
397  pSlidePersistPtr->createBackground( rFilter );
398  pSlidePersistPtr->createXShapes( rFilter );
399 
400  if(bImportNotesPage) {
401 
402  // now importing the notes page
403  OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"notesSlide" );
404  if( !aNotesFragmentPath.isEmpty() )
405  {
406  Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
407  if ( xPresentationPage.is() )
408  {
409  Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
410  if ( xNotesPage.is() )
411  {
412  SlidePersistPtr pNotesPersistPtr = std::make_shared<SlidePersist>( rFilter, false, true, xNotesPage,
413  std::make_shared<PPTShape>( Slide, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
414  FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
415  rFilter.getNotesPages().push_back( pNotesPersistPtr );
416  rFilter.setActualSlidePersist( pNotesPersistPtr );
417  importSlide( xNotesFragmentHandler, pNotesPersistPtr );
418  pNotesPersistPtr->createBackground( rFilter );
419  pNotesPersistPtr->createXShapes( rFilter );
420  }
421  }
422  }
423  }
424 
425  if( !mbCommentAuthorsRead && !aCommentFragmentPath.isEmpty() )
426  {
427  // Comments are present and commentAuthors.xml has still not been read
428  mbCommentAuthorsRead = true;
429  Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
430  Reference< XDrawPage > xCommentAuthorsPage( xPresentationPage->getNotesPage() );
431  SlidePersistPtr pCommentAuthorsPersistPtr =
432  std::make_shared<SlidePersist>( rFilter, false, true, xCommentAuthorsPage,
433  std::make_shared<PPTShape>(
434  Slide, "com.sun.star.drawing.GroupShape" ),
435  mpTextListStyle );
436  FragmentHandlerRef xCommentAuthorsFragmentHandler(
437  new SlideFragmentHandler( getFilter(),
438  "ppt/commentAuthors.xml",
439  pCommentAuthorsPersistPtr,
440  Slide ) );
441 
442  getFilter().importFragment( xCommentAuthorsFragmentHandler );
443  maAuthorList.setValues( pCommentAuthorsPersistPtr->getCommentAuthors() );
444  }
445  if( !aCommentFragmentPath.isEmpty() )
446  {
447  Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
448  Reference< XDrawPage > xCommentsPage( xPresentationPage->getNotesPage() );
449  SlidePersistPtr pCommentsPersistPtr =
450  std::make_shared<SlidePersist>(
451  rFilter, false, true, xCommentsPage,
452  std::make_shared<PPTShape>(
453  Slide, "com.sun.star.drawing.GroupShape" ),
454  mpTextListStyle );
455 
456  FragmentHandlerRef xCommentsFragmentHandler(
458  getFilter(),
459  aCommentFragmentPath,
460  pCommentsPersistPtr,
461  Slide ) );
462  pCommentsPersistPtr->getCommentsList().cmLst.clear();
463  getFilter().importFragment( xCommentsFragmentHandler );
464 
465  if (!pCommentsPersistPtr->getCommentsList().cmLst.empty())
466  {
467  //set comment chars for last comment on slide
468  SlideFragmentHandler* comment_handler =
469  dynamic_cast<SlideFragmentHandler*>(xCommentsFragmentHandler.get());
470  assert(comment_handler);
471  // some comments have no text -> set empty string as text to avoid
472  // crash (back() on empty vector is undefined) and losing other
473  // comment data that might be there (author, position, timestamp etc.)
474  pCommentsPersistPtr->getCommentsList().cmLst.back().setText(
475  comment_handler->getCharVector().empty() ? "" :
476  comment_handler->getCharVector().back() );
477  }
478  pCommentsPersistPtr->getCommentAuthors().setValues(maAuthorList);
479 
480  //insert all comments from commentsList
481  for(int i=0; i<pCommentsPersistPtr->getCommentsList().getSize(); i++)
482  {
483  try {
484  Comment aComment = pCommentsPersistPtr->getCommentsList().getCommentAtIndex(i);
485  uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xSlide, UNO_QUERY_THROW );
486  uno::Reference< office::XAnnotation > xAnnotation( xAnnotationAccess->createAndInsertAnnotation() );
487  int nPosX = aComment.getIntX();
488  int nPosY = aComment.getIntY();
489  xAnnotation->setPosition(
490  geometry::RealPoint2D(
491  ::oox::drawingml::convertEmuToHmm( nPosX ) * 15.87,
492  ::oox::drawingml::convertEmuToHmm( nPosY ) * 15.87 ) );
493  xAnnotation->setAuthor( aComment.getAuthor(maAuthorList) );
494  xAnnotation->setDateTime( aComment.getDateTime() );
495  uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
496  xText->setString( aComment.get_text());
497  } catch( css::lang::IllegalArgumentException& ) {}
498  }
499  }
500  }
501  }
502  catch( uno::Exception& )
503  {
504  TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::EndDocument()" );
505  }
506 }
507 
509 {
510  PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
511 
512  sal_Int32 nPageCount = maSlidesVector.size();
513 
514  // we will take the FilterData property "PageRange" if available, otherwise full range is used
515  comphelper::SequenceAsHashMap& rFilterData = rFilter.getFilterData();
516 
517  // writing back the original PageCount of this document, it can be accessed from the XModel
518  // via getArgs after the import.
519  rFilterData["OriginalPageCount"] <<= nPageCount;
520  bool bImportNotesPages = rFilterData.getUnpackedValueOrDefault("ImportNotesPages", true);
521  OUString aPageRange = rFilterData.getUnpackedValueOrDefault("PageRange", OUString());
522 
523  if( !aPageRange.getLength() )
524  {
525  aPageRange = "1-" + OUString::number( nPageCount );
526  }
527 
528  StringRangeEnumerator aRangeEnumerator( aPageRange, 0, nPageCount - 1 );
529  if (aRangeEnumerator.size())
530  {
531  // todo: localized progress bar text
532  const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
533  if ( rxStatusIndicator.is() )
534  rxStatusIndicator->start( OUString(), 10000 );
535 
536  try
537  {
538  int nPagesImported = 0;
539  for (sal_Int32 elem : aRangeEnumerator)
540  {
541  if ( rxStatusIndicator.is() )
542  rxStatusIndicator->setValue((nPagesImported * 10000) / aRangeEnumerator.size());
543 
544  importSlide(elem, !nPagesImported, bImportNotesPages);
545  nPagesImported++;
546  }
547  ResolveTextFields( rFilter );
548  if (!maCustomShowList.empty())
550  }
551  catch( uno::Exception& )
552  {
553  TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::finalizeImport()" );
554  }
555  // todo error handling;
556  if ( rxStatusIndicator.is() )
557  rxStatusIndicator->end();
558  }
559 
560  // open the VBA project storage
561  OUString aVbaFragmentPath = getFragmentPathFromFirstType(CREATE_MSOFFICE_RELATION_TYPE("vbaProject"));
562  if (!aVbaFragmentPath.isEmpty())
563  {
564  uno::Reference<io::XInputStream> xInStrm = getFilter().openInputStream(aVbaFragmentPath);
565  if (xInStrm.is())
566  {
567  StorageRef xPrjStrg = std::make_shared<oox::ole::OleStorage>(getFilter().getComponentContext(), xInStrm, false);
568  getFilter().getVbaProject().importVbaProject(*xPrjStrg);
569  }
570  }
571 }
572 
573 // CT_Presentation
575 {
576  switch( aElementToken )
577  {
578  case PPT_TOKEN( presentation ):
579  case PPT_TOKEN( sldMasterIdLst ):
580  case PPT_TOKEN( notesMasterIdLst ):
581  case PPT_TOKEN( sldIdLst ):
582  return this;
583  case PPT_TOKEN( sldMasterId ):
584  maSlideMasterVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
585  return this;
586  case PPT_TOKEN( sldId ):
587  maSlidesVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
588  return this;
589  case PPT_TOKEN( notesMasterId ):
590  maNotesMasterVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
591  return this;
592  case PPT_TOKEN( sldSz ):
594  return this;
595  case PPT_TOKEN( notesSz ):
597  return this;
598  case PPT_TOKEN( custShowLst ):
599  return new CustomShowListContext( *this, maCustomShowList );
600  case PPT_TOKEN( defaultTextStyle ):
601  return new TextListStyleContext( *this, *mpTextListStyle );
602  case PPT_TOKEN( modifyVerifier ):
603  OUString sAlgorithmClass = rAttribs.getString(XML_cryptAlgorithmClass, OUString());
604  OUString sAlgorithmType = rAttribs.getString(XML_cryptAlgorithmType, OUString());
605  sal_Int32 nAlgorithmSid = rAttribs.getInteger(XML_cryptAlgorithmSid, 0);
606  sal_Int32 nSpinCount = rAttribs.getInteger(XML_spinCount, 0);
607  OUString sSalt = rAttribs.getString(XML_saltData, OUString());
608  OUString sHash = rAttribs.getString(XML_hashData, OUString());
609  if (sAlgorithmClass == "hash" && sAlgorithmType == "typeAny" && nAlgorithmSid != 0
610  && !sSalt.isEmpty() && !sHash.isEmpty())
611  {
612  OUString sAlgorithmName;
613  switch (nAlgorithmSid)
614  {
615  case 1:
616  sAlgorithmName = "MD2";
617  break;
618  case 2:
619  sAlgorithmName = "MD4";
620  break;
621  case 3:
622  sAlgorithmName = "MD5";
623  break;
624  case 4:
625  sAlgorithmName = "SHA-1";
626  break;
627  case 5:
628  sAlgorithmName = "MAC";
629  break;
630  case 6:
631  sAlgorithmName = "RIPEMD";
632  break;
633  case 7:
634  sAlgorithmName = "RIPEMD-160";
635  break;
636  case 9:
637  sAlgorithmName = "HMAC";
638  break;
639  case 12:
640  sAlgorithmName = "SHA-256";
641  break;
642  case 13:
643  sAlgorithmName = "SHA-384";
644  break;
645  case 14:
646  sAlgorithmName = "SHA-512";
647  break;
648  default:; // 8, 10, 11, any other value: Undefined.
649  }
650 
651  if (!sAlgorithmName.isEmpty())
652  {
653  uno::Sequence<beans::PropertyValue> aResult;
654  aResult.realloc(4);
655  aResult[0].Name = "algorithm-name";
656  aResult[0].Value <<= sAlgorithmName;
657  aResult[1].Name = "salt";
658  aResult[1].Value <<= sSalt;
659  aResult[2].Name = "iteration-count";
660  aResult[2].Value <<= nSpinCount;
661  aResult[3].Name = "hash";
662  aResult[3].Value <<= sHash;
663  try
664  {
665  uno::Reference<beans::XPropertySet> xDocSettings(
666  getFilter().getModelFactory()->createInstance(
667  "com.sun.star.document.Settings"),
668  uno::UNO_QUERY);
669  xDocSettings->setPropertyValue("ModifyPasswordInfo", uno::makeAny(aResult));
670  }
671  catch (const uno::Exception&)
672  {
673  }
674  }
675  }
676  return this;
677  }
678  return this;
679 }
680 
681 void PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
682  const SlidePersistPtr& rSlidePersistPtr )
683 {
684  Reference< drawing::XDrawPage > xSlide( rSlidePersistPtr->getPage() );
685  SlidePersistPtr pMasterPersistPtr( rSlidePersistPtr->getMasterPersist() );
686  if ( pMasterPersistPtr )
687  {
688  // Setting "Layout" property adds extra title and outliner preset shapes to the master slide
689  Reference< drawing::XDrawPage > xMasterSlide(pMasterPersistPtr->getPage());
690  const int nCount = xMasterSlide->getCount();
691 
692  uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
693  xSet->setPropertyValue( "Layout", Any( pMasterPersistPtr->getLayoutFromValueToken() ) );
694 
695  while( nCount < xMasterSlide->getCount())
696  {
697  Reference< drawing::XShape > xShape;
698  xMasterSlide->getByIndex(xMasterSlide->getCount()-1) >>= xShape;
699  xMasterSlide->remove(xShape);
700  }
701  }
702  while( xSlide->getCount() )
703  {
704  Reference< drawing::XShape > xShape;
705  xSlide->getByIndex(0) >>= xShape;
706  xSlide->remove( xShape );
707  }
708 
709  Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
710  if ( xPropertySet.is() )
711  {
712  awt::Size& rPageSize( rSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
713  xPropertySet->setPropertyValue( "Width", Any( rPageSize.Width ) );
714  xPropertySet->setPropertyValue( "Height", Any( rPageSize.Height ) );
715 
716  oox::ppt::HeaderFooter aHeaderFooter( rSlidePersistPtr->getHeaderFooter() );
717  if ( !rSlidePersistPtr->isMasterPage() )
718  aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = false;
719  try
720  {
721  if ( rSlidePersistPtr->isNotesPage() )
722  xPropertySet->setPropertyValue( "IsHeaderVisible", Any( aHeaderFooter.mbHeader ) );
723  xPropertySet->setPropertyValue( "IsFooterVisible", Any( aHeaderFooter.mbFooter ) );
724  xPropertySet->setPropertyValue( "IsDateTimeVisible", Any( aHeaderFooter.mbDateTime ) );
725  xPropertySet->setPropertyValue( "IsPageNumberVisible", Any( aHeaderFooter.mbSlideNumber ) );
726  }
727  catch( uno::Exception& )
728  {
729  }
730  }
731  rSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
732  getFilter().importFragment( rxSlideFragmentHandler );
733 }
734 
735 }
736 
737 /* 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
OptValue< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
Returns the 32-bit signed integer value of the specified attribute (decimal).
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
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:242
void update(const SequenceAsHashMap &rSource)
OUString getAuthor(const CommentAuthorList &list)
Definition: comments.cxx:67
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
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:17
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)
#define SAL_WARN(area, stream)
Reference< XModel > xModel
PresentationFragmentHandler(::oox::core::XmlFilterBase &rFilter, const OUString &rFragmentPath)
static std::map< PredefinedClrSchemeId, sal_Int32 > PredefinedClrTokens
uno::Reference< ucb::XContent > xContent
std::shared_ptr< Theme > ThemePtr
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)
static void ResolveTextFields(XmlFilterBase const &rFilter)