Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/ppt/presentationfragmenthandler.cxx
Line
Count
Source
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
20
#include <sal/config.h>
21
22
#include <unordered_set>
23
24
#include <comphelper/anytostring.hxx>
25
#include <comphelper/propertyvalue.hxx>
26
#include <comphelper/sequence.hxx>
27
#include <comphelper/sequenceashashmap.hxx>
28
#include <o3tl/string_view.hxx>
29
#include <sal/log.hxx>
30
#include <tools/multisel.hxx>
31
#include <comphelper/diagnose_ex.hxx>
32
33
#include <frozen/bits/defines.h>
34
#include <frozen/bits/elsa_std.h>
35
#include <frozen/unordered_map.h>
36
37
#include <com/sun/star/container/XNamed.hpp>
38
#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
39
#include <com/sun/star/drawing/XDrawPages.hpp>
40
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
41
#include <com/sun/star/drawing/XMasterPageTarget.hpp>
42
#include <com/sun/star/frame/XModel.hpp>
43
#include <com/sun/star/io/XInputStream.hpp>
44
#include <com/sun/star/text/XTextField.hpp>
45
#include <com/sun/star/xml/dom/XDocument.hpp>
46
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
47
#include <com/sun/star/presentation/XPresentationPage.hpp>
48
#include <com/sun/star/task/XStatusIndicator.hpp>
49
#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
50
#include <com/sun/star/container/XIndexContainer.hpp>
51
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
52
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
53
#include <com/sun/star/container/XNameContainer.hpp>
54
55
#include <oox/drawingml/theme.hxx>
56
#include <oox/drawingml/drawingmltypes.hxx>
57
#include <oox/drawingml/themefragmenthandler.hxx>
58
#include <drawingml/textliststylecontext.hxx>
59
#include <oox/helper/attributelist.hxx>
60
#include <oox/ole/olestorage.hxx>
61
#include <oox/ole/vbaproject.hxx>
62
#include <oox/ppt/pptshape.hxx>
63
#include <oox/ppt/presentationfragmenthandler.hxx>
64
#include <oox/ppt/slidefragmenthandler.hxx>
65
#include <oox/ppt/layoutfragmenthandler.hxx>
66
#include <oox/ppt/pptimport.hxx>
67
#include <oox/token/namespaces.hxx>
68
#include <oox/token/tokens.hxx>
69
#include <sax/fastattribs.hxx>
70
71
#include <com/sun/star/office/XAnnotation.hpp>
72
#include <com/sun/star/office/XAnnotationAccess.hpp>
73
#include <ooxresid.hxx>
74
#include <strings.hrc>
75
76
#include "EmbeddedFontListContext.hxx"
77
78
using namespace ::com::sun::star;
79
using namespace ::oox::core;
80
using namespace ::oox::drawingml;
81
using namespace ::com::sun::star::uno;
82
using namespace ::com::sun::star::beans;
83
using namespace ::com::sun::star::drawing;
84
using namespace ::com::sun::star::presentation;
85
using namespace ::com::sun::star::xml::sax;
86
87
namespace oox::ppt
88
{
89
90
namespace
91
{
92
constexpr auto constPredefinedClrTokens = frozen::make_unordered_map<PredefinedClrSchemeId, sal_Int32>
93
({
94
    { dk1, XML_dk1 },
95
    { lt1, XML_lt1 },
96
    { dk2, XML_dk2 },
97
    { lt2, XML_lt2 },
98
    { accent1, XML_accent1 },
99
    { accent2, XML_accent2 },
100
    { accent3, XML_accent3 },
101
    { accent4, XML_accent4 },
102
    { accent5, XML_accent5 },
103
    { accent6, XML_accent6 },
104
    { hlink, XML_hlink },
105
    { folHlink, XML_folHlink }
106
});
107
108
sal_Int32 getPredefinedClrTokens(PredefinedClrSchemeId eID)
109
19.8k
{
110
19.8k
    auto iterator = constPredefinedClrTokens.find(eID);
111
19.8k
    if (iterator == constPredefinedClrTokens.end())
112
0
        return XML_TOKEN_INVALID;
113
19.8k
    return iterator->second;
114
19.8k
}
115
116
/** Reads a slide master's <p:sldLayoutIdLst> */
117
class SldLayoutIdListFragmentHandler final : public FragmentHandler2
118
{
119
public:
120
    SldLayoutIdListFragmentHandler(XmlFilterBase& rFilter, const OUString& rFragmentPath,
121
                                   std::vector<OUString>& rRelIds)
122
2.36k
        : FragmentHandler2(rFilter, rFragmentPath)
123
2.36k
        , mrRelIds(rRelIds)
124
2.36k
    {
125
2.36k
    }
126
127
    ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList& rAttribs) override
128
14.2k
    {
129
14.2k
        switch (nElement)
130
14.2k
        {
131
1.13k
            case PPT_TOKEN(sldMaster):
132
2.27k
            case PPT_TOKEN(sldLayoutIdLst):
133
2.27k
                return this;
134
9.01k
            case PPT_TOKEN(sldLayoutId):
135
9.01k
                mrRelIds.push_back(rAttribs.getStringDefaulted(R_TOKEN(id)));
136
9.01k
                break;
137
14.2k
        }
138
11.9k
        return nullptr;
139
14.2k
    }
140
141
private:
142
    std::vector<OUString>& mrRelIds;
143
};
144
145
/** The layouts of a slide master, in the order the master lists them.
146
147
    The relations carry no order at all: a relationship id is opaque, and a producer may assign any
148
    id to any part. */
149
std::vector<OUString> getLayoutFragmentPaths(XmlFilterBase& rFilter,
150
                                             const OUString& rMasterFragmentPath,
151
                                             const Relations& rMasterRelations)
152
2.36k
{
153
2.36k
    std::vector<OUString> aRelIds;
154
2.36k
    rFilter.importFragment(
155
2.36k
        new SldLayoutIdListFragmentHandler(rFilter, rMasterFragmentPath, aRelIds));
156
157
2.36k
    std::vector<OUString> aPaths;
158
2.36k
    std::unordered_set<OUString> aNamedRelIds;
159
2.36k
    for (const OUString& rRelId : aRelIds)
160
9.01k
    {
161
9.01k
        OUString aPath = rMasterRelations.getFragmentPathFromRelId(rRelId);
162
9.01k
        if (aPath.isEmpty())
163
278
            continue;
164
165
8.73k
        aPaths.push_back(aPath);
166
8.73k
        aNamedRelIds.insert(rRelId);
167
8.73k
    }
168
169
    // A layout the list does not name still gets its master page, as it did before the list was
170
    // consulted at all.
171
2.36k
    for (const auto& [rRelId, rRelation] : rMasterRelations)
172
19.1k
    {
173
19.1k
        if (!rRelation.maType.endsWith("relationships/slideLayout")
174
16.7k
            || aNamedRelIds.contains(rRelId))
175
11.0k
            continue;
176
177
8.05k
        aPaths.push_back(rMasterRelations.getFragmentPathFromRelation(rRelation));
178
8.05k
    }
179
180
2.36k
    return aPaths;
181
2.36k
}
182
} // end anonymous ns
183
184
PresentationFragmentHandler::PresentationFragmentHandler(XmlFilterBase& rFilter, const OUString& rFragmentPath)
185
2.29k
    : FragmentHandler2( rFilter, rFragmentPath )
186
2.29k
    , mpTextListStyle( std::make_shared<TextListStyle>() )
187
2.29k
    , mbCommentAuthorsRead(false)
188
2.29k
{
189
2.29k
    TextParagraphPropertiesArray& rParagraphDefaultsVector( mpTextListStyle->getListStyle() );
190
2.29k
    for (auto & elem : rParagraphDefaultsVector)
191
20.6k
    {
192
        // ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
193
        // so this attribute needs to be set always
194
20.6k
        elem.getParaBottomMargin() = TextSpacing( 0 );
195
20.6k
    }
196
2.29k
}
197
198
PresentationFragmentHandler::~PresentationFragmentHandler() noexcept
199
2.29k
{
200
2.29k
}
201
202
void PresentationFragmentHandler::importSlideNames(const XmlFilterBase& rFilter, const std::vector<SlidePersistPtr>& rSlidePersist)
203
2.26k
{
204
2.26k
    sal_Int32 nMaxPages = rSlidePersist.size();
205
6.73k
    for (sal_Int32 nPage = 0; nPage < nMaxPages; nPage++)
206
4.46k
    {
207
4.46k
        OUString aTitleText = rSlidePersist[nPage]->getTitleText();
208
4.46k
        if (!aTitleText.isEmpty())
209
143
        {
210
            // just a magic value but we don't want to drop out slide names which are too long
211
143
            if (aTitleText.getLength() > 63)
212
6
                aTitleText = aTitleText.copy(0, 63);
213
143
            bool bUseTitleAsSlideName = !aTitleText.isEmpty();
214
            // check duplicated title name
215
143
            if (bUseTitleAsSlideName)
216
143
            {
217
143
                sal_Int32 nCount = 1;
218
143
                Reference<XDrawPagesSupplier> xDPS(rFilter.getModel(), UNO_QUERY_THROW);
219
143
                Reference<XDrawPages> xDrawPages(xDPS->getDrawPages(), UNO_SET_THROW);
220
157
                for (sal_Int32 i = 0; i < nPage; ++i)
221
14
                {
222
14
                    Reference<XDrawPage> xDrawPage(xDrawPages->getByIndex(i), UNO_QUERY);
223
14
                    Reference<container::XNamed> xNamed(xDrawPage, UNO_QUERY_THROW);
224
14
                    std::u16string_view sRest;
225
14
                    if (o3tl::starts_with(xNamed->getName(), aTitleText, &sRest)
226
11
                        && (sRest.empty()
227
0
                            || (o3tl::starts_with(sRest, u" (") && o3tl::ends_with(sRest, u")")
228
0
                                && o3tl::toInt32(sRest.substr(2, sRest.size() - 3)) > 0)))
229
11
                        nCount++;
230
14
                }
231
143
                Reference<container::XNamed> xName(rSlidePersist[nPage]->getPage(), UNO_QUERY_THROW);
232
143
                xName->setName(
233
143
                    aTitleText
234
143
                    + (nCount == 1 ? u""_ustr : " (" + OUString::number(nCount) + ")"));
235
143
            }
236
143
        }
237
4.46k
    }
238
2.26k
}
239
240
void PresentationFragmentHandler::importCustomSlideShow(std::vector<CustomShow>& rCustomShowList)
241
0
{
242
0
    PowerPointImport& rFilter = dynamic_cast<PowerPointImport&>(getFilter());
243
0
    Reference<frame::XModel> xModel(rFilter.getModel());
244
0
    Reference<XDrawPagesSupplier> xDrawPagesSupplier(xModel, UNO_QUERY_THROW);
245
0
    Reference<XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW);
246
247
0
    Reference<css::lang::XSingleServiceFactory> mxShowFactory;
248
0
    Reference<css::container::XNameContainer> mxShows;
249
0
    Reference<XCustomPresentationSupplier> xShowsSupplier(xModel, UNO_QUERY);
250
0
    if (xShowsSupplier.is())
251
0
    {
252
0
        mxShows = xShowsSupplier->getCustomPresentations();
253
0
        mxShowFactory.set(mxShows, UNO_QUERY);
254
0
    }
255
256
0
    for (size_t i = 0; i < rCustomShowList.size(); ++i)
257
0
    {
258
0
        Reference<css::container::XIndexContainer> xShow(mxShowFactory->createInstance(),
259
0
                                                                    UNO_QUERY);
260
0
        if (xShow.is())
261
0
        {
262
0
            static constexpr OUString sSlide = u"slides/slide"_ustr;
263
0
            for (size_t j = 0; j < rCustomShowList[i].maSldLst.size(); ++j)
264
0
            {
265
0
                OUString sCustomSlide = rCustomShowList[i].maSldLst[j];
266
0
                sal_Int32 nPageNumber = 0;
267
0
                if (sCustomSlide.match(sSlide))
268
0
                    nPageNumber = o3tl::toInt32(sCustomSlide.subView(sSlide.getLength()));
269
270
0
                Reference<XDrawPage> xPage;
271
0
                xDrawPages->getByIndex(nPageNumber - 1) >>= xPage;
272
0
                if (xPage.is())
273
0
                    xShow->insertByIndex(xShow->getCount(), Any(xPage));
274
0
            }
275
276
0
            Any aAny;
277
0
            aAny <<= xShow;
278
0
            mxShows->insertByName(rCustomShowList[i].maCustomShowName, aAny);
279
0
        }
280
0
    }
281
0
}
282
283
void PresentationFragmentHandler::importMasterSlide(const Reference<frame::XModel>& xModel,
284
                                                    PowerPointImport& rFilter,
285
                                                    const OUString& rMasterFragmentPath)
286
2.36k
{
287
2.36k
    SlidePersistPtr pMasterPersistPtr;
288
2.36k
    Reference< drawing::XDrawPage > xMasterPage;
289
2.36k
    Reference< drawing::XMasterPagesSupplier > xMPS( xModel, uno::UNO_QUERY_THROW );
290
2.36k
    Reference< drawing::XDrawPages > xMasterPages( xMPS->getMasterPages(), uno::UNO_SET_THROW );
291
2.36k
    RelationsRef xMasterRelations = rFilter.importRelations( rMasterFragmentPath );
292
293
2.36k
    for (const OUString& aLayoutFragmentPath :
294
2.36k
         getLayoutFragmentPaths(rFilter, rMasterFragmentPath, *xMasterRelations))
295
16.4k
    {
296
16.4k
        sal_Int32 nIndex;
297
16.4k
        if( rFilter.getMasterPages().empty() )
298
2.09k
        {
299
2.09k
            nIndex = 0;
300
2.09k
            xMasterPages->getByIndex( nIndex ) >>= xMasterPage;
301
2.09k
        }
302
14.3k
        else
303
14.3k
        {
304
14.3k
            nIndex = xMasterPages->getCount();
305
14.3k
            xMasterPage = xMasterPages->insertNewByIndex( nIndex );
306
14.3k
        }
307
308
16.4k
        pMasterPersistPtr = std::make_shared<SlidePersist>( rFilter, true, false, xMasterPage,
309
16.4k
                                                            std::make_shared<PPTShape>( Master, u"com.sun.star.drawing.GroupShape"_ustr ), mpTextListStyle );
310
16.4k
        pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
311
16.4k
        rFilter.getMasterPages().push_back( pMasterPersistPtr );
312
16.4k
        rFilter.setActualSlidePersist( pMasterPersistPtr );
313
16.4k
        FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, rMasterFragmentPath, pMasterPersistPtr, Master ) );
314
315
        // set the correct theme
316
16.4k
        OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"theme" );
317
16.4k
        if( !aThemeFragmentPath.isEmpty() )
318
16.4k
        {
319
16.4k
            std::map< OUString, oox::drawingml::ThemePtr >& rThemes( rFilter.getThemes() );
320
16.4k
            std::map< OUString, oox::drawingml::ThemePtr >::iterator aIter2( rThemes.find( aThemeFragmentPath ) );
321
16.4k
            if( aIter2 == rThemes.end() )
322
2.16k
            {
323
2.16k
                oox::drawingml::ThemePtr pThemePtr = std::make_shared<oox::drawingml::Theme>();
324
2.16k
                pMasterPersistPtr->setTheme( pThemePtr );
325
2.16k
                Reference<xml::dom::XDocument> xDoc=
326
2.16k
                    rFilter.importFragment(aThemeFragmentPath);
327
328
2.16k
                auto pTheme = std::make_shared<model::Theme>();
329
2.16k
                pThemePtr->setTheme(pTheme);
330
331
2.16k
                rFilter.importFragment(
332
2.16k
                    new ThemeFragmentHandler(rFilter, aThemeFragmentPath, *pThemePtr, *pTheme),
333
2.16k
                    Reference<xml::sax::XFastSAXSerializable>(
334
2.16k
                        xDoc,
335
2.16k
                        UNO_QUERY_THROW));
336
2.16k
                rThemes[ aThemeFragmentPath ] = pThemePtr;
337
2.16k
                pThemePtr->setFragment(xDoc);
338
2.16k
                saveThemeToGrabBag(pThemePtr, nIndex + 1);
339
2.16k
            }
340
14.2k
            else
341
14.2k
            {
342
14.2k
                pMasterPersistPtr->setTheme( (*aIter2).second );
343
14.2k
            }
344
16.4k
        }
345
16.4k
        importSlide( xMasterFragmentHandler, pMasterPersistPtr );
346
347
        /* Save the master's clrMap before importing the layouts. A layout's
348
        clrMapOvr/overrideClrMapping element replaces the shared master persist's
349
        clrMap with the layout-local override */
350
16.4k
        oox::drawingml::ClrMapPtr pMasterClrMap = pMasterPersistPtr->getClrMap();
351
16.4k
        saveColorMapToGrabBag(pMasterClrMap);
352
353
16.4k
        rFilter.importFragment( new LayoutFragmentHandler( rFilter, aLayoutFragmentPath, pMasterPersistPtr ) );
354
355
        // Check if layout had a color map override (clrMap changed during layout import)
356
16.4k
        if (pMasterPersistPtr->getClrMap() != pMasterClrMap && pMasterPersistPtr->getClrMap())
357
0
        {
358
0
            saveLayoutColorMapToGrabBag(pMasterPersistPtr->getClrMap(), nIndex);
359
0
        }
360
361
16.4k
        pMasterPersistPtr->createBackground( rFilter );
362
16.4k
        pMasterPersistPtr->createXShapes( rFilter );
363
364
16.4k
        uno::Reference< beans::XPropertySet > xSet(pMasterPersistPtr->getPage(), uno::UNO_QUERY_THROW);
365
16.4k
        xSet->setPropertyValue(u"SlideLayout"_ustr, Any(pMasterPersistPtr->getLayoutFromValueToken()));
366
367
16.4k
        oox::drawingml::ThemePtr pTheme = pMasterPersistPtr->getTheme();
368
16.4k
        if (pTheme)
369
16.2k
        {
370
16.2k
            pTheme->addTheme(pMasterPersistPtr->getPage());
371
16.2k
        }
372
16.4k
    }
373
2.36k
}
374
375
void PresentationFragmentHandler::saveThemeToGrabBag(const oox::drawingml::ThemePtr& pThemePtr,
376
                                                     sal_Int32 nThemeIdx)
377
1.98k
{
378
1.98k
    if (!pThemePtr)
379
0
        return;
380
381
1.98k
    try
382
1.98k
    {
383
1.98k
        uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
384
1.98k
        if (xDocProps.is())
385
1.98k
        {
386
1.98k
            uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
387
388
1.98k
            static constexpr OUString aGrabBagPropName = u"InteropGrabBag"_ustr;
389
1.98k
            if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
390
1.98k
            {
391
                // get existing grab bag
392
1.98k
                comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
393
394
1.98k
                comphelper::SequenceAsHashMap aThemesHashMap;
395
396
                // create current theme
397
1.98k
                uno::Sequence<beans::PropertyValue> aCurrentTheme(PredefinedClrSchemeId::Count);
398
1.98k
                auto pCurrentTheme = aCurrentTheme.getArray();
399
400
1.98k
                ClrScheme rClrScheme = pThemePtr->getClrScheme();
401
21.8k
                for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
402
19.8k
                {
403
19.8k
                    auto eID = static_cast<PredefinedClrSchemeId>(nId);
404
19.8k
                    sal_uInt32 nToken = getPredefinedClrTokens(eID);
405
19.8k
                    OUString sName(getPredefinedClrNames(eID));
406
19.8k
                    ::Color nColor;
407
408
19.8k
                    rClrScheme.getColor(nToken, nColor);
409
410
19.8k
                    pCurrentTheme[nId].Name = sName;
411
19.8k
                    pCurrentTheme[nId].Value <<= nColor;
412
19.8k
                }
413
414
415
1.98k
                uno::Sequence<beans::PropertyValue> aTheme{
416
                    // add new theme to the sequence
417
                    // Export code uses the master slide's index to find the right theme
418
                    // so use the same index in the grabbag.
419
1.98k
                    comphelper::makePropertyValue(
420
1.98k
                        "ppt/theme/theme" + OUString::number(nThemeIdx) + ".xml", aCurrentTheme),
421
                    // store DOM fragment for SmartArt re-generation
422
1.98k
                    comphelper::makePropertyValue(u"OOXTheme"_ustr, pThemePtr->getFragment())
423
1.98k
                };
424
425
1.98k
                aThemesHashMap << aTheme;
426
427
                // put the new items
428
1.98k
                aGrabBag.update(aThemesHashMap);
429
430
                // put it back to the document
431
1.98k
                xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList()));
432
1.98k
            }
433
1.98k
        }
434
1.98k
    }
435
1.98k
    catch (const uno::Exception&)
436
1.98k
    {
437
0
        SAL_WARN("oox", "oox::ppt::PresentationFragmentHandler::saveThemeToGrabBag, Failed to save grab bag");
438
0
    }
439
1.98k
}
440
441
void PresentationFragmentHandler::saveColorMapToGrabBag(const oox::drawingml::ClrMapPtr& pClrMapPtr)
442
16.2k
{
443
16.2k
    if (!pClrMapPtr)
444
7.79k
        return;
445
446
8.48k
    try
447
8.48k
    {
448
8.48k
        uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
449
8.48k
        if (xDocProps.is())
450
8.48k
        {
451
8.48k
            uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
452
453
8.48k
            static constexpr OUString aGrabBagPropName = u"InteropGrabBag"_ustr;
454
8.48k
            if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
455
8.48k
            {
456
8.48k
                static constexpr auto constTokenArray = std::to_array<sal_Int32>({
457
8.48k
                        XML_bg1,     XML_tx1,     XML_bg2,     XML_tx2,
458
8.48k
                        XML_accent1, XML_accent2, XML_accent3, XML_accent4,
459
8.48k
                        XML_accent5, XML_accent6, XML_hlink,   XML_folHlink
460
8.48k
                });
461
462
8.48k
                comphelper::SequenceAsHashMap aClrMapHashMap;
463
8.48k
                comphelper::SequenceAsHashMap aGrabBag(
464
8.48k
                    xDocProps->getPropertyValue(aGrabBagPropName));
465
466
8.48k
                std::vector<beans::PropertyValue> aClrMapList;
467
8.48k
                size_t nColorMapSize = constTokenArray.size();
468
8.48k
                aClrMapList.reserve(nColorMapSize);
469
110k
                for (size_t i = 0; i < nColorMapSize; ++i)
470
101k
                {
471
101k
                    sal_Int32 nToken = constTokenArray[i];
472
101k
                    pClrMapPtr->getColorMap(nToken);
473
101k
                    aClrMapList.push_back(
474
101k
                        comphelper::makePropertyValue(OUString::number(i), nToken));
475
101k
                }
476
477
8.48k
                uno::Sequence<beans::PropertyValue> aClrMapPropValue{ comphelper::makePropertyValue(
478
8.48k
                    u"OOXColorMap"_ustr,
479
8.48k
                    uno::Any(comphelper::containerToSequence(aClrMapList))) };
480
481
8.48k
                aClrMapHashMap << aClrMapPropValue;
482
8.48k
                aGrabBag.update(aClrMapHashMap);
483
484
8.48k
                xDocProps->setPropertyValue(aGrabBagPropName,
485
8.48k
                                            uno::Any(aGrabBag.getAsConstPropertyValueList()));
486
8.48k
            }
487
8.48k
        }
488
8.48k
    }
489
8.48k
    catch (const uno::Exception&)
490
8.48k
    {
491
0
        SAL_WARN("oox", "oox::ppt::PresentationFragmentHandler::saveColorMapToGrabBag, Failed to save grab bag");
492
0
    }
493
8.48k
}
494
495
void PresentationFragmentHandler::saveSections()
496
2.26k
{
497
2.26k
    if (maSectionList.empty())
498
2.26k
        return;
499
500
0
    try
501
0
    {
502
0
        uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
503
0
        if (!xDocProps.is())
504
0
            return;
505
506
        // Get draw pages to resolve slide IDs to page names
507
0
        uno::Reference<drawing::XDrawPagesSupplier> xDPS(getFilter().getModel(), uno::UNO_QUERY);
508
0
        if (!xDPS.is())
509
0
            return;
510
0
        uno::Reference<drawing::XDrawPages> xDrawPages(xDPS->getDrawPages());
511
0
        if (!xDrawPages.is())
512
0
            return;
513
514
        // Build a sequence of sections, each section containing name, id, and slide names
515
0
        std::vector<beans::PropertyValue> aSectionsList;
516
0
        for (size_t i = 0; i < maSectionList.size(); ++i)
517
0
        {
518
0
            const SectionData& rSection = maSectionList[i];
519
520
            // Convert slide IDs to page names (stable across edits)
521
0
            std::vector<OUString> aSlideNames;
522
0
            for (sal_Int32 nSldId : rSection.maSldIdList)
523
0
            {
524
0
                auto it = maSlideIdToIndexMap.find(nSldId);
525
0
                if (it != maSlideIdToIndexMap.end())
526
0
                {
527
0
                    sal_Int32 nIndex = it->second;
528
0
                    if (nIndex < xDrawPages->getCount())
529
0
                    {
530
0
                        uno::Reference<drawing::XDrawPage> xPage;
531
0
                        xDrawPages->getByIndex(nIndex) >>= xPage;
532
0
                        uno::Reference<container::XNamed> xNamed(xPage, uno::UNO_QUERY);
533
0
                        if (xNamed.is())
534
0
                            aSlideNames.push_back(xNamed->getName());
535
0
                    }
536
0
                }
537
0
            }
538
539
0
            uno::Sequence<beans::PropertyValue> aSectionProps{
540
0
                comphelper::makePropertyValue(u"Name"_ustr, rSection.maName),
541
0
                comphelper::makePropertyValue(u"Id"_ustr, rSection.maId),
542
0
                comphelper::makePropertyValue(u"SlideNameList"_ustr,
543
0
                                              comphelper::containerToSequence(aSlideNames))
544
0
            };
545
546
0
            aSectionsList.push_back(
547
0
                comphelper::makePropertyValue(u"Section"_ustr + OUString::number(i), aSectionProps));
548
0
        }
549
550
0
        xDocProps->setPropertyValue(u"SlideSections"_ustr,
551
0
                                    uno::Any(comphelper::containerToSequence(aSectionsList)));
552
0
    }
553
0
    catch (const uno::Exception&)
554
0
    {
555
0
        SAL_WARN("oox", "oox::ppt::PresentationFragmentHandler::saveSections failed");
556
0
    }
557
0
}
558
559
void PresentationFragmentHandler::saveLayoutColorMapToGrabBag(
560
    const oox::drawingml::ClrMapPtr& pClrMapPtr,
561
    sal_Int32 nMasterIndex)
562
0
{
563
0
    if (!pClrMapPtr)
564
0
        return;
565
566
0
    try
567
0
    {
568
0
        uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
569
0
        if (xDocProps.is())
570
0
        {
571
0
            uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
572
573
0
            static constexpr OUString aGrabBagPropName = u"InteropGrabBag"_ustr;
574
0
            if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
575
0
            {
576
0
                static constexpr auto constTokenArray = std::to_array<sal_Int32>({
577
0
                        XML_bg1,     XML_tx1,     XML_bg2,     XML_tx2,
578
0
                        XML_accent1, XML_accent2, XML_accent3, XML_accent4,
579
0
                        XML_accent5, XML_accent6, XML_hlink,   XML_folHlink
580
0
                });
581
582
0
                comphelper::SequenceAsHashMap aGrabBag(
583
0
                    xDocProps->getPropertyValue(aGrabBagPropName));
584
585
0
                std::vector<beans::PropertyValue> aClrMapList;
586
0
                size_t nColorMapSize = constTokenArray.size();
587
0
                aClrMapList.reserve(nColorMapSize);
588
0
                for (size_t i = 0; i < nColorMapSize; ++i)
589
0
                {
590
0
                    sal_Int32 nToken = constTokenArray[i];
591
0
                    pClrMapPtr->getColorMap(nToken);
592
0
                    aClrMapList.push_back(
593
0
                        comphelper::makePropertyValue(OUString::number(i), nToken));
594
0
                }
595
596
                // Build key: "OOXLayoutClrMapOvr_<masterIndex>"
597
0
                OUString sKey = "OOXLayoutClrMapOvr_" + OUString::number(nMasterIndex);
598
599
0
                aGrabBag[sKey] <<= comphelper::containerToSequence(aClrMapList);
600
601
0
                xDocProps->setPropertyValue(aGrabBagPropName,
602
0
                                            uno::Any(aGrabBag.getAsConstPropertyValueList()));
603
0
            }
604
0
        }
605
0
    }
606
0
    catch (const uno::Exception&)
607
0
    {
608
0
        SAL_WARN("oox", "oox::ppt::PresentationFragmentHandler::saveLayoutColorMapToGrabBag, Failed to save grab bag");
609
0
    }
610
0
}
611
612
void PresentationFragmentHandler::importMasterSlides()
613
2.26k
{
614
2.26k
    OUString aMasterFragmentPath;
615
2.26k
    PowerPointImport& rFilter = dynamic_cast<PowerPointImport&>(getFilter());
616
2.26k
    Reference<frame::XModel> xModel(rFilter.getModel());
617
618
4.62k
    for (size_t nMaster = 0; nMaster < maSlideMasterVector.size(); ++nMaster)
619
2.36k
    {
620
2.36k
        aMasterFragmentPath = getFragmentPathFromRelId(maSlideMasterVector[nMaster]);
621
2.36k
        importMasterSlide(xModel, rFilter, aMasterFragmentPath);
622
2.36k
    }
623
2.26k
}
624
625
void PresentationFragmentHandler::importSlide(sal_uInt32 nSlide, sal_Int32 nPagesImported, bool bImportNotesPage)
626
4.67k
{
627
4.67k
    PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
628
629
4.67k
    Reference< frame::XModel > xModel( rFilter.getModel() );
630
4.67k
    Reference< drawing::XDrawPage > xSlide;
631
632
    // importing slide pages and its corresponding notes page
633
4.67k
    Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
634
4.67k
    Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_SET_THROW );
635
636
4.67k
    try {
637
638
4.67k
        if( !nPagesImported )
639
2.26k
        {
640
2.26k
            xDrawPages->getByIndex( 0 ) >>= xSlide;
641
2.26k
            importMasterSlides();
642
2.26k
        }
643
2.41k
        else
644
2.41k
            xSlide = xDrawPages->insertNewByIndex( nPagesImported );
645
646
4.67k
        OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] );
647
4.67k
        if( !aSlideFragmentPath.isEmpty() )
648
4.46k
        {
649
4.46k
            SlidePersistPtr pMasterPersistPtr;
650
4.46k
            SlidePersistPtr pSlidePersistPtr = std::make_shared<SlidePersist>( rFilter, false, false, xSlide,
651
4.46k
                                std::make_shared<PPTShape>( Slide, u"com.sun.star.drawing.GroupShape"_ustr ), mpTextListStyle );
652
653
4.46k
            FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( rFilter, aSlideFragmentPath, pSlidePersistPtr, Slide ) );
654
655
            // importing the corresponding masterpage/layout
656
4.46k
            OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideLayout" );
657
4.46k
            OUString aCommentFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"comments" );
658
4.46k
            if ( !aLayoutFragmentPath.isEmpty() )
659
3.30k
            {
660
                // importing layout
661
3.30k
                RelationsRef xLayoutRelations = rFilter.importRelations( aLayoutFragmentPath );
662
3.30k
                OUString aMasterFragmentPath = xLayoutRelations->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideMaster" );
663
3.30k
                if( !aMasterFragmentPath.isEmpty() )
664
2.81k
                {
665
                    // check if the corresponding masterpage+layout has already been imported
666
2.81k
                    std::vector< SlidePersistPtr >& rMasterPages( rFilter.getMasterPages() );
667
2.81k
                    for (auto const& masterPage : rMasterPages)
668
5.09k
                    {
669
5.09k
                        if ( ( masterPage->getPath() == aMasterFragmentPath ) && ( masterPage->getLayoutPath() == aLayoutFragmentPath ) )
670
2.48k
                        {
671
2.48k
                            pMasterPersistPtr = masterPage;
672
2.48k
                            break;
673
2.48k
                        }
674
5.09k
                    }
675
2.81k
                }
676
3.30k
            }
677
678
            // importing slide page
679
4.46k
            if (pMasterPersistPtr) {
680
2.48k
                pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
681
2.48k
                pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
682
2.48k
                Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
683
2.48k
                if( xMasterPageTarget.is() )
684
2.48k
                    xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
685
2.48k
            }
686
4.46k
            rFilter.getDrawPages().push_back( pSlidePersistPtr );
687
4.46k
            rFilter.setActualSlidePersist( pSlidePersistPtr );
688
4.46k
            importSlide( xSlideFragmentHandler, pSlidePersistPtr );
689
4.46k
            pSlidePersistPtr->createBackground( rFilter );
690
4.46k
            pSlidePersistPtr->createXShapes( rFilter );
691
4.46k
            pSlidePersistPtr->releaseShapes();
692
693
4.46k
            if(bImportNotesPage) {
694
695
                // now importing the notes page
696
4.46k
                OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"notesSlide" );
697
4.46k
                if( !aNotesFragmentPath.isEmpty() )
698
115
                {
699
115
                    Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
700
115
                    if ( xPresentationPage.is() )
701
115
                    {
702
115
                        Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
703
115
                        if ( xNotesPage.is() )
704
115
                        {
705
115
                            SlidePersistPtr pNotesPersistPtr = std::make_shared<SlidePersist>( rFilter, false, true, xNotesPage,
706
115
                                std::make_shared<PPTShape>( Slide, u"com.sun.star.drawing.GroupShape"_ustr ), mpTextListStyle );
707
115
                            FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
708
115
                            rFilter.getNotesPages().push_back( pNotesPersistPtr );
709
115
                            rFilter.setActualSlidePersist( pNotesPersistPtr );
710
115
                            importSlide( xNotesFragmentHandler, pNotesPersistPtr );
711
115
                            pNotesPersistPtr->createBackground( rFilter );
712
115
                            pNotesPersistPtr->createXShapes( rFilter );
713
115
                            pNotesPersistPtr->releaseShapes();
714
115
                        }
715
115
                    }
716
115
                }
717
4.46k
            }
718
719
4.46k
            if( !mbCommentAuthorsRead && !aCommentFragmentPath.isEmpty() )
720
12
            {
721
                // Comments are present and commentAuthors.xml has still not been read
722
12
                mbCommentAuthorsRead = true;
723
12
                Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
724
12
                Reference< XDrawPage > xCommentAuthorsPage( xPresentationPage->getNotesPage() );
725
12
                SlidePersistPtr pCommentAuthorsPersistPtr =
726
12
                    std::make_shared<SlidePersist>( rFilter, false, true, xCommentAuthorsPage,
727
12
                                      std::make_shared<PPTShape>(
728
12
                                              Slide, u"com.sun.star.drawing.GroupShape"_ustr ),
729
12
                                      mpTextListStyle );
730
12
                FragmentHandlerRef xCommentAuthorsFragmentHandler(
731
12
                    new SlideFragmentHandler( getFilter(),
732
12
                                              u"ppt/commentAuthors.xml"_ustr,
733
12
                                              pCommentAuthorsPersistPtr,
734
12
                                              Slide ) );
735
736
12
                getFilter().importFragment( xCommentAuthorsFragmentHandler );
737
12
                maAuthorList.setValues( pCommentAuthorsPersistPtr->getCommentAuthors() );
738
12
            }
739
4.46k
            if( !aCommentFragmentPath.isEmpty() )
740
16
            {
741
16
                Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
742
16
                Reference< XDrawPage > xCommentsPage( xPresentationPage->getNotesPage() );
743
16
                SlidePersistPtr pCommentsPersistPtr =
744
16
                    std::make_shared<SlidePersist>(
745
16
                        rFilter, false, true, xCommentsPage,
746
16
                        std::make_shared<PPTShape>(
747
16
                                Slide, u"com.sun.star.drawing.GroupShape"_ustr ),
748
16
                        mpTextListStyle );
749
750
16
                FragmentHandlerRef xCommentsFragmentHandler(
751
16
                    new SlideFragmentHandler(
752
16
                        getFilter(),
753
16
                        aCommentFragmentPath,
754
16
                        pCommentsPersistPtr,
755
16
                        Slide ) );
756
16
                pCommentsPersistPtr->getCommentsList().cmLst.clear();
757
16
                getFilter().importFragment( xCommentsFragmentHandler );
758
759
16
                if (!pCommentsPersistPtr->getCommentsList().cmLst.empty())
760
12
                {
761
                    //set comment chars for last comment on slide
762
12
                    SlideFragmentHandler* comment_handler =
763
12
                        dynamic_cast<SlideFragmentHandler*>(xCommentsFragmentHandler.get());
764
12
                    assert(comment_handler);
765
                    // some comments have no text -> set empty string as text to avoid
766
                    // crash (back() on empty vector is undefined) and losing other
767
                    // comment data that might be there (author, position, timestamp etc.)
768
12
                    pCommentsPersistPtr->getCommentsList().cmLst.back().setText(
769
12
                            comment_handler->getCharVector().empty() ? u""_ustr :
770
12
                            comment_handler->getCharVector().back() );
771
12
                }
772
16
                pCommentsPersistPtr->getCommentAuthors().setValues(maAuthorList);
773
774
                //insert all comments from commentsList
775
40
                for(int i=0; i<pCommentsPersistPtr->getCommentsList().getSize(); i++)
776
24
                {
777
24
                    try {
778
24
                        Comment aComment = pCommentsPersistPtr->getCommentsList().getCommentAtIndex(i);
779
24
                        uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xSlide, UNO_QUERY_THROW );
780
24
                        uno::Reference< office::XAnnotation > xAnnotation( xAnnotationAccess->createAndInsertAnnotation() );
781
24
                        int nPosX = aComment.getIntX();
782
24
                        int nPosY = aComment.getIntY();
783
24
                        xAnnotation->setPosition(
784
24
                            geometry::RealPoint2D(
785
24
                                ::oox::drawingml::convertEmuToHmm( nPosX ) * 15.87,
786
24
                                ::oox::drawingml::convertEmuToHmm( nPosY ) * 15.87 ) );
787
24
                        xAnnotation->setAuthor( aComment.getAuthor(maAuthorList) );
788
24
                        xAnnotation->setInitials( aComment.getInitials(maAuthorList) );
789
24
                        xAnnotation->setDateTime( aComment.getDateTime() );
790
24
                        uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
791
24
                        xText->setString( aComment.get_text());
792
24
                    } catch( css::lang::IllegalArgumentException& ) {}
793
24
                }
794
16
            }
795
4.46k
        }
796
4.67k
    }
797
4.67k
    catch( uno::Exception& )
798
4.67k
    {
799
177
        TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::EndDocument()" );
800
177
    }
801
4.67k
}
802
803
void PresentationFragmentHandler::finalizeImport()
804
2.26k
{
805
2.26k
    PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
806
807
2.26k
    sal_Int32 nPageCount = maSlidesVector.size();
808
809
    // we will take the FilterData property "PageRange" if available, otherwise full range is used
810
2.26k
    comphelper::SequenceAsHashMap& rFilterData = rFilter.getFilterData();
811
812
    // writing back the original PageCount of this document, it can be accessed from the XModel
813
    // via getArgs after the import.
814
2.26k
    rFilterData[u"OriginalPageCount"_ustr] <<= nPageCount;
815
2.26k
    bool bImportNotesPages = rFilterData.getUnpackedValueOrDefault(u"ImportNotesPages"_ustr, true);
816
2.26k
    OUString aPageRange = rFilterData.getUnpackedValueOrDefault(u"PageRange"_ustr, OUString());
817
818
2.26k
    if( !aPageRange.getLength() )
819
2.26k
    {
820
2.26k
        aPageRange = "1-" + OUString::number( nPageCount );
821
2.26k
    }
822
823
2.26k
    StringRangeEnumerator aRangeEnumerator( aPageRange, 0, nPageCount - 1 );
824
2.26k
    if (aRangeEnumerator.size())
825
2.26k
    {
826
        // todo: localized progress bar text
827
2.26k
        const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
828
2.26k
        if ( rxStatusIndicator.is() )
829
0
            rxStatusIndicator->start( OUString(), 10000 );
830
831
2.26k
        try
832
2.26k
        {
833
2.26k
            int nPagesImported = 0;
834
2.26k
            for (sal_Int32 elem : aRangeEnumerator)
835
4.67k
            {
836
4.67k
                if ( rxStatusIndicator.is() )
837
0
                    rxStatusIndicator->setValue((nPagesImported * 10000) / aRangeEnumerator.size());
838
839
4.67k
                importSlide(elem, nPagesImported, bImportNotesPages);
840
4.67k
                nPagesImported++;
841
4.67k
            }
842
2.26k
            importSlideNames( rFilter, rFilter.getDrawPages());
843
2.26k
            if (!maCustomShowList.empty())
844
0
                importCustomSlideShow(maCustomShowList);
845
846
2.26k
            saveSections();
847
2.26k
        }
848
2.26k
        catch( uno::Exception& )
849
2.26k
        {
850
0
            TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::finalizeImport()" );
851
0
        }
852
        // todo error handling;
853
2.26k
        if ( rxStatusIndicator.is() )
854
0
            rxStatusIndicator->end();
855
2.26k
    }
856
857
    // open the VBA project storage
858
2.26k
    OUString aVbaFragmentPath = getFragmentPathFromFirstType(CREATE_MSOFFICE_RELATION_TYPE("vbaProject"));
859
2.26k
    if (!aVbaFragmentPath.isEmpty())
860
0
    {
861
0
        uno::Reference<io::XInputStream> xInStrm = getFilter().openInputStream(aVbaFragmentPath);
862
0
        if (xInStrm.is())
863
0
        {
864
0
            StorageRef xPrjStrg = std::make_shared<oox::ole::OleStorage>(getFilter().getComponentContext(), xInStrm, false);
865
0
            getFilter().getVbaProject().importVbaProject(*xPrjStrg);
866
0
        }
867
0
    }
868
2.26k
}
869
870
// CT_Presentation
871
::oox::core::ContextHandlerRef PresentationFragmentHandler::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
872
20.8k
{
873
20.8k
    switch( aElementToken )
874
20.8k
    {
875
2.26k
    case PPT_TOKEN( presentation ):
876
2.26k
        mbEmbedTrueTypeFonts = rAttribs.getBool(XML_embedTrueTypeFonts, false);
877
2.26k
        return this;
878
2.26k
    case PPT_TOKEN( sldMasterIdLst ):
879
2.53k
    case PPT_TOKEN( notesMasterIdLst ):
880
4.79k
    case PPT_TOKEN( sldIdLst ):
881
4.79k
        return this;
882
2.36k
    case PPT_TOKEN( sldMasterId ):
883
2.36k
        maSlideMasterVector.push_back( rAttribs.getStringDefaulted( R_TOKEN( id )) );
884
2.36k
        return this;
885
4.67k
    case PPT_TOKEN( sldId ):
886
4.67k
    {
887
4.67k
        maSlidesVector.push_back( rAttribs.getStringDefaulted( R_TOKEN( id )) );
888
4.67k
        sal_Int32 nSldId = rAttribs.getInteger( XML_id, 0 );
889
4.67k
        if ( nSldId )
890
4.67k
            maSlideIdToIndexMap[ nSldId ] = maSlidesVector.size() - 1;
891
4.67k
        return this;
892
2.53k
    }
893
269
    case PPT_TOKEN( notesMasterId ):
894
269
        maNotesMasterVector.push_back( rAttribs.getStringDefaulted( R_TOKEN( id )) );
895
269
        return this;
896
2.26k
    case PPT_TOKEN( sldSz ):
897
2.26k
        maSlideSize = GetSize2D( rAttribs.getFastAttributeList() );
898
2.26k
        return this;
899
2.26k
    case PPT_TOKEN( notesSz ):
900
2.26k
        maNotesSize = GetSize2D( rAttribs.getFastAttributeList() );
901
2.26k
        return this;
902
37
    case PPT_TOKEN( custShowLst ):
903
37
        return new CustomShowListContext( *this, maCustomShowList );
904
914
    case PPT_TOKEN( defaultTextStyle ):
905
914
        return new TextListStyleContext( *this, *mpTextListStyle );
906
0
    case PPT_TOKEN(embeddedFontLst):
907
0
    {
908
0
        uno::Reference<beans::XPropertySet> xDocSettings(getFilter().getModelFactory()->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY);
909
0
        return new EmbeddedFontListContext(*this, mbEmbedTrueTypeFonts, xDocSettings);
910
2.53k
    }
911
324
    case PPT_TOKEN( extLst ):
912
324
        return this;
913
359
    case PPT_TOKEN( ext ):
914
359
    {
915
359
        mbInSectionExtension = false;
916
        // https://learn.microsoft.com/en-us/openspecs/office_standards/ms-pptx/1f21a089-944d-410b-bd47-4f5e692c2532
917
359
        static constexpr OUString aSectionExtUri
918
359
            = u"{521415D9-36F7-43E2-AB2F-B90AF26B5E84}"_ustr;
919
359
        OUString sUri = rAttribs.getStringDefaulted( XML_uri );
920
359
        if ( sUri == aSectionExtUri )
921
0
        {
922
0
            mbInSectionExtension = true;
923
0
            return this;
924
0
        }
925
359
        return nullptr;
926
359
    }
927
0
    case P14_TOKEN( sectionLst ):
928
0
        if ( !mbInSectionExtension )
929
0
            return nullptr;
930
0
        return this;
931
0
    case P14_TOKEN( section ):
932
0
    {
933
0
        if ( !mbInSectionExtension )
934
0
            return nullptr;
935
0
        SectionData aSection;
936
0
        aSection.maName = rAttribs.getStringDefaulted( XML_name );
937
0
        aSection.maId = rAttribs.getStringDefaulted( XML_id );
938
0
        maSectionList.push_back( std::move(aSection) );
939
0
        return this;
940
0
    }
941
0
    case P14_TOKEN( sldIdLst ):
942
0
        if ( !mbInSectionExtension )
943
0
            return nullptr;
944
0
        return this;
945
0
    case P14_TOKEN( sldId ):
946
0
    {
947
0
        if ( !mbInSectionExtension || maSectionList.empty() )
948
0
            return nullptr;
949
0
        sal_Int32 nSldId = rAttribs.getInteger( XML_id, 0 );
950
0
        if ( nSldId )
951
0
            maSectionList.back().maSldIdList.push_back( nSldId );
952
0
        return this;
953
0
    }
954
0
    case PPT_TOKEN( modifyVerifier ):
955
0
        OUString sAlgorithmClass = rAttribs.getStringDefaulted(XML_cryptAlgorithmClass);
956
0
        OUString sAlgorithmType = rAttribs.getStringDefaulted(XML_cryptAlgorithmType);
957
0
        sal_Int32 nAlgorithmSid = rAttribs.getInteger(XML_cryptAlgorithmSid, 0);
958
0
        sal_Int32 nSpinCount = rAttribs.getInteger(XML_spinCount, 0);
959
0
        OUString sSalt = rAttribs.getStringDefaulted(XML_saltData);
960
0
        OUString sHash = rAttribs.getStringDefaulted(XML_hashData);
961
0
        if (sAlgorithmClass == "hash" && sAlgorithmType == "typeAny" && nAlgorithmSid != 0
962
0
            && !sSalt.isEmpty() && !sHash.isEmpty())
963
0
        {
964
0
            OUString sAlgorithmName;
965
0
            switch (nAlgorithmSid)
966
0
            {
967
0
                case 1:
968
0
                    sAlgorithmName = "MD2";
969
0
                    break;
970
0
                case 2:
971
0
                    sAlgorithmName = "MD4";
972
0
                    break;
973
0
                case 3:
974
0
                    sAlgorithmName = "MD5";
975
0
                    break;
976
0
                case 4:
977
0
                    sAlgorithmName = "SHA-1";
978
0
                    break;
979
0
                case 5:
980
0
                    sAlgorithmName = "MAC";
981
0
                    break;
982
0
                case 6:
983
0
                    sAlgorithmName = "RIPEMD";
984
0
                    break;
985
0
                case 7:
986
0
                    sAlgorithmName = "RIPEMD-160";
987
0
                    break;
988
0
                case 9:
989
0
                    sAlgorithmName = "HMAC";
990
0
                    break;
991
0
                case 12:
992
0
                    sAlgorithmName = "SHA-256";
993
0
                    break;
994
0
                case 13:
995
0
                    sAlgorithmName = "SHA-384";
996
0
                    break;
997
0
                case 14:
998
0
                    sAlgorithmName = "SHA-512";
999
0
                    break;
1000
0
                default:; // 8, 10, 11, any other value: Undefined.
1001
0
            }
1002
1003
0
            if (!sAlgorithmName.isEmpty())
1004
0
            {
1005
0
                uno::Sequence<beans::PropertyValue> aResult{
1006
0
                    comphelper::makePropertyValue(u"algorithm-name"_ustr, sAlgorithmName),
1007
0
                    comphelper::makePropertyValue(u"salt"_ustr, sSalt),
1008
0
                    comphelper::makePropertyValue(u"iteration-count"_ustr, nSpinCount),
1009
0
                    comphelper::makePropertyValue(u"hash"_ustr, sHash)
1010
0
                };
1011
0
                try
1012
0
                {
1013
0
                    uno::Reference<beans::XPropertySet> xDocSettings(
1014
0
                        getFilter().getModelFactory()->createInstance(
1015
0
                            u"com.sun.star.document.Settings"_ustr),
1016
0
                        uno::UNO_QUERY);
1017
0
                    xDocSettings->setPropertyValue(u"ModifyPasswordInfo"_ustr, uno::Any(aResult));
1018
0
                }
1019
0
                catch (const uno::Exception&)
1020
0
                {
1021
0
                }
1022
0
            }
1023
0
        }
1024
0
        return this;
1025
20.8k
    }
1026
334
    return this;
1027
20.8k
}
1028
1029
void PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
1030
        const SlidePersistPtr& rSlidePersistPtr )
1031
20.8k
{
1032
20.8k
    Reference< drawing::XDrawPage > xSlide( rSlidePersistPtr->getPage() );
1033
20.8k
    SlidePersistPtr pMasterPersistPtr( rSlidePersistPtr->getMasterPersist() );
1034
20.8k
    if ( pMasterPersistPtr )
1035
2.48k
    {
1036
        // Setting "Layout" property adds extra title and outliner preset shapes to the master slide
1037
2.48k
        Reference< drawing::XDrawPage > xMasterSlide(pMasterPersistPtr->getPage());
1038
2.48k
        const int nCount = xMasterSlide->getCount();
1039
1040
2.48k
        uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
1041
2.48k
        xSet->setPropertyValue( u"Layout"_ustr, Any( pMasterPersistPtr->getLayoutFromValueToken() ) );
1042
1043
4.60k
        while( nCount < xMasterSlide->getCount())
1044
2.11k
        {
1045
2.11k
            Reference< drawing::XShape > xShape;
1046
2.11k
            xMasterSlide->getByIndex(xMasterSlide->getCount()-1) >>= xShape;
1047
2.11k
            xMasterSlide->remove(xShape);
1048
2.11k
        }
1049
2.48k
    }
1050
35.6k
    while( xSlide->getCount() )
1051
14.8k
    {
1052
14.8k
        Reference< drawing::XShape > xShape;
1053
14.8k
        xSlide->getByIndex(0) >>= xShape;
1054
14.8k
        xSlide->remove( xShape );
1055
14.8k
    }
1056
1057
20.8k
    Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
1058
20.8k
    if ( xPropertySet.is() )
1059
20.8k
    {
1060
20.8k
        awt::Size& rPageSize( rSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
1061
20.8k
        xPropertySet->setPropertyValue( u"Width"_ustr, Any( rPageSize.Width ) );
1062
20.8k
        xPropertySet->setPropertyValue( u"Height"_ustr, Any( rPageSize.Height ) );
1063
1064
20.8k
        oox::ppt::HeaderFooter aHeaderFooter( rSlidePersistPtr->getHeaderFooter() );
1065
20.8k
        if ( !rSlidePersistPtr->isMasterPage() )
1066
4.58k
            aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = false;
1067
20.8k
        try
1068
20.8k
        {
1069
20.8k
            if ( rSlidePersistPtr->isNotesPage() )
1070
115
                xPropertySet->setPropertyValue( u"IsHeaderVisible"_ustr, Any( aHeaderFooter.mbHeader ) );
1071
20.8k
            xPropertySet->setPropertyValue( u"IsFooterVisible"_ustr, Any( aHeaderFooter.mbFooter ) );
1072
20.8k
            xPropertySet->setPropertyValue( u"IsDateTimeVisible"_ustr, Any( aHeaderFooter.mbDateTime ) );
1073
20.8k
            xPropertySet->setPropertyValue( u"IsPageNumberVisible"_ustr, Any( aHeaderFooter.mbSlideNumber ) );
1074
20.8k
        }
1075
20.8k
        catch( uno::Exception& )
1076
20.8k
        {
1077
16.2k
        }
1078
20.8k
    }
1079
20.8k
    rSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
1080
20.8k
    getFilter().importFragment( rxSlideFragmentHandler );
1081
20.8k
}
1082
1083
}
1084
1085
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */