Bump version to 24.04.3.4
[LibreOffice.git] / oox / source / ppt / presentationfragmenthandler.cxx
blob2e0f48bbae98ec984d6bd0229bbe34a9babc94f5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <comphelper/anytostring.hxx>
21 #include <comphelper/propertyvalue.hxx>
22 #include <comphelper/sequenceashashmap.hxx>
23 #include <o3tl/string_view.hxx>
24 #include <sal/log.hxx>
25 #include <tools/multisel.hxx>
26 #include <comphelper/diagnose_ex.hxx>
28 #include <frozen/bits/defines.h>
29 #include <frozen/bits/elsa_std.h>
30 #include <frozen/unordered_map.h>
32 #include <com/sun/star/container/XNamed.hpp>
33 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
34 #include <com/sun/star/drawing/XDrawPages.hpp>
35 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
36 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
37 #include <com/sun/star/frame/XModel.hpp>
38 #include <com/sun/star/io/XInputStream.hpp>
39 #include <com/sun/star/text/XTextField.hpp>
40 #include <com/sun/star/xml/dom/XDocument.hpp>
41 #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
42 #include <com/sun/star/presentation/XPresentationPage.hpp>
43 #include <com/sun/star/task/XStatusIndicator.hpp>
44 #include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
45 #include <com/sun/star/container/XIndexContainer.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
48 #include <com/sun/star/container/XNameContainer.hpp>
50 #include <oox/drawingml/theme.hxx>
51 #include <oox/drawingml/drawingmltypes.hxx>
52 #include <oox/drawingml/themefragmenthandler.hxx>
53 #include <drawingml/textliststylecontext.hxx>
54 #include <oox/helper/attributelist.hxx>
55 #include <oox/ole/olestorage.hxx>
56 #include <oox/ole/vbaproject.hxx>
57 #include <oox/ppt/pptshape.hxx>
58 #include <oox/ppt/presentationfragmenthandler.hxx>
59 #include <oox/ppt/slidefragmenthandler.hxx>
60 #include <oox/ppt/layoutfragmenthandler.hxx>
61 #include <oox/ppt/pptimport.hxx>
62 #include <oox/token/namespaces.hxx>
63 #include <oox/token/tokens.hxx>
65 #include <com/sun/star/office/XAnnotation.hpp>
66 #include <com/sun/star/office/XAnnotationAccess.hpp>
67 #include <ooxresid.hxx>
68 #include <strings.hrc>
70 using namespace ::com::sun::star;
71 using namespace ::oox::core;
72 using namespace ::oox::drawingml;
73 using namespace ::com::sun::star::uno;
74 using namespace ::com::sun::star::beans;
75 using namespace ::com::sun::star::drawing;
76 using namespace ::com::sun::star::presentation;
77 using namespace ::com::sun::star::xml::sax;
79 namespace oox::ppt
82 namespace
84 constexpr frozen::unordered_map<PredefinedClrSchemeId, sal_Int32, 12> constPredefinedClrTokens
86 { dk1, XML_dk1 },
87 { lt1, XML_lt1 },
88 { dk2, XML_dk2 },
89 { lt2, XML_lt2 },
90 { accent1, XML_accent1 },
91 { accent2, XML_accent2 },
92 { accent3, XML_accent3 },
93 { accent4, XML_accent4 },
94 { accent5, XML_accent5 },
95 { accent6, XML_accent6 },
96 { hlink, XML_hlink },
97 { folHlink, XML_folHlink }
100 sal_Int32 getPredefinedClrTokens(PredefinedClrSchemeId eID)
102 auto iterator = constPredefinedClrTokens.find(eID);
103 if (iterator == constPredefinedClrTokens.end())
104 return XML_TOKEN_INVALID;
105 return iterator->second;
107 } // end anonymous ns
109 PresentationFragmentHandler::PresentationFragmentHandler(XmlFilterBase& rFilter, const OUString& rFragmentPath)
110 : FragmentHandler2( rFilter, rFragmentPath )
111 , mpTextListStyle( std::make_shared<TextListStyle>() )
112 , mbCommentAuthorsRead(false)
114 TextParagraphPropertiesArray& rParagraphDefaultsVector( mpTextListStyle->getListStyle() );
115 for (auto & elem : rParagraphDefaultsVector)
117 // ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
118 // so this attribute needs to be set always
119 elem.getParaBottomMargin() = TextSpacing( 0 );
123 PresentationFragmentHandler::~PresentationFragmentHandler() noexcept
127 void PresentationFragmentHandler::importSlideNames(XmlFilterBase& rFilter, const std::vector<SlidePersistPtr>& rSlidePersist)
129 sal_Int32 nMaxPages = rSlidePersist.size();
130 for (sal_Int32 nPage = 0; nPage < nMaxPages; nPage++)
132 auto aShapeMap = rSlidePersist[nPage]->getShapeMap();
133 auto aIter = std::find_if(aShapeMap.begin(), aShapeMap.end(),
134 [](const std::pair<OUString, ShapePtr>& element) {
135 auto pShapePtr = element.second;
136 return (pShapePtr
137 && (pShapePtr->getSubType() == XML_title
138 || pShapePtr->getSubType() == XML_ctrTitle));
140 if (aIter != aShapeMap.end())
142 OUString aTitleText;
143 Reference<text::XTextRange> xText(aIter->second->getXShape(), UNO_QUERY_THROW);
144 aTitleText = xText->getString();
145 // just a magic value but we don't want to drop out slide names which are too long
146 if (aTitleText.getLength() > 63)
147 aTitleText = aTitleText.copy(0, 63);
148 bool bUseTitleAsSlideName = !aTitleText.isEmpty();
149 // check duplicated title name
150 if (bUseTitleAsSlideName)
152 sal_Int32 nCount = 1;
153 Reference<XDrawPagesSupplier> xDPS(rFilter.getModel(), UNO_QUERY_THROW);
154 Reference<XDrawPages> xDrawPages(xDPS->getDrawPages(), UNO_SET_THROW);
155 for (sal_Int32 i = 0; i < nPage; ++i)
157 Reference<XDrawPage> xDrawPage(xDrawPages->getByIndex(i), UNO_QUERY);
158 Reference<container::XNamed> xNamed(xDrawPage, UNO_QUERY_THROW);
159 std::u16string_view sRest;
160 if (o3tl::starts_with(xNamed->getName(), aTitleText, &sRest)
161 && (sRest.empty()
162 || (o3tl::starts_with(sRest, u" (") && o3tl::ends_with(sRest, u")")
163 && o3tl::toInt32(sRest.substr(2, sRest.size() - 3)) > 0)))
164 nCount++;
166 Reference<container::XNamed> xName(rSlidePersist[nPage]->getPage(), UNO_QUERY_THROW);
167 xName->setName(
168 aTitleText
169 + (nCount == 1 ? OUString("") : " (" + OUString::number(nCount) + ")"));
175 void PresentationFragmentHandler::importCustomSlideShow(std::vector<CustomShow>& rCustomShowList)
177 PowerPointImport& rFilter = dynamic_cast<PowerPointImport&>(getFilter());
178 Reference<frame::XModel> xModel(rFilter.getModel());
179 Reference<XDrawPagesSupplier> xDrawPagesSupplier(xModel, UNO_QUERY_THROW);
180 Reference<XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW);
182 Reference<css::lang::XSingleServiceFactory> mxShowFactory;
183 Reference<css::container::XNameContainer> mxShows;
184 Reference<XCustomPresentationSupplier> xShowsSupplier(xModel, UNO_QUERY);
185 if (xShowsSupplier.is())
187 mxShows = xShowsSupplier->getCustomPresentations();
188 mxShowFactory.set(mxShows, UNO_QUERY);
191 for (size_t i = 0; i < rCustomShowList.size(); ++i)
193 Reference<com::sun::star::container::XIndexContainer> xShow(mxShowFactory->createInstance(),
194 UNO_QUERY);
195 if (xShow.is())
197 static constexpr OUString sSlide = u"slides/slide"_ustr;
198 for (size_t j = 0; j < rCustomShowList[i].maSldLst.size(); ++j)
200 OUString sCustomSlide = rCustomShowList[i].maSldLst[j];
201 sal_Int32 nPageNumber = 0;
202 if (sCustomSlide.match(sSlide))
203 nPageNumber = o3tl::toInt32(sCustomSlide.subView(sSlide.getLength()));
205 Reference<XDrawPage> xPage;
206 xDrawPages->getByIndex(nPageNumber - 1) >>= xPage;
207 if (xPage.is())
208 xShow->insertByIndex(xShow->getCount(), Any(xPage));
211 Any aAny;
212 aAny <<= xShow;
213 mxShows->insertByName(rCustomShowList[i].maCustomShowName, aAny);
218 void PresentationFragmentHandler::importMasterSlide(const Reference<frame::XModel>& xModel,
219 PowerPointImport& rFilter,
220 const OUString& rMasterFragmentPath)
222 OUString aLayoutFragmentPath;
223 SlidePersistPtr pMasterPersistPtr;
224 Reference< drawing::XDrawPage > xMasterPage;
225 Reference< drawing::XMasterPagesSupplier > xMPS( xModel, uno::UNO_QUERY_THROW );
226 Reference< drawing::XDrawPages > xMasterPages( xMPS->getMasterPages(), uno::UNO_SET_THROW );
227 RelationsRef xMasterRelations = rFilter.importRelations( rMasterFragmentPath );
229 for (const auto& rEntry : *xMasterRelations)
231 if (!rEntry.second.maType.endsWith("relationships/slideLayout"))
232 continue;
234 aLayoutFragmentPath = xMasterRelations->getFragmentPathFromRelation(rEntry.second);
236 sal_Int32 nIndex;
237 if( rFilter.getMasterPages().empty() )
239 nIndex = 0;
240 xMasterPages->getByIndex( nIndex ) >>= xMasterPage;
242 else
244 nIndex = xMasterPages->getCount();
245 xMasterPage = xMasterPages->insertNewByIndex( nIndex );
248 pMasterPersistPtr = std::make_shared<SlidePersist>( rFilter, true, false, xMasterPage,
249 std::make_shared<PPTShape>( Master, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
250 pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
251 rFilter.getMasterPages().push_back( pMasterPersistPtr );
252 rFilter.setActualSlidePersist( pMasterPersistPtr );
253 FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, rMasterFragmentPath, pMasterPersistPtr, Master ) );
255 // set the correct theme
256 OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"theme" );
257 if( !aThemeFragmentPath.isEmpty() )
259 std::map< OUString, oox::drawingml::ThemePtr >& rThemes( rFilter.getThemes() );
260 std::map< OUString, oox::drawingml::ThemePtr >::iterator aIter2( rThemes.find( aThemeFragmentPath ) );
261 if( aIter2 == rThemes.end() )
263 oox::drawingml::ThemePtr pThemePtr = std::make_shared<oox::drawingml::Theme>();
264 pMasterPersistPtr->setTheme( pThemePtr );
265 Reference<xml::dom::XDocument> xDoc=
266 rFilter.importFragment(aThemeFragmentPath);
268 auto pTheme = std::make_shared<model::Theme>();
269 pThemePtr->setTheme(pTheme);
271 rFilter.importFragment(
272 new ThemeFragmentHandler(rFilter, aThemeFragmentPath, *pThemePtr, *pTheme),
273 Reference<xml::sax::XFastSAXSerializable>(
274 xDoc,
275 UNO_QUERY_THROW));
276 rThemes[ aThemeFragmentPath ] = pThemePtr;
277 pThemePtr->setFragment(xDoc);
278 saveThemeToGrabBag(pThemePtr, nIndex + 1);
280 else
282 pMasterPersistPtr->setTheme( (*aIter2).second );
285 importSlide( xMasterFragmentHandler, pMasterPersistPtr );
286 rFilter.importFragment( new LayoutFragmentHandler( rFilter, aLayoutFragmentPath, pMasterPersistPtr ) );
287 pMasterPersistPtr->createBackground( rFilter );
288 pMasterPersistPtr->createXShapes( rFilter );
290 uno::Reference< beans::XPropertySet > xSet(pMasterPersistPtr->getPage(), uno::UNO_QUERY_THROW);
291 xSet->setPropertyValue("SlideLayout", Any(pMasterPersistPtr->getLayoutFromValueToken()));
293 oox::drawingml::ThemePtr pTheme = pMasterPersistPtr->getTheme();
294 if (pTheme)
296 pTheme->addTheme(pMasterPersistPtr->getPage());
301 void PresentationFragmentHandler::saveThemeToGrabBag(const oox::drawingml::ThemePtr& pThemePtr,
302 sal_Int32 nThemeIdx)
304 if (!pThemePtr)
305 return;
309 uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
310 if (xDocProps.is())
312 uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
314 static constexpr OUString aGrabBagPropName = u"InteropGrabBag"_ustr;
315 if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
317 // get existing grab bag
318 comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
320 comphelper::SequenceAsHashMap aThemesHashMap;
322 // create current theme
323 uno::Sequence<beans::PropertyValue> aCurrentTheme(PredefinedClrSchemeId::Count);
324 auto pCurrentTheme = aCurrentTheme.getArray();
326 ClrScheme rClrScheme = pThemePtr->getClrScheme();
327 for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
329 auto eID = static_cast<PredefinedClrSchemeId>(nId);
330 sal_uInt32 nToken = getPredefinedClrTokens(eID);
331 OUString sName(getPredefinedClrNames(eID));
332 ::Color nColor;
334 rClrScheme.getColor(nToken, nColor);
335 const uno::Any& rColor = uno::Any(nColor);
337 pCurrentTheme[nId].Name = sName;
338 pCurrentTheme[nId].Value = rColor;
342 uno::Sequence<beans::PropertyValue> aTheme{
343 // add new theme to the sequence
344 // Export code uses the master slide's index to find the right theme
345 // so use the same index in the grabbag.
346 comphelper::makePropertyValue(
347 "ppt/theme/theme" + OUString::number(nThemeIdx) + ".xml", aCurrentTheme),
348 // store DOM fragment for SmartArt re-generation
349 comphelper::makePropertyValue("OOXTheme", pThemePtr->getFragment())
352 aThemesHashMap << aTheme;
354 // put the new items
355 aGrabBag.update(aThemesHashMap);
357 // put it back to the document
358 xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList()));
362 catch (const uno::Exception&)
364 SAL_WARN("oox", "oox::ppt::PresentationFragmentHandler::saveThemeToGrabBag, Failed to save grab bag");
368 void PresentationFragmentHandler::importMasterSlides()
370 OUString aMasterFragmentPath;
371 PowerPointImport& rFilter = dynamic_cast<PowerPointImport&>(getFilter());
372 Reference<frame::XModel> xModel(rFilter.getModel());
374 for (size_t nMaster = 0; nMaster < maSlideMasterVector.size(); ++nMaster)
376 aMasterFragmentPath = getFragmentPathFromRelId(maSlideMasterVector[nMaster]);
377 importMasterSlide(xModel, rFilter, aMasterFragmentPath);
381 void PresentationFragmentHandler::importSlide(sal_uInt32 nSlide, bool bFirstPage, bool bImportNotesPage)
383 PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
385 Reference< frame::XModel > xModel( rFilter.getModel() );
386 Reference< drawing::XDrawPage > xSlide;
388 // importing slide pages and its corresponding notes page
389 Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
390 Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_SET_THROW );
392 try {
394 if( bFirstPage )
396 xDrawPages->getByIndex( 0 ) >>= xSlide;
397 importMasterSlides();
399 else
400 xSlide = xDrawPages->insertNewByIndex( xDrawPages->getCount() );
402 OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] );
403 if( !aSlideFragmentPath.isEmpty() )
405 SlidePersistPtr pMasterPersistPtr;
406 SlidePersistPtr pSlidePersistPtr = std::make_shared<SlidePersist>( rFilter, false, false, xSlide,
407 std::make_shared<PPTShape>( Slide, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
409 FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( rFilter, aSlideFragmentPath, pSlidePersistPtr, Slide ) );
411 // importing the corresponding masterpage/layout
412 OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideLayout" );
413 OUString aCommentFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"comments" );
414 if ( !aLayoutFragmentPath.isEmpty() )
416 // importing layout
417 RelationsRef xLayoutRelations = rFilter.importRelations( aLayoutFragmentPath );
418 OUString aMasterFragmentPath = xLayoutRelations->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideMaster" );
419 if( !aMasterFragmentPath.isEmpty() )
421 // check if the corresponding masterpage+layout has already been imported
422 std::vector< SlidePersistPtr >& rMasterPages( rFilter.getMasterPages() );
423 for (auto const& masterPage : rMasterPages)
425 if ( ( masterPage->getPath() == aMasterFragmentPath ) && ( masterPage->getLayoutPath() == aLayoutFragmentPath ) )
427 pMasterPersistPtr = masterPage;
428 break;
434 // importing slide page
435 if (pMasterPersistPtr) {
436 pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
437 pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
438 Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
439 if( xMasterPageTarget.is() )
440 xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
442 rFilter.getDrawPages().push_back( pSlidePersistPtr );
443 rFilter.setActualSlidePersist( pSlidePersistPtr );
444 importSlide( xSlideFragmentHandler, pSlidePersistPtr );
445 pSlidePersistPtr->createBackground( rFilter );
446 pSlidePersistPtr->createXShapes( rFilter );
448 if(bImportNotesPage) {
450 // now importing the notes page
451 OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"notesSlide" );
452 if( !aNotesFragmentPath.isEmpty() )
454 Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
455 if ( xPresentationPage.is() )
457 Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
458 if ( xNotesPage.is() )
460 SlidePersistPtr pNotesPersistPtr = std::make_shared<SlidePersist>( rFilter, false, true, xNotesPage,
461 std::make_shared<PPTShape>( Slide, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
462 FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
463 rFilter.getNotesPages().push_back( pNotesPersistPtr );
464 rFilter.setActualSlidePersist( pNotesPersistPtr );
465 importSlide( xNotesFragmentHandler, pNotesPersistPtr );
466 pNotesPersistPtr->createBackground( rFilter );
467 pNotesPersistPtr->createXShapes( rFilter );
473 if( !mbCommentAuthorsRead && !aCommentFragmentPath.isEmpty() )
475 // Comments are present and commentAuthors.xml has still not been read
476 mbCommentAuthorsRead = true;
477 Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
478 Reference< XDrawPage > xCommentAuthorsPage( xPresentationPage->getNotesPage() );
479 SlidePersistPtr pCommentAuthorsPersistPtr =
480 std::make_shared<SlidePersist>( rFilter, false, true, xCommentAuthorsPage,
481 std::make_shared<PPTShape>(
482 Slide, "com.sun.star.drawing.GroupShape" ),
483 mpTextListStyle );
484 FragmentHandlerRef xCommentAuthorsFragmentHandler(
485 new SlideFragmentHandler( getFilter(),
486 "ppt/commentAuthors.xml",
487 pCommentAuthorsPersistPtr,
488 Slide ) );
490 getFilter().importFragment( xCommentAuthorsFragmentHandler );
491 maAuthorList.setValues( pCommentAuthorsPersistPtr->getCommentAuthors() );
493 if( !aCommentFragmentPath.isEmpty() )
495 Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
496 Reference< XDrawPage > xCommentsPage( xPresentationPage->getNotesPage() );
497 SlidePersistPtr pCommentsPersistPtr =
498 std::make_shared<SlidePersist>(
499 rFilter, false, true, xCommentsPage,
500 std::make_shared<PPTShape>(
501 Slide, "com.sun.star.drawing.GroupShape" ),
502 mpTextListStyle );
504 FragmentHandlerRef xCommentsFragmentHandler(
505 new SlideFragmentHandler(
506 getFilter(),
507 aCommentFragmentPath,
508 pCommentsPersistPtr,
509 Slide ) );
510 pCommentsPersistPtr->getCommentsList().cmLst.clear();
511 getFilter().importFragment( xCommentsFragmentHandler );
513 if (!pCommentsPersistPtr->getCommentsList().cmLst.empty())
515 //set comment chars for last comment on slide
516 SlideFragmentHandler* comment_handler =
517 dynamic_cast<SlideFragmentHandler*>(xCommentsFragmentHandler.get());
518 assert(comment_handler);
519 // some comments have no text -> set empty string as text to avoid
520 // crash (back() on empty vector is undefined) and losing other
521 // comment data that might be there (author, position, timestamp etc.)
522 pCommentsPersistPtr->getCommentsList().cmLst.back().setText(
523 comment_handler->getCharVector().empty() ? "" :
524 comment_handler->getCharVector().back() );
526 pCommentsPersistPtr->getCommentAuthors().setValues(maAuthorList);
528 //insert all comments from commentsList
529 for(int i=0; i<pCommentsPersistPtr->getCommentsList().getSize(); i++)
531 try {
532 Comment aComment = pCommentsPersistPtr->getCommentsList().getCommentAtIndex(i);
533 uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xSlide, UNO_QUERY_THROW );
534 uno::Reference< office::XAnnotation > xAnnotation( xAnnotationAccess->createAndInsertAnnotation() );
535 int nPosX = aComment.getIntX();
536 int nPosY = aComment.getIntY();
537 xAnnotation->setPosition(
538 geometry::RealPoint2D(
539 ::oox::drawingml::convertEmuToHmm( nPosX ) * 15.87,
540 ::oox::drawingml::convertEmuToHmm( nPosY ) * 15.87 ) );
541 xAnnotation->setAuthor( aComment.getAuthor(maAuthorList) );
542 xAnnotation->setDateTime( aComment.getDateTime() );
543 uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
544 xText->setString( aComment.get_text());
545 } catch( css::lang::IllegalArgumentException& ) {}
550 catch( uno::Exception& )
552 TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::EndDocument()" );
556 void PresentationFragmentHandler::finalizeImport()
558 PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
560 sal_Int32 nPageCount = maSlidesVector.size();
562 // we will take the FilterData property "PageRange" if available, otherwise full range is used
563 comphelper::SequenceAsHashMap& rFilterData = rFilter.getFilterData();
565 // writing back the original PageCount of this document, it can be accessed from the XModel
566 // via getArgs after the import.
567 rFilterData["OriginalPageCount"] <<= nPageCount;
568 bool bImportNotesPages = rFilterData.getUnpackedValueOrDefault("ImportNotesPages", true);
569 OUString aPageRange = rFilterData.getUnpackedValueOrDefault("PageRange", OUString());
571 if( !aPageRange.getLength() )
573 aPageRange = "1-" + OUString::number( nPageCount );
576 StringRangeEnumerator aRangeEnumerator( aPageRange, 0, nPageCount - 1 );
577 if (aRangeEnumerator.size())
579 // todo: localized progress bar text
580 const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
581 if ( rxStatusIndicator.is() )
582 rxStatusIndicator->start( OUString(), 10000 );
586 int nPagesImported = 0;
587 for (sal_Int32 elem : aRangeEnumerator)
589 if ( rxStatusIndicator.is() )
590 rxStatusIndicator->setValue((nPagesImported * 10000) / aRangeEnumerator.size());
592 importSlide(elem, !nPagesImported, bImportNotesPages);
593 nPagesImported++;
595 importSlideNames( rFilter, rFilter.getDrawPages());
596 if (!maCustomShowList.empty())
597 importCustomSlideShow(maCustomShowList);
599 catch( uno::Exception& )
601 TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::finalizeImport()" );
603 // todo error handling;
604 if ( rxStatusIndicator.is() )
605 rxStatusIndicator->end();
608 // open the VBA project storage
609 OUString aVbaFragmentPath = getFragmentPathFromFirstType(CREATE_MSOFFICE_RELATION_TYPE("vbaProject"));
610 if (!aVbaFragmentPath.isEmpty())
612 uno::Reference<io::XInputStream> xInStrm = getFilter().openInputStream(aVbaFragmentPath);
613 if (xInStrm.is())
615 StorageRef xPrjStrg = std::make_shared<oox::ole::OleStorage>(getFilter().getComponentContext(), xInStrm, false);
616 getFilter().getVbaProject().importVbaProject(*xPrjStrg);
621 // CT_Presentation
622 ::oox::core::ContextHandlerRef PresentationFragmentHandler::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
624 switch( aElementToken )
626 case PPT_TOKEN( presentation ):
627 case PPT_TOKEN( sldMasterIdLst ):
628 case PPT_TOKEN( notesMasterIdLst ):
629 case PPT_TOKEN( sldIdLst ):
630 return this;
631 case PPT_TOKEN( sldMasterId ):
632 maSlideMasterVector.push_back( rAttribs.getStringDefaulted( R_TOKEN( id )) );
633 return this;
634 case PPT_TOKEN( sldId ):
635 maSlidesVector.push_back( rAttribs.getStringDefaulted( R_TOKEN( id )) );
636 return this;
637 case PPT_TOKEN( notesMasterId ):
638 maNotesMasterVector.push_back( rAttribs.getStringDefaulted( R_TOKEN( id )) );
639 return this;
640 case PPT_TOKEN( sldSz ):
641 maSlideSize = GetSize2D( rAttribs.getFastAttributeList() );
642 return this;
643 case PPT_TOKEN( notesSz ):
644 maNotesSize = GetSize2D( rAttribs.getFastAttributeList() );
645 return this;
646 case PPT_TOKEN( custShowLst ):
647 return new CustomShowListContext( *this, maCustomShowList );
648 case PPT_TOKEN( defaultTextStyle ):
649 return new TextListStyleContext( *this, *mpTextListStyle );
650 case PPT_TOKEN( modifyVerifier ):
651 OUString sAlgorithmClass = rAttribs.getStringDefaulted(XML_cryptAlgorithmClass);
652 OUString sAlgorithmType = rAttribs.getStringDefaulted(XML_cryptAlgorithmType);
653 sal_Int32 nAlgorithmSid = rAttribs.getInteger(XML_cryptAlgorithmSid, 0);
654 sal_Int32 nSpinCount = rAttribs.getInteger(XML_spinCount, 0);
655 OUString sSalt = rAttribs.getStringDefaulted(XML_saltData);
656 OUString sHash = rAttribs.getStringDefaulted(XML_hashData);
657 if (sAlgorithmClass == "hash" && sAlgorithmType == "typeAny" && nAlgorithmSid != 0
658 && !sSalt.isEmpty() && !sHash.isEmpty())
660 OUString sAlgorithmName;
661 switch (nAlgorithmSid)
663 case 1:
664 sAlgorithmName = "MD2";
665 break;
666 case 2:
667 sAlgorithmName = "MD4";
668 break;
669 case 3:
670 sAlgorithmName = "MD5";
671 break;
672 case 4:
673 sAlgorithmName = "SHA-1";
674 break;
675 case 5:
676 sAlgorithmName = "MAC";
677 break;
678 case 6:
679 sAlgorithmName = "RIPEMD";
680 break;
681 case 7:
682 sAlgorithmName = "RIPEMD-160";
683 break;
684 case 9:
685 sAlgorithmName = "HMAC";
686 break;
687 case 12:
688 sAlgorithmName = "SHA-256";
689 break;
690 case 13:
691 sAlgorithmName = "SHA-384";
692 break;
693 case 14:
694 sAlgorithmName = "SHA-512";
695 break;
696 default:; // 8, 10, 11, any other value: Undefined.
699 if (!sAlgorithmName.isEmpty())
701 uno::Sequence<beans::PropertyValue> aResult{
702 comphelper::makePropertyValue("algorithm-name", sAlgorithmName),
703 comphelper::makePropertyValue("salt", sSalt),
704 comphelper::makePropertyValue("iteration-count", nSpinCount),
705 comphelper::makePropertyValue("hash", sHash)
709 uno::Reference<beans::XPropertySet> xDocSettings(
710 getFilter().getModelFactory()->createInstance(
711 "com.sun.star.document.Settings"),
712 uno::UNO_QUERY);
713 xDocSettings->setPropertyValue("ModifyPasswordInfo", uno::Any(aResult));
715 catch (const uno::Exception&)
720 return this;
722 return this;
725 void PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
726 const SlidePersistPtr& rSlidePersistPtr )
728 Reference< drawing::XDrawPage > xSlide( rSlidePersistPtr->getPage() );
729 SlidePersistPtr pMasterPersistPtr( rSlidePersistPtr->getMasterPersist() );
730 if ( pMasterPersistPtr )
732 // Setting "Layout" property adds extra title and outliner preset shapes to the master slide
733 Reference< drawing::XDrawPage > xMasterSlide(pMasterPersistPtr->getPage());
734 const int nCount = xMasterSlide->getCount();
736 uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
737 xSet->setPropertyValue( "Layout", Any( pMasterPersistPtr->getLayoutFromValueToken() ) );
739 while( nCount < xMasterSlide->getCount())
741 Reference< drawing::XShape > xShape;
742 xMasterSlide->getByIndex(xMasterSlide->getCount()-1) >>= xShape;
743 xMasterSlide->remove(xShape);
746 while( xSlide->getCount() )
748 Reference< drawing::XShape > xShape;
749 xSlide->getByIndex(0) >>= xShape;
750 xSlide->remove( xShape );
753 Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
754 if ( xPropertySet.is() )
756 awt::Size& rPageSize( rSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
757 xPropertySet->setPropertyValue( "Width", Any( rPageSize.Width ) );
758 xPropertySet->setPropertyValue( "Height", Any( rPageSize.Height ) );
760 oox::ppt::HeaderFooter aHeaderFooter( rSlidePersistPtr->getHeaderFooter() );
761 if ( !rSlidePersistPtr->isMasterPage() )
762 aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = false;
765 if ( rSlidePersistPtr->isNotesPage() )
766 xPropertySet->setPropertyValue( "IsHeaderVisible", Any( aHeaderFooter.mbHeader ) );
767 xPropertySet->setPropertyValue( "IsFooterVisible", Any( aHeaderFooter.mbFooter ) );
768 xPropertySet->setPropertyValue( "IsDateTimeVisible", Any( aHeaderFooter.mbDateTime ) );
769 xPropertySet->setPropertyValue( "IsPageNumberVisible", Any( aHeaderFooter.mbSlideNumber ) );
771 catch( uno::Exception& )
775 rSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
776 getFilter().importFragment( rxSlideFragmentHandler );
781 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */