Update ooo320-m1
[ooovba.git] / sd / source / ui / view / sdview4.cxx
blob0596d55d1ac6fb44019399d00b25b591c43dcd35
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sdview4.cxx,v $
10 * $Revision: 1.36 $
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"
34 #include "View.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>
49 #ifndef _IMPGRF_HXX
50 #include <svx/impgrf.hxx>
51 #endif
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>
58 #include "app.hrc"
59 #include "Window.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"
67 #include "sdpage.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;
82 namespace sd {
84 #ifdef _MSC_VER
85 #pragma optimize ( "", off )
86 #endif
88 /*************************************************************************
90 |* Graphik einfuegen
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 )
101 SdrEndTextEdit();
102 mnAction = rAction;
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))
112 pPV = 0L;
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();
138 if( bUndo )
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());
147 if( bUndo )
149 AddUndo( new sd::UndoObjectPresentationKind( *pPickObj ) );
150 AddUndo( new sd::UndoObjectPresentationKind( *pNewGrafObj ) );
152 pPage->RemovePresObj(pPickObj);
153 pPage->InsertPresObj(pNewGrafObj, PRESOBJ_GRAPHIC);
155 if( !bUndo )
157 SdrObject::Free( pPickObj );
161 if (pImageMap)
162 pNewGrafObj->InsertUserData(new SdIMapInfo(*pImageMap));
164 ReplaceObjectAtView(pPickObj, *pPV, pNewGrafObj); // maybe ReplaceObjectAtView
166 if( bUndo )
167 EndUndo();
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));
178 EndUndo();
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);
188 else if ( pPV )
190 // create new object
191 Size aSize;
193 if ( rGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
195 ::OutputDevice* pOutDev = 0;
196 if( mpViewSh )
197 pOutDev = mpViewSh->GetActiveWindow();
199 if( !pOutDev )
200 pOutDev = Application::GetDefaultDevice();
202 if( pOutDev )
203 aSize = pOutDev->PixelToLogic( rGraphic.GetPrefSize(), MAP_100TH_MM );
205 else
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;
223 if ((mpViewSh
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 )
240 // replace object
241 if (pImageMap)
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();
258 if( bUndo )
259 BegUndo(String(SdResId(STR_UNDO_DRAGDROP)));
260 pNewGrafObj->NbcSetLayer(pPickObj->GetLayer());
261 SdrPage* pP = pPV->GetPage();
262 pP->InsertObject(pNewGrafObj);
263 if( bUndo )
265 AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoNewObject(*pNewGrafObj));
266 AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoDeleteObject(*pPickObj));
268 pP->RemoveObject(pPickObj->GetOrdNum());
270 if( bUndo )
272 EndUndo();
274 else
276 SdrObject::Free(pPickObj);
278 mnAction = DND_ACTION_COPY;
280 else
282 InsertObjectAtView(pNewGrafObj, *pPV, nOptions);
284 if( pImageMap )
285 pNewGrafObj->InsertUserData(new SdIMapInfo(*pImageMap));
289 rAction = mnAction;
291 return pNewGrafObj;
294 // -----------------------------------------------------------------------------
296 SdrMediaObj* View::InsertMediaURL( const rtl::OUString& rMediaURL, sal_Int8& rAction,
297 const Point& rPos, const Size& rSize )
299 SdrEndTextEdit();
300 mnAction = rAction;
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))
309 pPV = 0L;
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);
325 EndUndo();
327 else if( pPV )
329 pNewMediaObj = new SdrMediaObj( Rectangle( rPos, rSize ) );
331 if( pPV && InsertObjectAtView( pNewMediaObj, *pPV, SDRINSERT_SETDEFLAYER ) )
332 pNewMediaObj->setURL( rMediaURL );
335 rAction = mnAction;
337 return pNewMediaObj;
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!" );
349 if( !mpViewSh )
350 return 0;
352 SfxErrorContext aEc( ERRCTX_ERROR, mpViewSh->GetActiveWindow(), RID_SO_ERRCTX );
353 ErrCode nError = 0;
355 ::std::vector< String >::const_iterator aIter( maDropFileVector.begin() );
357 while( (aIter != maDropFileVector.end()) && !nError )
359 String aCurrentDropFile( *aIter );
360 INetURLObject aURL( aCurrentDropFile );
361 BOOL bOK = FALSE;
363 if( aURL.GetProtocol() == INET_PROT_NOT_VALID )
365 String aURLStr;
366 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aCurrentDropFile, aURLStr );
367 aURL = INetURLObject( aURLStr );
370 GraphicFilter* pGraphicFilter = GetGrfFilter();
371 Graphic aGraphic;
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;
386 bOK = TRUE;
388 if( !bOK )
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 );
422 bOK = TRUE;
428 if( !bOK )
430 Size aPrefSize;
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();
439 if( pWin )
440 aPrefSize = pWin->PixelToLogic( aPrefSize, MAP_100TH_MM );
441 else
442 aPrefSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM );
444 else
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 );
451 else
453 if( mpViewSh )
457 //TODO/MBA: testing
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 );
467 if ( xPersist.is())
469 // TODO/LEAN: VisualArea access can switch the object to running state
470 sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
472 xPersist->storeOwn();
474 awt::Size aSz;
477 aSz = xObj->getVisualAreaSize( nAspect );
479 catch( embed::NoVisualAreaSizeException& )
481 // the default size will be set later
484 Size aSize( aSz.Width, aSz.Height );
485 Rectangle aRect;
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
523 ++aIter;
526 if( nError )
527 ErrorHandler::HandleError( nError );
529 return 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();
541 return 0;
544 #ifdef _MSC_VER
545 #pragma optimize ( "", on )
546 #endif
548 /*************************************************************************
550 |* Redraw sperren oder erlauben
552 \************************************************************************/
554 void View::LockRedraw(BOOL bLock)
556 if (bLock)
558 mnLockRedrawSmph++;
559 DBG_ASSERT(mnLockRedrawSmph, "Ueberlauf im LockRedraw");
561 else
563 DBG_ASSERT(mnLockRedrawSmph, "Unterlauf im LockRedraw");
564 mnLockRedrawSmph--;
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);
575 delete pRec;
577 pRec = (SdViewRedrawRec*)mpLockedRedraws->First();
578 while (pRec)
580 if (pRec->mpOut == pCurrentOut)
582 aBoundRect.Union(pRec->aRect);
583 mpLockedRedraws->Remove(pRec);
584 delete pRec;
585 pRec = (SdViewRedrawRec*)mpLockedRedraws->GetCurObject();
587 else
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