Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <sfx2/opengrf.hxx>
22 : #include <svx/svdograf.hxx>
23 : #include <svx/svdomedia.hxx>
24 : #include <svx/svdpage.hxx>
25 : #include <svx/svdpagv.hxx>
26 : #include <svx/svdview.hxx>
27 : #include <svx/linkwarn.hxx>
28 : #include <svtools/filter.hxx>
29 : #include <svl/stritem.hxx>
30 : #include <svtools/miscopt.hxx>
31 : #include <vcl/msgbox.hxx>
32 : #include <avmedia/mediawindow.hxx>
33 : #include <vcl/svapp.hxx>
34 :
35 : #include "fuinsert.hxx"
36 : #include "tabvwsh.hxx"
37 : #include "drwlayer.hxx"
38 : #include "drawview.hxx"
39 : #include "document.hxx"
40 : #include "scresid.hxx"
41 : #include "progress.hxx"
42 : #include "sc.hrc"
43 :
44 :
45 : using namespace ::com::sun::star;
46 :
47 : //------------------------------------------------------------------------
48 :
49 0 : void SC_DLLPUBLIC ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage )
50 : {
51 0 : if ( !rPage.Width() || !rPage.Height() )
52 0 : return;
53 :
54 0 : Size aPageSize = rPage;
55 0 : sal_Bool bNegative = aPageSize.Width() < 0;
56 0 : if ( bNegative )
57 : {
58 : // make everything positive temporarily
59 0 : aPageSize.Width() = -aPageSize.Width();
60 0 : rPos.X() = -rPos.X() - rSize.Width();
61 : }
62 :
63 0 : if ( rSize.Width() > aPageSize.Width() || rSize.Height() > aPageSize.Height() )
64 : {
65 0 : double fX = aPageSize.Width() / (double) rSize.Width();
66 0 : double fY = aPageSize.Height() / (double) rSize.Height();
67 :
68 0 : if ( fX < fY )
69 : {
70 0 : rSize.Width() = aPageSize.Width();
71 0 : rSize.Height() = (long) ( rSize.Height() * fX );
72 : }
73 : else
74 : {
75 0 : rSize.Height() = aPageSize.Height();
76 0 : rSize.Width() = (long) ( rSize.Width() * fY );
77 : }
78 :
79 0 : if (!rSize.Width())
80 0 : rSize.Width() = 1;
81 0 : if (!rSize.Height())
82 0 : rSize.Height() = 1;
83 : }
84 :
85 0 : if ( rPos.X() + rSize.Width() > aPageSize.Width() )
86 0 : rPos.X() = aPageSize.Width() - rSize.Width();
87 0 : if ( rPos.Y() + rSize.Height() > aPageSize.Height() )
88 0 : rPos.Y() = aPageSize.Height() - rSize.Height();
89 :
90 0 : if ( bNegative )
91 0 : rPos.X() = -rPos.X() - rSize.Width(); // back to real position
92 : }
93 :
94 : //------------------------------------------------------------------------
95 :
96 0 : static void lcl_InsertGraphic( const Graphic& rGraphic,
97 : const String& rFileName, const String& rFilterName, sal_Bool bAsLink, sal_Bool bApi,
98 : ScTabViewShell* pViewSh, Window* pWindow, SdrView* pView )
99 : {
100 : // set the size so the graphic has its original pixel size
101 : // at 100% view scale (as in SetMarkedOriginalSize),
102 : // instead of respecting the current view scale
103 :
104 0 : ScDrawView* pDrawView = pViewSh->GetScDrawView();
105 0 : MapMode aSourceMap = rGraphic.GetPrefMapMode();
106 0 : MapMode aDestMap( MAP_100TH_MM );
107 0 : if ( aSourceMap.GetMapUnit() == MAP_PIXEL && pDrawView )
108 : {
109 0 : Fraction aScaleX, aScaleY;
110 0 : pDrawView->CalcNormScale( aScaleX, aScaleY );
111 0 : aDestMap.SetScaleX(aScaleX);
112 0 : aDestMap.SetScaleY(aScaleY);
113 : }
114 : Size aLogicSize = pWindow->LogicToLogic(
115 0 : rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
116 :
117 : // Limit size
118 :
119 0 : SdrPageView* pPV = pView->GetSdrPageView();
120 0 : SdrPage* pPage = pPV->GetPage();
121 0 : Point aInsertPos = pViewSh->GetInsertPos();
122 :
123 0 : ScViewData* pData = pViewSh->GetViewData();
124 0 : if ( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
125 0 : aInsertPos.X() -= aLogicSize.Width(); // move position to left edge
126 :
127 0 : ScLimitSizeOnDrawPage( aLogicSize, aInsertPos, pPage->GetSize() );
128 :
129 0 : Rectangle aRect ( aInsertPos, aLogicSize );
130 :
131 0 : SdrGrafObj* pObj = new SdrGrafObj( rGraphic, aRect );
132 :
133 : // calling SetGraphicLink here doesn't work
134 :
135 : // Path is no longer used as name for the graphics object
136 :
137 0 : ScDrawLayer* pLayer = (ScDrawLayer*) pView->GetModel();
138 0 : String aName = pLayer->GetNewGraphicName(); // "Grafik x"
139 0 : pObj->SetName(aName);
140 :
141 : // don't select if from (dispatch) API, to allow subsequent cell operations
142 0 : sal_uLong nInsOptions = bApi ? SDRINSERT_DONTMARK : 0;
143 0 : pView->InsertObjectAtView( pObj, *pPV, nInsOptions );
144 :
145 : // SetGraphicLink has to be used after inserting the object,
146 : // otherwise an empty graphic is swapped in and the contact stuff crashes.
147 : // See #i37444#.
148 0 : if ( bAsLink )
149 0 : pObj->SetGraphicLink( rFileName, rFilterName );
150 0 : }
151 :
152 : //------------------------------------------------------------------------
153 :
154 0 : static void lcl_InsertMedia( const ::rtl::OUString& rMediaURL, bool bApi,
155 : ScTabViewShell* pViewSh, Window* pWindow, SdrView* pView,
156 : const Size& rPrefSize, bool const bLink )
157 : {
158 0 : SdrPageView* pPV = pView->GetSdrPageView();
159 0 : SdrPage* pPage = pPV->GetPage();
160 0 : ScViewData* pData = pViewSh->GetViewData();
161 0 : Point aInsertPos( pViewSh->GetInsertPos() );
162 0 : Size aSize;
163 :
164 0 : if( rPrefSize.Width() && rPrefSize.Height() )
165 : {
166 0 : if( pWindow )
167 0 : aSize = pWindow->PixelToLogic( rPrefSize, MAP_100TH_MM );
168 : else
169 0 : aSize = Application::GetDefaultDevice()->PixelToLogic( rPrefSize, MAP_100TH_MM );
170 : }
171 : else
172 0 : aSize = Size( 5000, 5000 );
173 :
174 0 : ScLimitSizeOnDrawPage( aSize, aInsertPos, pPage->GetSize() );
175 :
176 0 : if( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) )
177 0 : aInsertPos.X() -= aSize.Width();
178 :
179 0 : ::rtl::OUString realURL;
180 0 : if (bLink)
181 : {
182 0 : realURL = rMediaURL;
183 : }
184 : else
185 : {
186 : uno::Reference<frame::XModel> const xModel(
187 0 : pData->GetDocument()->GetDocumentShell()->GetModel());
188 0 : bool const bRet = ::avmedia::EmbedMedia(xModel, rMediaURL, realURL);
189 0 : if (!bRet) { return; }
190 : }
191 :
192 0 : SdrMediaObj* pObj = new SdrMediaObj( Rectangle( aInsertPos, aSize ) );
193 :
194 0 : pObj->SetModel(pData->GetDocument()->GetDrawLayer()); // set before setURL
195 0 : pObj->setURL( realURL );
196 0 : pView->InsertObjectAtView( pObj, *pPV, bApi ? SDRINSERT_DONTMARK : 0 );
197 : }
198 :
199 : /*************************************************************************
200 : |*
201 : |* FuInsertGraphic::Konstruktor
202 : |*
203 : \************************************************************************/
204 :
205 : #ifdef _MSC_VER
206 : #pragma optimize("",off)
207 : #endif
208 :
209 0 : FuInsertGraphic::FuInsertGraphic( ScTabViewShell* pViewSh,
210 : Window* pWin,
211 : ScDrawView* pViewP,
212 : SdrModel* pDoc,
213 : SfxRequest& rReq )
214 0 : : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
215 : {
216 0 : const SfxItemSet* pReqArgs = rReq.GetArgs();
217 : const SfxPoolItem* pItem;
218 0 : if ( pReqArgs &&
219 0 : pReqArgs->GetItemState( SID_INSERT_GRAPHIC, sal_True, &pItem ) == SFX_ITEM_SET )
220 : {
221 0 : String aFileName = ((const SfxStringItem*)pItem)->GetValue();
222 :
223 0 : String aFilterName;
224 0 : if ( pReqArgs->GetItemState( FN_PARAM_FILTER, sal_True, &pItem ) == SFX_ITEM_SET )
225 0 : aFilterName = ((const SfxStringItem*)pItem)->GetValue();
226 :
227 0 : sal_Bool bAsLink = false;
228 0 : if ( pReqArgs->GetItemState( FN_PARAM_1, sal_True, &pItem ) == SFX_ITEM_SET )
229 0 : bAsLink = ((const SfxBoolItem*)pItem)->GetValue();
230 :
231 0 : Graphic aGraphic;
232 0 : int nError = GraphicFilter::LoadGraphic( aFileName, aFilterName, aGraphic, &GraphicFilter::GetGraphicFilter() );
233 0 : if ( nError == GRFILTER_OK )
234 : {
235 0 : lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, sal_True, pViewSh, pWindow, pView );
236 0 : }
237 : }
238 : else
239 : {
240 0 : SvxOpenGraphicDialog aDlg(ScResId(STR_INSERTGRAPHIC));
241 :
242 0 : if( aDlg.Execute() == GRFILTER_OK )
243 : {
244 0 : Graphic aGraphic;
245 0 : int nError = aDlg.GetGraphic(aGraphic);
246 0 : if( nError == GRFILTER_OK )
247 : {
248 0 : String aFileName = aDlg.GetPath();
249 0 : String aFilterName = aDlg.GetCurrentFilter();
250 0 : sal_Bool bAsLink = aDlg.IsAsLink();
251 :
252 : // really store as link only?
253 0 : if( bAsLink && SvtMiscOptions().ShowLinkWarningDialog() )
254 : {
255 0 : SvxLinkWarningDialog aWarnDlg(pWin,aFileName);
256 0 : if( aWarnDlg.Execute() != RET_OK )
257 0 : bAsLink = false; // don't store as link
258 : }
259 :
260 0 : lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, false, pViewSh, pWindow, pView );
261 :
262 : // append items for recording
263 0 : rReq.AppendItem( SfxStringItem( SID_INSERT_GRAPHIC, aFileName ) );
264 0 : rReq.AppendItem( SfxStringItem( FN_PARAM_FILTER, aFilterName ) );
265 0 : rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bAsLink ) );
266 0 : rReq.Done();
267 : }
268 : else
269 : {
270 : // error is handled in SvxOpenGraphicDialog::GetGraphic
271 0 : }
272 0 : }
273 : }
274 0 : }
275 :
276 : /*************************************************************************
277 : |*
278 : |* FuInsertGraphic::Destruktor
279 : |*
280 : \************************************************************************/
281 :
282 0 : FuInsertGraphic::~FuInsertGraphic()
283 : {
284 0 : }
285 :
286 : /*************************************************************************
287 : |*
288 : |* FuInsertGraphic::Function aktivieren
289 : |*
290 : \************************************************************************/
291 :
292 0 : void FuInsertGraphic::Activate()
293 : {
294 0 : FuPoor::Activate();
295 0 : }
296 :
297 : /*************************************************************************
298 : |*
299 : |* FuInsertGraphic::Function deaktivieren
300 : |*
301 : \************************************************************************/
302 :
303 0 : void FuInsertGraphic::Deactivate()
304 : {
305 0 : FuPoor::Deactivate();
306 0 : }
307 :
308 : /*************************************************************************
309 : |*
310 : |* FuInsertMedia::Konstruktor
311 : |*
312 : \************************************************************************/
313 :
314 0 : FuInsertMedia::FuInsertMedia( ScTabViewShell* pViewSh,
315 : Window* pWin,
316 : ScDrawView* pViewP,
317 : SdrModel* pDoc,
318 : SfxRequest& rReq ) :
319 0 : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
320 : {
321 0 : ::rtl::OUString aURL;
322 0 : const SfxItemSet* pReqArgs = rReq.GetArgs();
323 0 : bool bAPI = false;
324 :
325 0 : if( pReqArgs )
326 : {
327 0 : const SfxStringItem* pStringItem = PTR_CAST( SfxStringItem, &pReqArgs->Get( rReq.GetSlot() ) );
328 :
329 0 : if( pStringItem )
330 : {
331 0 : aURL = pStringItem->GetValue();
332 0 : bAPI = aURL.getLength();
333 : }
334 : }
335 :
336 0 : bool bLink(true);
337 0 : if (bAPI ||
338 0 : ::avmedia::MediaWindow::executeMediaURLDialog(pWindow, aURL, & bLink))
339 : {
340 0 : Size aPrefSize;
341 :
342 0 : if( pWin )
343 0 : pWin->EnterWait();
344 :
345 0 : if( !::avmedia::MediaWindow::isMediaURL( aURL, true, &aPrefSize ) )
346 : {
347 0 : if( pWin )
348 0 : pWin->LeaveWait();
349 :
350 0 : if( !bAPI )
351 0 : ::avmedia::MediaWindow::executeFormatErrorBox( pWindow );
352 : }
353 : else
354 : {
355 : lcl_InsertMedia( aURL, bAPI, pViewSh, pWindow, pView, aPrefSize,
356 0 : bLink );
357 :
358 0 : if( pWin )
359 0 : pWin->LeaveWait();
360 : }
361 0 : }
362 0 : }
363 :
364 : /*************************************************************************
365 : |*
366 : |* FuInsertMedia::Destruktor
367 : |*
368 : \************************************************************************/
369 :
370 0 : FuInsertMedia::~FuInsertMedia()
371 : {
372 0 : }
373 :
374 : /*************************************************************************
375 : |*
376 : |* FuInsertMedia::Function aktivieren
377 : |*
378 : \************************************************************************/
379 :
380 0 : void FuInsertMedia::Activate()
381 : {
382 0 : FuPoor::Activate();
383 0 : }
384 :
385 : /*************************************************************************
386 : |*
387 : |* FuInsertMedia::Function deaktivieren
388 : |*
389 : \************************************************************************/
390 :
391 0 : void FuInsertMedia::Deactivate()
392 : {
393 0 : FuPoor::Deactivate();
394 15 : }
395 :
396 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|