xref: /aoo41x/main/sc/source/ui/drawfunc/fuins1.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 #include <sfx2/opengrf.hxx>
32 #include <svx/svdograf.hxx>
33 #include <svx/svdomedia.hxx>
34 #include <svx/svdpage.hxx>
35 #include <svx/svdpagv.hxx>
36 #include <svx/svdview.hxx>
37 #include <svtools/filter.hxx>
38 #include <svl/stritem.hxx>
39 #include <vcl/msgbox.hxx>
40 #include <tools/urlobj.hxx>
41 #include <avmedia/mediawindow.hxx>
42 #include <vcl/svapp.hxx>
43 
44 #include "fuinsert.hxx"
45 #include "tabvwsh.hxx"
46 #include "drwlayer.hxx"
47 #include "drawview.hxx"
48 #include "document.hxx"
49 #include "scresid.hxx"
50 #include "progress.hxx"
51 #include "sc.hrc"
52 
53 
54 
55 ////========================================================================
56 ////	class ImportProgress
57 ////
58 ////  Bemerkung:
59 ////	Diese Klasse stellt lediglich den Handler fuer den ImportProgress des
60 ////	Grafikfilters bereit.
61 ////========================================================================
62 //
63 //class ImportProgress
64 //{
65 //public:
66 //		ImportProgress( GraphicFilter& rFilter );
67 //		~ImportProgress();
68 //
69 //	DECL_LINK( Update, GraphicFilter* );
70 //
71 //private:
72 //	ScProgress aProgress;
73 //};
74 //
75 ////------------------------------------------------------------------------
76 //
77 //ImportProgress::ImportProgress( GraphicFilter& rFilter )
78 //	: aProgress( NULL, // SfxViewFrame*, NULL == alle Docs locken
79 //				 String( ScResId(STR_INSERTGRAPHIC) ),
80 //				 100 )
81 //{
82 //	rFilter.SetUpdatePercentHdl( LINK( this, ImportProgress, Update) );
83 //}
84 //
85 ////------------------------------------------------------------------------
86 //
87 //__EXPORT ImportProgress::~ImportProgress()
88 //{
89 //	aProgress.SetState( 100 );
90 //}
91 //
92 ////------------------------------------------------------------------------
93 //
94 //IMPL_LINK( ImportProgress, Update, GraphicFilter*, pGraphicFilter )
95 //{
96 //	aProgress.SetState( pGraphicFilter->GetPercent() );
97 //	return 0;
98 //}
99 
100 
101 //------------------------------------------------------------------------
102 
103 void SC_DLLPUBLIC ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage )
104 {
105 	if ( !rPage.Width() || !rPage.Height() )
106 		return;
107 
108 	Size aPageSize = rPage;
109 	sal_Bool bNegative = aPageSize.Width() < 0;
110 	if ( bNegative )
111 	{
112 		//	make everything positive temporarily
113 		aPageSize.Width() = -aPageSize.Width();
114 		rPos.X() = -rPos.X() - rSize.Width();
115 	}
116 
117 	if ( rSize.Width() > aPageSize.Width() || rSize.Height() > aPageSize.Height() )
118 	{
119 		double fX = aPageSize.Width()  / (double) rSize.Width();
120 		double fY = aPageSize.Height() / (double) rSize.Height();
121 
122 		if ( fX < fY )
123 		{
124 			rSize.Width()  = aPageSize.Width();
125 			rSize.Height() = (long) ( rSize.Height() * fX );
126 		}
127 		else
128 		{
129 			rSize.Height() = aPageSize.Height();
130 			rSize.Width()  = (long) ( rSize.Width() * fY );
131 		}
132 
133 		if (!rSize.Width())
134 			rSize.Width() = 1;
135 		if (!rSize.Height())
136 			rSize.Height() = 1;
137 	}
138 
139 	if ( rPos.X() + rSize.Width() > aPageSize.Width() )
140 		rPos.X() = aPageSize.Width() - rSize.Width();
141 	if ( rPos.Y() + rSize.Height() > aPageSize.Height() )
142 		rPos.Y() = aPageSize.Height() - rSize.Height();
143 
144 	if ( bNegative )
145 		rPos.X() = -rPos.X() - rSize.Width();		// back to real position
146 }
147 
148 //------------------------------------------------------------------------
149 
150 void lcl_InsertGraphic( const Graphic& rGraphic,
151 						const String& rFileName, const String& rFilterName, sal_Bool bAsLink, sal_Bool bApi,
152 						ScTabViewShell*	pViewSh, Window* pWindow, SdrView* pView )
153 {
154 	//	#74778# set the size so the graphic has its original pixel size
155 	//	at 100% view scale (as in SetMarkedOriginalSize),
156 	//	instead of respecting the current view scale
157 
158 	ScDrawView* pDrawView = pViewSh->GetScDrawView();
159 	MapMode aSourceMap = rGraphic.GetPrefMapMode();
160 	MapMode aDestMap( MAP_100TH_MM );
161 	if ( aSourceMap.GetMapUnit() == MAP_PIXEL && pDrawView )
162 	{
163 		Fraction aScaleX, aScaleY;
164 		pDrawView->CalcNormScale( aScaleX, aScaleY );
165 		aDestMap.SetScaleX(aScaleX);
166 		aDestMap.SetScaleY(aScaleY);
167 	}
168 	Size aLogicSize = pWindow->LogicToLogic(
169 							rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
170 
171 	//	Limit size
172 
173 	SdrPageView* pPV  = pView->GetSdrPageView();
174 	SdrPage* pPage = pPV->GetPage();
175 	Point aInsertPos = pViewSh->GetInsertPos();
176 
177 	ScViewData* pData = pViewSh->GetViewData();
178 	if ( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
179 		aInsertPos.X() -= aLogicSize.Width();		// move position to left edge
180 
181 	ScLimitSizeOnDrawPage( aLogicSize, aInsertPos, pPage->GetSize() );
182 
183 	Rectangle aRect ( aInsertPos, aLogicSize );
184 
185 	SdrGrafObj* pObj = new SdrGrafObj( rGraphic, aRect );
186 
187     // #118522# calling SetGraphicLink here doesn't work
188 
189 	//	#49961# Path is no longer used as name for the graphics object
190 
191 	ScDrawLayer* pLayer = (ScDrawLayer*) pView->GetModel();
192 	String aName = pLayer->GetNewGraphicName();					// "Grafik x"
193 	pObj->SetName(aName);
194 
195 	//	don't select if from (dispatch) API, to allow subsequent cell operations
196 	sal_uLong nInsOptions = bApi ? SDRINSERT_DONTMARK : 0;
197 	pView->InsertObjectAtView( pObj, *pPV, nInsOptions );
198 
199     // #118522# SetGraphicLink has to be used after inserting the object,
200     // otherwise an empty graphic is swapped in and the contact stuff crashes.
201     // See #i37444#.
202 	if ( bAsLink )
203 		pObj->SetGraphicLink( rFileName, rFilterName );
204 }
205 
206 //------------------------------------------------------------------------
207 
208 void lcl_InsertMedia( const ::rtl::OUString& rMediaURL, bool bApi,
209 					  ScTabViewShell* pViewSh, Window* pWindow, SdrView* pView,
210 					  const Size& rPrefSize )
211 {
212 	SdrPageView* 	pPV  = pView->GetSdrPageView();
213 	SdrPage* 		pPage = pPV->GetPage();
214 	ScViewData* 	pData = pViewSh->GetViewData();
215 	Point 			aInsertPos( pViewSh->GetInsertPos() );
216 	Size 			aSize;
217 
218 	if( rPrefSize.Width() && rPrefSize.Height() )
219 	{
220 		if( pWindow )
221 			aSize = pWindow->PixelToLogic( rPrefSize, MAP_100TH_MM );
222 		else
223 			aSize = Application::GetDefaultDevice()->PixelToLogic( rPrefSize, MAP_100TH_MM );
224 	}
225 	else
226 		aSize = Size( 5000, 5000 );
227 
228 	ScLimitSizeOnDrawPage( aSize, aInsertPos, pPage->GetSize() );
229 
230 	if( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
231 		aInsertPos.X() -= aSize.Width();
232 
233 	SdrMediaObj* pObj = new SdrMediaObj( Rectangle( aInsertPos, aSize ) );
234 
235 	pObj->setURL( rMediaURL );
236 	pView->InsertObjectAtView( pObj, *pPV, bApi ? SDRINSERT_DONTMARK : 0 );
237 }
238 
239 /*************************************************************************
240 |*
241 |* FuInsertGraphic::Konstruktor
242 |*
243 \************************************************************************/
244 
245 #ifdef _MSC_VER
246 #pragma optimize("",off)
247 #endif
248 
249 FuInsertGraphic::FuInsertGraphic( ScTabViewShell*	pViewSh,
250 								  Window*			pWin,
251                                   ScDrawView*       pViewP,
252 								  SdrModel*			pDoc,
253 								  SfxRequest&		rReq )
254        : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
255 {
256 	const SfxItemSet* pReqArgs = rReq.GetArgs();
257 	const SfxPoolItem* pItem;
258 	if ( pReqArgs &&
259 		 pReqArgs->GetItemState( SID_INSERT_GRAPHIC, sal_True, &pItem ) == SFX_ITEM_SET )
260 	{
261 		String aFileName = ((const SfxStringItem*)pItem)->GetValue();
262 
263 		String aFilterName;
264 		if ( pReqArgs->GetItemState( FN_PARAM_FILTER, sal_True, &pItem ) == SFX_ITEM_SET )
265 			aFilterName = ((const SfxStringItem*)pItem)->GetValue();
266 
267 		sal_Bool bAsLink = sal_False;
268 		if ( pReqArgs->GetItemState( FN_PARAM_1, sal_True, &pItem ) == SFX_ITEM_SET )
269 			bAsLink = ((const SfxBoolItem*)pItem)->GetValue();
270 
271 		Graphic aGraphic;
272         int nError = GraphicFilter::LoadGraphic( aFileName, aFilterName, aGraphic, GraphicFilter::GetGraphicFilter() );
273         if ( nError == GRFILTER_OK )
274         {
275 			lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, sal_True, pViewSh, pWindow, pView );
276         }
277 	}
278 	else
279 	{
280 		SvxOpenGraphicDialog aDlg(ScResId(STR_INSERTGRAPHIC));
281 
282 		if( aDlg.Execute() == GRFILTER_OK )
283 		{
284 			Graphic aGraphic;
285             int nError = aDlg.GetGraphic(aGraphic);
286 			if( nError == GRFILTER_OK )
287 			{
288 				String aFileName = aDlg.GetPath();
289 				String aFilterName = aDlg.GetCurrentFilter();
290 				sal_Bool bAsLink = aDlg.IsAsLink();
291 
292 				lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, sal_False, pViewSh, pWindow, pView );
293 
294 				//	append items for recording
295 				rReq.AppendItem( SfxStringItem( SID_INSERT_GRAPHIC, aFileName ) );
296 				rReq.AppendItem( SfxStringItem( FN_PARAM_FILTER, aFilterName ) );
297 				rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bAsLink ) );
298 				rReq.Done();
299 			}
300 			else
301 			{
302 				//	error is handled in SvxOpenGraphicDialog::GetGraphic
303 
304 #if 0
305 				sal_uInt16 nRes = 0;
306 				switch ( nError )
307 				{
308 					case GRFILTER_OPENERROR:	nRes = SCSTR_GRFILTER_OPENERROR;	break;
309 					case GRFILTER_IOERROR:		nRes = SCSTR_GRFILTER_IOERROR;		break;
310 					case GRFILTER_FORMATERROR:	nRes = SCSTR_GRFILTER_FORMATERROR;	break;
311 					case GRFILTER_VERSIONERROR:	nRes = SCSTR_GRFILTER_VERSIONERROR;	break;
312 					case GRFILTER_FILTERERROR:	nRes = SCSTR_GRFILTER_FILTERERROR;	break;
313 					case GRFILTER_TOOBIG:		nRes = SCSTR_GRFILTER_TOOBIG;		break;
314 				}
315 				if ( nRes )
316 				{
317 					InfoBox aInfoBox( pWindow, String(ScResId(nRes)) );
318 					aInfoBox.Execute();
319 				}
320 				else
321 				{
322 					sal_uLong nStreamError = GetGrfFilter()->GetLastError().nStreamError;
323 					if( ERRCODE_NONE != nStreamError )
324 						ErrorHandler::HandleError( nStreamError );
325 				}
326 #endif
327 			}
328 		}
329 	}
330 }
331 
332 /*************************************************************************
333 |*
334 |* FuInsertGraphic::Destruktor
335 |*
336 \************************************************************************/
337 
338 FuInsertGraphic::~FuInsertGraphic()
339 {
340 }
341 
342 /*************************************************************************
343 |*
344 |* FuInsertGraphic::Function aktivieren
345 |*
346 \************************************************************************/
347 
348 void FuInsertGraphic::Activate()
349 {
350 	FuPoor::Activate();
351 }
352 
353 /*************************************************************************
354 |*
355 |* FuInsertGraphic::Function deaktivieren
356 |*
357 \************************************************************************/
358 
359 void FuInsertGraphic::Deactivate()
360 {
361 	FuPoor::Deactivate();
362 }
363 
364 /*************************************************************************
365 |*
366 |* FuInsertMedia::Konstruktor
367 |*
368 \************************************************************************/
369 
370 FuInsertMedia::FuInsertMedia( ScTabViewShell*	pViewSh,
371 							  Window*			pWin,
372                               ScDrawView*       pViewP,
373 							  SdrModel*			pDoc,
374 							  SfxRequest&		rReq ) :
375     FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
376 {
377 	::rtl::OUString 	aURL;
378 	const SfxItemSet*	pReqArgs = rReq.GetArgs();
379 	bool				bAPI = false;
380 
381 	if( pReqArgs )
382 	{
383 		const SfxStringItem* pStringItem = PTR_CAST( SfxStringItem, &pReqArgs->Get( rReq.GetSlot() ) );
384 
385 		if( pStringItem )
386 		{
387 			aURL = pStringItem->GetValue();
388 			bAPI = aURL.getLength();
389 		}
390 	}
391 
392 	if( bAPI || ::avmedia::MediaWindow::executeMediaURLDialog( pWindow, aURL ) )
393 	{
394 		Size aPrefSize;
395 
396 		if( pWin )
397 			pWin->EnterWait();
398 
399 		if( !::avmedia::MediaWindow::isMediaURL( aURL, true, &aPrefSize ) )
400 		{
401 			if( pWin )
402 				pWin->LeaveWait();
403 
404 			if( !bAPI )
405 				::avmedia::MediaWindow::executeFormatErrorBox( pWindow );
406 		}
407 		else
408 		{
409 			lcl_InsertMedia( aURL, bAPI, pViewSh, pWindow, pView, aPrefSize );
410 
411 			if( pWin )
412 				pWin->LeaveWait();
413 		}
414 	}
415 }
416 
417 /*************************************************************************
418 |*
419 |* FuInsertMedia::Destruktor
420 |*
421 \************************************************************************/
422 
423 FuInsertMedia::~FuInsertMedia()
424 {
425 }
426 
427 /*************************************************************************
428 |*
429 |* FuInsertMedia::Function aktivieren
430 |*
431 \************************************************************************/
432 
433 void FuInsertMedia::Activate()
434 {
435 	FuPoor::Activate();
436 }
437 
438 /*************************************************************************
439 |*
440 |* FuInsertMedia::Function deaktivieren
441 |*
442 \************************************************************************/
443 
444 void FuInsertMedia::Deactivate()
445 {
446 	FuPoor::Deactivate();
447 }
448