summaryrefslogtreecommitdiffstats
path: root/sd/source/filter/grf/sdgrffilter.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/filter/grf/sdgrffilter.cxx')
-rw-r--r--sd/source/filter/grf/sdgrffilter.cxx326
1 files changed, 326 insertions, 0 deletions
diff --git a/sd/source/filter/grf/sdgrffilter.cxx b/sd/source/filter/grf/sdgrffilter.cxx
new file mode 100644
index 0000000000..1bb51ae40f
--- /dev/null
+++ b/sd/source/filter/grf/sdgrffilter.cxx
@@ -0,0 +1,326 @@
+/* -*- 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 <com/sun/star/drawing/GraphicExportFilter.hpp>
+
+#include <utility>
+#include <vcl/errinf.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/sfxuno.hxx>
+#include <svx/svdograf.hxx>
+
+#include <strings.hrc>
+#include <DrawViewShell.hxx>
+#include <DrawDocShell.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/svapp.hxx>
+
+#include <sdpage.hxx>
+#include <drawdoc.hxx>
+#include <sdresid.hxx>
+#include <sdgrffilter.hxx>
+#include <ViewShellBase.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/task/XInteractionRequest.hpp>
+#include <com/sun/star/drawing/GraphicFilterRequest.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::ucb;
+using namespace com::sun::star::ui::dialogs;
+using namespace ::sfx2;
+
+namespace {
+
+class SdGRFFilter_ImplInteractionHdl : public ::cppu::WeakImplHelper< css::task::XInteractionHandler >
+{
+ css::uno::Reference< css::task::XInteractionHandler > m_xInter;
+ ErrCode nFilterError;
+
+ public:
+
+ explicit SdGRFFilter_ImplInteractionHdl( css::uno::Reference< css::task::XInteractionHandler > xInteraction ) :
+ m_xInter(std::move( xInteraction )),
+ nFilterError( ERRCODE_NONE )
+ {}
+
+ ErrCode const & GetErrorCode() const { return nFilterError; };
+
+ virtual void SAL_CALL handle( const css::uno::Reference< css::task::XInteractionRequest >& ) override;
+};
+
+}
+
+void SdGRFFilter_ImplInteractionHdl::handle( const css::uno::Reference< css::task::XInteractionRequest >& xRequest )
+{
+ if( !m_xInter.is() )
+ return;
+
+ css::drawing::GraphicFilterRequest aErr;
+ if ( xRequest->getRequest() >>= aErr )
+ nFilterError = ErrCode(aErr.ErrCode);
+ else
+ m_xInter->handle( xRequest );
+}
+
+
+SdGRFFilter::SdGRFFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell ) :
+ SdFilter( rMedium, rDocShell )
+{
+}
+
+SdGRFFilter::~SdGRFFilter()
+{
+}
+
+void SdGRFFilter::HandleGraphicFilterError( ErrCode nFilterError, ErrCode nStreamError )
+{
+ if (ERRCODE_NONE != nStreamError)
+ {
+ ErrorHandler::HandleError(nStreamError);
+ return;
+ }
+
+ TranslateId pId;
+
+ if( nFilterError == ERRCODE_GRFILTER_OPENERROR )
+ pId = STR_IMPORT_GRFILTER_OPENERROR;
+ else if( nFilterError == ERRCODE_GRFILTER_IOERROR )
+ pId = STR_IMPORT_GRFILTER_IOERROR;
+ else if( nFilterError == ERRCODE_GRFILTER_FORMATERROR )
+ pId = STR_IMPORT_GRFILTER_FORMATERROR;
+ else if( nFilterError == ERRCODE_GRFILTER_VERSIONERROR )
+ pId = STR_IMPORT_GRFILTER_VERSIONERROR;
+ else if( nFilterError == ERRCODE_GRFILTER_TOOBIG )
+ pId = STR_IMPORT_GRFILTER_TOOBIG;
+ else if( nFilterError == ERRCODE_NONE )
+ ;
+ else
+ pId = STR_IMPORT_GRFILTER_FILTERERROR;
+
+ if (pId && pId == STR_IMPORT_GRFILTER_IOERROR)
+ ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(nullptr,
+ VclMessageType::Warning, VclButtonsType::Ok, pId ? SdResId(pId) : OUString()));
+ xErrorBox->run();
+ }
+}
+
+bool SdGRFFilter::Import()
+{
+ Graphic aGraphic;
+ const OUString aFileName( mrMedium.GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
+ const sal_uInt16 nFilter = rGraphicFilter.GetImportFormatNumberForTypeName( mrMedium.GetFilter()->GetTypeName() );
+ bool bRet = false;
+
+ SvStream* pIStm = mrMedium.GetInStream();
+ ErrCode nReturn = pIStm ? rGraphicFilter.ImportGraphic( aGraphic, aFileName, *pIStm, nFilter ) : ErrCode(1);
+
+ if( nReturn )
+ HandleGraphicFilterError( nReturn, rGraphicFilter.GetLastError() );
+ else
+ {
+ if( mrDocument.GetPageCount() == 0 )
+ mrDocument.CreateFirstPages();
+
+ GfxLink aGfxLink = aGraphic.GetGfxLink();
+ if( aGfxLink.GetType() == GfxLinkType::NativeTif && aGraphic.IsAnimated() )
+ {
+ Animation aAnim( aGraphic.GetAnimation() );
+ const auto nImages = aAnim.Count();
+ for (size_t i = 0; i < nImages - 1; ++i)
+ {
+ mrDocument.DuplicatePage(0);
+ }
+ for (size_t nPageIndex = 0; nPageIndex < nImages; ++nPageIndex)
+ {
+ Graphic pGraphic = aAnim.Get(nPageIndex).maBitmapEx;
+ SdPage* pPage = mrDocument.GetSdPage(nPageIndex, PageKind::Standard);
+ InsertSdrGrafObj(pGraphic, pPage);
+ }
+ }
+ else
+ {
+ SdPage* pPage = mrDocument.GetSdPage(0, PageKind::Standard);
+ InsertSdrGrafObj(aGraphic, pPage);
+ }
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+void SdGRFFilter::InsertSdrGrafObj(Graphic pGraphic, SdPage* pPage)
+{
+ Point aPos;
+ Size aPagSize(pPage->GetSize());
+ Size aGrfSize(OutputDevice::LogicToLogic(pGraphic.GetPrefSize(), pGraphic.GetPrefMapMode(),
+ MapMode(MapUnit::Map100thMM)));
+
+ aPagSize.AdjustWidth(-(pPage->GetLeftBorder() + pPage->GetRightBorder()));
+ aPagSize.AdjustHeight(-(pPage->GetUpperBorder() + pPage->GetLowerBorder()));
+
+ // scale to fit page
+ if (((aGrfSize.Height() > aPagSize.Height()) || (aGrfSize.Width() > aPagSize.Width()))
+ && aGrfSize.Height() && aPagSize.Height())
+ {
+ double fGrfWH = static_cast<double>(aGrfSize.Width()) / aGrfSize.Height();
+ double fWinWH = static_cast<double>(aPagSize.Width()) / aPagSize.Height();
+
+ // adjust graphic to page size (scales)
+ if (fGrfWH < fWinWH)
+ {
+ aGrfSize.setWidth(static_cast<tools::Long>(aPagSize.Height() * fGrfWH));
+ aGrfSize.setHeight(aPagSize.Height());
+ }
+ else if (fGrfWH > 0.F)
+ {
+ aGrfSize.setWidth(aPagSize.Width());
+ aGrfSize.setHeight(static_cast<tools::Long>(aPagSize.Width() / fGrfWH));
+ }
+ }
+
+ // set output rectangle for graphic
+ aPos.setX(((aPagSize.Width() - aGrfSize.Width()) >> 1) + pPage->GetLeftBorder());
+ aPos.setY(((aPagSize.Height() - aGrfSize.Height()) >> 1) + pPage->GetUpperBorder());
+
+ pPage->InsertObject(new SdrGrafObj(pPage->getSdrModelFromSdrPage(), pGraphic,
+ ::tools::Rectangle(aPos, aGrfSize)));
+}
+
+bool SdGRFFilter::Export()
+{
+ // SJ: todo: error handling, the GraphicExportFilter does not support proper errorhandling
+ bool bRet = false;
+
+ uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( xContext );
+
+ SdPage* pPage = nullptr;
+ sd::DrawViewShell* pDrawViewShell = dynamic_cast<::sd::DrawViewShell* >(mrDocShell.GetViewShell() );
+
+ PageKind ePageKind = PageKind::Standard;
+ if( pDrawViewShell )
+ {
+ ePageKind = pDrawViewShell->GetPageKind();
+ if( PageKind::Handout == ePageKind )
+ pPage = mrDocument.GetSdPage( 0, PageKind::Handout );
+ else
+ pPage = pDrawViewShell->GetActualPage();
+ }
+ else
+ pPage = mrDocument.GetSdPage( 0, PageKind::Standard );
+
+ if ( pPage )
+ {
+ // taking the 'correct' page number, seems that there might exist a better method to archive this
+ pPage = mrDocument.GetSdPage( pPage->GetPageNum() ? ( pPage->GetPageNum() - 1 ) >> 1 : 0, ePageKind );
+ if ( pPage )
+ {
+ uno::Reference< lang::XComponent > xSource( pPage->getUnoPage(), uno::UNO_QUERY );
+ if (xSource.is())
+ {
+ SfxItemSet& rSet = mrMedium.GetItemSet();
+ const OUString aTypeName( mrMedium.GetFilter()->GetTypeName() );
+ GraphicFilter &rGraphicFilter = GraphicFilter::GetGraphicFilter();
+ const sal_uInt16 nFilter = rGraphicFilter.GetExportFormatNumberForTypeName( aTypeName );
+ if ( nFilter != GRFILTER_FORMAT_NOTFOUND )
+ {
+ uno::Reference< task::XInteractionHandler > xInteractionHandler;
+
+ beans::PropertyValues aArgs;
+ TransformItems( SID_SAVEASDOC, rSet, aArgs );
+
+ static constexpr OUString sFilterName( u"FilterName"_ustr );
+ OUString sShortName( rGraphicFilter.GetExportFormatShortName( nFilter ) );
+
+ bool bFilterNameFound = false;
+ for ( auto& rArg : asNonConstRange(aArgs) )
+ {
+ OUString& rStr = rArg.Name;
+ if ( rStr == sFilterName )
+ {
+ bFilterNameFound = true;
+ rArg.Value <<= sShortName;
+ }
+ else if ( rStr == "InteractionHandler" )
+ {
+ uno::Reference< task::XInteractionHandler > xHdl;
+ if ( rArg.Value >>= xHdl )
+ {
+ xInteractionHandler = new SdGRFFilter_ImplInteractionHdl( xHdl );
+ rArg.Value <<= xInteractionHandler;
+ }
+ }
+ }
+ if ( !bFilterNameFound )
+ {
+ sal_Int32 nCount = aArgs.getLength();
+ aArgs.realloc( nCount + 1 );
+ auto pArgs = aArgs.getArray();
+ pArgs[ nCount ].Name = sFilterName;
+ pArgs[ nCount ].Value <<= sShortName;
+ }
+
+ // take selection if needed
+ if( ( SfxItemState::SET == rSet.GetItemState( SID_SELECTION ) )
+ && rSet.Get( SID_SELECTION ).GetValue()
+ && pDrawViewShell )
+ {
+ uno::Reference< view::XSelectionSupplier > xSelectionSupplier(
+ pDrawViewShell->GetViewShellBase().GetController(), uno::UNO_QUERY );
+ if ( xSelectionSupplier.is() )
+ {
+ uno::Any aSelection( xSelectionSupplier->getSelection() );
+ uno::Reference< lang::XComponent > xSelection;
+ if ( aSelection >>= xSelection )
+ xSource = xSelection;
+ }
+ }
+ xExporter->setSourceDocument( xSource );
+ bRet = xExporter->filter( aArgs );
+ if ( !bRet && xInteractionHandler.is() )
+ SdGRFFilter::HandleGraphicFilterError(
+ static_cast< SdGRFFilter_ImplInteractionHdl* >( xInteractionHandler.get() )->GetErrorCode(),
+ rGraphicFilter.GetLastError() );
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */