xref: /trunk/main/sc/source/ui/drawfunc/fuins1.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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