1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <unotools/localfilehelper.hxx>
22 #include <sfx2/request.hxx>
23 #include <sfx2/docfilt.hxx>
24 #include <sfx2/fcontnr.hxx>
25 #include <sfx2/docfile.hxx>
26 #include <vcl/msgbox.hxx>
27 #include <svl/urlbmk.hxx>
28 #include <svx/svdpagv.hxx>
29 #include <svx/xfillit.hxx>
30 #include <svx/svdundo.hxx>
31 #include <svx/xoutbmp.hxx>
32 #include <svx/svdograf.hxx>
33 #include <svx/svdomedia.hxx>
34 #include <svx/svdoole2.hxx>
35 #include <sot/storage.hxx>
36 #include <sfx2/app.hxx>
37 #include <avmedia/mediawindow.hxx>
38 #include <svtools/ehdl.hxx>
39 #include <svtools/sfxecode.hxx>
40 #include <vcl/graphicfilter.hxx>
43 #include "DrawDocShell.hxx"
44 #include "DrawViewShell.hxx"
45 #include "fuinsfil.hxx"
46 #include "drawdoc.hxx"
47 #include "sdresid.hxx"
48 #include "strings.hrc"
49 #include "imapinfo.hxx"
51 #include "view/SlideSorterView.hxx"
52 #include "undo/undoobjects.hxx"
54 #include <comphelper/processfactory.hxx>
55 #include <com/sun/star/embed/ElementModes.hpp>
56 #include <com/sun/star/embed/XEmbedPersist.hpp>
57 #include <com/sun/star/embed/Aspects.hpp>
58 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
59 #include <svtools/soerr.hxx>
61 #include <sfx2/ipclient.hxx>
64 using namespace com::sun::star
;
69 * If an empty graphic object is provided, we fill it. Otherwise we fill an
70 * existing object at the specified position. If there is no object at the
71 * position, we create a new object and return a pointer to it.
73 SdrGrafObj
* View::InsertGraphic( const Graphic
& rGraphic
, sal_Int8
& rAction
,
74 const Point
& rPos
, SdrObject
* pObj
, ImageMap
* pImageMap
)
79 // Is there a object at the position rPos?
80 SdrGrafObj
* pNewGrafObj
= NULL
;
81 SdrPageView
* pPV
= GetSdrPageView();
82 SdrObject
* pPickObj
= pObj
;
83 const bool bOnMaster
= pPV
&& pPV
->GetPage() && pPV
->GetPage()->IsMasterPage();
85 if(pPV
&& this->ISA(::sd::slidesorter::view::SlideSorterView
))
87 if(!pPV
->GetPageRect().IsInside(rPos
))
91 if( !pPickObj
&& pPV
)
93 SdrPageView
* pPageView
= pPV
;
94 PickObj(rPos
, getHitTolLog(), pPickObj
, pPageView
);
97 if( mnAction
== DND_ACTION_LINK
&& pPickObj
&& pPV
)
99 const bool bIsGraphic
= pPickObj
->ISA( SdrGrafObj
);
100 if( bIsGraphic
|| (pObj
&& pObj
->IsEmptyPresObj() && !bOnMaster
) )
102 if( IsUndoEnabled() )
103 BegUndo(String(SdResId(STR_INSERTGRAPHIC
)));
105 SdPage
* pPage
= (SdPage
*) pPickObj
->GetPage();
109 // We fill the object with the Bitmap
110 pNewGrafObj
= (SdrGrafObj
*) pPickObj
->Clone();
111 pNewGrafObj
->SetGraphic(rGraphic
);
115 pNewGrafObj
= new SdrGrafObj( rGraphic
, pPickObj
->GetSnapRect() );
116 pNewGrafObj
->SetEmptyPresObj(sal_True
);
119 if ( pNewGrafObj
->IsEmptyPresObj() )
121 Rectangle
aRect( pNewGrafObj
->GetLogicRect() );
122 pNewGrafObj
->AdjustToMaxRect( aRect
, sal_False
);
123 pNewGrafObj
->SetOutlinerParaObject(NULL
);
124 pNewGrafObj
->SetEmptyPresObj(sal_False
);
127 if (pPage
&& pPage
->IsPresObj(pPickObj
))
129 // Insert new PresObj into the list
130 pPage
->InsertPresObj( pNewGrafObj
, PRESOBJ_GRAPHIC
);
131 pNewGrafObj
->SetUserCall(pPickObj
->GetUserCall());
135 pNewGrafObj
->AppendUserData(new SdIMapInfo(*pImageMap
));
137 ReplaceObjectAtView(pPickObj
, *pPV
, pNewGrafObj
); // maybe ReplaceObjectAtView
139 if( IsUndoEnabled() )
142 else if (pPickObj
->IsClosedObj() && !pPickObj
->ISA(SdrOle2Obj
))
144 // we fill the object with the graphic
145 if( IsUndoEnabled() )
147 BegUndo(String(SdResId(STR_UNDO_DRAGDROP
)));
148 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pPickObj
));
152 SfxItemSet
aSet(mpDocSh
->GetPool(), XATTR_FILLSTYLE
, XATTR_FILLBITMAP
);
153 aSet
.Put(XFillStyleItem(XFILL_BITMAP
));
154 aSet
.Put(XFillBitmapItem(&mpDocSh
->GetPool(), rGraphic
));
155 pPickObj
->SetMergedItemSetAndBroadcast(aSet
);
163 if ( rGraphic
.GetPrefMapMode().GetMapUnit() == MAP_PIXEL
)
165 ::OutputDevice
* pOutDev
= 0;
167 pOutDev
= mpViewSh
->GetActiveWindow();
170 pOutDev
= Application::GetDefaultDevice();
173 aSize
= pOutDev
->PixelToLogic( rGraphic
.GetPrefSize(), MAP_100TH_MM
);
177 aSize
= OutputDevice::LogicToLogic( rGraphic
.GetPrefSize(),
178 rGraphic
.GetPrefMapMode(),
179 MapMode( MAP_100TH_MM
) );
182 pNewGrafObj
= new SdrGrafObj( rGraphic
, Rectangle( rPos
, aSize
) );
183 SdrPage
* pPage
= pPV
->GetPage();
184 Size
aPageSize( pPage
->GetSize() );
185 aPageSize
.Width() -= pPage
->GetLftBorder() + pPage
->GetRgtBorder();
186 aPageSize
.Height() -= pPage
->GetUppBorder() + pPage
->GetLwrBorder();
187 pNewGrafObj
->AdjustToMaxRect( Rectangle( Point(), aPageSize
), sal_True
);
189 sal_uLong nOptions
= SDRINSERT_SETDEFLAYER
;
190 sal_Bool bIsPresTarget
= sal_False
;
193 && mpViewSh
->GetViewShell()!=NULL
194 && mpViewSh
->GetViewShell()->GetIPClient()
195 && mpViewSh
->GetViewShell()->GetIPClient()->IsObjectInPlaceActive())
196 || this->ISA(::sd::slidesorter::view::SlideSorterView
))
197 nOptions
|= SDRINSERT_DONTMARK
;
199 if( ( mnAction
& DND_ACTION_MOVE
) && pPickObj
&& (pPickObj
->IsEmptyPresObj() || pPickObj
->GetUserCall()) )
201 SdPage
* pP
= static_cast< SdPage
* >( pPickObj
->GetPage() );
203 if ( pP
&& pP
->IsMasterPage() )
204 bIsPresTarget
= pP
->IsPresObj(pPickObj
);
207 if( ( mnAction
& DND_ACTION_MOVE
) && pPickObj
&& !bIsPresTarget
)
211 pNewGrafObj
->AppendUserData(new SdIMapInfo(*pImageMap
));
213 Rectangle
aPickObjRect(pPickObj
->GetCurrentBoundRect());
214 Size
aPickObjSize(aPickObjRect
.GetSize());
215 Rectangle
aObjRect(pNewGrafObj
->GetCurrentBoundRect());
216 Size
aObjSize(aObjRect
.GetSize());
218 Fraction
aScaleWidth(aPickObjSize
.Width(), aObjSize
.Width());
219 Fraction
aScaleHeight(aPickObjSize
.Height(), aObjSize
.Height());
220 pNewGrafObj
->NbcResize(aObjRect
.TopLeft(), aScaleWidth
, aScaleHeight
);
222 Point aVec
= aPickObjRect
.TopLeft() - aObjRect
.TopLeft();
223 pNewGrafObj
->NbcMove(Size(aVec
.X(), aVec
.Y()));
225 const bool bUndo
= IsUndoEnabled();
228 BegUndo(String(SdResId(STR_UNDO_DRAGDROP
)));
229 pNewGrafObj
->NbcSetLayer(pPickObj
->GetLayer());
230 SdrPage
* pP
= pPV
->GetPage();
231 pP
->InsertObject(pNewGrafObj
);
234 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoNewObject(*pNewGrafObj
));
235 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoDeleteObject(*pPickObj
));
237 pP
->RemoveObject(pPickObj
->GetOrdNum());
245 SdrObject::Free(pPickObj
);
247 mnAction
= DND_ACTION_COPY
;
251 InsertObjectAtView(pNewGrafObj
, *pPV
, nOptions
);
254 pNewGrafObj
->AppendUserData(new SdIMapInfo(*pImageMap
));
263 // -----------------------------------------------------------------------------
265 SdrMediaObj
* View::InsertMediaURL( const OUString
& rMediaURL
, sal_Int8
& rAction
,
266 const Point
& rPos
, const Size
& rSize
,
276 uno::Reference
<frame::XModel
> const xModel(
277 GetDoc().GetObjectShell()->GetModel());
278 bool const bRet
= ::avmedia::EmbedMedia(xModel
, rMediaURL
, realURL
);
279 if (!bRet
) { return 0; }
285 SdrMediaObj
* pNewMediaObj
= NULL
;
286 SdrPageView
* pPV
= GetSdrPageView();
287 SdrObject
* pPickObj
= GetEmptyPresentationObject( PRESOBJ_MEDIA
);
289 if(pPV
&& this->ISA(::sd::slidesorter::view::SlideSorterView
))
291 if(!pPV
->GetPageRect().IsInside(rPos
))
295 if( !pPickObj
&& pPV
)
297 SdrPageView
* pPageView
= pPV
;
298 PickObj(rPos
, getHitTolLog(), pPickObj
, pPageView
);
301 if( mnAction
== DND_ACTION_LINK
&& pPickObj
&& pPV
&& pPickObj
->ISA( SdrMediaObj
) )
303 pNewMediaObj
= static_cast< SdrMediaObj
* >( pPickObj
->Clone() );
304 pNewMediaObj
->setURL( realURL
);
306 BegUndo(String(SdResId(STR_UNDO_DRAGDROP
)));
307 ReplaceObjectAtView(pPickObj
, *pPV
, pNewMediaObj
);
312 Rectangle
aRect( rPos
, rSize
);
314 aRect
= pPickObj
->GetLogicRect();
317 pNewMediaObj
= new SdrMediaObj( aRect
);
319 bool bIsPres
= false;
322 SdPage
* pPage
= static_cast< SdPage
* >(pPickObj
->GetPage());
323 bIsPres
= pPage
&& pPage
->IsPresObj(pPickObj
);
326 pPage
->InsertPresObj( pNewMediaObj
, PRESOBJ_MEDIA
);
331 ReplaceObjectAtView(pPickObj
, *pPV
, pNewMediaObj
);
333 InsertObjectAtView( pNewMediaObj
, *pPV
, SDRINSERT_SETDEFLAYER
);
335 pNewMediaObj
->setURL( realURL
);
339 pNewMediaObj
->AdjustToMaxRect( pPickObj
->GetLogicRect() );
341 pNewMediaObj
->SetUserCall(pPickObj
->GetUserCall());
351 * Timer handler for InsertFile at Drop()
353 IMPL_LINK_NOARG(View
, DropInsertFileHdl
)
355 DBG_ASSERT( mpViewSh
, "sd::View::DropInsertFileHdl(), I need a view shell to work!" );
359 SfxErrorContext
aEc( ERRCTX_ERROR
, mpViewSh
->GetActiveWindow(), RID_SO_ERRCTX
);
362 ::std::vector
< String
>::const_iterator
aIter( maDropFileVector
.begin() );
364 while( (aIter
!= maDropFileVector
.end()) && !nError
)
366 String
aCurrentDropFile( *aIter
);
367 INetURLObject
aURL( aCurrentDropFile
);
368 sal_Bool bOK
= sal_False
;
370 if( aURL
.GetProtocol() == INET_PROT_NOT_VALID
)
373 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aCurrentDropFile
, aURLStr
);
374 aURL
= INetURLObject( aURLStr
);
377 GraphicFilter
& rGraphicFilter
= GraphicFilter::GetGraphicFilter();
380 aCurrentDropFile
= aURL
.GetMainURL( INetURLObject::NO_DECODE
);
382 if( !::avmedia::MediaWindow::isMediaURL( aCurrentDropFile
) )
384 if( !rGraphicFilter
.ImportGraphic( aGraphic
, aURL
) )
386 sal_Int8 nTempAction
= ( aIter
== maDropFileVector
.begin() ) ? mnAction
: 0;
387 const bool bLink
= ( ( nTempAction
& DND_ACTION_LINK
) != 0 );
388 SdrGrafObj
* pGrafObj
= InsertGraphic( aGraphic
, nTempAction
, maDropPos
, NULL
, NULL
);
389 if(pGrafObj
&& bLink
)
391 pGrafObj
->SetGraphicLink( aCurrentDropFile
, String() );
394 // return action from first inserted graphic
395 if( aIter
== maDropFileVector
.begin() )
396 mnAction
= nTempAction
;
402 const SfxFilter
* pFoundFilter
= NULL
;
403 SfxMedium
aSfxMedium( aCurrentDropFile
, STREAM_READ
| STREAM_SHARE_DENYNONE
);
404 ErrCode nErr
= SFX_APP()->GetFilterMatcher().GuessFilter( aSfxMedium
, &pFoundFilter
, SFX_FILTER_IMPORT
, SFX_FILTER_NOTINSTALLED
| SFX_FILTER_EXECUTABLE
);
406 if( pFoundFilter
&& !nErr
)
408 ::std::vector
< OUString
> aFilterVector
;
409 const String
aFilterName( pFoundFilter
->GetFilterName() );
410 String
aLowerAsciiFileName( aCurrentDropFile
);
411 aLowerAsciiFileName
.ToLowerAscii();
413 FuInsertFile::GetSupportedFilterVector( aFilterVector
);
415 if( ( ::std::find( aFilterVector
.begin(), aFilterVector
.end(), pFoundFilter
->GetMimeType() ) != aFilterVector
.end() ) ||
416 aFilterName
.SearchAscii( "Text" ) != STRING_NOTFOUND
||
417 aFilterName
.SearchAscii( "Rich" ) != STRING_NOTFOUND
||
418 aFilterName
.SearchAscii( "RTF" ) != STRING_NOTFOUND
||
419 aFilterName
.SearchAscii( "HTML" ) != STRING_NOTFOUND
||
420 aLowerAsciiFileName
.SearchAscii(".sdd") != STRING_NOTFOUND
||
421 aLowerAsciiFileName
.SearchAscii(".sda") != STRING_NOTFOUND
||
422 aLowerAsciiFileName
.SearchAscii(".sxd") != STRING_NOTFOUND
||
423 aLowerAsciiFileName
.SearchAscii(".sxi") != STRING_NOTFOUND
||
424 aLowerAsciiFileName
.SearchAscii(".std") != STRING_NOTFOUND
||
425 aLowerAsciiFileName
.SearchAscii(".sti") != STRING_NOTFOUND
)
427 ::sd::Window
* pWin
= mpViewSh
->GetActiveWindow();
428 SfxRequest
aReq(SID_INSERTFILE
, 0, mrDoc
.GetItemPool());
429 SfxStringItem
aItem1( ID_VAL_DUMMY0
, aCurrentDropFile
), aItem2( ID_VAL_DUMMY1
, pFoundFilter
->GetFilterName() );
431 aReq
.AppendItem( aItem1
);
432 aReq
.AppendItem( aItem2
);
433 FuInsertFile::Create( mpViewSh
, pWin
, this, &mrDoc
, aReq
);
444 if( ::avmedia::MediaWindow::isMediaURL( aCurrentDropFile
) &&
445 ::avmedia::MediaWindow::isMediaURL( aCurrentDropFile
, true, &aPrefSize
) )
447 if( aPrefSize
.Width() && aPrefSize
.Height() )
449 ::sd::Window
* pWin
= mpViewSh
->GetActiveWindow();
452 aPrefSize
= pWin
->PixelToLogic( aPrefSize
, MAP_100TH_MM
);
454 aPrefSize
= Application::GetDefaultDevice()->PixelToLogic( aPrefSize
, MAP_100TH_MM
);
457 aPrefSize
= Size( 5000, 5000 );
459 InsertMediaURL( aCurrentDropFile
, mnAction
, maDropPos
, aPrefSize
, true ) ;
461 else if( mnAction
& DND_ACTION_LINK
)
462 static_cast< DrawViewShell
* >( mpViewSh
)->InsertURLButton( aCurrentDropFile
, aCurrentDropFile
, String(), &maDropPos
);
471 uno::Sequence
< beans::PropertyValue
> aMedium(1);
472 aMedium
[0].Name
= "URL" ;
473 aMedium
[0].Value
<<= OUString(aCurrentDropFile
) ;
475 uno::Reference
< embed::XEmbeddedObject
> xObj
= mpDocSh
->GetEmbeddedObjectContainer().
476 InsertEmbeddedObject( aMedium
, aName
);
478 uno::Reference
< embed::XEmbedPersist
> xPersist( xObj
, uno::UNO_QUERY
);
481 // TODO/LEAN: VisualArea access can switch the object to running state
482 sal_Int64 nAspect
= embed::Aspects::MSOLE_CONTENT
;
484 xPersist
->storeOwn();
489 aSz
= xObj
->getVisualAreaSize( nAspect
);
491 catch( embed::NoVisualAreaSizeException
& )
493 // the default size will be set later
496 Size
aSize( aSz
.Width
, aSz
.Height
);
499 if (!aSize
.Width() || !aSize
.Height())
501 aSize
.Width() = 1410;
502 aSize
.Height() = 1000;
505 aRect
= Rectangle( maDropPos
, aSize
);
507 SdrOle2Obj
* pOleObj
= new SdrOle2Obj( svt::EmbeddedObjectRef( xObj
, nAspect
), aName
, aRect
);
508 sal_uLong nOptions
= SDRINSERT_SETDEFLAYER
;
510 if (mpViewSh
!= NULL
)
512 OSL_ASSERT (mpViewSh
->GetViewShell()!=NULL
);
513 SfxInPlaceClient
* pIpClient
=
514 mpViewSh
->GetViewShell()->GetIPClient();
515 if (pIpClient
!=NULL
&& pIpClient
->IsObjectInPlaceActive())
516 nOptions
|= SDRINSERT_DONTMARK
;
519 InsertObjectAtView( pOleObj
, *GetSdrPageView(), nOptions
);
520 pOleObj
->SetLogicRect( aRect
);
521 aSz
.Width
= aRect
.GetWidth();
522 aSz
.Height
= aRect
.GetHeight();
523 xObj
->setVisualAreaSize( nAspect
,aSz
);
526 catch( uno::Exception
& )
528 nError
= ERRCODE_IO_GENERAL
;
529 // TODO/LATER: better error handling
539 ErrorHandler::HandleError( nError
);
545 * Timer handler for Errorhandling at Drop()
547 IMPL_LINK_NOARG(View
, DropErrorHdl
)
549 InfoBox( mpViewSh
? mpViewSh
->GetActiveWindow() : 0, String(SdResId(STR_ACTION_NOTPOSSIBLE
) ) ).Execute();
554 * @returns StyleSheet from selection
556 SfxStyleSheet
* View::GetStyleSheet() const
558 return SdrView::GetStyleSheet();
561 } // end of namespace sd
563 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */