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: viewfun7.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_sc.hxx"
33 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
37 // INCLUDE ---------------------------------------------------------------
39 #include <svx/svditer.hxx>
40 #include <svx/svdograf.hxx>
41 #include <svx/svdoole2.hxx>
42 #include <svx/svdouno.hxx>
43 #include <svx/svdpage.hxx>
44 #include <svx/svdpagv.hxx>
45 #include <svx/svdundo.hxx>
46 #include <svx/xbitmap.hxx>
47 #include <svx/xbtmpit.hxx>
48 #include <svx/xoutbmp.hxx>
49 #include <sfx2/objsh.hxx>
50 #include <sfx2/viewfrm.hxx>
51 #include <toolkit/helper/vclunohelper.hxx>
52 #include <com/sun/star/embed/Aspects.hpp>
54 #include "document.hxx" // fuer MapMode Initialisierung in PasteDraw
55 #include "viewfunc.hxx"
56 #include "tabvwsh.hxx"
57 #include "drawview.hxx"
59 #include "drwlayer.hxx"
60 #include "drwtrans.hxx"
61 #include "globstr.hrc"
63 extern Point aDragStartDiff
;
65 // STATIC DATA -----------------------------------------------------------
67 BOOL bPasteIsMove
= FALSE
;
69 using namespace com::sun::star
;
71 //==================================================================
73 void lcl_AdjustInsertPos( ScViewData
* pData
, Point
& rPos
, Size
& rSize
)
75 // SdrPage* pPage = pData->GetDocument()->GetDrawLayer()->GetPage( pData->GetTabNo() );
76 SdrPage
* pPage
= pData
->GetScDrawView()->GetModel()->GetPage( static_cast<sal_uInt16
>(pData
->GetTabNo()) );
77 DBG_ASSERT(pPage
,"pPage ???");
78 Size
aPgSize( pPage
->GetSize() );
79 if (aPgSize
.Width() < 0)
80 aPgSize
.Width() = -aPgSize
.Width();
81 long x
= aPgSize
.Width() - rPos
.X() - rSize
.Width();
82 long y
= aPgSize
.Height() - rPos
.Y() - rSize
.Height();
83 // ggf. Ajustments (80/200) fuer Pixel-Rundungsfehler
88 rPos
.X() += rSize
.Width() / 2; // Position bei Paste gibt Mittelpunkt an
89 rPos
.Y() += rSize
.Height() / 2;
92 void ScViewFunc::PasteDraw( const Point
& rLogicPos
, SdrModel
* pModel
,
93 BOOL bGroup
, BOOL bSameDocClipboard
)
96 Point
aPos( rLogicPos
);
98 // #64184# MapMode am Outliner-RefDevice muss stimmen (wie in FuText::MakeOutliner)
99 //! mit FuText::MakeOutliner zusammenfassen?
101 OutputDevice
* pRef
= GetViewData()->GetDocument()->GetDrawLayer()->GetRefDevice();
104 aOldMapMode
= pRef
->GetMapMode();
105 pRef
->SetMapMode( MapMode(MAP_100TH_MM
) );
108 BOOL bNegativePage
= GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() );
110 SdrView
* pDragEditView
= NULL
;
111 ScModule
* pScMod
= SC_MOD();
112 const ScDragData
& rData
= pScMod
->GetDragData();
113 ScDrawTransferObj
* pDrawTrans
= rData
.pDrawTransfer
;
116 pDragEditView
= pDrawTrans
->GetDragSourceView();
118 aPos
-= aDragStartDiff
;
121 if (aPos
.X() > 0) aPos
.X() = 0;
125 if (aPos
.X() < 0) aPos
.X() = 0;
127 if (aPos
.Y() < 0) aPos
.Y() = 0;
130 ScDrawView
* pScDrawView
= GetScDrawView();
132 pScDrawView
->BegUndo( ScGlobal::GetRscString( STR_UNDO_PASTE
) );
134 BOOL bSameDoc
= ( pDragEditView
&& pDragEditView
->GetModel() == pScDrawView
->GetModel() );
137 // lokal kopieren - incl. Charts
139 Point aSourceStart
= pDragEditView
->GetAllMarkedRect().TopLeft();
140 long nDiffX
= aPos
.X() - aSourceStart
.X();
141 long nDiffY
= aPos
.Y() - aSourceStart
.Y();
143 // innerhalb einer Page verschieben?
146 pScDrawView
->GetSdrPageView()->GetPage() ==
147 pDragEditView
->GetSdrPageView()->GetPage() )
149 if ( nDiffX
!= 0 || nDiffY
!= 0 )
150 pDragEditView
->MoveAllMarked(Size(nDiffX
,nDiffY
), FALSE
);
154 SdrModel
* pDrawModel
= pDragEditView
->GetModel();
155 SdrPage
* pDestPage
= pDrawModel
->GetPage( static_cast<sal_uInt16
>(GetViewData()->GetTabNo()) );
156 DBG_ASSERT(pDestPage
,"nanu, Page?");
158 SdrMarkList aMark
= pDragEditView
->GetMarkedObjectList();
160 ULONG nMarkAnz
=aMark
.GetMarkCount();
161 for (ULONG nm
=0; nm
<nMarkAnz
; nm
++) {
162 const SdrMark
* pM
=aMark
.GetMark(nm
);
163 const SdrObject
* pObj
=pM
->GetMarkedSdrObj();
166 SdrObject
* pNeuObj
=pObj
->Clone();
167 //SdrObject* pNeuObj=pObj->Clone(pDestPage,pDrawModel);
171 pNeuObj
->SetModel(pDrawModel
);
172 pNeuObj
->SetPage(pDestPage
);
174 // #68787# copy graphics within the same model - always needs new name
175 if ( pNeuObj
->ISA(SdrGrafObj
) && !bPasteIsMove
)
176 pNeuObj
->SetName(((ScDrawLayer
*)pDrawModel
)->GetNewGraphicName());
178 if (nDiffX
!=0 || nDiffY
!=0)
179 pNeuObj
->NbcMove(Size(nDiffX
,nDiffY
));
180 pDestPage
->InsertObject( pNeuObj
);
181 pScDrawView
->AddUndo(new SdrUndoInsertObj( *pNeuObj
));
183 // Chart braucht nicht mehr getrennt behandelt zu werden,
184 // weil es seine Daten jetzt selber hat
189 pDragEditView
->DeleteMarked();
194 bPasteIsMove
= FALSE
; // kein internes Verschieben passiert
196 SdrView
aView(pModel
); // #i71529# never create a base class of SdrView directly!
197 SdrPageView
* pPv
= aView
.ShowSdrPage(aView
.GetModel()->GetPage(0));
198 aView
.MarkAllObj(pPv
);
199 Size aSize
= aView
.GetAllMarkedRect().GetSize();
200 lcl_AdjustInsertPos( GetViewData(), aPos
, aSize
);
202 // #41333# Markierung nicht aendern, wenn Ole-Objekt aktiv
203 // (bei Drop aus Ole-Objekt wuerde sonst mitten im ExecuteDrag deaktiviert!)
206 SfxInPlaceClient
* pClient
= GetViewData()->GetViewShell()->GetIPClient();
207 if ( pClient
&& pClient
->IsObjectInPlaceActive() )
208 nOptions
|= SDRINSERT_DONTMARK
;
210 // #89247# Set flag for ScDocument::UpdateChartListeners() which is
211 // called during paste.
212 if ( !bSameDocClipboard
)
213 GetViewData()->GetDocument()->SetPastingDrawFromOtherDoc( TRUE
);
215 pScDrawView
->Paste( *pModel
, aPos
, NULL
, nOptions
);
217 if ( !bSameDocClipboard
)
218 GetViewData()->GetDocument()->SetPastingDrawFromOtherDoc( FALSE
);
220 // #68991# Paste puts all objects on the active (front) layer
221 // controls must be on SC_LAYER_CONTROLS
223 SCTAB nTab
= GetViewData()->GetTabNo();
224 SdrPage
* pPage
= pScDrawView
->GetModel()->GetPage(static_cast<sal_uInt16
>(nTab
));
225 DBG_ASSERT(pPage
,"Page?");
228 SdrObjListIter
aIter( *pPage
, IM_DEEPNOGROUPS
);
229 SdrObject
* pObject
= aIter
.Next();
232 if ( pObject
->ISA(SdrUnoObj
) && pObject
->GetLayer() != SC_LAYER_CONTROLS
)
233 pObject
->NbcSetLayer(SC_LAYER_CONTROLS
);
234 pObject
= aIter
.Next();
238 // #75299# all graphics objects must have names
239 GetViewData()->GetDocument()->EnsureGraphicNames();
244 pScDrawView
->GroupMarked();
245 pScDrawView
->EndUndo();
249 pRef
->SetMapMode( aOldMapMode
);
251 // GetViewData()->GetViewShell()->SetDrawShell( TRUE );
252 // #99759# It is not sufficient to just set the DrawShell if we pasted, for
253 // example, a chart. SetDrawShellOrSub() would only work for D&D in the
254 // same document but not if inserting from the clipboard, therefore
255 // MarkListHasChanged() is what we need.
256 pScDrawView
->MarkListHasChanged();
260 BOOL
ScViewFunc::PasteObject( const Point
& rPos
, const uno::Reference
< embed::XEmbeddedObject
>& xObj
,
261 const Size
* pDescSize
, const Graphic
* pReplGraph
, const ::rtl::OUString
& aMediaType
, sal_Int64 nAspect
)
266 ::rtl::OUString aName
;
267 //TODO/MBA: is that OK?
268 comphelper::EmbeddedObjectContainer
& aCnt
= GetViewData()->GetViewShell()->GetObjectShell()->GetEmbeddedObjectContainer();
269 if ( !aCnt
.HasEmbeddedObject( xObj
) )
270 aCnt
.InsertEmbeddedObject( xObj
, aName
);
272 aName
= aCnt
.GetEmbeddedObjectName( xObj
);
274 svt::EmbeddedObjectRef
aObjRef( xObj
, nAspect
);
276 aObjRef
.SetGraphic( *pReplGraph
, aMediaType
);
279 if ( nAspect
== embed::Aspects::MSOLE_ICON
)
281 MapMode
aMapMode( MAP_100TH_MM
);
282 aSize
= aObjRef
.GetSize( &aMapMode
);
286 // working with visual area can switch object to running state
287 MapUnit aMapObj
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( nAspect
) );
288 MapUnit aMap100
= MAP_100TH_MM
;
290 if ( pDescSize
&& pDescSize
->Width() && pDescSize
->Height() )
292 // use size from object descriptor if given
293 aSize
= OutputDevice::LogicToLogic( *pDescSize
, aMap100
, aMapObj
);
295 aSz
.Width
= aSize
.Width();
296 aSz
.Height
= aSize
.Height();
297 xObj
->setVisualAreaSize( nAspect
, aSz
);
303 aSz
= xObj
->getVisualAreaSize( nAspect
);
305 catch ( embed::NoVisualAreaSizeException
& )
307 // the default size will be set later
310 aSize
= Size( aSz
.Width
, aSz
.Height
);
311 aSize
= OutputDevice::LogicToLogic( aSize
, aMapObj
, aMap100
); // fuer SdrOle2Obj
313 if( aSize
.Height() == 0 || aSize
.Width() == 0 )
315 DBG_ERROR("SvObjectDescriptor::GetSize == 0");
316 aSize
.Width() = 5000;
317 aSize
.Height() = 5000;
318 aSize
= OutputDevice::LogicToLogic( aSize
, aMap100
, aMapObj
);
319 aSz
.Width
= aSize
.Width();
320 aSz
.Height
= aSize
.Height();
321 xObj
->setVisualAreaSize( nAspect
, aSz
);
325 // don't call AdjustInsertPos
326 Point aInsPos
= rPos
;
327 if ( GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() ) )
328 aInsPos
.X() -= aSize
.Width();
329 Rectangle
aRect( aInsPos
, aSize
);
331 ScDrawView
* pDrView
= GetScDrawView();
332 SdrOle2Obj
* pSdrObj
= new SdrOle2Obj( aObjRef
, aName
, aRect
);
334 SdrPageView
* pPV
= pDrView
->GetSdrPageView();
335 pDrView
->InsertObjectSafe( pSdrObj
, *pPV
); // nicht markieren wenn Ole
336 GetViewData()->GetViewShell()->SetDrawShell( TRUE
);
343 BOOL
ScViewFunc::PasteBitmap( const Point
& rPos
, const Bitmap
& rBmp
)
346 Graphic
aGraphic(rBmp
);
347 return PasteGraphic( rPos
, aGraphic
, aEmpty
, aEmpty
);
350 BOOL
ScViewFunc::PasteMetaFile( const Point
& rPos
, const GDIMetaFile
& rMtf
)
353 Graphic
aGraphic(rMtf
);
354 return PasteGraphic( rPos
, aGraphic
, aEmpty
, aEmpty
);
357 BOOL
ScViewFunc::PasteGraphic( const Point
& rPos
, const Graphic
& rGraphic
,
358 const String
& rFile
, const String
& rFilter
)
361 ScDrawView
* pScDrawView
= GetScDrawView();
364 Window
* pWin
= GetActiveWin();
365 MapMode aSourceMap
= rGraphic
.GetPrefMapMode();
366 MapMode
aDestMap( MAP_100TH_MM
);
368 if (aSourceMap
.GetMapUnit() == MAP_PIXEL
)
370 // Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
372 Fraction aScaleX
, aScaleY
;
373 pScDrawView
->CalcNormScale( aScaleX
, aScaleY
);
374 aDestMap
.SetScaleX(aScaleX
);
375 aDestMap
.SetScaleY(aScaleY
);
378 Size aSize
= pWin
->LogicToLogic( rGraphic
.GetPrefSize(), &aSourceMap
, &aDestMap
);
379 // lcl_AdjustInsertPos( GetViewData(), aPos, aSize );
380 if ( GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() ) )
381 aPos
.X() -= aSize
.Width();
383 GetViewData()->GetViewShell()->SetDrawShell( TRUE
);
385 Rectangle
aRect(aPos
, aSize
);
386 SdrGrafObj
* pGrafObj
= new SdrGrafObj(rGraphic
, aRect
);
388 // #118522# calling SetGraphicLink here doesn't work
390 // #49961# Pfad wird nicht mehr als Name der Grafik gesetzt
392 ScDrawLayer
* pLayer
= (ScDrawLayer
*) pScDrawView
->GetModel();
393 String aName
= pLayer
->GetNewGraphicName(); // "Grafik x"
394 pGrafObj
->SetName(aName
);
396 // nicht markieren wenn Ole
397 pScDrawView
->InsertObjectSafe(pGrafObj
, *pScDrawView
->GetSdrPageView());
399 // #118522# SetGraphicLink has to be used after inserting the object,
400 // otherwise an empty graphic is swapped in and the contact stuff crashes.
403 pGrafObj
->SetGraphicLink( rFile
, rFilter
);
408 BOOL
ScViewFunc::ApplyGraphicToObject( SdrObject
* pPickObj
, const Graphic
& rGraphic
)
411 SdrGrafObj
* pNewGrafObj
= NULL
;
413 ScDrawView
* pScDrawView
= GetScDrawView();
414 if ( pScDrawView
&& pPickObj
)
416 /**********************************************************************
417 * Objekt neu attributieren
418 **********************************************************************/
419 SdrPageView
* pPV
= pScDrawView
->GetSdrPageView();
420 if (pPickObj
->ISA(SdrGrafObj
))
422 /******************************************************************
423 * Das Graphik-Objekt bekommt eine neue Graphik
424 ******************************************************************/
425 pNewGrafObj
= (SdrGrafObj
*) pPickObj
->Clone();
426 pNewGrafObj
->SetGraphic(rGraphic
);
428 pScDrawView
->BegUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP
));
429 pScDrawView
->ReplaceObjectAtView(pPickObj
, *pPV
, pNewGrafObj
);
430 pScDrawView
->EndUndo();
434 else if (pPickObj
->IsClosedObj() && !pPickObj
->ISA(SdrOle2Obj
))
436 /******************************************************************
437 * Das Objekt wird mit der Graphik gefuellt
438 ******************************************************************/
439 //pScDrawView->BegUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP));
440 pScDrawView
->AddUndo(new SdrUndoAttrObj(*pPickObj
));
441 //pScDrawView->EndUndo();
443 XOBitmap
aXOBitmap( rGraphic
.GetBitmap() );
444 SfxItemSet
aSet( pScDrawView
->GetModel()->GetItemPool(),
445 XATTR_FILLSTYLE
, XATTR_FILLBITMAP
);
446 aSet
.Put(XFillStyleItem(XFILL_BITMAP
));
447 aSet
.Put(XFillBitmapItem(String(), aXOBitmap
));
449 pPickObj
->SetMergedItemSetAndBroadcast(aSet
);