Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/oox/source/ppt/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 36 kB image not shown  

Quelle  presentationfragmenthandler.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <comphelper/anytostring.hxx>
#include <comphelper/propertyvalue.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <o3tl/string_view.hxx>
#include <sal/log.hxx>
#include <tools/multisel.hxx>
#include <comphelper/diagnose_ex.hxx>

#include <frozen/bits/defines.h>
#include <frozen/bits/elsa_std.h>
#include <frozen/unordered_map.h>

#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
#include <com/sun/star/drawing/XDrawPages.hpp>
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/drawing/XMasterPageTarget.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/text/XTextField.hpp>
#include <com/sun/star/xml/dom/XDocument.hpp>
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
#include <com/sun/star/presentation/XPresentationPage.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/container/XNameContainer.hpp>

#include <oox/drawingml/theme.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
#include <oox/drawingml/themefragmenthandler.hxx>
#include <drawingml/textliststylecontext.hxx>
#include <oox/helper/attributelist.hxx>
#include <oox/ole/olestorage.hxx>
#include <oox/ole/vbaproject.hxx>
#include <oox/ppt/pptshape.hxx>
#include <oox/ppt/presentationfragmenthandler.hxx>
#include <oox/ppt/slidefragmenthandler.hxx>
#include <oox/ppt/layoutfragmenthandler.hxx>
#include <oox/ppt/pptimport.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
#include <sax/fastattribs.hxx>

#include <com/sun/star/office/XAnnotation.hpp>
#include <com/sun/star/office/XAnnotationAccess.hpp>
#include <ooxresid.hxx>
#include <strings.hrc>

#include "EmbeddedFontListContext.hxx"

using namespace ::com::sun::star;
using namespace ::oox::core;
using namespace ::oox::drawingml;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::presentation;
using namespace ::com::sun::star::xml::sax;

namespace oox::ppt
{

namespace
{
constexpr frozen::unordered_map<PredefinedClrSchemeId, sal_Int32, 12> constPredefinedClrTokens
{
    { dk1, XML_dk1 },
    { lt1, XML_lt1 },
    { dk2, XML_dk2 },
    { lt2, XML_lt2 },
    { accent1, XML_accent1 },
    { accent2, XML_accent2 },
    { accent3, XML_accent3 },
    { accent4, XML_accent4 },
    { accent5, XML_accent5 },
    { accent6, XML_accent6 },
    { hlink, XML_hlink },
    { folHlink, XML_folHlink }
};

sal_Int32 getPredefinedClrTokens(PredefinedClrSchemeId eID)
{
    auto iterator = constPredefinedClrTokens.find(eID);
    if (iterator == constPredefinedClrTokens.end())
        return XML_TOKEN_INVALID;
    return iterator->second;
}
// end anonymous ns

PresentationFragmentHandler::PresentationFragmentHandler(XmlFilterBase& rFilter, const OUString& rFragmentPath)
    : FragmentHandler2( rFilter, rFragmentPath )
    , mpTextListStyle( std::make_shared<TextListStyle>() )
    , mbCommentAuthorsRead(false)
{
    TextParagraphPropertiesArray& rParagraphDefaultsVector( mpTextListStyle->getListStyle() );
    for (auto & elem : rParagraphDefaultsVector)
    {
        // ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
        // so this attribute needs to be set always
        elem.getParaBottomMargin() = TextSpacing( 0 );
    }
}

PresentationFragmentHandler::~PresentationFragmentHandler() noexcept
{
}

void PresentationFragmentHandler::importSlideNames(const XmlFilterBase& rFilterconst std::vector<SlidePersistPtr>& rSlidePersist)
{
    sal_Int32 nMaxPages = rSlidePersist.size();
    for (sal_Int32 nPage = 0; nPage < nMaxPages; nPage++)
    {
        auto aShapeMap = rSlidePersist[nPage]->getShapeMap();
        auto aIter = std::find_if(aShapeMap.begin(), aShapeMap.end(),
                                  [](const std::pair<OUString, ShapePtr>& element) {
                                      auto pShapePtr = element.second;
                                      return (pShapePtr
                                              && (pShapePtr->getSubType() == XML_title
                                                  || pShapePtr->getSubType() == XML_ctrTitle));
                                  });
        if (aIter != aShapeMap.end())
        {
            OUString aTitleText;
            Reference<text::XTextRange> xText(aIter->second->getXShape(), UNO_QUERY_THROW);
            aTitleText = xText->getString();
            // just a magic value but we don't want to drop out slide names which are too long
            if (aTitleText.getLength() > 63)
                aTitleText = aTitleText.copy(0, 63);
            bool bUseTitleAsSlideName = !aTitleText.isEmpty();
            // check duplicated title name
            if (bUseTitleAsSlideName)
            {
                sal_Int32 nCount = 1;
                Reference<XDrawPagesSupplier> xDPS(rFilter.getModel(), UNO_QUERY_THROW);
                Reference<XDrawPages> xDrawPages(xDPS->getDrawPages(), UNO_SET_THROW);
                for (sal_Int32 i = 0; i < nPage; ++i)
                {
                    Reference<XDrawPage> xDrawPage(xDrawPages->getByIndex(i), UNO_QUERY);
                    Reference<container::XNamed> xNamed(xDrawPage, UNO_QUERY_THROW);
                    std::u16string_view sRest;
                    if (o3tl::starts_with(xNamed->getName(), aTitleText, &sRest)
                        && (sRest.empty()
                            || (o3tl::starts_with(sRest, u" (") && o3tl::ends_with(sRest, u")")
                                && o3tl::toInt32(sRest.substr(2, sRest.size() - 3)) > 0)))
                        nCount++;
                }
                Reference<container::XNamed> xName(rSlidePersist[nPage]->getPage(), UNO_QUERY_THROW);
                xName->setName(
                    aTitleText
                    + (nCount == 1 ? u""_ustr : " (" + OUString::number(nCount) + ")"));
            }
        }
    }
}

void PresentationFragmentHandler::importCustomSlideShow(std::vector<CustomShow>& ;rCustomShowList)
{
    PowerPointImport& rFilter = dynamic_cast<PowerPointImport&>(getFilter());
    Reference<frame::XModel> xModel(rFilter.getModel());
    Reference<XDrawPagesSupplier> xDrawPagesSupplier(xModel, UNO_QUERY_THROW);
    Reference<XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW);

    Reference<css::lang::XSingleServiceFactory> mxShowFactory;
    Reference<css::container::XNameContainer> mxShows;
    Reference<XCustomPresentationSupplier> xShowsSupplier(xModel, UNO_QUERY);
    if (xShowsSupplier.is())
    {
        mxShows = xShowsSupplier->getCustomPresentations();
        mxShowFactory.set(mxShows, UNO_QUERY);
    }

    for (size_t i = 0; i < rCustomShowList.size(); ++i)
    {
        Reference<css::container::XIndexContainer> xShow(mxShowFactory->createInstance(),
                                                                    UNO_QUERY);
        if (xShow.is())
        {
            static constexpr OUString sSlide = u"slides/slide"_ustr;
            for (size_t j = 0; j < rCustomShowList[i].maSldLst.size(); ++j)
            {
                OUString sCustomSlide = rCustomShowList[i].maSldLst[j];
                sal_Int32 nPageNumber = 0;
                if (sCustomSlide.match(sSlide))
                    nPageNumber = o3tl::toInt32(sCustomSlide.subView(sSlide.getLength()));

                Reference<XDrawPage> xPage;
                xDrawPages->getByIndex(nPageNumber - 1) >>= xPage;
                if (xPage.is())
                    xShow->insertByIndex(xShow->getCount(), Any(xPage));
            }

            Any aAny;
            aAny <<= xShow;
            mxShows->insertByName(rCustomShowList[i].maCustomShowName, aAny);
        }
    }
}

void PresentationFragmentHandler::importMasterSlide(const Reference<frame::XModel>&&nbsp;xModel,
                                                    PowerPointImport& rFilter,
                                                    const OUString& rMasterFragmentPath)
{
    OUString aLayoutFragmentPath;
    SlidePersistPtr pMasterPersistPtr;
    Reference< drawing::XDrawPage > xMasterPage;
    Reference< drawing::XMasterPagesSupplier > xMPS( xModel, uno::UNO_QUERY_THROW );
    Reference< drawing::XDrawPages > xMasterPages( xMPS->getMasterPages(), uno::UNO_SET_THROW );
    RelationsRef xMasterRelations = rFilter.importRelations( rMasterFragmentPath );

    for (const auto& rEntry : *xMasterRelations)
    {
        if (!rEntry.second.maType.endsWith("relationships/slideLayout"))
            continue;

        aLayoutFragmentPath = xMasterRelations->getFragmentPathFromRelation(rEntry.second);

        sal_Int32 nIndex;
        if( rFilter.getMasterPages().empty() )
        {
            nIndex = 0;
            xMasterPages->getByIndex( nIndex ) >>= xMasterPage;
        }
        else
        {
            nIndex = xMasterPages->getCount();
            xMasterPage = xMasterPages->insertNewByIndex( nIndex );
        }

        pMasterPersistPtr = std::make_shared<SlidePersist>( rFilter, truefalse, xMasterPage,
                                                            std::make_shared<PPTShape>( Master, u"com.sun.star.drawing.GroupShape"_ustr ), mpTextListStyle );
        pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
        rFilter.getMasterPages().push_back( pMasterPersistPtr );
        rFilter.setActualSlidePersist( pMasterPersistPtr );
        FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, rMasterFragmentPath, pMasterPersistPtr, Master ) );

        // set the correct theme
        OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"theme" );
        if( !aThemeFragmentPath.isEmpty() )
        {
            std::map< OUString, oox::drawingml::ThemePtr >& rThemes( rFilter.getThemes() );
            std::map< OUString, oox::drawingml::ThemePtr >::iterator aIter2( rThemes.find( aThemeFragmentPath ) );
            if( aIter2 == rThemes.end() )
            {
                oox::drawingml::ThemePtr pThemePtr = std::make_shared<oox::drawingml::Theme>();
                pMasterPersistPtr->setTheme( pThemePtr );
                Reference<xml::dom::XDocument> xDoc=
                    rFilter.importFragment(aThemeFragmentPath);

                auto pTheme = std::make_shared<model::Theme>();
                pThemePtr->setTheme(pTheme);

                rFilter.importFragment(
                    new ThemeFragmentHandler(rFilter, aThemeFragmentPath, *pThemePtr, *pTheme),
                    Reference<xml::sax::XFastSAXSerializable>(
                        xDoc,
                        UNO_QUERY_THROW));
                rThemes[ aThemeFragmentPath ] = pThemePtr;
                pThemePtr->setFragment(xDoc);
                saveThemeToGrabBag(pThemePtr, nIndex + 1);
            }
            else
            {
                pMasterPersistPtr->setTheme( (*aIter2).second );
            }
        }
        importSlide( xMasterFragmentHandler, pMasterPersistPtr );
        rFilter.importFragment( new LayoutFragmentHandler( rFilter, aLayoutFragmentPath, pMasterPersistPtr ) );
        pMasterPersistPtr->createBackground( rFilter );
        pMasterPersistPtr->createXShapes( rFilter );

        saveColorMapToGrabBag(pMasterPersistPtr->getClrMap());

        uno::Reference< beans::XPropertySet > xSet(pMasterPersistPtr->getPage(), uno::UNO_QUERY_THROW);
        xSet->setPropertyValue(u"SlideLayout"_ustr, Any(pMasterPersistPtr->getLayoutFromValueToken()));

        oox::drawingml::ThemePtr pTheme = pMasterPersistPtr->getTheme();
        if (pTheme)
        {
            pTheme->addTheme(pMasterPersistPtr->getPage());
        }
    }
}

void PresentationFragmentHandler::saveThemeToGrabBag(const oox::drawingml::ThemePtr& pThemePtr,
                                                     sal_Int32 nThemeIdx)
{
    if (!pThemePtr)
        return;

    try
    {
        uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
        if (xDocProps.is())
        {
            uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();

            static constexpr OUString aGrabBagPropName = u"InteropGrabBag"_ustr;
            if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
            {
                // get existing grab bag
                comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));

                comphelper::SequenceAsHashMap aThemesHashMap;

                // create current theme
                uno::Sequence<beans::PropertyValue> aCurrentTheme(PredefinedClrSchemeId::Count);
                auto pCurrentTheme = aCurrentTheme.getArray();

                ClrScheme rClrScheme = pThemePtr->getClrScheme();
                for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
                {
                    auto eID = static_cast<PredefinedClrSchemeId>(nId);
                    sal_uInt32 nToken = getPredefinedClrTokens(eID);
                    OUString sName(getPredefinedClrNames(eID));
                    ::Color nColor;

                    rClrScheme.getColor(nToken, nColor);

                    pCurrentTheme[nId].Name = sName;
                    pCurrentTheme[nId].Value <<= nColor;
                }


                uno::Sequence<beans::PropertyValue> aTheme{
                    // add new theme to the sequence
                    // Export code uses the master slide's index to find the right theme
                    // so use the same index in the grabbag.
                    comphelper::makePropertyValue(
                        "ppt/theme/theme" + OUString::number(nThemeIdx) + ".xml", aCurrentTheme),
                    // store DOM fragment for SmartArt re-generation
                    comphelper::makePropertyValue(u"OOXTheme"_ustr, pThemePtr->getFragment())
                };

                aThemesHashMap << aTheme;

                // put the new items
                aGrabBag.update(aThemesHashMap);

                // put it back to the document
                xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList()));
            }
        }
    }
    catch (const uno::Exception&)
    {
        SAL_WARN("oox""oox::ppt::PresentationFragmentHandler::saveThemeToGrabBag, Failed to save grab bag");
    }
}

void PresentationFragmentHandler::saveColorMapToGrabBag(const oox::drawingml::ClrMapPtr& pClrMapPtr)
{
    if (!pClrMapPtr)
        return;

    try
    {
        uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
        if (xDocProps.is())
        {
            uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();

            static constexpr OUString aGrabBagPropName = u"InteropGrabBag"_ustr;
            if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
            {
                static const constexpr std::array<sal_Int32, 12> constTokenArray
                    = { XML_bg1,     XML_tx1,     XML_bg2,     XML_tx2,
                        XML_accent1, XML_accent2, XML_accent3, XML_accent4,
                        XML_accent5, XML_accent6, XML_hlink,   XML_folHlink };

                comphelper::SequenceAsHashMap aClrMapHashMap;
                comphelper::SequenceAsHashMap aGrabBag(
                    xDocProps->getPropertyValue(aGrabBagPropName));

                std::vector<beans::PropertyValue> aClrMapList;
                size_t nColorMapSize = constTokenArray.size();
                aClrMapList.reserve(nColorMapSize);
                for (size_t i = 0; i < nColorMapSize; ++i)
                {
                    sal_Int32 nToken = constTokenArray[i];
                    pClrMapPtr->getColorMap(nToken);
                    aClrMapList.push_back(
                        comphelper::makePropertyValue(OUString::number(i), nToken));
                }

                uno::Sequence<beans::PropertyValue> aClrMapPropValue{ comphelper::makePropertyValue(
                    u"OOXColorMap"_ustr,
                    uno::Any(comphelper::containerToSequence(aClrMapList))) };

                aClrMapHashMap << aClrMapPropValue;
                aGrabBag.update(aClrMapHashMap);

                xDocProps->setPropertyValue(aGrabBagPropName,
                                            uno::Any(aGrabBag.getAsConstPropertyValueList()));
            }
        }
    }
    catch (const uno::Exception&)
    {
        SAL_WARN("oox""oox::ppt::PresentationFragmentHandler::saveColorMapToGrabBag, Failed to save grab bag");
    }
}

void PresentationFragmentHandler::importMasterSlides()
{
    OUString aMasterFragmentPath;
    PowerPointImport& rFilter = dynamic_cast<PowerPointImport&>(getFilter());
    Reference<frame::XModel> xModel(rFilter.getModel());

    for (size_t nMaster = 0; nMaster < maSlideMasterVector.size(); ++nMaster)
    {
        aMasterFragmentPath = getFragmentPathFromRelId(maSlideMasterVector[nMaster]);
        importMasterSlide(xModel, rFilter, aMasterFragmentPath);
    }
}

void PresentationFragmentHandler::importSlide(sal_uInt32 nSlide, bool bFirstPage, bool bImportNotesPage)
{
    PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );

    Reference< frame::XModel > xModel( rFilter.getModel() );
    Reference< drawing::XDrawPage > xSlide;

    // importing slide pages and its corresponding notes page
    Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
    Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_SET_THROW );

    try {

        if( bFirstPage )
        {
            xDrawPages->getByIndex( 0 ) >>= xSlide;
            importMasterSlides();
        }
        else
            xSlide = xDrawPages->insertNewByIndex( xDrawPages->getCount() );

        OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] );
        if( !aSlideFragmentPath.isEmpty() )
        {
            SlidePersistPtr pMasterPersistPtr;
            SlidePersistPtr pSlidePersistPtr = std::make_shared<SlidePersist>( rFilter, falsefalse, xSlide,
                                std::make_shared<PPTShape>( Slide, u"com.sun.star.drawing.GroupShape"_ustr ), mpTextListStyle );

            FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( rFilter, aSlideFragmentPath, pSlidePersistPtr, Slide ) );

            // importing the corresponding masterpage/layout
            OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideLayout" );
            OUString aCommentFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"comments" );
            if ( !aLayoutFragmentPath.isEmpty() )
            {
                // importing layout
                RelationsRef xLayoutRelations = rFilter.importRelations( aLayoutFragmentPath );
                OUString aMasterFragmentPath = xLayoutRelations->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideMaster" );
                if( !aMasterFragmentPath.isEmpty() )
                {
                    // check if the corresponding masterpage+layout has already been imported
                    std::vector< SlidePersistPtr >& rMasterPages( rFilter.getMasterPages() );
                    for (auto const& masterPage : rMasterPages)
                    {
                        if ( ( masterPage->getPath() == aMasterFragmentPath ) && ( masterPage->getLayoutPath() == aLayoutFragmentPath ) )
                        {
                            pMasterPersistPtr = masterPage;
                            break;
                        }
                    }
                }
            }

            // importing slide page
            if (pMasterPersistPtr) {
                pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
                pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
                Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
                if( xMasterPageTarget.is() )
                    xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
            }
            rFilter.getDrawPages().push_back( pSlidePersistPtr );
            rFilter.setActualSlidePersist( pSlidePersistPtr );
            importSlide( xSlideFragmentHandler, pSlidePersistPtr );
            pSlidePersistPtr->createBackground( rFilter );
            pSlidePersistPtr->createXShapes( rFilter );

            if(bImportNotesPage) {

                // now importing the notes page
                OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"notesSlide" );
                if( !aNotesFragmentPath.isEmpty() )
                {
                    Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
                    if ( xPresentationPage.is() )
                    {
                        Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
                        if ( xNotesPage.is() )
                        {
                            SlidePersistPtr pNotesPersistPtr = std::make_shared<SlidePersist>( rFilter, falsetruexNotesPage,
                                std::make_shared<PPTShape>( Slide, u"com.sun.star.drawing.GroupShape"_ustr ), mpTextListStyle );
                            FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
                            rFilter.getNotesPages().push_back( pNotesPersistPtr );
                            rFilter.setActualSlidePersist( pNotesPersistPtr );
                            importSlide( xNotesFragmentHandler, pNotesPersistPtr );
                            pNotesPersistPtr->createBackground( rFilter );
                            pNotesPersistPtr->createXShapes( rFilter );
                        }
                    }
                }
            }

            if( !mbCommentAuthorsRead && !aCommentFragmentPath.isEmpty() )
            {
                // Comments are present and commentAuthors.xml has still not been read
                mbCommentAuthorsRead = true;
                Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
                Reference< XDrawPage > xCommentAuthorsPage( xPresentationPage->getNotesPage() );
                SlidePersistPtr pCommentAuthorsPersistPtr =
                    std::make_shared<SlidePersist>( rFilter, falsetrue, xCommentAuthorsPage,
                                      std::make_shared<PPTShape>(
                                              Slide, u"com.sun.star.drawing.GroupShape"_ustr ),
                                      mpTextListStyle );
                FragmentHandlerRef xCommentAuthorsFragmentHandler(
                    new SlideFragmentHandler( getFilter(),
                                              u"ppt/commentAuthors.xml"_ustr,
                                              pCommentAuthorsPersistPtr,
                                              Slide ) );

                getFilter().importFragment( xCommentAuthorsFragmentHandler );
                maAuthorList.setValues( pCommentAuthorsPersistPtr->getCommentAuthors() );
            }
            if( !aCommentFragmentPath.isEmpty() )
            {
                Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
                Reference< XDrawPage > xCommentsPage( xPresentationPage->getNotesPage() );
                SlidePersistPtr pCommentsPersistPtr =
                    std::make_shared<SlidePersist>(
                        rFilter, falsetrue, xCommentsPage,
                        std::make_shared<PPTShape>(
                                Slide, u"com.sun.star.drawing.GroupShape"_ustr ),
                        mpTextListStyle );

                FragmentHandlerRef xCommentsFragmentHandler(
                    new SlideFragmentHandler(
                        getFilter(),
                        aCommentFragmentPath,
                        pCommentsPersistPtr,
                        Slide ) );
                pCommentsPersistPtr->getCommentsList().cmLst.clear();
                getFilter().importFragment( xCommentsFragmentHandler );

                if (!pCommentsPersistPtr->getCommentsList().cmLst.empty())
                {
                    //set comment chars for last comment on slide
                    SlideFragmentHandler* comment_handler =
                        dynamic_cast<SlideFragmentHandler*>(xCommentsFragmentHandler.get());
                    assert(comment_handler);
                    // some comments have no text -> set empty string as text to avoid
                    // crash (back() on empty vector is undefined) and losing other
                    // comment data that might be there (author, position, timestamp etc.)
                    pCommentsPersistPtr->getCommentsList().cmLst.back().setText(
                            comment_handler->getCharVector().empty() ? u""_ustr :
                            comment_handler->getCharVector().back() );
                }
                pCommentsPersistPtr->getCommentAuthors().setValues(maAuthorList);

                //insert all comments from commentsList
                for(int i=0; i<pCommentsPersistPtr->getCommentsList().getSize(); i++)
                {
                    try {
                        Comment aComment = pCommentsPersistPtr->getCommentsList().getCommentAtIndex(i);
                        uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xSlide, UNO_QUERY_THROW );
                        uno::Reference< office::XAnnotation > xAnnotation( xAnnotationAccess->createAndInsertAnnotation() );
                        int nPosX = aComment.getIntX();
                        int nPosY = aComment.getIntY();
                        xAnnotation->setPosition(
                            geometry::RealPoint2D(
                                ::oox::drawingml::convertEmuToHmm( nPosX ) * 15.87,
                                ::oox::drawingml::convertEmuToHmm( nPosY ) * 15.87 ) );
                        xAnnotation->setAuthor( aComment.getAuthor(maAuthorList) );
                        xAnnotation->setInitials( aComment.getInitials(maAuthorList) );
                        xAnnotation->setDateTime( aComment.getDateTime() );
                        uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
                        xText->setString( aComment.get_text());
                    } catch( css::lang::IllegalArgumentException& ) {}
                }
            }
        }
    }
    catch( uno::Exception& )
    {
        TOOLS_WARN_EXCEPTION( "oox""oox::ppt::PresentationFragmentHandler::EndDocument()" );
    }
}

void PresentationFragmentHandler::finalizeImport()
{
    PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );

    sal_Int32 nPageCount = maSlidesVector.size();

    // we will take the FilterData property "PageRange" if available, otherwise full range is used
    comphelper::SequenceAsHashMap& rFilterData = rFilter.getFilterData();

    // writing back the original PageCount of this document, it can be accessed from the XModel
    // via getArgs after the import.
    rFilterData[u"OriginalPageCount"_ustr] <<= nPageCount;
    bool bImportNotesPages = rFilterData.getUnpackedValueOrDefault(u"ImportNotesPages"_ustr, true);
    OUString aPageRange = rFilterData.getUnpackedValueOrDefault(u"PageRange"_ustr, OUString());

    if( !aPageRange.getLength() )
    {
        aPageRange = "1-" + OUString::number( nPageCount );
    }

    StringRangeEnumerator aRangeEnumerator( aPageRange, 0, nPageCount - 1 );
    if (aRangeEnumerator.size())
    {
        // todo: localized progress bar text
        const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
        if ( rxStatusIndicator.is() )
            rxStatusIndicator->start( OUString(), 10000 );

        try
        {
            int nPagesImported = 0;
            for (sal_Int32 elem : aRangeEnumerator)
            {
                if ( rxStatusIndicator.is() )
                    rxStatusIndicator->setValue((nPagesImported * 10000) / aRangeEnumerator.size());

                importSlide(elem, !nPagesImported, bImportNotesPages);
                nPagesImported++;
            }
            importSlideNames( rFilter, rFilter.getDrawPages());
            if (!maCustomShowList.empty())
                importCustomSlideShow(maCustomShowList);
        }
        catch( uno::Exception& )
        {
            TOOLS_WARN_EXCEPTION( "oox""oox::ppt::PresentationFragmentHandler::finalizeImport()" );
        }
        // todo error handling;
        if ( rxStatusIndicator.is() )
            rxStatusIndicator->end();
    }

    // open the VBA project storage
    OUString aVbaFragmentPath = getFragmentPathFromFirstType(CREATE_MSOFFICE_RELATION_TYPE("vbaProject"));
    if (!aVbaFragmentPath.isEmpty())
    {
        uno::Reference<io::XInputStream> xInStrm = getFilter().openInputStream(aVbaFragmentPath);
        if (xInStrm.is())
        {
            StorageRef xPrjStrg = std::make_shared<oox::ole::OleStorage>(getFilter().getComponentContext(), xInStrm, false);
            getFilter().getVbaProject().importVbaProject(*xPrjStrg);
        }
    }
}

// CT_Presentation
::oox::core::ContextHandlerRef PresentationFragmentHandler::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
{
    switch( aElementToken )
    {
    case PPT_TOKEN( presentation ):
        mbEmbedTrueTypeFonts = rAttribs.getBool(XML_embedTrueTypeFonts, false);
        return this;
    case PPT_TOKEN( sldMasterIdLst ):
    case PPT_TOKEN( notesMasterIdLst ):
    case PPT_TOKEN( sldIdLst ):
        return this;
    case PPT_TOKEN( sldMasterId ):
        maSlideMasterVector.push_back( rAttribs.getStringDefaulted( R_TOKEN( id )) );
        return this;
    case PPT_TOKEN( sldId ):
        maSlidesVector.push_back( rAttribs.getStringDefaulted( R_TOKEN( id )) );
        return this;
    case PPT_TOKEN( notesMasterId ):
        maNotesMasterVector.push_back( rAttribs.getStringDefaulted( R_TOKEN( id )) );
        return this;
    case PPT_TOKEN( sldSz ):
        maSlideSize = GetSize2D( rAttribs.getFastAttributeList() );
        return this;
    case PPT_TOKEN( notesSz ):
        maNotesSize = GetSize2D( rAttribs.getFastAttributeList() );
        return this;
    case PPT_TOKEN( custShowLst ):
        return new CustomShowListContext( *this, maCustomShowList );
    case PPT_TOKEN( defaultTextStyle ):
        return new TextListStyleContext( *this, *mpTextListStyle );
    case PPT_TOKEN(embeddedFontLst):
    {
        uno::Reference<beans::XPropertySet> xDocSettings(getFilter().getModelFactory()->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY);
        return new EmbeddedFontListContext(*this, mbEmbedTrueTypeFonts, xDocSettings);
    }
    case PPT_TOKEN( modifyVerifier ):
        OUString sAlgorithmClass = rAttribs.getStringDefaulted(XML_cryptAlgorithmClass);
        OUString sAlgorithmType = rAttribs.getStringDefaulted(XML_cryptAlgorithmType);
        sal_Int32 nAlgorithmSid = rAttribs.getInteger(XML_cryptAlgorithmSid, 0);
        sal_Int32 nSpinCount = rAttribs.getInteger(XML_spinCount, 0);
        OUString sSalt = rAttribs.getStringDefaulted(XML_saltData);
        OUString sHash = rAttribs.getStringDefaulted(XML_hashData);
        if (sAlgorithmClass == "hash" && sAlgorithmType == "typeAny" && nAlgorithmSid != 0
            && !sSalt.isEmpty() && !sHash.isEmpty())
        {
            OUString sAlgorithmName;
            switch (nAlgorithmSid)
            {
                case 1:
                    sAlgorithmName = "MD2";
                    break;
                case 2:
                    sAlgorithmName = "MD4";
                    break;
                case 3:
                    sAlgorithmName = "MD5";
                    break;
                case 4:
                    sAlgorithmName = "SHA-1";
                    break;
                case 5:
                    sAlgorithmName = "MAC";
                    break;
                case 6:
                    sAlgorithmName = "RIPEMD";
                    break;
                case 7:
                    sAlgorithmName = "RIPEMD-160";
                    break;
                case 9:
                    sAlgorithmName = "HMAC";
                    break;
                case 12:
                    sAlgorithmName = "SHA-256";
                    break;
                case 13:
                    sAlgorithmName = "SHA-384";
                    break;
                case 14:
                    sAlgorithmName = "SHA-512";
                    break;
                default:; // 8, 10, 11, any other value: Undefined.
            }

            if (!sAlgorithmName.isEmpty())
            {
                uno::Sequence<beans::PropertyValue> aResult{
                    comphelper::makePropertyValue(u"algorithm-name"_ustr, sAlgorithmName),
                    comphelper::makePropertyValue(u"salt"_ustr, sSalt),
                    comphelper::makePropertyValue(u"iteration-count"_ustr, nSpinCount),
                    comphelper::makePropertyValue(u"hash"_ustr, sHash)
                };
                try
                {
                    uno::Reference<beans::XPropertySet> xDocSettings(
                        getFilter().getModelFactory()->createInstance(
                            u"com.sun.star.document.Settings"_ustr),
                        uno::UNO_QUERY);
                    xDocSettings->setPropertyValue(u"ModifyPasswordInfo"_ustr, uno::Any(aResult));
                }
                catch (const uno::Exception&)
                {
                }
            }
        }
        return this;
    }
    return this;
}

void PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
        const SlidePersistPtr& rSlidePersistPtr )
{
    Reference< drawing::XDrawPage > xSlide( rSlidePersistPtr->getPage() );
    SlidePersistPtr pMasterPersistPtr( rSlidePersistPtr->getMasterPersist() );
    if ( pMasterPersistPtr )
    {
        // Setting "Layout" property adds extra title and outliner preset shapes to the master slide
        Reference< drawing::XDrawPage > xMasterSlide(pMasterPersistPtr->getPage());
        const int nCount = xMasterSlide->getCount();

        uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
        xSet->setPropertyValue( u"Layout"_ustr, Any( pMasterPersistPtr->getLayoutFromValueToken() ) );

        while( nCount < xMasterSlide->getCount())
        {
            Reference< drawing::XShape > xShape;
            xMasterSlide->getByIndex(xMasterSlide->getCount()-1) >>= xShape;
            xMasterSlide->remove(xShape);
        }
    }
    while( xSlide->getCount() )
    {
        Reference< drawing::XShape > xShape;
        xSlide->getByIndex(0) >>= xShape;
        xSlide->remove( xShape );
    }

    Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
    if ( xPropertySet.is() )
    {
        awt::Size& rPageSize( rSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
        xPropertySet->setPropertyValue( u"Width"_ustr, Any( rPageSize.Width ) );
        xPropertySet->setPropertyValue( u"Height"_ustr, Any( rPageSize.Height ) );

        oox::ppt::HeaderFooter aHeaderFooter( rSlidePersistPtr->getHeaderFooter() );
        if ( !rSlidePersistPtr->isMasterPage() )
            aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = false;
        try
        {
            if ( rSlidePersistPtr->isNotesPage() )
                xPropertySet->setPropertyValue( u"IsHeaderVisible"_ustr, Any( aHeaderFooter.mbHeader ) );
            xPropertySet->setPropertyValue( u"IsFooterVisible"_ustr, Any( aHeaderFooter.mbFooter ) );
            xPropertySet->setPropertyValue( u"IsDateTimeVisible"_ustr, Any( aHeaderFooter.mbDateTime ) );
            xPropertySet->setPropertyValue( u"IsPageNumberVisible"_ustr, Any( aHeaderFooter.mbSlideNumber ) );
        }
        catch( uno::Exception& )
        {
        }
    }
    rSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
    getFilter().importFragment( rxSlideFragmentHandler );
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=96 H=89 G=92

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.