/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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& 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:////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 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 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 aArguments(comphelper::InitAnyPropertySequence( { {"IsPPTM", uno::makeAny(exportVBA())}, {"IsTemplate", uno::makeAny(isExportTemplate())}, })); Reference aFactory(getComponentContext()->getServiceManager(), UNO_QUERY_THROW); Reference< XExporter > xExporter(aFactory->createInstanceWithArguments("com.sun.star.comp.Impress.oox.PowerPointExport", aArguments), UNO_QUERY); if (Reference xFilter{ xExporter, UNO_QUERY }) { Reference xUndoManager; bool bWasUnLocked = true; if (Reference 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( ); 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 const& /*rSeq*/) { return cppu::acquire(new oox::ppt::PowerPointImport(pCtx)); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */