1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sdview4.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
35 #include <unotools/localfilehelper.hxx>
36 #include <sfx2/request.hxx>
37 #include <sfx2/docfilt.hxx>
38 #include <sfx2/fcontnr.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <vcl/msgbox.hxx>
41 #include <svtools/urlbmk.hxx>
42 #include <svx/svdpagv.hxx>
43 #include <svx/xfillit.hxx>
44 #include <svx/svdundo.hxx>
45 #include <svx/xoutbmp.hxx>
46 #include <svx/svdograf.hxx>
47 #include <svx/svdomedia.hxx>
48 #include <svx/svdoole2.hxx>
50 #include <svx/impgrf.hxx>
52 #include <sot/storage.hxx>
53 #include <sfx2/app.hxx>
54 #include <avmedia/mediawindow.hxx>
55 #include <svtools/ehdl.hxx>
56 #include <svtools/sfxecode.hxx>
60 #include "DrawDocShell.hxx"
61 #include "DrawViewShell.hxx"
62 #include "fuinsfil.hxx"
63 #include "drawdoc.hxx"
64 #include "sdresid.hxx"
65 #include "strings.hrc"
66 #include "imapinfo.hxx"
68 #include "view/SlideSorterView.hxx"
69 #include "undo/undoobjects.hxx"
71 #include <comphelper/processfactory.hxx>
72 #include <com/sun/star/embed/ElementModes.hpp>
73 #include <com/sun/star/embed/XEmbedPersist.hpp>
74 #include <com/sun/star/embed/Aspects.hpp>
75 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
76 #include <svtools/soerr.hxx>
78 #include <sfx2/ipclient.hxx>
80 using namespace com::sun::star
;
85 #pragma optimize ( "", off )
88 /*************************************************************************
91 |* Wird ein leeres Graphikobjekt uebergeben, so wird dieses gefuellt.
92 |* Andernfalls wird ein an der gegebenen Position vorhandenes Objekt
93 |* gefuellt. Ist an der Position kein Objekt vorhanden, so wird ein neues
94 |* Objekt erzeugt und ein Pointer auf dieses Objekt zurueckgegeben.
96 \************************************************************************/
98 SdrGrafObj
* View::InsertGraphic( const Graphic
& rGraphic
, sal_Int8
& rAction
,
99 const Point
& rPos
, SdrObject
* pObj
, ImageMap
* pImageMap
)
104 // Liegt ein Objekt an der Position rPos?
105 SdrGrafObj
* pNewGrafObj
= NULL
;
106 SdrPageView
* pPV
= GetSdrPageView();
107 SdrObject
* pPickObj
= pObj
;
109 if(pPV
&& this->ISA(::sd::slidesorter::view::SlideSorterView
))
111 if(!pPV
->GetPageRect().IsInside(rPos
))
115 if( !pPickObj
&& pPV
)
117 SdrPageView
* pPageView
= pPV
;
118 PickObj(rPos
, getHitTolLog(), pPickObj
, pPageView
);
121 if( mnAction
== DND_ACTION_LINK
&& pPickObj
&& pPV
)
123 if( pPickObj
->ISA( SdrGrafObj
) )
125 // Das Objekt wird mit der Bitmap gefuellt
126 pNewGrafObj
= (SdrGrafObj
*) pPickObj
->Clone();
127 pNewGrafObj
->SetGraphic(rGraphic
);
129 if ( pNewGrafObj
->IsEmptyPresObj() )
131 Rectangle
aRect( pNewGrafObj
->GetLogicRect() );
132 pNewGrafObj
->AdjustToMaxRect( aRect
, FALSE
);
133 pNewGrafObj
->SetOutlinerParaObject(NULL
);
134 pNewGrafObj
->SetEmptyPresObj(FALSE
);
137 const bool bUndo
= IsUndoEnabled();
139 BegUndo(String(SdResId(STR_UNDO_DRAGDROP
)));
141 SdPage
* pPage
= (SdPage
*) pPickObj
->GetPage();
143 if (pPage
&& pPage
->GetPresObjKind(pPickObj
) == PRESOBJ_GRAPHIC
)
145 // Neues PresObj in die Liste eintragen
146 pNewGrafObj
->SetUserCall(pPickObj
->GetUserCall());
149 AddUndo( new sd::UndoObjectPresentationKind( *pPickObj
) );
150 AddUndo( new sd::UndoObjectPresentationKind( *pNewGrafObj
) );
152 pPage
->RemovePresObj(pPickObj
);
153 pPage
->InsertPresObj(pNewGrafObj
, PRESOBJ_GRAPHIC
);
157 SdrObject::Free( pPickObj
);
162 pNewGrafObj
->InsertUserData(new SdIMapInfo(*pImageMap
));
164 ReplaceObjectAtView(pPickObj
, *pPV
, pNewGrafObj
); // maybe ReplaceObjectAtView
169 else if (pPickObj
->IsClosedObj() && !pPickObj
->ISA(SdrOle2Obj
))
171 /******************************************************************
172 * Das Objekt wird mit der Graphik gefuellt
173 ******************************************************************/
174 if( IsUndoEnabled() )
176 BegUndo(String(SdResId(STR_UNDO_DRAGDROP
)));
177 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pPickObj
));
181 XOBitmap
aXOBitmap( rGraphic
.GetBitmap() );
182 SfxItemSet
aSet(mpDocSh
->GetPool(), XATTR_FILLSTYLE
, XATTR_FILLBITMAP
);
183 aSet
.Put(XFillStyleItem(XFILL_BITMAP
));
184 aSet
.Put(XFillBitmapItem(&mpDocSh
->GetPool(), aXOBitmap
));
185 pPickObj
->SetMergedItemSetAndBroadcast(aSet
);
193 if ( rGraphic
.GetPrefMapMode().GetMapUnit() == MAP_PIXEL
)
195 ::OutputDevice
* pOutDev
= 0;
197 pOutDev
= mpViewSh
->GetActiveWindow();
200 pOutDev
= Application::GetDefaultDevice();
203 aSize
= pOutDev
->PixelToLogic( rGraphic
.GetPrefSize(), MAP_100TH_MM
);
207 aSize
= OutputDevice::LogicToLogic( rGraphic
.GetPrefSize(),
208 rGraphic
.GetPrefMapMode(),
209 MapMode( MAP_100TH_MM
) );
212 pNewGrafObj
= new SdrGrafObj( rGraphic
, Rectangle( rPos
, aSize
) );
213 SdrPage
* pPage
= pPV
->GetPage();
214 Size
aPageSize( pPage
->GetSize() );
215 aPageSize
.Width() -= pPage
->GetLftBorder() + pPage
->GetRgtBorder();
216 aPageSize
.Height() -= pPage
->GetUppBorder() + pPage
->GetLwrBorder();
217 pNewGrafObj
->AdjustToMaxRect( Rectangle( Point(), aPageSize
), TRUE
);
218 // pNewGrafObj->AdjustToMaxRect( Rectangle( pPV->GetOffset(), aPageSize ), TRUE );
220 ULONG nOptions
= SDRINSERT_SETDEFLAYER
;
221 BOOL bIsPresTarget
= FALSE
;
224 && mpViewSh
->GetViewShell()!=NULL
225 && mpViewSh
->GetViewShell()->GetIPClient()
226 && mpViewSh
->GetViewShell()->GetIPClient()->IsObjectInPlaceActive())
227 || this->ISA(::sd::slidesorter::view::SlideSorterView
))
228 nOptions
|= SDRINSERT_DONTMARK
;
230 if( ( mnAction
& DND_ACTION_MOVE
) && pPickObj
&& (pPickObj
->IsEmptyPresObj() || pPickObj
->GetUserCall()) )
232 SdPage
* pP
= static_cast< SdPage
* >( pPickObj
->GetPage() );
234 if ( pP
&& pP
->IsMasterPage() )
235 bIsPresTarget
= pP
->IsPresObj(pPickObj
);
238 if( ( mnAction
& DND_ACTION_MOVE
) && pPickObj
&& !bIsPresTarget
)
242 pNewGrafObj
->InsertUserData(new SdIMapInfo(*pImageMap
));
244 Rectangle
aPickObjRect(pPickObj
->GetCurrentBoundRect());
245 Size
aPickObjSize(aPickObjRect
.GetSize());
246 Rectangle
aObjRect(pNewGrafObj
->GetCurrentBoundRect());
247 Size
aObjSize(aObjRect
.GetSize());
249 Fraction
aScaleWidth(aPickObjSize
.Width(), aObjSize
.Width());
250 Fraction
aScaleHeight(aPickObjSize
.Height(), aObjSize
.Height());
251 pNewGrafObj
->NbcResize(aObjRect
.TopLeft(), aScaleWidth
, aScaleHeight
);
253 Point aVec
= aPickObjRect
.TopLeft() - aObjRect
.TopLeft();
254 pNewGrafObj
->NbcMove(Size(aVec
.X(), aVec
.Y()));
256 const bool bUndo
= IsUndoEnabled();
259 BegUndo(String(SdResId(STR_UNDO_DRAGDROP
)));
260 pNewGrafObj
->NbcSetLayer(pPickObj
->GetLayer());
261 SdrPage
* pP
= pPV
->GetPage();
262 pP
->InsertObject(pNewGrafObj
);
265 AddUndo(mpDoc
->GetSdrUndoFactory().CreateUndoNewObject(*pNewGrafObj
));
266 AddUndo(mpDoc
->GetSdrUndoFactory().CreateUndoDeleteObject(*pPickObj
));
268 pP
->RemoveObject(pPickObj
->GetOrdNum());
276 SdrObject::Free(pPickObj
);
278 mnAction
= DND_ACTION_COPY
;
282 InsertObjectAtView(pNewGrafObj
, *pPV
, nOptions
);
285 pNewGrafObj
->InsertUserData(new SdIMapInfo(*pImageMap
));
294 // -----------------------------------------------------------------------------
296 SdrMediaObj
* View::InsertMediaURL( const rtl::OUString
& rMediaURL
, sal_Int8
& rAction
,
297 const Point
& rPos
, const Size
& rSize
)
302 SdrMediaObj
* pNewMediaObj
= NULL
;
303 SdrPageView
* pPV
= GetSdrPageView();
304 SdrObject
* pPickObj
= NULL
;
306 if(pPV
&& this->ISA(::sd::slidesorter::view::SlideSorterView
))
308 if(!pPV
->GetPageRect().IsInside(rPos
))
312 if( !pPickObj
&& pPV
)
314 SdrPageView
* pPageView
= pPV
;
315 PickObj(rPos
, getHitTolLog(), pPickObj
, pPageView
);
318 if( mnAction
== DND_ACTION_LINK
&& pPickObj
&& pPV
&& pPickObj
->ISA( SdrMediaObj
) )
320 pNewMediaObj
= static_cast< SdrMediaObj
* >( pPickObj
->Clone() );
321 pNewMediaObj
->setURL( rMediaURL
);
323 BegUndo(String(SdResId(STR_UNDO_DRAGDROP
)));
324 ReplaceObjectAtView(pPickObj
, *pPV
, pNewMediaObj
);
329 pNewMediaObj
= new SdrMediaObj( Rectangle( rPos
, rSize
) );
331 if( pPV
&& InsertObjectAtView( pNewMediaObj
, *pPV
, SDRINSERT_SETDEFLAYER
) )
332 pNewMediaObj
->setURL( rMediaURL
);
340 /*************************************************************************
342 |* Timer-Handler fuer InsertFile beim Drop()
344 \************************************************************************/
346 IMPL_LINK( View
, DropInsertFileHdl
, Timer
*, EMPTYARG
)
348 DBG_ASSERT( mpViewSh
, "sd::View::DropInsertFileHdl(), I need a view shell to work!" );
352 SfxErrorContext
aEc( ERRCTX_ERROR
, mpViewSh
->GetActiveWindow(), RID_SO_ERRCTX
);
355 ::std::vector
< String
>::const_iterator
aIter( maDropFileVector
.begin() );
357 while( (aIter
!= maDropFileVector
.end()) && !nError
)
359 String
aCurrentDropFile( *aIter
);
360 INetURLObject
aURL( aCurrentDropFile
);
363 if( aURL
.GetProtocol() == INET_PROT_NOT_VALID
)
366 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aCurrentDropFile
, aURLStr
);
367 aURL
= INetURLObject( aURLStr
);
370 GraphicFilter
* pGraphicFilter
= GetGrfFilter();
373 aCurrentDropFile
= aURL
.GetMainURL( INetURLObject::NO_DECODE
);
375 if( !::avmedia::MediaWindow::isMediaURL( aCurrentDropFile
) )
377 if( !pGraphicFilter
->ImportGraphic( aGraphic
, aURL
) )
379 sal_Int8 nTempAction
= ( aIter
== maDropFileVector
.begin() ) ? mnAction
: 0;
380 SdrGrafObj
* pGrafObj
= InsertGraphic( aGraphic
, nTempAction
, maDropPos
, NULL
, NULL
);
382 // return action from first inserted graphic
383 if( aIter
== maDropFileVector
.begin() )
384 mnAction
= nTempAction
;
390 const SfxFilter
* pFoundFilter
= NULL
;
391 SfxMedium
aSfxMedium( aCurrentDropFile
, STREAM_READ
| STREAM_SHARE_DENYNONE
, FALSE
);
392 ErrCode nErr
= SFX_APP()->GetFilterMatcher().GuessFilter( aSfxMedium
, &pFoundFilter
, SFX_FILTER_IMPORT
, SFX_FILTER_NOTINSTALLED
| SFX_FILTER_EXECUTABLE
);
394 if( pFoundFilter
&& !nErr
)
396 ::std::vector
< String
> aFilterVector
;
397 const String
aFilterName( pFoundFilter
->GetFilterName() );
398 String
aLowerAsciiFileName( aCurrentDropFile
);
399 aLowerAsciiFileName
.ToLowerAscii();
401 FuInsertFile::GetSupportedFilterVector( aFilterVector
);
403 if( ( ::std::find( aFilterVector
.begin(), aFilterVector
.end(), pFoundFilter
->GetMimeType() ) != aFilterVector
.end() ) ||
404 aFilterName
.SearchAscii( "Text" ) != STRING_NOTFOUND
||
405 aFilterName
.SearchAscii( "Rich" ) != STRING_NOTFOUND
||
406 aFilterName
.SearchAscii( "RTF" ) != STRING_NOTFOUND
||
407 aFilterName
.SearchAscii( "HTML" ) != STRING_NOTFOUND
||
408 aLowerAsciiFileName
.SearchAscii(".sdd") != STRING_NOTFOUND
||
409 aLowerAsciiFileName
.SearchAscii(".sda") != STRING_NOTFOUND
||
410 aLowerAsciiFileName
.SearchAscii(".sxd") != STRING_NOTFOUND
||
411 aLowerAsciiFileName
.SearchAscii(".sxi") != STRING_NOTFOUND
||
412 aLowerAsciiFileName
.SearchAscii(".std") != STRING_NOTFOUND
||
413 aLowerAsciiFileName
.SearchAscii(".sti") != STRING_NOTFOUND
)
415 ::sd::Window
* pWin
= mpViewSh
->GetActiveWindow();
416 SfxRequest
aReq(SID_INSERTFILE
, 0, mpDoc
->GetItemPool());
417 SfxStringItem
aItem1( ID_VAL_DUMMY0
, aCurrentDropFile
), aItem2( ID_VAL_DUMMY1
, pFoundFilter
->GetFilterName() );
419 aReq
.AppendItem( aItem1
);
420 aReq
.AppendItem( aItem2
);
421 FuInsertFile::Create( mpViewSh
, pWin
, this, mpDoc
, aReq
);
432 if( ::avmedia::MediaWindow::isMediaURL( aCurrentDropFile
) &&
433 ::avmedia::MediaWindow::isMediaURL( aCurrentDropFile
, true, &aPrefSize
) )
435 if( aPrefSize
.Width() && aPrefSize
.Height() )
437 ::sd::Window
* pWin
= mpViewSh
->GetActiveWindow();
440 aPrefSize
= pWin
->PixelToLogic( aPrefSize
, MAP_100TH_MM
);
442 aPrefSize
= Application::GetDefaultDevice()->PixelToLogic( aPrefSize
, MAP_100TH_MM
);
445 aPrefSize
= Size( 5000, 5000 );
447 InsertMediaURL( aCurrentDropFile
, mnAction
, maDropPos
, aPrefSize
) ;
449 else if( mnAction
& DND_ACTION_LINK
)
450 static_cast< DrawViewShell
* >( mpViewSh
)->InsertURLButton( aCurrentDropFile
, aCurrentDropFile
, String(), &maDropPos
);
458 ::rtl::OUString aName
;
459 uno::Sequence
< beans::PropertyValue
> aMedium(1);
460 aMedium
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
461 aMedium
[0].Value
<<= ::rtl::OUString( aCurrentDropFile
);
463 uno::Reference
< embed::XEmbeddedObject
> xObj
= mpDocSh
->GetEmbeddedObjectContainer().
464 InsertEmbeddedObject( aMedium
, aName
);
466 uno::Reference
< embed::XEmbedPersist
> xPersist( xObj
, uno::UNO_QUERY
);
469 // TODO/LEAN: VisualArea access can switch the object to running state
470 sal_Int64 nAspect
= embed::Aspects::MSOLE_CONTENT
;
472 xPersist
->storeOwn();
477 aSz
= xObj
->getVisualAreaSize( nAspect
);
479 catch( embed::NoVisualAreaSizeException
& )
481 // the default size will be set later
484 Size
aSize( aSz
.Width
, aSz
.Height
);
487 if (!aSize
.Width() || !aSize
.Height())
489 aSize
.Width() = 1410;
490 aSize
.Height() = 1000;
493 aRect
= Rectangle( maDropPos
, aSize
);
495 SdrOle2Obj
* pOleObj
= new SdrOle2Obj( svt::EmbeddedObjectRef( xObj
, nAspect
), aName
, aRect
);
496 ULONG nOptions
= SDRINSERT_SETDEFLAYER
;
498 if (mpViewSh
!= NULL
)
500 OSL_ASSERT (mpViewSh
->GetViewShell()!=NULL
);
501 SfxInPlaceClient
* pIpClient
=
502 mpViewSh
->GetViewShell()->GetIPClient();
503 if (pIpClient
!=NULL
&& pIpClient
->IsObjectInPlaceActive())
504 nOptions
|= SDRINSERT_DONTMARK
;
507 InsertObjectAtView( pOleObj
, *GetSdrPageView(), nOptions
);
508 pOleObj
->SetLogicRect( aRect
);
509 aSz
.Width
= aRect
.GetWidth();
510 aSz
.Height
= aRect
.GetHeight();
511 xObj
->setVisualAreaSize( nAspect
,aSz
);
514 catch( uno::Exception
& )
516 nError
= ERRCODE_IO_GENERAL
;
517 // TODO/LATER: better error handling
527 ErrorHandler::HandleError( nError
);
532 /*************************************************************************
534 |* Timer-Handler fuer Errorhandling beim Drop()
536 \************************************************************************/
538 IMPL_LINK( View
, DropErrorHdl
, Timer
*, EMPTYARG
)
540 InfoBox( mpViewSh
? mpViewSh
->GetActiveWindow() : 0, String(SdResId(STR_ACTION_NOTPOSSIBLE
) ) ).Execute();
545 #pragma optimize ( "", on )
548 /*************************************************************************
550 |* Redraw sperren oder erlauben
552 \************************************************************************/
554 void View::LockRedraw(BOOL bLock
)
559 DBG_ASSERT(mnLockRedrawSmph
, "Ueberlauf im LockRedraw");
563 DBG_ASSERT(mnLockRedrawSmph
, "Unterlauf im LockRedraw");
566 // alle gespeicherten Redraws ausfuehren
567 if (!mnLockRedrawSmph
)
569 while (mpLockedRedraws
&& mpLockedRedraws
->Count())
571 SdViewRedrawRec
* pRec
= (SdViewRedrawRec
*)mpLockedRedraws
->First();
572 OutputDevice
* pCurrentOut
= pRec
->mpOut
;
573 Rectangle
aBoundRect(pRec
->aRect
);
574 mpLockedRedraws
->Remove(pRec
);
577 pRec
= (SdViewRedrawRec
*)mpLockedRedraws
->First();
580 if (pRec
->mpOut
== pCurrentOut
)
582 aBoundRect
.Union(pRec
->aRect
);
583 mpLockedRedraws
->Remove(pRec
);
585 pRec
= (SdViewRedrawRec
*)mpLockedRedraws
->GetCurObject();
589 pRec
= (SdViewRedrawRec
*)mpLockedRedraws
->Next();
593 CompleteRedraw(pCurrentOut
, Region(aBoundRect
));
595 delete mpLockedRedraws
;
596 mpLockedRedraws
= NULL
;
604 bool View::IsRedrawLocked (void) const
606 return mnLockRedrawSmph
>0;
609 /*************************************************************************
611 |* StyleSheet aus der Sleketion besorgen
613 \************************************************************************/
615 SfxStyleSheet
* View::GetStyleSheet() const
617 return SdrView::GetStyleSheet();
620 } // end of namespace sd