diff options
Diffstat (limited to 'sc/source/ui/app/seltrans.cxx')
-rw-r--r-- | sc/source/ui/app/seltrans.cxx | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/sc/source/ui/app/seltrans.cxx b/sc/source/ui/app/seltrans.cxx new file mode 100644 index 000000000000..0b213709863d --- /dev/null +++ b/sc/source/ui/app/seltrans.cxx @@ -0,0 +1,449 @@ +/************************************************************************* + * + * 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 --------------------------------------------------------------- + + + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/form/FormButtonType.hpp> + +#include <tools/urlobj.hxx> +#include <sfx2/docfile.hxx> +#include <svx/fmglob.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdouno.hxx> + +#include "seltrans.hxx" +#include "transobj.hxx" +#include "drwtrans.hxx" +#include "scmod.hxx" +#include "dbfunc.hxx" // for CopyToClip +#include "docsh.hxx" +#include "drawview.hxx" +#include "drwlayer.hxx" + +using namespace com::sun::star; + +// ----------------------------------------------------------------------- + +BOOL lcl_IsURLButton( SdrObject* pObject ) +{ + BOOL bRet = FALSE; + + SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObject); + if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor()) + { + uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel(); + DBG_ASSERT( xControlModel.is(), "uno control without model" ); + if ( xControlModel.is() ) + { + uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY ); + uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo(); + + rtl::OUString sPropButtonType = rtl::OUString::createFromAscii( "ButtonType" ); + if(xInfo->hasPropertyByName( sPropButtonType )) + { + uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType ); + form::FormButtonType eTmp; + if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL ) + bRet = TRUE; + } + } + } + + return bRet; +} + +// static + +ScSelectionTransferObj* ScSelectionTransferObj::CreateFromView( ScTabView* pView ) +{ + ScSelectionTransferObj* pRet = NULL; + + if ( pView ) + { + ScSelectionTransferMode eMode = SC_SELTRANS_INVALID; + + SdrView* pSdrView = pView->GetSdrView(); + if ( pSdrView ) + { + // handle selection on drawing layer + const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); + ULONG nMarkCount = rMarkList.GetMarkCount(); + if ( nMarkCount ) + { + if ( nMarkCount == 1 ) + { + SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + UINT16 nSdrObjKind = pObj->GetObjIdentifier(); + + if ( nSdrObjKind == OBJ_GRAF ) + { + if ( ((SdrGrafObj*)pObj)->GetGraphic().GetType() == GRAPHIC_BITMAP ) + eMode = SC_SELTRANS_DRAW_BITMAP; + else + eMode = SC_SELTRANS_DRAW_GRAPHIC; + } + else if ( nSdrObjKind == OBJ_OLE2 ) + eMode = SC_SELTRANS_DRAW_OLE; + else if ( lcl_IsURLButton( pObj ) ) + eMode = SC_SELTRANS_DRAW_BOOKMARK; + } + + if ( eMode == SC_SELTRANS_INVALID ) + eMode = SC_SELTRANS_DRAW_OTHER; // something selected but no special selection + } + } + if ( eMode == SC_SELTRANS_INVALID ) // no drawing object selected + { + ScRange aRange; + ScViewData* pViewData = pView->GetViewData(); + const ScMarkData& rMark = pViewData->GetMarkData(); + // allow MultiMarked because GetSimpleArea may be able to merge into a simple range + // (GetSimpleArea modifies a local copy of MarkData) + // Also allow simple filtered area. + ScMarkType eMarkType; + if ( ( rMark.IsMarked() || rMark.IsMultiMarked() ) && + (((eMarkType = pViewData->GetSimpleArea( aRange )) == SC_MARK_SIMPLE) || + (eMarkType == SC_MARK_SIMPLE_FILTERED)) ) + { + // only for "real" selection, cursor alone isn't used + if ( aRange.aStart == aRange.aEnd ) + eMode = SC_SELTRANS_CELL; + else + eMode = SC_SELTRANS_CELLS; + } + } + + if ( eMode != SC_SELTRANS_INVALID ) + pRet = new ScSelectionTransferObj( pView, eMode ); + } + + return pRet; +} + + +ScSelectionTransferObj::ScSelectionTransferObj( ScTabView* pSource, ScSelectionTransferMode eNewMode ) : + pView( pSource ), + eMode( eNewMode ), + pCellData( NULL ), + pDrawData( NULL ) +{ + //! store range for StillValid +} + +ScSelectionTransferObj::~ScSelectionTransferObj() +{ + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetSelectionTransfer() == this ) + { + // this is reached when the object wasn't really copied to the selection + // (CopyToSelection has no effect under Windows) + + ForgetView(); + pScMod->SetSelectionTransfer( NULL ); + } + + DBG_ASSERT( !pView, "ScSelectionTransferObj dtor: ForgetView not called" ); +} + +BOOL ScSelectionTransferObj::StillValid() +{ + //! check if view still has same cell selection + //! (but return FALSE if data has changed inbetween) + return FALSE; +} + +void ScSelectionTransferObj::ForgetView() +{ + pView = NULL; + eMode = SC_SELTRANS_INVALID; + + if (pCellData) + { + pCellData->release(); + pCellData = NULL; + } + if (pDrawData) + { + pDrawData->release(); + pDrawData = NULL; + } +} + +void ScSelectionTransferObj::AddSupportedFormats() +{ + // AddSupportedFormats must work without actually creating the + // "real" transfer object + + switch (eMode) + { + case SC_SELTRANS_CELL: + case SC_SELTRANS_CELLS: + // same formats as in ScTransferObj::AddSupportedFormats + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMAT_BITMAP ); + AddFormat( SOT_FORMATSTR_ID_HTML ); + AddFormat( SOT_FORMATSTR_ID_SYLK ); + AddFormat( SOT_FORMATSTR_ID_LINK ); + AddFormat( SOT_FORMATSTR_ID_DIF ); + AddFormat( SOT_FORMAT_STRING ); + AddFormat( SOT_FORMAT_RTF ); + if ( eMode == SC_SELTRANS_CELL ) + AddFormat( SOT_FORMATSTR_ID_EDITENGINE ); + break; + + // different graphic formats as in ScDrawTransferObj::AddSupportedFormats: + + case SC_SELTRANS_DRAW_BITMAP: + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_SVXB ); + AddFormat( SOT_FORMAT_BITMAP ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + break; + + case SC_SELTRANS_DRAW_GRAPHIC: + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_SVXB ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + AddFormat( SOT_FORMAT_BITMAP ); + break; + + case SC_SELTRANS_DRAW_BOOKMARK: + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_SOLK ); + AddFormat( SOT_FORMAT_STRING ); + AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); + AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + break; + + case SC_SELTRANS_DRAW_OLE: + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + break; + + case SC_SELTRANS_DRAW_OTHER: + // other drawing objects + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + AddFormat( SOT_FORMAT_BITMAP ); + AddFormat( SOT_FORMAT_GDIMETAFILE ); + break; + + default: + { + // added to avoid warnings + } + } +} + +void ScSelectionTransferObj::CreateCellData() +{ + DBG_ASSERT( !pCellData, "CreateCellData twice" ); + if ( pView ) + { + ScViewData* pViewData = pView->GetViewData(); + ScMarkData aNewMark( pViewData->GetMarkData() ); // use local copy for MarkToSimple + aNewMark.MarkToSimple(); + + // similar to ScViewFunctionSet::BeginDrag + if ( aNewMark.IsMarked() && !aNewMark.IsMultiMarked() ) + { + ScDocShell* pDocSh = pViewData->GetDocShell(); + + ScRange aSelRange; + aNewMark.GetMarkArea( aSelRange ); + ScDocShellRef aDragShellRef; + if ( pDocSh->GetDocument()->HasOLEObjectsInArea( aSelRange, &aNewMark ) ) + { + aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately + aDragShellRef->DoInitNew(NULL); + } + ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); + + ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); + // bApi = TRUE -> no error mesages + // #i18364# bStopEdit = FALSE -> don't end edit mode + // (this may be called from pasting into the edit line) + BOOL bCopied = pViewData->GetView()->CopyToClip( pClipDoc, FALSE, TRUE, TRUE, FALSE ); + + ScDrawLayer::SetGlobalDrawPersist(NULL); + + if ( bCopied ) + { + TransferableObjectDescriptor aObjDesc; + pDocSh->FillTransferableObjectDescriptor( aObjDesc ); + aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); + // maSize is set in ScTransferObj ctor + + ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); + uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); + + // SetDragHandlePos is not used - there is no mouse position + //? pTransferObj->SetVisibleTab( nTab ); + + SfxObjectShellRef aPersistRef( aDragShellRef ); + pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive + + pTransferObj->SetDragSource( pDocSh, aNewMark ); + + pCellData = pTransferObj; + pCellData->acquire(); // keep ref count up - released in ForgetView + } + else + delete pClipDoc; + } + } + DBG_ASSERT( pCellData, "can't create CellData" ); +} + +//! make static member of ScDrawView +extern void lcl_CheckOle( const SdrMarkList& rMarkList, BOOL& rAnyOle, BOOL& rOneOle ); + +void ScSelectionTransferObj::CreateDrawData() +{ + DBG_ASSERT( !pDrawData, "CreateDrawData twice" ); + if ( pView ) + { + // similar to ScDrawView::BeginDrag + + ScDrawView* pDrawView = pView->GetScDrawView(); + if ( pDrawView ) + { + BOOL bAnyOle, bOneOle; + const SdrMarkList& rMarkList = pDrawView->GetMarkedObjectList(); + lcl_CheckOle( rMarkList, bAnyOle, bOneOle ); + + //--------------------------------------------------------- + ScDocShellRef aDragShellRef; + if (bAnyOle) + { + aDragShellRef = new ScDocShell; // ohne Ref lebt die DocShell nicht !!! + aDragShellRef->DoInitNew(NULL); + } + //--------------------------------------------------------- + + ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); + SdrModel* pModel = pDrawView->GetAllMarkedModel(); + ScDrawLayer::SetGlobalDrawPersist(NULL); + + ScViewData* pViewData = pView->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + + TransferableObjectDescriptor aObjDesc; + pDocSh->FillTransferableObjectDescriptor( aObjDesc ); + aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); + // maSize is set in ScDrawTransferObj ctor + + ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc ); + uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); + + SfxObjectShellRef aPersistRef( aDragShellRef ); + pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive + pTransferObj->SetDragSource( pDrawView ); // copies selection + + pDrawData = pTransferObj; + pDrawData->acquire(); // keep ref count up - released in ForgetView + } + } + DBG_ASSERT( pDrawData, "can't create DrawData" ); +} + +ScTransferObj* ScSelectionTransferObj::GetCellData() +{ + if ( !pCellData && ( eMode == SC_SELTRANS_CELL || eMode == SC_SELTRANS_CELLS ) ) + CreateCellData(); + return pCellData; +} + +ScDrawTransferObj* ScSelectionTransferObj::GetDrawData() +{ + if ( !pDrawData && ( eMode == SC_SELTRANS_DRAW_BITMAP || eMode == SC_SELTRANS_DRAW_GRAPHIC || + eMode == SC_SELTRANS_DRAW_BOOKMARK || eMode == SC_SELTRANS_DRAW_OLE || + eMode == SC_SELTRANS_DRAW_OTHER ) ) + CreateDrawData(); + return pDrawData; +} + +sal_Bool ScSelectionTransferObj::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ) +{ + sal_Bool bOK = sal_False; + + uno::Reference<datatransfer::XTransferable> xSource; + switch (eMode) + { + case SC_SELTRANS_CELL: + case SC_SELTRANS_CELLS: + xSource = GetCellData(); + break; + case SC_SELTRANS_DRAW_BITMAP: + case SC_SELTRANS_DRAW_GRAPHIC: + case SC_SELTRANS_DRAW_BOOKMARK: + case SC_SELTRANS_DRAW_OLE: + case SC_SELTRANS_DRAW_OTHER: + xSource = GetDrawData(); + break; + default: + { + // added to avoid warnings + } + } + + if ( xSource.is() ) + { + TransferableDataHelper aHelper( xSource ); + uno::Any aAny = aHelper.GetAny( rFlavor ); + bOK = SetAny( aAny, rFlavor ); + } + + return bOK; +} + +void ScSelectionTransferObj::ObjectReleased() +{ + // called when another selection is set from outside + + ForgetView(); + + ScModule* pScMod = SC_MOD(); + if ( pScMod->GetSelectionTransfer() == this ) + pScMod->SetSelectionTransfer( NULL ); + + TransferableHelper::ObjectReleased(); +} + + |