Line data Source code
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 :
21 : #ifdef _MSC_VER
22 : #pragma warning (disable:4190)
23 : #endif
24 : #include <com/sun/star/drawing/GraphicExportFilter.hpp>
25 : #include <com/sun/star/graphic/GraphicProvider.hpp>
26 : #include <com/sun/star/graphic/XGraphicProvider.hpp>
27 : #include <com/sun/star/graphic/GraphicType.hpp>
28 : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
29 : #include <com/sun/star/ucb/XSimpleFileAccess2.hpp>
30 :
31 : #include <unotools/localfilehelper.hxx>
32 : #include <tools/errinf.hxx>
33 : #include <vcl/msgbox.hxx>
34 : #include <vcl/metaact.hxx>
35 : #include <vcl/virdev.hxx>
36 : #include <sfx2/docfile.hxx>
37 : #include <sfx2/docfilt.hxx>
38 : #include <sfx2/frame.hxx>
39 : #include <svx/svdograf.hxx>
40 : #include <svx/svdpagv.hxx>
41 :
42 : #include "../../ui/inc/strings.hrc"
43 : #include "../../ui/inc/DrawViewShell.hxx"
44 : #include "../../ui/inc/DrawDocShell.hxx"
45 : #include "../../ui/inc/ClientView.hxx"
46 : #include "../../ui/inc/FrameView.hxx"
47 :
48 : #include "comphelper/anytostring.hxx"
49 : #include "cppuhelper/exc_hlp.hxx"
50 :
51 :
52 : #include <comphelper/processfactory.hxx>
53 : #include <unotools/pathoptions.hxx>
54 : #include <sfx2/filedlghelper.hxx>
55 : #include <vcl/graphicfilter.hxx>
56 : #include <svx/xoutbmp.hxx>
57 :
58 :
59 :
60 : #include "sdpage.hxx"
61 : #include "drawdoc.hxx"
62 : #include "sdresid.hxx"
63 : #include "sdgrffilter.hxx"
64 : #include "../../ui/inc/ViewShellBase.hxx"
65 : #include <com/sun/star/uno/Sequence.h>
66 : #include <com/sun/star/beans/PropertyValue.hpp>
67 : #include <com/sun/star/beans/PropertyValues.hpp>
68 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
69 : #include <com/sun/star/lang/XComponent.hpp>
70 : #include <com/sun/star/document/XFilter.hpp>
71 : #include <com/sun/star/document/XExporter.hpp>
72 : #include <com/sun/star/view/XSelectionSupplier.hpp>
73 : #include <com/sun/star/drawing/XDrawView.hpp>
74 : #include "../../ui/inc/DrawController.hxx"
75 : #include <cppuhelper/implbase2.hxx>
76 : #include <com/sun/star/drawing/XShape.hpp>
77 : #include <com/sun/star/task/XInteractionHandler.hpp>
78 : #include <com/sun/star/task/XInteractionRequest.hpp>
79 : #include <com/sun/star/drawing/GraphicFilterRequest.hpp>
80 :
81 : using namespace ::com::sun::star;
82 : using namespace ::com::sun::star::uno;
83 : using namespace ::com::sun::star::lang;
84 : using namespace ::com::sun::star::beans;
85 : using namespace ::com::sun::star::graphic;
86 : using namespace ::com::sun::star::io;
87 : using namespace ::com::sun::star::ucb;
88 : using namespace com::sun::star::ui::dialogs;
89 : using namespace ::sfx2;
90 :
91 :
92 :
93 :
94 : class SdGRFFilter_ImplInteractionHdl : public ::cppu::WeakImplHelper1< com::sun::star::task::XInteractionHandler >
95 : {
96 : com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter;
97 : sal_uInt16 nFilterError;
98 :
99 : public:
100 :
101 0 : SdGRFFilter_ImplInteractionHdl( com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteraction ) :
102 : m_xInter( xInteraction ),
103 0 : nFilterError( GRFILTER_OK )
104 0 : {}
105 :
106 : virtual ~SdGRFFilter_ImplInteractionHdl();
107 :
108 0 : sal_uInt16 GetErrorCode() const { return nFilterError; };
109 :
110 : virtual void SAL_CALL handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& )
111 : throw( com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
112 : };
113 :
114 0 : SdGRFFilter_ImplInteractionHdl::~SdGRFFilter_ImplInteractionHdl()
115 : {
116 0 : }
117 :
118 0 : void SdGRFFilter_ImplInteractionHdl::handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest )
119 : throw( com::sun::star::uno::RuntimeException, std::exception )
120 : {
121 0 : if( !m_xInter.is() )
122 0 : return;
123 :
124 0 : com::sun::star::drawing::GraphicFilterRequest aErr;
125 0 : if ( xRequest->getRequest() >>= aErr )
126 0 : nFilterError = (sal_uInt16)aErr.ErrCode;
127 : else
128 0 : m_xInter->handle( xRequest );
129 : }
130 :
131 :
132 :
133 : // - SdPPTFilter -
134 :
135 :
136 0 : SdGRFFilter::SdGRFFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell ) :
137 0 : SdFilter( rMedium, rDocShell, sal_True )
138 : {
139 0 : }
140 :
141 :
142 :
143 0 : SdGRFFilter::~SdGRFFilter()
144 : {
145 0 : }
146 :
147 :
148 :
149 0 : void SdGRFFilter::HandleGraphicFilterError( sal_uInt16 nFilterError, sal_uLong nStreamError )
150 : {
151 : sal_uInt16 nId;
152 :
153 0 : switch( nFilterError )
154 : {
155 : case GRFILTER_OPENERROR:
156 0 : nId = STR_IMPORT_GRFILTER_OPENERROR;
157 0 : break;
158 : case GRFILTER_IOERROR:
159 0 : nId = STR_IMPORT_GRFILTER_IOERROR;
160 0 : break;
161 : case GRFILTER_FORMATERROR:
162 0 : nId = STR_IMPORT_GRFILTER_FORMATERROR;
163 0 : break;
164 : case GRFILTER_VERSIONERROR:
165 0 : nId = STR_IMPORT_GRFILTER_VERSIONERROR;
166 0 : break;
167 : case GRFILTER_TOOBIG:
168 0 : nId = STR_IMPORT_GRFILTER_TOOBIG;
169 0 : break;
170 : case 0 :
171 0 : nId = 0;
172 0 : break;
173 :
174 : default:
175 : case GRFILTER_FILTERERROR:
176 0 : nId = STR_IMPORT_GRFILTER_FILTERERROR;
177 0 : break;
178 : }
179 :
180 0 : if( ERRCODE_NONE != nStreamError )
181 0 : ErrorHandler::HandleError( nStreamError );
182 0 : else if( STR_IMPORT_GRFILTER_IOERROR == nId )
183 0 : ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
184 : else
185 : {
186 0 : ErrorBox aErrorBox(NULL, WB_OK, SD_RESSTR(nId));
187 0 : aErrorBox.Execute();
188 : }
189 0 : }
190 :
191 :
192 :
193 0 : sal_Bool SdGRFFilter::Import()
194 : {
195 0 : Graphic aGraphic;
196 0 : const OUString aFileName( mrMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
197 0 : GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
198 0 : const sal_uInt16 nFilter = rGraphicFilter.GetImportFormatNumberForTypeName( mrMedium.GetFilter()->GetTypeName() );
199 0 : sal_Bool bRet = sal_False;
200 :
201 0 : SvStream* pIStm = mrMedium.GetInStream();
202 0 : sal_uInt16 nReturn = pIStm ? rGraphicFilter.ImportGraphic( aGraphic, aFileName, *pIStm, nFilter ) : 1;
203 :
204 0 : if( nReturn )
205 0 : HandleGraphicFilterError( nReturn, rGraphicFilter.GetLastError().nStreamError );
206 : else
207 : {
208 0 : if( mrDocument.GetPageCount() == 0L )
209 0 : mrDocument.CreateFirstPages();
210 :
211 0 : SdPage* pPage = mrDocument.GetSdPage( 0, PK_STANDARD );
212 0 : Point aPos;
213 0 : Size aPagSize( pPage->GetSize() );
214 : Size aGrfSize( OutputDevice::LogicToLogic( aGraphic.GetPrefSize(),
215 0 : aGraphic.GetPrefMapMode(), MAP_100TH_MM ) );
216 :
217 0 : aPagSize.Width() -= pPage->GetLftBorder() + pPage->GetRgtBorder();
218 0 : aPagSize.Height() -= pPage->GetUppBorder() + pPage->GetLwrBorder();
219 :
220 : // scale to fit page
221 0 : if ( ( ( aGrfSize.Height() > aPagSize.Height() ) || ( aGrfSize.Width() > aPagSize.Width() ) ) &&
222 0 : aGrfSize.Height() && aPagSize.Height() )
223 : {
224 0 : double fGrfWH = (double) aGrfSize.Width() / aGrfSize.Height();
225 0 : double fWinWH = (double) aPagSize.Width() / aPagSize.Height();
226 :
227 : // adjust graphic to page size (scales)
228 0 : if( fGrfWH < fWinWH )
229 : {
230 0 : aGrfSize.Width() = (long) ( aPagSize.Height() * fGrfWH );
231 0 : aGrfSize.Height() = aPagSize.Height();
232 : }
233 0 : else if( fGrfWH > 0.F )
234 : {
235 0 : aGrfSize.Width() = aPagSize.Width();
236 0 : aGrfSize.Height()= (long) ( aPagSize.Width() / fGrfWH );
237 : }
238 : }
239 :
240 : // set output rectangle for graphic
241 0 : aPos.X() = ( ( aPagSize.Width() - aGrfSize.Width() ) >> 1 ) + pPage->GetLftBorder();
242 0 : aPos.Y() = ( ( aPagSize.Height() - aGrfSize.Height() ) >> 1 ) + pPage->GetUppBorder();
243 :
244 0 : pPage->InsertObject( new SdrGrafObj( aGraphic, Rectangle( aPos, aGrfSize ) ) );
245 0 : bRet = sal_True;
246 : }
247 0 : return bRet;
248 : }
249 :
250 :
251 :
252 0 : sal_Bool SdGRFFilter::Export()
253 : {
254 : // SJ: todo: error handling, the GraphicExportFilter does not support proper errorhandling
255 :
256 0 : sal_Bool bRet = sal_False;
257 :
258 0 : uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
259 0 : uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( xContext );
260 :
261 0 : SdPage* pPage = NULL;
262 : sd::DrawViewShell* pDrawViewShell = static_cast< ::sd::DrawViewShell* >
263 0 : ( ( ( mrDocShell.GetViewShell() && mrDocShell.GetViewShell()->ISA(::sd::DrawViewShell ) ) ? mrDocShell.GetViewShell() : NULL ) );
264 :
265 0 : PageKind ePageKind = PK_STANDARD;
266 0 : if( pDrawViewShell )
267 : {
268 0 : ePageKind = pDrawViewShell->GetPageKind();
269 0 : if( PK_HANDOUT == ePageKind )
270 0 : pPage = mrDocument.GetSdPage( 0, PK_HANDOUT );
271 : else
272 0 : pPage = pDrawViewShell->GetActualPage();
273 : }
274 : else
275 0 : pPage = mrDocument.GetSdPage( 0, PK_STANDARD );
276 :
277 0 : if ( pPage )
278 : {
279 : // taking the 'correct' page number, seems that there might exist a better method to archive this
280 0 : pPage = mrDocument.GetSdPage( pPage->GetPageNum() ? ( pPage->GetPageNum() - 1 ) >> 1 : 0, ePageKind );
281 0 : if ( pPage )
282 : {
283 0 : uno::Reference< lang::XComponent > xSource( pPage->getUnoPage(), uno::UNO_QUERY );
284 0 : SfxItemSet* pSet = mrMedium.GetItemSet();
285 0 : if ( pSet && xSource.is() )
286 : {
287 0 : const OUString aTypeName( mrMedium.GetFilter()->GetTypeName() );
288 0 : GraphicFilter &rGraphicFilter = GraphicFilter::GetGraphicFilter();
289 0 : const sal_uInt16 nFilter = rGraphicFilter.GetExportFormatNumberForTypeName( aTypeName );
290 0 : if ( nFilter != GRFILTER_FORMAT_NOTFOUND )
291 : {
292 0 : uno::Reference< task::XInteractionHandler > mXInteractionHandler;
293 :
294 0 : beans::PropertyValues aArgs;
295 0 : TransformItems( SID_SAVEASDOC, *pSet, aArgs );
296 :
297 0 : OUString sInteractionHandler( "InteractionHandler" );
298 0 : OUString sFilterName( "FilterName" );
299 0 : OUString sShortName( rGraphicFilter.GetExportFormatShortName( nFilter ) );
300 :
301 0 : sal_Bool bFilterNameFound = sal_False;
302 : sal_Int32 i, nCount;
303 0 : for ( i = 0, nCount = aArgs.getLength(); i < nCount; i++ )
304 : {
305 0 : OUString& rStr = aArgs[ i ].Name;
306 0 : if ( rStr == sFilterName )
307 : {
308 0 : bFilterNameFound = sal_True;
309 0 : aArgs[ i ].Name = sFilterName;
310 0 : aArgs[ i ].Value <<= sShortName;
311 : }
312 0 : else if ( rStr == sInteractionHandler )
313 : {
314 0 : uno::Reference< task::XInteractionHandler > xHdl;
315 0 : if ( aArgs[ i ].Value >>= xHdl )
316 : {
317 0 : mXInteractionHandler = new SdGRFFilter_ImplInteractionHdl( xHdl );
318 0 : aArgs[ i ].Value <<= mXInteractionHandler;
319 0 : }
320 : }
321 : }
322 0 : if ( !bFilterNameFound )
323 : {
324 0 : aArgs.realloc( ++nCount );
325 0 : aArgs[ i ].Name = sFilterName;
326 0 : aArgs[ i ].Value <<= sShortName;
327 : }
328 :
329 : // take selection if needed
330 0 : if( ( SFX_ITEM_SET == pSet->GetItemState( SID_SELECTION ) )
331 0 : && static_cast< const SfxBoolItem& >( pSet->Get( SID_SELECTION ) ).GetValue()
332 0 : && pDrawViewShell )
333 : {
334 : uno::Reference< view::XSelectionSupplier > xSelectionSupplier(
335 0 : pDrawViewShell->GetViewShellBase().GetController(), uno::UNO_QUERY );
336 0 : if ( xSelectionSupplier.is() )
337 : {
338 0 : uno::Any aSelection( xSelectionSupplier->getSelection() );
339 0 : uno::Reference< lang::XComponent > xSelection;
340 0 : if ( aSelection >>= xSelection )
341 0 : xSource = xSelection;
342 0 : }
343 : }
344 0 : xExporter->setSourceDocument( xSource );
345 0 : bRet = xExporter->filter( aArgs );
346 0 : if ( !bRet && mXInteractionHandler.is() )
347 : SdGRFFilter::HandleGraphicFilterError(
348 0 : static_cast< SdGRFFilter_ImplInteractionHdl* >( mXInteractionHandler.get() )->GetErrorCode(),
349 0 : rGraphicFilter.GetLastError().nStreamError );
350 0 : }
351 0 : }
352 : }
353 : }
354 0 : return bRet;
355 : }
356 :
357 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|