xref: /AOO41X/main/sc/source/ui/drawfunc/fuins1.cxx (revision 52f1c2ee1b77392125ca30aec3c767684308e131)
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