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