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 : #include <sfx2/opengrf.hxx>
21 : #include <svx/svdograf.hxx>
22 : #include <svx/svdomedia.hxx>
23 : #include <svx/svdpage.hxx>
24 : #include <svx/svdpagv.hxx>
25 : #include <svx/svdview.hxx>
26 : #include <svx/linkwarn.hxx>
27 : #include <vcl/graphicfilter.hxx>
28 : #include <svl/stritem.hxx>
29 : #include <svtools/miscopt.hxx>
30 : #include <vcl/msgbox.hxx>
31 : #include <avmedia/mediawindow.hxx>
32 : #include <vcl/svapp.hxx>
33 :
34 : #include "fuinsert.hxx"
35 : #include "tabvwsh.hxx"
36 : #include "drwlayer.hxx"
37 : #include "drawview.hxx"
38 : #include "document.hxx"
39 : #include "scresid.hxx"
40 : #include "progress.hxx"
41 : #include "sc.hrc"
42 : #include "globstr.hrc"
43 :
44 : using namespace ::com::sun::star;
45 :
46 0 : void ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage )
47 : {
48 0 : if ( !rPage.Width() || !rPage.Height() )
49 0 : return;
50 :
51 0 : Size aPageSize = rPage;
52 0 : bool bNegative = aPageSize.Width() < 0;
53 0 : if ( bNegative )
54 : {
55 : // make everything positive temporarily
56 0 : aPageSize.Width() = -aPageSize.Width();
57 0 : rPos.X() = -rPos.X() - rSize.Width();
58 : }
59 :
60 0 : if ( rSize.Width() > aPageSize.Width() || rSize.Height() > aPageSize.Height() )
61 : {
62 0 : double fX = aPageSize.Width() / (double) rSize.Width();
63 0 : double fY = aPageSize.Height() / (double) rSize.Height();
64 :
65 0 : if ( fX < fY )
66 : {
67 0 : rSize.Width() = aPageSize.Width();
68 0 : rSize.Height() = (long) ( rSize.Height() * fX );
69 : }
70 : else
71 : {
72 0 : rSize.Height() = aPageSize.Height();
73 0 : rSize.Width() = (long) ( rSize.Width() * fY );
74 : }
75 :
76 0 : if (!rSize.Width())
77 0 : rSize.Width() = 1;
78 0 : if (!rSize.Height())
79 0 : rSize.Height() = 1;
80 : }
81 :
82 0 : if ( rPos.X() + rSize.Width() > aPageSize.Width() )
83 0 : rPos.X() = aPageSize.Width() - rSize.Width();
84 0 : if ( rPos.Y() + rSize.Height() > aPageSize.Height() )
85 0 : rPos.Y() = aPageSize.Height() - rSize.Height();
86 :
87 0 : if ( bNegative )
88 0 : rPos.X() = -rPos.X() - rSize.Width(); // back to real position
89 : }
90 :
91 0 : static void lcl_InsertGraphic( const Graphic& rGraphic,
92 : const OUString& rFileName, const OUString& rFilterName, bool bAsLink, bool bApi,
93 : ScTabViewShell* pViewSh, vcl::Window* pWindow, SdrView* pView )
94 : {
95 0 : ScDrawView* pDrawView = pViewSh->GetScDrawView();
96 :
97 : // #i123922# check if an existing object is selected; if yes, evtl. replace
98 : // the graphic for a SdrGraphObj (including link state updates) or adapt the fill
99 : // style for other objects
100 0 : if(pDrawView && 1 == pDrawView->GetMarkedObjectCount())
101 : {
102 0 : SdrObject* pPickObj = pDrawView->GetMarkedObjectByIndex(0);
103 :
104 0 : if(pPickObj)
105 : {
106 : //sal_Int8 nAction(DND_ACTION_MOVE);
107 : //Point aPos;
108 0 : const OUString aBeginUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP));
109 0 : const OUString aEmpty;
110 :
111 : SdrObject* pResult = pDrawView->ApplyGraphicToObject(
112 : *pPickObj,
113 : rGraphic,
114 : aBeginUndo,
115 : bAsLink ? rFileName : aEmpty,
116 0 : bAsLink ? rFilterName : aEmpty);
117 :
118 0 : if(pResult)
119 : {
120 : // we are done; mark the modified/new object
121 0 : pDrawView->MarkObj(pResult, pDrawView->GetSdrPageView());
122 0 : return;
123 0 : }
124 : }
125 : }
126 :
127 : // set the size so the graphic has its original pixel size
128 : // at 100% view scale (as in SetMarkedOriginalSize),
129 : // instead of respecting the current view scale
130 0 : MapMode aSourceMap = rGraphic.GetPrefMapMode();
131 0 : MapMode aDestMap( MAP_100TH_MM );
132 0 : if ( aSourceMap.GetMapUnit() == MAP_PIXEL && pDrawView )
133 : {
134 0 : Fraction aScaleX, aScaleY;
135 0 : pDrawView->CalcNormScale( aScaleX, aScaleY );
136 0 : aDestMap.SetScaleX(aScaleX);
137 0 : aDestMap.SetScaleY(aScaleY);
138 : }
139 : Size aLogicSize = pWindow->LogicToLogic(
140 0 : rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
141 :
142 : // Limit size
143 :
144 0 : SdrPageView* pPV = pView->GetSdrPageView();
145 0 : SdrPage* pPage = pPV->GetPage();
146 0 : Point aInsertPos = pViewSh->GetInsertPos();
147 :
148 0 : ScViewData& rData = pViewSh->GetViewData();
149 0 : if ( rData.GetDocument()->IsNegativePage( rData.GetTabNo() ) )
150 0 : aInsertPos.X() -= aLogicSize.Width(); // move position to left edge
151 :
152 0 : ScLimitSizeOnDrawPage( aLogicSize, aInsertPos, pPage->GetSize() );
153 :
154 0 : Rectangle aRect ( aInsertPos, aLogicSize );
155 :
156 0 : SdrGrafObj* pObj = new SdrGrafObj( rGraphic, aRect );
157 :
158 : // calling SetGraphicLink here doesn't work
159 :
160 : // Path is no longer used as name for the graphics object
161 :
162 0 : ScDrawLayer* pLayer = static_cast<ScDrawLayer*>(pView->GetModel());
163 0 : OUString aName = pLayer->GetNewGraphicName(); // "Graphics"
164 0 : pObj->SetName(aName);
165 :
166 : // don't select if from (dispatch) API, to allow subsequent cell operations
167 0 : SdrInsertFlags nInsOptions = bApi ? SdrInsertFlags::DONTMARK : SdrInsertFlags::NONE;
168 0 : pView->InsertObjectAtView( pObj, *pPV, nInsOptions );
169 :
170 : // SetGraphicLink has to be used after inserting the object,
171 : // otherwise an empty graphic is swapped in and the contact stuff crashes.
172 : // See #i37444#.
173 0 : if ( bAsLink )
174 0 : pObj->SetGraphicLink( rFileName, ""/*TODO?*/, rFilterName );
175 : }
176 :
177 0 : static void lcl_InsertMedia( const OUString& rMediaURL, bool bApi,
178 : ScTabViewShell* pViewSh, vcl::Window* pWindow, SdrView* pView,
179 : const Size& rPrefSize, bool const bLink )
180 : {
181 0 : SdrPageView* pPV = pView->GetSdrPageView();
182 0 : SdrPage* pPage = pPV->GetPage();
183 0 : ScViewData& rData = pViewSh->GetViewData();
184 0 : Point aInsertPos( pViewSh->GetInsertPos() );
185 0 : Size aSize;
186 :
187 0 : if( rPrefSize.Width() && rPrefSize.Height() )
188 : {
189 0 : if( pWindow )
190 0 : aSize = pWindow->PixelToLogic( rPrefSize, MAP_100TH_MM );
191 : else
192 0 : aSize = Application::GetDefaultDevice()->PixelToLogic( rPrefSize, MAP_100TH_MM );
193 : }
194 : else
195 0 : aSize = Size( 5000, 5000 );
196 :
197 0 : ScLimitSizeOnDrawPage( aSize, aInsertPos, pPage->GetSize() );
198 :
199 0 : if( rData.GetDocument()->IsNegativePage( rData.GetTabNo() ) )
200 0 : aInsertPos.X() -= aSize.Width();
201 :
202 0 : OUString realURL;
203 0 : if (bLink)
204 : {
205 0 : realURL = rMediaURL;
206 : }
207 : else
208 : {
209 : uno::Reference<frame::XModel> const xModel(
210 0 : rData.GetDocument()->GetDocumentShell()->GetModel());
211 0 : bool const bRet = ::avmedia::EmbedMedia(xModel, rMediaURL, realURL);
212 0 : if (!bRet) { return; }
213 : }
214 :
215 0 : SdrMediaObj* pObj = new SdrMediaObj( Rectangle( aInsertPos, aSize ) );
216 :
217 0 : pObj->SetModel(rData.GetDocument()->GetDrawLayer()); // set before setURL
218 0 : pObj->setURL( realURL, ""/*TODO?*/ );
219 0 : pView->InsertObjectAtView( pObj, *pPV, bApi ? SdrInsertFlags::DONTMARK : SdrInsertFlags::NONE );
220 : }
221 :
222 : /*************************************************************************
223 : |*
224 : |* FuInsertGraphic::Konstruktor
225 : |*
226 : \************************************************************************/
227 :
228 0 : FuInsertGraphic::FuInsertGraphic( ScTabViewShell* pViewSh,
229 : vcl::Window* pWin,
230 : ScDrawView* pViewP,
231 : SdrModel* pDoc,
232 : SfxRequest& rReq )
233 0 : : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
234 : {
235 0 : const SfxItemSet* pReqArgs = rReq.GetArgs();
236 : const SfxPoolItem* pItem;
237 0 : if ( pReqArgs &&
238 0 : pReqArgs->GetItemState( SID_INSERT_GRAPHIC, true, &pItem ) == SfxItemState::SET )
239 : {
240 0 : OUString aFileName = static_cast<const SfxStringItem*>(pItem)->GetValue();
241 :
242 0 : OUString aFilterName;
243 0 : if ( pReqArgs->GetItemState( FN_PARAM_FILTER, true, &pItem ) == SfxItemState::SET )
244 0 : aFilterName = static_cast<const SfxStringItem*>(pItem)->GetValue();
245 :
246 0 : bool bAsLink = false;
247 0 : if ( pReqArgs->GetItemState( FN_PARAM_1, true, &pItem ) == SfxItemState::SET )
248 0 : bAsLink = static_cast<const SfxBoolItem*>(pItem)->GetValue();
249 :
250 0 : Graphic aGraphic;
251 0 : int nError = GraphicFilter::LoadGraphic( aFileName, aFilterName, aGraphic, &GraphicFilter::GetGraphicFilter() );
252 0 : if ( nError == GRFILTER_OK )
253 : {
254 0 : lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, true, pViewSh, pWindow, pView );
255 0 : }
256 : }
257 : else
258 : {
259 0 : SvxOpenGraphicDialog aDlg(ScResId(STR_INSERTGRAPHIC));
260 :
261 0 : if( aDlg.Execute() == GRFILTER_OK )
262 : {
263 0 : Graphic aGraphic;
264 0 : int nError = aDlg.GetGraphic(aGraphic);
265 0 : if( nError == GRFILTER_OK )
266 : {
267 0 : OUString aFileName = aDlg.GetPath();
268 0 : OUString aFilterName = aDlg.GetCurrentFilter();
269 0 : bool bAsLink = aDlg.IsAsLink();
270 :
271 : // really store as link only?
272 0 : if( bAsLink && SvtMiscOptions().ShowLinkWarningDialog() )
273 : {
274 0 : ScopedVclPtrInstance< SvxLinkWarningDialog > aWarnDlg(pWin,aFileName);
275 0 : if( aWarnDlg->Execute() != RET_OK )
276 0 : bAsLink = false; // don't store as link
277 : }
278 :
279 0 : lcl_InsertGraphic( aGraphic, aFileName, aFilterName, bAsLink, false, pViewSh, pWindow, pView );
280 :
281 : // append items for recording
282 0 : rReq.AppendItem( SfxStringItem( SID_INSERT_GRAPHIC, aFileName ) );
283 0 : rReq.AppendItem( SfxStringItem( FN_PARAM_FILTER, aFilterName ) );
284 0 : rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bAsLink ) );
285 0 : rReq.Done();
286 : }
287 : else
288 : {
289 : // error is handled in SvxOpenGraphicDialog::GetGraphic
290 0 : }
291 0 : }
292 : }
293 0 : }
294 :
295 : /*************************************************************************
296 : |*
297 : |* FuInsertGraphic::Destruktor
298 : |*
299 : \************************************************************************/
300 :
301 0 : FuInsertGraphic::~FuInsertGraphic()
302 : {
303 0 : }
304 :
305 : /*************************************************************************
306 : |*
307 : |* FuInsertGraphic::Function aktivieren
308 : |*
309 : \************************************************************************/
310 :
311 0 : void FuInsertGraphic::Activate()
312 : {
313 0 : FuPoor::Activate();
314 0 : }
315 :
316 : /*************************************************************************
317 : |*
318 : |* FuInsertGraphic::Function deaktivieren
319 : |*
320 : \************************************************************************/
321 :
322 0 : void FuInsertGraphic::Deactivate()
323 : {
324 0 : FuPoor::Deactivate();
325 0 : }
326 :
327 : /*************************************************************************
328 : |*
329 : |* FuInsertMedia::Konstruktor
330 : |*
331 : \************************************************************************/
332 :
333 0 : FuInsertMedia::FuInsertMedia( ScTabViewShell* pViewSh,
334 : vcl::Window* pWin,
335 : ScDrawView* pViewP,
336 : SdrModel* pDoc,
337 : SfxRequest& rReq ) :
338 0 : FuPoor(pViewSh, pWin, pViewP, pDoc, rReq)
339 : {
340 0 : OUString aURL;
341 0 : const SfxItemSet* pReqArgs = rReq.GetArgs();
342 0 : bool bAPI = false;
343 :
344 0 : if( pReqArgs )
345 : {
346 0 : const SfxStringItem* pStringItem = PTR_CAST( SfxStringItem, &pReqArgs->Get( rReq.GetSlot() ) );
347 :
348 0 : if( pStringItem )
349 : {
350 0 : aURL = pStringItem->GetValue();
351 0 : bAPI = aURL.getLength();
352 : }
353 : }
354 :
355 0 : bool bLink(true);
356 0 : if (bAPI ||
357 0 : ::avmedia::MediaWindow::executeMediaURLDialog(pWindow, aURL, & bLink))
358 : {
359 0 : Size aPrefSize;
360 :
361 0 : if( pWin )
362 0 : pWin->EnterWait();
363 :
364 0 : if( !::avmedia::MediaWindow::isMediaURL( aURL, ""/*TODO?*/, true, &aPrefSize ) )
365 : {
366 0 : if( pWin )
367 0 : pWin->LeaveWait();
368 :
369 0 : if( !bAPI )
370 0 : ::avmedia::MediaWindow::executeFormatErrorBox( pWindow );
371 : }
372 : else
373 : {
374 : lcl_InsertMedia( aURL, bAPI, pViewSh, pWindow, pView, aPrefSize,
375 0 : bLink );
376 :
377 0 : if( pWin )
378 0 : pWin->LeaveWait();
379 : }
380 0 : }
381 0 : }
382 :
383 : /*************************************************************************
384 : |*
385 : |* FuInsertMedia::Destruktor
386 : |*
387 : \************************************************************************/
388 :
389 0 : FuInsertMedia::~FuInsertMedia()
390 : {
391 0 : }
392 :
393 : /*************************************************************************
394 : |*
395 : |* FuInsertMedia::Function aktivieren
396 : |*
397 : \************************************************************************/
398 :
399 0 : void FuInsertMedia::Activate()
400 : {
401 0 : FuPoor::Activate();
402 0 : }
403 :
404 : /*************************************************************************
405 : |*
406 : |* FuInsertMedia::Function deaktivieren
407 : |*
408 : \************************************************************************/
409 :
410 0 : void FuInsertMedia::Deactivate()
411 : {
412 0 : FuPoor::Deactivate();
413 156 : }
414 :
415 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|