LibreOffice Module sd (master) 1
sdgrffilter.cxx
Go to the documentation of this file.
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 <com/sun/star/drawing/GraphicExportFilter.hpp>
21
22#include <utility>
23#include <vcl/errinf.hxx>
24#include <vcl/weld.hxx>
25#include <sfx2/sfxsids.hrc>
26#include <sfx2/docfile.hxx>
27#include <sfx2/docfilt.hxx>
28#include <sfx2/sfxuno.hxx>
29#include <svx/svdograf.hxx>
30
31#include <strings.hrc>
32#include <DrawViewShell.hxx>
33#include <DrawDocShell.hxx>
34
36#include <vcl/graphicfilter.hxx>
37#include <vcl/svapp.hxx>
38
39#include <sdpage.hxx>
40#include <drawdoc.hxx>
41#include <sdresid.hxx>
42#include <sdgrffilter.hxx>
43#include <ViewShellBase.hxx>
44#include <com/sun/star/beans/PropertyValue.hpp>
45#include <com/sun/star/beans/PropertyValues.hpp>
46#include <com/sun/star/lang/XComponent.hpp>
47#include <com/sun/star/view/XSelectionSupplier.hpp>
49#include <com/sun/star/task/XInteractionHandler.hpp>
50#include <com/sun/star/task/XInteractionRequest.hpp>
51#include <com/sun/star/drawing/GraphicFilterRequest.hpp>
52
53using namespace ::com::sun::star;
54using namespace ::com::sun::star::uno;
55using namespace ::com::sun::star::lang;
56using namespace ::com::sun::star::beans;
57using namespace ::com::sun::star::graphic;
58using namespace ::com::sun::star::io;
59using namespace ::com::sun::star::ucb;
60using namespace com::sun::star::ui::dialogs;
61using namespace ::sfx2;
62
63namespace {
64
65class SdGRFFilter_ImplInteractionHdl : public ::cppu::WeakImplHelper< css::task::XInteractionHandler >
66{
67 css::uno::Reference< css::task::XInteractionHandler > m_xInter;
68 ErrCode nFilterError;
69
70 public:
71
72 explicit SdGRFFilter_ImplInteractionHdl( css::uno::Reference< css::task::XInteractionHandler > xInteraction ) :
73 m_xInter(std::move( xInteraction )),
74 nFilterError( ERRCODE_NONE )
75 {}
76
77 ErrCode const & GetErrorCode() const { return nFilterError; };
78
79 virtual void SAL_CALL handle( const css::uno::Reference< css::task::XInteractionRequest >& ) override;
80};
81
82}
83
84void SdGRFFilter_ImplInteractionHdl::handle( const css::uno::Reference< css::task::XInteractionRequest >& xRequest )
85{
86 if( !m_xInter.is() )
87 return;
88
89 css::drawing::GraphicFilterRequest aErr;
90 if ( xRequest->getRequest() >>= aErr )
91 nFilterError = ErrCode(aErr.ErrCode);
92 else
93 m_xInter->handle( xRequest );
94}
95
96
98 SdFilter( rMedium, rDocShell )
99{
100}
101
103{
104}
105
106void SdGRFFilter::HandleGraphicFilterError( ErrCode nFilterError, ErrCode nStreamError )
107{
108 if (ERRCODE_NONE != nStreamError)
109 {
110 ErrorHandler::HandleError(nStreamError);
111 return;
112 }
113
114 TranslateId pId;
115
116 if( nFilterError == ERRCODE_GRFILTER_OPENERROR )
117 pId = STR_IMPORT_GRFILTER_OPENERROR;
118 else if( nFilterError == ERRCODE_GRFILTER_IOERROR )
119 pId = STR_IMPORT_GRFILTER_IOERROR;
120 else if( nFilterError == ERRCODE_GRFILTER_FORMATERROR )
121 pId = STR_IMPORT_GRFILTER_FORMATERROR;
122 else if( nFilterError == ERRCODE_GRFILTER_VERSIONERROR )
123 pId = STR_IMPORT_GRFILTER_VERSIONERROR;
124 else if( nFilterError == ERRCODE_GRFILTER_TOOBIG )
125 pId = STR_IMPORT_GRFILTER_TOOBIG;
126 else if( nFilterError == ERRCODE_NONE )
127 ;
128 else
129 pId = STR_IMPORT_GRFILTER_FILTERERROR;
130
131 if (pId && pId == STR_IMPORT_GRFILTER_IOERROR)
133 else
134 {
135 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(nullptr,
136 VclMessageType::Warning, VclButtonsType::Ok, pId ? SdResId(pId) : OUString()));
137 xErrorBox->run();
138 }
139}
140
142{
143 Graphic aGraphic;
146 const sal_uInt16 nFilter = rGraphicFilter.GetImportFormatNumberForTypeName( mrMedium.GetFilter()->GetTypeName() );
147 bool bRet = false;
148
149 SvStream* pIStm = mrMedium.GetInStream();
150 ErrCode nReturn = pIStm ? rGraphicFilter.ImportGraphic( aGraphic, aFileName, *pIStm, nFilter ) : ErrCode(1);
151
152 if( nReturn )
153 HandleGraphicFilterError( nReturn, rGraphicFilter.GetLastError() );
154 else
155 {
156 if( mrDocument.GetPageCount() == 0 )
158
159 GfxLink aGfxLink = aGraphic.GetGfxLink();
160 if( aGfxLink.GetType() == GfxLinkType::NativeTif && aGraphic.IsAnimated() )
161 {
162 Animation aAnim( aGraphic.GetAnimation() );
163 const auto nImages = aAnim.Count();
164 for (size_t i = 0; i < nImages - 1; ++i)
165 {
167 }
168 for (size_t nPageIndex = 0; nPageIndex < nImages; ++nPageIndex)
169 {
170 Graphic pGraphic = aAnim.Get(nPageIndex).maBitmapEx;
171 SdPage* pPage = mrDocument.GetSdPage(nPageIndex, PageKind::Standard);
172 InsertSdrGrafObj(pGraphic, pPage);
173 }
174 }
175 else
176 {
178 InsertSdrGrafObj(aGraphic, pPage);
179 }
180 bRet = true;
181 }
182
183 return bRet;
184}
185
187{
188 Point aPos;
189 Size aPagSize(pPage->GetSize());
190 Size aGrfSize(OutputDevice::LogicToLogic(pGraphic.GetPrefSize(), pGraphic.GetPrefMapMode(),
191 MapMode(MapUnit::Map100thMM)));
192
193 aPagSize.AdjustWidth(-(pPage->GetLeftBorder() + pPage->GetRightBorder()));
194 aPagSize.AdjustHeight(-(pPage->GetUpperBorder() + pPage->GetLowerBorder()));
195
196 // scale to fit page
197 if (((aGrfSize.Height() > aPagSize.Height()) || (aGrfSize.Width() > aPagSize.Width()))
198 && aGrfSize.Height() && aPagSize.Height())
199 {
200 double fGrfWH = static_cast<double>(aGrfSize.Width()) / aGrfSize.Height();
201 double fWinWH = static_cast<double>(aPagSize.Width()) / aPagSize.Height();
202
203 // adjust graphic to page size (scales)
204 if (fGrfWH < fWinWH)
205 {
206 aGrfSize.setWidth(static_cast<tools::Long>(aPagSize.Height() * fGrfWH));
207 aGrfSize.setHeight(aPagSize.Height());
208 }
209 else if (fGrfWH > 0.F)
210 {
211 aGrfSize.setWidth(aPagSize.Width());
212 aGrfSize.setHeight(static_cast<tools::Long>(aPagSize.Width() / fGrfWH));
213 }
214 }
215
216 // set output rectangle for graphic
217 aPos.setX(((aPagSize.Width() - aGrfSize.Width()) >> 1) + pPage->GetLeftBorder());
218 aPos.setY(((aPagSize.Height() - aGrfSize.Height()) >> 1) + pPage->GetUpperBorder());
219
220 pPage->InsertObject(new SdrGrafObj(pPage->getSdrModelFromSdrPage(), pGraphic,
221 ::tools::Rectangle(aPos, aGrfSize)));
222}
223
225{
226 // SJ: todo: error handling, the GraphicExportFilter does not support proper errorhandling
227 bool bRet = false;
228
229 uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
230 uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( xContext );
231
232 SdPage* pPage = nullptr;
233 sd::DrawViewShell* pDrawViewShell = dynamic_cast<::sd::DrawViewShell* >(mrDocShell.GetViewShell() );
234
235 PageKind ePageKind = PageKind::Standard;
236 if( pDrawViewShell )
237 {
238 ePageKind = pDrawViewShell->GetPageKind();
239 if( PageKind::Handout == ePageKind )
241 else
242 pPage = pDrawViewShell->GetActualPage();
243 }
244 else
246
247 if ( pPage )
248 {
249 // taking the 'correct' page number, seems that there might exist a better method to archive this
250 pPage = mrDocument.GetSdPage( pPage->GetPageNum() ? ( pPage->GetPageNum() - 1 ) >> 1 : 0, ePageKind );
251 if ( pPage )
252 {
253 uno::Reference< lang::XComponent > xSource( pPage->getUnoPage(), uno::UNO_QUERY );
254 if (xSource.is())
255 {
257 const OUString aTypeName( mrMedium.GetFilter()->GetTypeName() );
259 const sal_uInt16 nFilter = rGraphicFilter.GetExportFormatNumberForTypeName( aTypeName );
260 if ( nFilter != GRFILTER_FORMAT_NOTFOUND )
261 {
262 uno::Reference< task::XInteractionHandler > xInteractionHandler;
263
264 beans::PropertyValues aArgs;
265 TransformItems( SID_SAVEASDOC, rSet, aArgs );
266
267 static constexpr OUStringLiteral sFilterName( u"FilterName" );
268 OUString sShortName( rGraphicFilter.GetExportFormatShortName( nFilter ) );
269
270 bool bFilterNameFound = false;
271 for ( auto& rArg : asNonConstRange(aArgs) )
272 {
273 OUString& rStr = rArg.Name;
274 if ( rStr == sFilterName )
275 {
276 bFilterNameFound = true;
277 rArg.Value <<= sShortName;
278 }
279 else if ( rStr == "InteractionHandler" )
280 {
281 uno::Reference< task::XInteractionHandler > xHdl;
282 if ( rArg.Value >>= xHdl )
283 {
284 xInteractionHandler = new SdGRFFilter_ImplInteractionHdl( xHdl );
285 rArg.Value <<= xInteractionHandler;
286 }
287 }
288 }
289 if ( !bFilterNameFound )
290 {
291 sal_Int32 nCount = aArgs.getLength();
292 aArgs.realloc( nCount + 1 );
293 auto pArgs = aArgs.getArray();
294 pArgs[ nCount ].Name = sFilterName;
295 pArgs[ nCount ].Value <<= sShortName;
296 }
297
298 // take selection if needed
299 if( ( SfxItemState::SET == rSet.GetItemState( SID_SELECTION ) )
300 && rSet.Get( SID_SELECTION ).GetValue()
301 && pDrawViewShell )
302 {
303 uno::Reference< view::XSelectionSupplier > xSelectionSupplier(
304 pDrawViewShell->GetViewShellBase().GetController(), uno::UNO_QUERY );
305 if ( xSelectionSupplier.is() )
306 {
307 uno::Any aSelection( xSelectionSupplier->getSelection() );
308 uno::Reference< lang::XComponent > xSelection;
309 if ( aSelection >>= xSelection )
310 xSource = xSelection;
311 }
312 }
313 xExporter->setSourceDocument( xSource );
314 bRet = xExporter->filter( aArgs );
315 if ( !bRet && xInteractionHandler.is() )
317 static_cast< SdGRFFilter_ImplInteractionHdl* >( xInteractionHandler.get() )->GetErrorCode(),
318 rGraphicFilter.GetLastError() );
319 }
320 }
321 }
322 }
323 return bRet;
324}
325
326/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
size_t Count() const
const AnimationFrame & Get(sal_uInt16 nAnimation) const
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
static DialogMask HandleError(ErrCode nId, weld::Window *pParent=nullptr, DialogMask nMask=DialogMask::MAX)
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE) override
sal_uInt16 GetExportFormatNumberForTypeName(std::u16string_view rType)
sal_uInt16 GetImportFormatNumberForTypeName(std::u16string_view rType)
static GraphicFilter & GetGraphicFilter()
OUString GetExportFormatShortName(sal_uInt16 nFormat)
ErrCode ImportGraphic(Graphic &rGraphic, const INetURLObject &rPath, sal_uInt16 nFormat=GRFILTER_FORMAT_DONTKNOW, sal_uInt16 *pDeterminedFormat=nullptr, GraphicFilterImportFlags nImportFlags=GraphicFilterImportFlags::NONE)
const ErrCode & GetLastError() const
Size GetPrefSize() const
Animation GetAnimation() const
GfxLink GetGfxLink() const
bool IsAnimated() const
MapMode GetPrefMapMode() const
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
void setX(tools::Long nX)
void setY(tools::Long nY)
void CreateFirstPages(SdDrawDocument const *pRefDocument=nullptr)
if the document does not contain at least one handout, one slide and one notes page with at least one...
Definition: drawdoc2.cxx:493
SAL_DLLPRIVATE sal_uInt16 DuplicatePage(sal_uInt16 nPageNum)
This method acts as a simplified front end for the more complex <member>DuplicatePage()</member> meth...
Definition: drawdoc2.cxx:1215
SdPage * GetSdPage(sal_uInt16 nPgNum, PageKind ePgKind) const
Definition: drawdoc2.cxx:207
SfxMedium & mrMedium
Definition: sdfilter.hxx:52
::sd::DrawDocShell & mrDocShell
Definition: sdfilter.hxx:53
SdDrawDocument & mrDocument
Definition: sdfilter.hxx:54
SdGRFFilter(SfxMedium &rMedium, ::sd::DrawDocShell &rDocShell)
Definition: sdgrffilter.cxx:97
virtual ~SdGRFFilter() override
static void InsertSdrGrafObj(Graphic pGraphic, SdPage *pPage)
bool Export() override
static void HandleGraphicFilterError(ErrCode nFilterError, ErrCode nStreamError)
sal_uInt16 GetPageCount() const
css::uno::Reference< css::uno::XInterface > const & getUnoPage()
sal_uInt16 GetPageNum() const
Size GetSize() const
sal_Int32 GetUpperBorder() const
sal_Int32 GetRightBorder() const
sal_Int32 GetLeftBorder() const
SdrModel & getSdrModelFromSdrPage() const
sal_Int32 GetLowerBorder() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
const std::shared_ptr< const SfxFilter > & GetFilter() const
const INetURLObject & GetURLObject() const
SfxItemSet & GetItemSet() const
SvStream * GetInStream()
css::uno::Reference< css::frame::XController > GetController() const
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
void setWidth(tools::Long nWidth)
tools::Long AdjustWidth(tools::Long n)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
sd::ViewShell * GetViewShell()
Base class of the stacked shells that provide graphical views to Draw and Impress documents and editi...
virtual SdPage * GetActualPage() override
PageKind GetPageKind() const
SD_DLLPUBLIC ViewShellBase & GetViewShellBase() const
Definition: viewshel.cxx:1397
int nCount
float u
#define ERRCODE_IO_GENERAL
#define ERRCODE_NONE
#define GRFILTER_FORMAT_NOTFOUND
#define ERRCODE_GRFILTER_OPENERROR
#define ERRCODE_GRFILTER_TOOBIG
#define ERRCODE_GRFILTER_FORMATERROR
#define ERRCODE_GRFILTER_IOERROR
#define ERRCODE_GRFILTER_VERSIONERROR
int i
long Long
PageKind
Definition: pres.hxx:45
OUString SdResId(TranslateId aId)
Definition: sdmod.cxx:83
SFX2_DLLPUBLIC void TransformItems(sal_uInt16 nSlotId, const SfxItemSet &aSet, css::uno::Sequence< css::beans::PropertyValue > &seqArgs, const SfxSlot *pSlot=nullptr)
static SfxItemSet & rSet
BitmapEx maBitmapEx