merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / view / viewfun7.cxx
blob2d4b64163ad1b39df35df4838ded754b039578c2
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: viewfun7.cxx,v $
10 * $Revision: 1.31 $
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"
58 #include "scmod.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
84 if( x < 0 )
85 rPos.X() += x + 80;
86 if( y < 0 )
87 rPos.Y() += y + 200;
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 )
95 MakeDrawLayer();
96 Point aPos( rLogicPos );
98 // #64184# MapMode am Outliner-RefDevice muss stimmen (wie in FuText::MakeOutliner)
99 //! mit FuText::MakeOutliner zusammenfassen?
100 MapMode aOldMapMode;
101 OutputDevice* pRef = GetViewData()->GetDocument()->GetDrawLayer()->GetRefDevice();
102 if (pRef)
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;
114 if (pDrawTrans)
116 pDragEditView = pDrawTrans->GetDragSourceView();
118 aPos -= aDragStartDiff;
119 if ( bNegativePage )
121 if (aPos.X() > 0) aPos.X() = 0;
123 else
125 if (aPos.X() < 0) aPos.X() = 0;
127 if (aPos.Y() < 0) aPos.Y() = 0;
130 ScDrawView* pScDrawView = GetScDrawView();
131 if (bGroup)
132 pScDrawView->BegUndo( ScGlobal::GetRscString( STR_UNDO_PASTE ) );
134 BOOL bSameDoc = ( pDragEditView && pDragEditView->GetModel() == pScDrawView->GetModel() );
135 if (bSameDoc)
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?
145 if ( bPasteIsMove &&
146 pScDrawView->GetSdrPageView()->GetPage() ==
147 pDragEditView->GetSdrPageView()->GetPage() )
149 if ( nDiffX != 0 || nDiffY != 0 )
150 pDragEditView->MoveAllMarked(Size(nDiffX,nDiffY), FALSE);
152 else
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();
159 aMark.ForceSort();
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();
165 // #116235#
166 SdrObject* pNeuObj=pObj->Clone();
167 //SdrObject* pNeuObj=pObj->Clone(pDestPage,pDrawModel);
169 if (pNeuObj!=NULL)
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
188 if (bPasteIsMove)
189 pDragEditView->DeleteMarked();
192 else
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!)
205 ULONG nOptions = 0;
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?");
226 if (pPage)
228 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
229 SdrObject* pObject = aIter.Next();
230 while (pObject)
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();
242 if (bGroup)
244 pScDrawView->GroupMarked();
245 pScDrawView->EndUndo();
248 if (pRef)
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 )
263 MakeDrawLayer();
264 if ( xObj.is() )
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 );
271 else
272 aName = aCnt.GetEmbeddedObjectName( xObj );
274 svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
275 if ( pReplGraph )
276 aObjRef.SetGraphic( *pReplGraph, aMediaType );
278 Size aSize;
279 if ( nAspect == embed::Aspects::MSOLE_ICON )
281 MapMode aMapMode( MAP_100TH_MM );
282 aSize = aObjRef.GetSize( &aMapMode );
284 else
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 );
294 awt::Size aSz;
295 aSz.Width = aSize.Width();
296 aSz.Height = aSize.Height();
297 xObj->setVisualAreaSize( nAspect, aSz );
300 awt::Size 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 );
337 return TRUE;
339 else
340 return FALSE;
343 BOOL ScViewFunc::PasteBitmap( const Point& rPos, const Bitmap& rBmp )
345 String aEmpty;
346 Graphic aGraphic(rBmp);
347 return PasteGraphic( rPos, aGraphic, aEmpty, aEmpty );
350 BOOL ScViewFunc::PasteMetaFile( const Point& rPos, const GDIMetaFile& rMtf )
352 String aEmpty;
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 )
360 MakeDrawLayer();
361 ScDrawView* pScDrawView = GetScDrawView();
363 Point aPos( rPos );
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.
401 // See #i37444#.
402 if (rFile.Len())
403 pGrafObj->SetGraphicLink( rFile, rFilter );
405 return TRUE;
408 BOOL ScViewFunc::ApplyGraphicToObject( SdrObject* pPickObj, const Graphic& rGraphic )
410 BOOL bRet = FALSE;
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();
432 bRet = TRUE;
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);
451 bRet = TRUE;
454 return bRet;