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