diff options
Diffstat (limited to 'sc/source/ui/view/viewfun7.cxx')
-rw-r--r-- | sc/source/ui/view/viewfun7.cxx | 491 |
1 files changed, 491 insertions, 0 deletions
diff --git a/sc/source/ui/view/viewfun7.cxx b/sc/source/ui/view/viewfun7.cxx new file mode 100644 index 000000000000..99307c20f96c --- /dev/null +++ b/sc/source/ui/view/viewfun7.cxx @@ -0,0 +1,491 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +#include <com/sun/star/embed/NoVisualAreaSizeException.hpp> + + + +// INCLUDE --------------------------------------------------------------- + +#include <svx/svditer.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdouno.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdundo.hxx> +#include <svx/xbitmap.hxx> +#include <svx/xbtmpit.hxx> +#include <svx/xoutbmp.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/viewfrm.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <com/sun/star/embed/Aspects.hpp> + +#include "document.hxx" // fuer MapMode Initialisierung in PasteDraw +#include "viewfunc.hxx" +#include "tabvwsh.hxx" +#include "drawview.hxx" +#include "scmod.hxx" +#include "drwlayer.hxx" +#include "drwtrans.hxx" +#include "globstr.hrc" +#include "chartlis.hxx" +#include "docuno.hxx" +#include "docsh.hxx" +#include "convuno.hxx" + +extern Point aDragStartDiff; + +// STATIC DATA ----------------------------------------------------------- + +sal_Bool bPasteIsMove = false; + +using namespace com::sun::star; + +//================================================================== + +void lcl_AdjustInsertPos( ScViewData* pData, Point& rPos, Size& rSize ) +{ + SdrPage* pPage = pData->GetScDrawView()->GetModel()->GetPage( static_cast<sal_uInt16>(pData->GetTabNo()) ); + DBG_ASSERT(pPage,"pPage ???"); + Size aPgSize( pPage->GetSize() ); + if (aPgSize.Width() < 0) + aPgSize.Width() = -aPgSize.Width(); + long x = aPgSize.Width() - rPos.X() - rSize.Width(); + long y = aPgSize.Height() - rPos.Y() - rSize.Height(); + // ggf. Ajustments (80/200) fuer Pixel-Rundungsfehler + if( x < 0 ) + rPos.X() += x + 80; + if( y < 0 ) + rPos.Y() += y + 200; + rPos.X() += rSize.Width() / 2; // Position bei Paste gibt Mittelpunkt an + rPos.Y() += rSize.Height() / 2; +} + +void ScViewFunc::PasteDraw( const Point& rLogicPos, SdrModel* pModel, + sal_Bool bGroup, sal_Bool bSameDocClipboard ) +{ + MakeDrawLayer(); + Point aPos( rLogicPos ); + + // MapMode am Outliner-RefDevice muss stimmen (wie in FuText::MakeOutliner) + //! mit FuText::MakeOutliner zusammenfassen? + MapMode aOldMapMode; + OutputDevice* pRef = GetViewData()->GetDocument()->GetDrawLayer()->GetRefDevice(); + if (pRef) + { + aOldMapMode = pRef->GetMapMode(); + pRef->SetMapMode( MapMode(MAP_100TH_MM) ); + } + + sal_Bool bNegativePage = GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() ); + + SdrView* pDragEditView = NULL; + ScModule* pScMod = SC_MOD(); + const ScDragData& rData = pScMod->GetDragData(); + ScDrawTransferObj* pDrawTrans = rData.pDrawTransfer; + if (pDrawTrans) + { + pDragEditView = pDrawTrans->GetDragSourceView(); + + aPos -= aDragStartDiff; + if ( bNegativePage ) + { + if (aPos.X() > 0) aPos.X() = 0; + } + else + { + if (aPos.X() < 0) aPos.X() = 0; + } + if (aPos.Y() < 0) aPos.Y() = 0; + } + + ScDrawView* pScDrawView = GetScDrawView(); + if (bGroup) + pScDrawView->BegUndo( ScGlobal::GetRscString( STR_UNDO_PASTE ) ); + + sal_Bool bSameDoc = ( pDragEditView && pDragEditView->GetModel() == pScDrawView->GetModel() ); + if (bSameDoc) + { + // lokal kopieren - incl. Charts + + Point aSourceStart = pDragEditView->GetAllMarkedRect().TopLeft(); + long nDiffX = aPos.X() - aSourceStart.X(); + long nDiffY = aPos.Y() - aSourceStart.Y(); + + // innerhalb einer Page verschieben? + + if ( bPasteIsMove && + pScDrawView->GetSdrPageView()->GetPage() == + pDragEditView->GetSdrPageView()->GetPage() ) + { + if ( nDiffX != 0 || nDiffY != 0 ) + pDragEditView->MoveAllMarked(Size(nDiffX,nDiffY), false); + } + else + { + SdrModel* pDrawModel = pDragEditView->GetModel(); + SCTAB nTab = GetViewData()->GetTabNo(); + SdrPage* pDestPage = pDrawModel->GetPage( static_cast< sal_uInt16 >( nTab ) ); + DBG_ASSERT(pDestPage,"nanu, Page?"); + + ::std::vector< ::rtl::OUString > aExcludedChartNames; + if ( pDestPage ) + { + ScChartHelper::GetChartNames( aExcludedChartNames, pDestPage ); + } + + SdrMarkList aMark = pDragEditView->GetMarkedObjectList(); + aMark.ForceSort(); + sal_uLong nMarkAnz=aMark.GetMarkCount(); + for (sal_uLong nm=0; nm<nMarkAnz; nm++) { + const SdrMark* pM=aMark.GetMark(nm); + const SdrObject* pObj=pM->GetMarkedSdrObj(); + + SdrObject* pNeuObj=pObj->Clone(); + + if (pNeuObj!=NULL) + { + pNeuObj->SetModel(pDrawModel); + pNeuObj->SetPage(pDestPage); + + // copy graphics within the same model - always needs new name + if ( pNeuObj->ISA(SdrGrafObj) && !bPasteIsMove ) + pNeuObj->SetName(((ScDrawLayer*)pDrawModel)->GetNewGraphicName()); + + if (nDiffX!=0 || nDiffY!=0) + pNeuObj->NbcMove(Size(nDiffX,nDiffY)); + pDestPage->InsertObject( pNeuObj ); + pScDrawView->AddUndo(new SdrUndoInsertObj( *pNeuObj )); + + // Chart braucht nicht mehr getrennt behandelt zu werden, + // weil es seine Daten jetzt selber hat + } + } + + if (bPasteIsMove) + pDragEditView->DeleteMarked(); + + ScDocument* pDocument = GetViewData()->GetDocument(); + ScDocShell* pDocShell = GetViewData()->GetDocShell(); + ScModelObj* pModelObj = ( pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : NULL ); + if ( pDocument && pDestPage && pModelObj && pDrawTrans ) + { + const ScRangeListVector& rProtectedChartRangesVector( pDrawTrans->GetProtectedChartRangesVector() ); + ScChartHelper::CreateProtectedChartListenersAndNotify( pDocument, pDestPage, pModelObj, nTab, + rProtectedChartRangesVector, aExcludedChartNames, bSameDoc ); + } + } + } + else + { + bPasteIsMove = false; // kein internes Verschieben passiert + + SdrView aView(pModel); // #i71529# never create a base class of SdrView directly! + SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0)); + aView.MarkAllObj(pPv); + Size aSize = aView.GetAllMarkedRect().GetSize(); + lcl_AdjustInsertPos( GetViewData(), aPos, aSize ); + + // Markierung nicht aendern, wenn Ole-Objekt aktiv + // (bei Drop aus Ole-Objekt wuerde sonst mitten im ExecuteDrag deaktiviert!) + + sal_uLong nOptions = 0; + SfxInPlaceClient* pClient = GetViewData()->GetViewShell()->GetIPClient(); + if ( pClient && pClient->IsObjectInPlaceActive() ) + nOptions |= SDRINSERT_DONTMARK; + + ::std::vector< ::rtl::OUString > aExcludedChartNames; + SCTAB nTab = GetViewData()->GetTabNo(); + SdrPage* pPage = pScDrawView->GetModel()->GetPage( static_cast< sal_uInt16 >( nTab ) ); + DBG_ASSERT( pPage, "Page?" ); + if ( pPage ) + { + ScChartHelper::GetChartNames( aExcludedChartNames, pPage ); + } + + // #89247# Set flag for ScDocument::UpdateChartListeners() which is + // called during paste. + if ( !bSameDocClipboard ) + GetViewData()->GetDocument()->SetPastingDrawFromOtherDoc( sal_True ); + + pScDrawView->Paste( *pModel, aPos, NULL, nOptions ); + + if ( !bSameDocClipboard ) + GetViewData()->GetDocument()->SetPastingDrawFromOtherDoc( false ); + + // Paste puts all objects on the active (front) layer + // controls must be on SC_LAYER_CONTROLS + if (pPage) + { + SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); + SdrObject* pObject = aIter.Next(); + while (pObject) + { + if ( pObject->ISA(SdrUnoObj) && pObject->GetLayer() != SC_LAYER_CONTROLS ) + pObject->NbcSetLayer(SC_LAYER_CONTROLS); + pObject = aIter.Next(); + } + } + + // all graphics objects must have names + GetViewData()->GetDocument()->EnsureGraphicNames(); + + ScDocument* pDocument = GetViewData()->GetDocument(); + ScDocShell* pDocShell = GetViewData()->GetDocShell(); + ScModelObj* pModelObj = ( pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : NULL ); + ScDrawTransferObj* pTransferObj = ScDrawTransferObj::GetOwnClipboard( NULL ); + if ( pDocument && pPage && pModelObj && ( pTransferObj || pDrawTrans ) ) + { + const ScRangeListVector& rProtectedChartRangesVector( + pTransferObj ? pTransferObj->GetProtectedChartRangesVector() : pDrawTrans->GetProtectedChartRangesVector() ); + ScChartHelper::CreateProtectedChartListenersAndNotify( pDocument, pPage, pModelObj, nTab, + rProtectedChartRangesVector, aExcludedChartNames, bSameDocClipboard ); + } + } + + if (bGroup) + { + pScDrawView->GroupMarked(); + pScDrawView->EndUndo(); + } + + if (pRef) + pRef->SetMapMode( aOldMapMode ); + + // GetViewData()->GetViewShell()->SetDrawShell( TRUE ); + // It is not sufficient to just set the DrawShell if we pasted, for + // example, a chart. SetDrawShellOrSub() would only work for D&D in the + // same document but not if inserting from the clipboard, therefore + // MarkListHasChanged() is what we need. + pScDrawView->MarkListHasChanged(); + +} + +sal_Bool ScViewFunc::PasteObject( const Point& rPos, const uno::Reference < embed::XEmbeddedObject >& xObj, + const Size* pDescSize, const Graphic* pReplGraph, const ::rtl::OUString& aMediaType, sal_Int64 nAspect ) +{ + MakeDrawLayer(); + if ( xObj.is() ) + { + ::rtl::OUString aName; + //TODO/MBA: is that OK? + comphelper::EmbeddedObjectContainer& aCnt = GetViewData()->GetViewShell()->GetObjectShell()->GetEmbeddedObjectContainer(); + if ( !aCnt.HasEmbeddedObject( xObj ) ) + aCnt.InsertEmbeddedObject( xObj, aName ); + else + aName = aCnt.GetEmbeddedObjectName( xObj ); + + svt::EmbeddedObjectRef aObjRef( xObj, nAspect ); + if ( pReplGraph ) + aObjRef.SetGraphic( *pReplGraph, aMediaType ); + + Size aSize; + if ( nAspect == embed::Aspects::MSOLE_ICON ) + { + MapMode aMapMode( MAP_100TH_MM ); + aSize = aObjRef.GetSize( &aMapMode ); + } + else + { + // working with visual area can switch object to running state + MapUnit aMapObj = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ); + MapUnit aMap100 = MAP_100TH_MM; + + if ( pDescSize && pDescSize->Width() && pDescSize->Height() ) + { + // use size from object descriptor if given + aSize = OutputDevice::LogicToLogic( *pDescSize, aMap100, aMapObj ); + awt::Size aSz; + aSz.Width = aSize.Width(); + aSz.Height = aSize.Height(); + xObj->setVisualAreaSize( nAspect, aSz ); + } + + awt::Size aSz; + try + { + aSz = xObj->getVisualAreaSize( nAspect ); + } + catch ( embed::NoVisualAreaSizeException& ) + { + // the default size will be set later + } + + aSize = Size( aSz.Width, aSz.Height ); + aSize = OutputDevice::LogicToLogic( aSize, aMapObj, aMap100 ); // fuer SdrOle2Obj + + if( aSize.Height() == 0 || aSize.Width() == 0 ) + { + OSL_FAIL("SvObjectDescriptor::GetSize == 0"); + aSize.Width() = 5000; + aSize.Height() = 5000; + aSize = OutputDevice::LogicToLogic( aSize, aMap100, aMapObj ); + aSz.Width = aSize.Width(); + aSz.Height = aSize.Height(); + xObj->setVisualAreaSize( nAspect, aSz ); + } + } + + // don't call AdjustInsertPos + Point aInsPos = rPos; + if ( GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() ) ) + aInsPos.X() -= aSize.Width(); + Rectangle aRect( aInsPos, aSize ); + + ScDrawView* pDrView = GetScDrawView(); + SdrOle2Obj* pSdrObj = new SdrOle2Obj( aObjRef, aName, aRect ); + + SdrPageView* pPV = pDrView->GetSdrPageView(); + pDrView->InsertObjectSafe( pSdrObj, *pPV ); // nicht markieren wenn Ole + GetViewData()->GetViewShell()->SetDrawShell( sal_True ); + return sal_True; + } + else + return false; +} + +sal_Bool ScViewFunc::PasteBitmap( const Point& rPos, const Bitmap& rBmp ) +{ + String aEmpty; + Graphic aGraphic(rBmp); + return PasteGraphic( rPos, aGraphic, aEmpty, aEmpty ); +} + +sal_Bool ScViewFunc::PasteMetaFile( const Point& rPos, const GDIMetaFile& rMtf ) +{ + String aEmpty; + Graphic aGraphic(rMtf); + return PasteGraphic( rPos, aGraphic, aEmpty, aEmpty ); +} + +sal_Bool ScViewFunc::PasteGraphic( const Point& rPos, const Graphic& rGraphic, + const String& rFile, const String& rFilter ) +{ + MakeDrawLayer(); + ScDrawView* pScDrawView = GetScDrawView(); + + Point aPos( rPos ); + Window* pWin = GetActiveWin(); + MapMode aSourceMap = rGraphic.GetPrefMapMode(); + MapMode aDestMap( MAP_100TH_MM ); + + if (aSourceMap.GetMapUnit() == MAP_PIXEL) + { + // Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt + + Fraction aScaleX, aScaleY; + pScDrawView->CalcNormScale( aScaleX, aScaleY ); + aDestMap.SetScaleX(aScaleX); + aDestMap.SetScaleY(aScaleY); + } + + Size aSize = pWin->LogicToLogic( rGraphic.GetPrefSize(), &aSourceMap, &aDestMap ); + + if ( GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() ) ) + aPos.X() -= aSize.Width(); + + GetViewData()->GetViewShell()->SetDrawShell( sal_True ); + + Rectangle aRect(aPos, aSize); + SdrGrafObj* pGrafObj = new SdrGrafObj(rGraphic, aRect); + + // calling SetGraphicLink here doesn't work + + // Pfad wird nicht mehr als Name der Grafik gesetzt + + ScDrawLayer* pLayer = (ScDrawLayer*) pScDrawView->GetModel(); + String aName = pLayer->GetNewGraphicName(); // "Grafik x" + pGrafObj->SetName(aName); + + // nicht markieren wenn Ole + pScDrawView->InsertObjectSafe(pGrafObj, *pScDrawView->GetSdrPageView()); + + // SetGraphicLink has to be used after inserting the object, + // otherwise an empty graphic is swapped in and the contact stuff crashes. + // See #i37444#. + if (rFile.Len()) + pGrafObj->SetGraphicLink( rFile, rFilter ); + + return sal_True; +} + +sal_Bool ScViewFunc::ApplyGraphicToObject( SdrObject* pPickObj, const Graphic& rGraphic ) +{ + sal_Bool bRet = false; + SdrGrafObj* pNewGrafObj = NULL; + + ScDrawView* pScDrawView = GetScDrawView(); + if ( pScDrawView && pPickObj ) + { + /********************************************************************** + * Objekt neu attributieren + **********************************************************************/ + SdrPageView* pPV = pScDrawView->GetSdrPageView(); + if (pPickObj->ISA(SdrGrafObj)) + { + /****************************************************************** + * Das Graphik-Objekt bekommt eine neue Graphik + ******************************************************************/ + pNewGrafObj = (SdrGrafObj*) pPickObj->Clone(); + pNewGrafObj->SetGraphic(rGraphic); + + pScDrawView->BegUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP)); + pScDrawView->ReplaceObjectAtView(pPickObj, *pPV, pNewGrafObj); + pScDrawView->EndUndo(); + + bRet = sal_True; + } + else if (pPickObj->IsClosedObj() && !pPickObj->ISA(SdrOle2Obj)) + { + /****************************************************************** + * Das Objekt wird mit der Graphik gefuellt + ******************************************************************/ + //pScDrawView->BegUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP)); + pScDrawView->AddUndo(new SdrUndoAttrObj(*pPickObj)); + //pScDrawView->EndUndo(); + + XOBitmap aXOBitmap( rGraphic.GetBitmap() ); + SfxItemSet aSet( pScDrawView->GetModel()->GetItemPool(), + XATTR_FILLSTYLE, XATTR_FILLBITMAP ); + aSet.Put(XFillStyleItem(XFILL_BITMAP)); + aSet.Put(XFillBitmapItem(String(), aXOBitmap)); + + pPickObj->SetMergedItemSetAndBroadcast(aSet); + + bRet = sal_True; + } + } + return bRet; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |