diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /oox/source/ppt/pptimport.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'oox/source/ppt/pptimport.cxx')
-rw-r--r-- | oox/source/ppt/pptimport.cxx | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/oox/source/ppt/pptimport.cxx b/oox/source/ppt/pptimport.cxx new file mode 100644 index 000000000..f7d009207 --- /dev/null +++ b/oox/source/ppt/pptimport.cxx @@ -0,0 +1,340 @@ +/* -*- 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 <sal/config.h> +#include <sal/log.hxx> + +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/document/XUndoManager.hpp> +#include <com/sun/star/document/XUndoManagerSupplier.hpp> +#include <comphelper/propertysequence.hxx> +#include <comphelper/scopeguard.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <svtools/sfxecode.hxx> +#include <svtools/ehdl.hxx> +#include <tools/urlobj.hxx> +#include <svx/dialmgr.hxx> +#include <svx/strings.hrc> +#include <oox/ppt/pptimport.hxx> +#include <oox/drawingml/chart/chartconverter.hxx> +#include <oox/dump/pptxdumper.hxx> +#include <drawingml/table/tablestylelistfragmenthandler.hxx> +#include <oox/helper/graphichelper.hxx> +#include <oox/ole/vbaproject.hxx> +#include <oox/ppt/presentationfragmenthandler.hxx> +#include <oox/ppt/presPropsfragmenthandler.hxx> +#include <oox/token/tokens.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace oox::core; + +using ::com::sun::star::beans::PropertyValue; +using ::com::sun::star::lang::XComponent; + +namespace oox::ppt { + +#if OSL_DEBUG_LEVEL > 0 +XmlFilterBase* PowerPointImport::mpDebugFilterBase = nullptr; +#endif + +PowerPointImport::PowerPointImport( const Reference< XComponentContext >& rxContext ) : + XmlFilterBase( rxContext ), + mxChartConv( std::make_shared<::oox::drawingml::chart::ChartConverter>() ) + +{ +#if OSL_DEBUG_LEVEL > 0 + mpDebugFilterBase = this; +#endif +} + +PowerPointImport::~PowerPointImport() +{ + maPPTShapes.clear(); +} + +/// Visits the relations from pRelations which are of type rType. +static void visitRelations(PowerPointImport& rImport, const core::RelationsRef& pRelations, const OUString& rType, std::vector<OUString>& rImageFragments) +{ + core::RelationsRef pRelationsOfType = pRelations->getRelationsFromTypeFromOfficeDoc(rType); + if (!pRelationsOfType) + return; + + for (const auto& rRelation : *pRelationsOfType) + { + OUString aFragment = pRelationsOfType->getFragmentPathFromRelation(rRelation.second); + if (core::RelationsRef pFragmentRelations = rImport.importRelations(aFragment)) + { + // See if the fragment has images. + if (core::RelationsRef pImages = pFragmentRelations->getRelationsFromTypeFromOfficeDoc("image")) + { + for (const auto& rImage : *pImages) + { + OUString aPath = pImages->getFragmentPathFromRelation(rImage.second); + // Safe subset: e.g. WMF may have an external header from the + // referencing fragment. + if (aPath.endsWith(".jpg") || aPath.endsWith(".jpeg")) + rImageFragments.push_back(aPath); + } + } + + // See if the fragment has a slide layout, and recurse. + visitRelations(rImport, pFragmentRelations, "slideLayout", rImageFragments); + } + } +} + +bool PowerPointImport::importDocument() +{ + /* to activate the PPTX dumper, define the environment variable + OOO_PPTXDUMPER and insert the full path to the file + file:///<path-to-oox-module>/source/dump/pptxdumper.ini. */ + OOX_DUMP_FILE( ::oox::dump::pptx::Dumper ); + + uno::Reference< document::XUndoManagerSupplier > xUndoManagerSupplier (getModel(), UNO_QUERY ); + uno::Reference< util::XLockable > xUndoManager; + bool bWasUnLocked = true; + if(xUndoManagerSupplier.is()) + { + xUndoManager = xUndoManagerSupplier->getUndoManager(); + if(xUndoManager.is()) + { + bWasUnLocked = !xUndoManager->isLocked(); + xUndoManager->lock(); + } + } + + importDocumentProperties(); + + OUString aFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( "officeDocument" ); + FragmentHandlerRef xPresentationFragmentHandler( new PresentationFragmentHandler( *this, aFragmentPath ) ); + maTableStyleListPath = xPresentationFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( "tableStyles" ); + const OUString sPresPropsPath + = xPresentationFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc("presProps"); + + // importRelations() is cheap, it will do an actual import for the first time only. + if (core::RelationsRef pFragmentRelations = importRelations(aFragmentPath)) + { + std::vector<OUString> aImageFragments; + visitRelations(*this, pFragmentRelations, "slide", aImageFragments); + visitRelations(*this, pFragmentRelations, "slideMaster", aImageFragments); + + getGraphicHelper().importEmbeddedGraphics(aImageFragments); + } + + bool bRet = importFragment(xPresentationFragmentHandler); + if (bRet && !sPresPropsPath.isEmpty()) + { + FragmentHandlerRef xPresPropsFragmentHandler( + new PresPropsFragmentHandler(*this, sPresPropsPath)); + importFragment(xPresPropsFragmentHandler); + } + + static bool bNoSmartartWarning = getenv("OOX_NO_SMARTART_WARNING"); + if (!bNoSmartartWarning && mbMissingExtDrawing) + { + // Construct a warning message. + INetURLObject aURL(getFileUrl()); + SfxErrorContext aContext(ERRCTX_SFX_OPENDOC, aURL.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset), nullptr, RID_ERRCTX); + OUString aWarning; + aContext.GetString(ERRCODE_NONE.MakeWarning(), aWarning); + aWarning += ":\n" + SvxResId(RID_SVXSTR_WARN_MISSING_SMARTART); + + // Show it. + std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(nullptr, + VclMessageType::Warning, VclButtonsType::Ok, + aWarning)); + xWarn->run(); + } + + if(xUndoManager.is() && bWasUnLocked) + xUndoManager->unlock(); + + return bRet; + +} + +bool PowerPointImport::exportDocument() throw() +{ + return false; +} + +::Color PowerPointImport::getSchemeColor( sal_Int32 nToken ) const +{ + ::Color nColor; + if ( mpActualSlidePersist ) + { + bool bColorMapped = false; + oox::drawingml::ClrMapPtr pClrMapPtr( mpActualSlidePersist->getClrMap() ); + if ( pClrMapPtr ) + bColorMapped = pClrMapPtr->getColorMap( nToken ); + + if ( !bColorMapped ) // try masterpage mapping + { + SlidePersistPtr pMasterPersist = mpActualSlidePersist->getMasterPersist(); + if ( pMasterPersist ) + { + pClrMapPtr = pMasterPersist->getClrMap(); + if ( pClrMapPtr ) + pClrMapPtr->getColorMap( nToken ); + } + } + + ::oox::drawingml::ThemePtr pTheme = mpActualSlidePersist->getTheme(); + if( pTheme ) + { + pTheme->getClrScheme().getColor( nToken, nColor ); + } + else + { + SAL_WARN("oox", "OOX: PowerPointImport::mpThemePtr is NULL"); + } + } + return nColor; +} + +const ::oox::drawingml::Theme* PowerPointImport::getCurrentTheme() const +{ + return mpActualSlidePersist ? mpActualSlidePersist->getTheme().get() : nullptr; +} + +sal_Bool SAL_CALL PowerPointImport::filter( const Sequence< PropertyValue >& rDescriptor ) +{ + if( XmlFilterBase::filter( rDescriptor ) ) + return true; + + if (isExportFilter()) + { + uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence( + { + {"IsPPTM", uno::makeAny(exportVBA())}, + {"IsTemplate", uno::makeAny(isExportTemplate())}, + })); + + Reference<css::lang::XMultiServiceFactory> aFactory(getComponentContext()->getServiceManager(), UNO_QUERY_THROW); + Reference< XExporter > xExporter(aFactory->createInstanceWithArguments("com.sun.star.comp.Impress.oox.PowerPointExport", aArguments), UNO_QUERY); + + if (Reference<XFilter> xFilter{ xExporter, UNO_QUERY }) + { + Reference<util::XLockable> xUndoManager; + bool bWasUnLocked = true; + if (Reference<document::XUndoManagerSupplier> xUMS{ getModel(), UNO_QUERY }) + { + xUndoManager = xUMS->getUndoManager(); + if (xUndoManager.is()) + { + bWasUnLocked = !xUndoManager->isLocked(); + xUndoManager->lock(); + } + } + comphelper::ScopeGuard aGuard([xUndoManager, bWasUnLocked] { + if (xUndoManager && bWasUnLocked) + xUndoManager->unlock(); + }); + + Reference< XComponent > xDocument = getModel(); + xExporter->setSourceDocument(xDocument); + if (xFilter->filter(rDescriptor)) + return true; + } + } + + return false; +} + +::oox::vml::Drawing* PowerPointImport::getVmlDrawing() +{ + return mpActualSlidePersist ? mpActualSlidePersist->getDrawing() : nullptr; +} + +oox::drawingml::table::TableStyleListPtr PowerPointImport::getTableStyles() +{ + if ( !mpTableStyleList && !maTableStyleListPath.isEmpty() ) + { + mpTableStyleList = std::make_shared<oox::drawingml::table::TableStyleList>( ); + importFragment( new oox::drawingml::table::TableStyleListFragmentHandler( + *this, maTableStyleListPath, *mpTableStyleList ) ); + } + return mpTableStyleList; +} + +::oox::drawingml::chart::ChartConverter* PowerPointImport::getChartConverter() +{ + return mxChartConv.get(); +} + +namespace { + +class PptGraphicHelper : public GraphicHelper +{ +public: + explicit PptGraphicHelper( const PowerPointImport& rFilter ); + virtual ::Color getSchemeColor( sal_Int32 nToken ) const override; + virtual sal_Int32 getDefaultChartAreaFillStyle() const override; +private: + const PowerPointImport& mrFilter; +}; + +PptGraphicHelper::PptGraphicHelper( const PowerPointImport& rFilter ) : + GraphicHelper( rFilter.getComponentContext(), rFilter.getTargetFrame(), rFilter.getStorage() ), + mrFilter( rFilter ) +{ +} + +::Color PptGraphicHelper::getSchemeColor( sal_Int32 nToken ) const +{ + return mrFilter.getSchemeColor( nToken ); +} + +sal_Int32 PptGraphicHelper::getDefaultChartAreaFillStyle() const +{ + return XML_noFill; +} + +} // namespace + +GraphicHelper* PowerPointImport::implCreateGraphicHelper() const +{ + return new PptGraphicHelper( *this ); +} + +::oox::ole::VbaProject* PowerPointImport::implCreateVbaProject() const +{ + return new ::oox::ole::VbaProject( getComponentContext(), getModel(), "Impress" ); +} + +OUString PowerPointImport::getImplementationName() +{ + return "com.sun.star.comp.oox.ppt.PowerPointImport"; +} + +} + +extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* +com_sun_star_comp_oox_ppt_PowerPointImport_get_implementation( + uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/) +{ + return cppu::acquire(new oox::ppt::PowerPointImport(pCtx)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |