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