diff options
Diffstat (limited to 'sw/source/ui/dochdl/swdtflvr.cxx')
-rw-r--r-- | sw/source/ui/dochdl/swdtflvr.cxx | 3873 |
1 files changed, 3873 insertions, 0 deletions
diff --git a/sw/source/ui/dochdl/swdtflvr.cxx b/sw/source/ui/dochdl/swdtflvr.cxx new file mode 100644 index 000000000000..704172b21074 --- /dev/null +++ b/sw/source/ui/dochdl/swdtflvr.cxx @@ -0,0 +1,3873 @@ +/************************************************************************* + * + * 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_sw.hxx" +#ifdef PRECOMPILED +#include "ui_pch.hxx" +#endif + + +#include <com/sun/star/embed/XVisualObject.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/embed/Aspects.hpp> +#include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp> +#include <com/sun/star/embed/NoVisualAreaSizeException.hpp> + +#include <svtools/embedtransfer.hxx> +#include <svtools/insdlg.hxx> +#include <unotools/tempfile.hxx> +#include <comphelper/storagehelper.hxx> +#include <comphelper/processfactory.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <sot/filelist.hxx> +#include <svx/svxdlg.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <osl/endian.h> +#include <sfx2/linkmgr.hxx> +#include <tools/urlobj.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/msgbox.hxx> +#include <sfx2/dispatch.hxx> +#include <svl/stritem.hxx> +#include <svtools/imap.hxx> +#include <sot/storage.hxx> +#include <vcl/graph.hxx> +#include <svl/urihelper.hxx> +#include <svx/svdmodel.hxx> +#include <svx/xexch.hxx> +#include <svx/xmlexchg.hxx> +#include <svx/dbaexchange.hxx> +#include <svx/clipfmtitem.hxx> +#include <sfx2/mieclip.hxx> +#include <svx/svdetc.hxx> +#include <svx/xoutbmp.hxx> +#include <svl/urlbmk.hxx> +#include <svtools/htmlout.hxx> +#include <svx/hlnkitem.hxx> +#include <svtools/inetimg.hxx> +#include <editeng/paperinf.hxx> +#include <svx/fmview.hxx> +#include <editeng/scripttypeitem.hxx> +#include <sfx2/docfilt.hxx> +#include <svtools/imapobj.hxx> +#include <sfx2/docfile.hxx> +#include <unotools/transliterationwrapper.hxx> +#include <unotools/streamwrap.hxx> +#include <svtools/filter.hxx> + +#include <svx/unomodel.hxx> +#include <fmturl.hxx> +#include <fmtinfmt.hxx> +#include <fmtfsize.hxx> +#include <swdtflvr.hxx> +#include <shellio.hxx> +#include <ddefld.hxx> +#include <doc.hxx> +#include <pagedesc.hxx> +#include <IMark.hxx> +#include <docary.hxx> +#include <section.hxx> +#include <ndtxt.hxx> +#include <edtwin.hxx> +#include <navicont.hxx> +#include <swcont.hxx> +#include <wrtsh.hxx> +#include <swmodule.hxx> +#include <view.hxx> +#include <docsh.hxx> +#include <wdocsh.hxx> +#include <fldbas.hxx> //DDE +#include <swundo.hxx> // fuer Undo-Ids +#include <pam.hxx> +#include <ndole.hxx> +#include <swwait.hxx> +#include <viewopt.hxx> +#include <swunodef.hxx> +#include <vcl/sound.hxx> +#include <swerror.h> +#include <SwCapObjType.hxx> +#include <cmdid.h> +#include <dochdl.hrc> +#include <comcore.hrc> // #111827# +#include <sot/stg.hxx> + +// #108584# +#include <svx/svditer.hxx> + +// #108584# +#include <editeng/eeitem.hxx> + +// #108584# +#include <editeng/fhgtitem.hxx> + +// #108584# +#include <svx/svdpage.hxx> +#include <avmedia/mediawindow.hxx> + +// #109590# +#include <swcrsr.hxx> +#include <SwRewriter.hxx> +#include <undobj.hxx> +#include <globals.hrc> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <swserv.hxx> + +extern BOOL bFrmDrag; +extern BOOL bDDINetAttr; +extern BOOL bExecuteDrag; + + +#define OLESIZE 11905 - 2 * lMinBorder, 6 * MM50 + +#define SWTRANSFER_OBJECTTYPE_DRAWMODEL 0x00000001 +#define SWTRANSFER_OBJECTTYPE_HTML 0x00000002 +#define SWTRANSFER_OBJECTTYPE_RTF 0x00000004 +#define SWTRANSFER_OBJECTTYPE_STRING 0x00000008 +#define SWTRANSFER_OBJECTTYPE_SWOLE 0x00000010 +#define SWTRANSFER_OBJECTTYPE_DDE 0x00000020 + +#define SWTRANSFER_GRAPHIC_INSERTED 0x00000040 + +using namespace ::svx; +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::datatransfer; +using namespace nsTransferBufferType; + +#define DDE_TXT_ENCODING gsl_getSystemTextEncoding() + +//--------------------------------------------- +// this struct conforms to the Microsoft +// OBJECTDESCRIPTOR -> see oleidl.h +// (MS platform sdk) +//--------------------------------------------- + +struct OleObjectDescriptor +{ + sal_uInt32 cbSize; + ClsId clsid; + sal_uInt32 dwDrawAspect; + Size sizel; + Point pointl; + sal_uInt32 dwStatus; + sal_uInt32 dwFullUserTypeName; + sal_uInt32 dwSrcOfCopy; +}; + +class SwTrnsfrDdeLink : public ::sfx2::SvBaseLink +{ + String sName; + ::sfx2::SvLinkSourceRef refObj; + SwTransferable& rTrnsfr; + SwDocShell* pDocShell; + ULONG nOldTimeOut; + BOOL bDelBookmrk : 1; + BOOL bInDisconnect : 1; + + BOOL FindDocShell(); + + using sfx2::SvBaseLink::Disconnect; + +protected: + virtual ~SwTrnsfrDdeLink(); + +public: + SwTrnsfrDdeLink( SwTransferable& rTrans, SwWrtShell& rSh ); + + virtual void DataChanged( const String& rMimeType, + const uno::Any & rValue ); + virtual void Closed(); + + BOOL WriteData( SvStream& rStrm ); + + void Disconnect( BOOL bRemoveDataAdvise ); +}; + +// helper class for Action and Undo enclosing +class SwTrnsfrActionAndUndo +{ + SwWrtShell *pSh; + SwUndoId eUndoId; +public: + SwTrnsfrActionAndUndo( SwWrtShell *pS, SwUndoId nId, + const SwRewriter * pRewriter = 0, + BOOL bDelSel = FALSE) + : pSh( pS ), eUndoId( nId ) + { + pSh->StartUndo( eUndoId, pRewriter ); + if( bDelSel ) + pSh->DelRight(); + pSh->StartAllAction(); + } + ~SwTrnsfrActionAndUndo() + { + pSh->EndUndo( eUndoId ); + pSh->EndAllAction(); + } +}; + + +// ----------------------------------------------------------------------- + +SwTransferable::SwTransferable( SwWrtShell& rSh ) + : pWrtShell( &rSh ), + pCreatorView( 0 ), + pClpDocFac( 0 ), + pClpGraphic( 0 ), + pClpBitmap( 0 ), + pOrigGrf( 0 ), + pBkmk( 0 ), + pImageMap( 0 ), + pTargetURL( 0 ), + eBufferType( TRNSFR_NONE ) +{ + rSh.GetView().AddTransferable(*this); + SwDocShell* pDShell = rSh.GetDoc()->GetDocShell(); + if( pDShell ) + { + pDShell->FillTransferableObjectDescriptor( aObjDesc ); + if( pDShell->GetMedium() ) + { + const INetURLObject& rURLObj = pDShell->GetMedium()->GetURLObject(); + aObjDesc.maDisplayName = URIHelper::removePassword( + rURLObj.GetMainURL( INetURLObject::NO_DECODE ), + INetURLObject::WAS_ENCODED, + INetURLObject::DECODE_UNAMBIGUOUS ); + } + + PrepareOLE( aObjDesc ); + } +} + +// ----------------------------------------------------------------------- + +SwTransferable::~SwTransferable() +{ + Application::GetSolarMutex().acquire(); + + // der DDELink braucht noch die WrtShell! + if( refDdeLink.Is() ) + { + ((SwTrnsfrDdeLink*)&refDdeLink)->Disconnect( TRUE ); + refDdeLink.Clear(); + } + + pWrtShell = 0; + + // dvo 2002-05-30, #99239#: release reference to the document so that + // aDocShellRef will delete it (if aDocShellRef is set). Otherwise, the OLE + // nodes keep references to their sub-storage when the storage is already + // dead. + delete pClpDocFac; + + //JP 22.04.95: erst schliessen, dann kann die Ref. auch gecleared werden, + // so das die DocShell auch tatsaechlich geloescht wird! + if( aDocShellRef.Is() ) + { + SfxObjectShell * pObj = aDocShellRef; + SwDocShell* pDocSh = (SwDocShell*)pObj; + pDocSh->DoClose(); + } + aDocShellRef.Clear(); + + SwModule* pMod = SW_MOD(); + if(pMod) + { + if ( pMod->pClipboard == this ) + pMod->pClipboard = 0; + else if ( pMod->pDragDrop == this ) + pMod->pDragDrop = 0; + else if ( pMod->pXSelection == this ) + pMod->pXSelection = 0; + } + + delete pClpGraphic; + delete pClpBitmap; + delete pImageMap; + delete pTargetURL; + delete pBkmk; + + + eBufferType = TRNSFR_NONE; + + Application::GetSolarMutex().release(); +} + +// ----------------------------------------------------------------------- + +static SwDoc * lcl_GetDoc(SwDocFac & rDocFac) +{ + SwDoc *const pDoc = rDocFac.GetDoc(); + ASSERT( pDoc, "Document not found" ); + if (pDoc) + { + pDoc->SetClipBoard( true ); + } + return pDoc; +} + +// ----------------------------------------------------------------------- + +void SwTransferable::ObjectReleased() +{ + SwModule *pMod = SW_MOD(); + if( this == pMod->pClipboard ) + pMod->pClipboard = 0; + else if( this == pMod->pDragDrop ) + pMod->pDragDrop = 0; + else if( this == pMod->pXSelection ) + pMod->pXSelection = 0; +} + +// ----------------------------------------------------------------------- + +void SwTransferable::AddSupportedFormats() +{ + // only need if we are the current XSelection Object + SwModule *pMod = SW_MOD(); + if( this == pMod->pXSelection ) + { + SetDataForDragAndDrop( Point( 0,0) ); + } +} + +// ----------------------------------------------------------------------- + +void SwTransferable::InitOle( SfxObjectShell* pDoc, SwDoc& rDoc ) +{ + //OleVisArea einstellen. Linke obere Ecke der Seite und Groesse + //der RealSize in Twips. + const Size aSz( OLESIZE ); + SwRect aVis( Point( DOCUMENTBORDER, DOCUMENTBORDER ), aSz ); + pDoc->SetVisArea( aVis.SVRect() ); + rDoc.set(IDocumentSettingAccess::BROWSE_MODE, true ); +} + +// ----------------------------------------------------------------------- + +uno::Reference < embed::XEmbeddedObject > SwTransferable::FindOLEObj( sal_Int64& nAspect ) const +{ + uno::Reference < embed::XEmbeddedObject > xObj; + if( pClpDocFac ) + { + SwClientIter aIter( *(SwModify*)pClpDocFac->GetDoc()-> + GetDfltGrfFmtColl() ); + for( SwCntntNode* pNd = (SwCntntNode*)aIter.First( TYPE( SwCntntNode ) ); + pNd; pNd = (SwCntntNode*)aIter.Next() ) + if( ND_OLENODE == pNd->GetNodeType() ) + { + xObj = ((SwOLENode*)pNd)->GetOLEObj().GetOleRef(); + nAspect = ((SwOLENode*)pNd)->GetAspect(); + break; + } + } + return xObj; +} + +// ----------------------------------------------------------------------- + +Graphic* SwTransferable::FindOLEReplacementGraphic() const +{ + if( pClpDocFac ) + { + SwClientIter aIter( *(SwModify*)pClpDocFac->GetDoc()-> + GetDfltGrfFmtColl() ); + for( SwCntntNode* pNd = (SwCntntNode*)aIter.First( TYPE( SwCntntNode ) ); + pNd; pNd = (SwCntntNode*)aIter.Next() ) + if( ND_OLENODE == pNd->GetNodeType() ) + { + return ((SwOLENode*)pNd)->GetGraphic(); + } + } + + return NULL; +} + + +// ----------------------------------------------------------------------- + +void SwTransferable::RemoveDDELinkFormat( const Window& rWin ) +{ + RemoveFormat( SOT_FORMATSTR_ID_LINK ); + CopyToClipboard( (Window*)&rWin ); +} + +// ----------------------------------------------------------------------- + +sal_Bool SwTransferable::GetData( const DATA_FLAVOR& rFlavor ) +{ + sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor ); + + // we can only fullfil the request if + // 1) we have data for this format + // 2) we have either a clipboard document (pClpDocFac), or + // we have a SwWrtShell (so we can generate a new clipboard document) + if( !HasFormat( nFormat ) || ( pClpDocFac == NULL && pWrtShell == NULL ) ) + return sal_False; + + if( !pClpDocFac ) + { + SelectionType nSelectionType = pWrtShell->GetSelectionType(); + +// SEL_GRF kommt vom ContentType der editsh + if( (nsSelectionType::SEL_GRF | nsSelectionType::SEL_DRW_FORM) & nSelectionType ) + { + pClpGraphic = new Graphic; + if( !pWrtShell->GetDrawObjGraphic( FORMAT_GDIMETAFILE, *pClpGraphic )) + pOrigGrf = pClpGraphic; + pClpBitmap = new Graphic; + if( !pWrtShell->GetDrawObjGraphic( FORMAT_BITMAP, *pClpBitmap )) + pOrigGrf = pClpBitmap; + + // ist es ein URL-Button ? + String sURL, sDesc; + if( pWrtShell->GetURLFromButton( sURL, sDesc ) ) + { + pBkmk = new INetBookmark( sURL, sDesc ); + eBufferType = TRNSFR_INETFLD; + } + } + + pClpDocFac = new SwDocFac; + SwDoc *const pTmpDoc = lcl_GetDoc(*pClpDocFac); + + pTmpDoc->SetRefForDocShell( boost::addressof(aDocShellRef) ); + pTmpDoc->LockExpFlds(); // nie die Felder updaten - Text so belassen + pWrtShell->Copy( pTmpDoc ); + + // es wurde in der CORE eine neu angelegt (OLE-Objekte kopiert!) + if( aDocShellRef.Is() ) + SwTransferable::InitOle( aDocShellRef, *pTmpDoc ); + pTmpDoc->SetRefForDocShell( 0 ); + + if( nSelectionType & nsSelectionType::SEL_TXT && !pWrtShell->HasMark() ) + { + SwContentAtPos aCntntAtPos( SwContentAtPos::SW_INETATTR ); + + Point aPos( SwEditWin::GetDDStartPosX(), SwEditWin::GetDDStartPosY()); + + BOOL bSelect = bExecuteDrag && + pWrtShell->GetView().GetDocShell() && + !pWrtShell->GetView().GetDocShell()->IsReadOnly(); + if( pWrtShell->GetContentAtPos( aPos, aCntntAtPos, bSelect ) ) + { + pBkmk = new INetBookmark( + ((SwFmtINetFmt*)aCntntAtPos.aFnd.pAttr)->GetValue(), + aCntntAtPos.sStr ); + eBufferType = TRNSFR_INETFLD; + if( bSelect ) + pWrtShell->SelectTxtAttr( RES_TXTATR_INETFMT ); + } + } + if( pWrtShell->IsFrmSelected() ) + { + SfxItemSet aSet( pWrtShell->GetAttrPool(), RES_URL, RES_URL ); + pWrtShell->GetFlyFrmAttr( aSet ); + const SwFmtURL& rURL = (SwFmtURL&)aSet.Get( RES_URL ); + if( rURL.GetMap() ) + pImageMap = new ImageMap( *rURL.GetMap() ); + else if( rURL.GetURL().Len() ) + pTargetURL = new INetImage( aEmptyStr, rURL.GetURL(), + rURL.GetTargetFrameName(), + aEmptyStr, Size() ); + } + } + + sal_Bool bOK = sal_False; + if( TRNSFR_OLE == eBufferType ) + { + //TODO/MBA: testing - is this the "single OLE object" case?! + // aus dem ClipDoc das OLE-Object besorgen und von dem die Daten + // besorgen. + sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT; // will be set in the next statement + uno::Reference < embed::XEmbeddedObject > xObj = FindOLEObj( nAspect ); + Graphic* pOLEGraph = FindOLEReplacementGraphic(); + if( xObj.is() ) + { + TransferableDataHelper aD( new SvEmbedTransferHelper( xObj, pOLEGraph, nAspect ) ); + uno::Any aAny( aD.GetAny( rFlavor )); + if( aAny.hasValue() ) + bOK = SetAny( aAny, rFlavor ); + } + + // the following solution will be used in the case when the object can not generate the image + // TODO/LATER: in future the transferhelper must probably be created based on object and the replacement stream + if ( nFormat == SOT_FORMAT_GDIMETAFILE ) + { + pOLEGraph = FindOLEReplacementGraphic(); + if ( pOLEGraph ) + bOK = SetGDIMetaFile( pOLEGraph->GetGDIMetaFile(), rFlavor ); + } + } + else + { + switch( nFormat ) + { + case SOT_FORMATSTR_ID_LINK: + if( refDdeLink.Is() ) + bOK = SetObject( &refDdeLink, + SWTRANSFER_OBJECTTYPE_DDE, rFlavor ); + break; + + case SOT_FORMATSTR_ID_OBJECTDESCRIPTOR: + case SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR: + bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor ); + break; + + case SOT_FORMATSTR_ID_DRAWING: + { + SwDoc *const pDoc = lcl_GetDoc(*pClpDocFac); + bOK = SetObject( pDoc->GetDrawModel(), + SWTRANSFER_OBJECTTYPE_DRAWMODEL, rFlavor ); + } + break; + + case SOT_FORMAT_STRING: + { + SwDoc *const pDoc = lcl_GetDoc(*pClpDocFac); + bOK = SetObject( pDoc, SWTRANSFER_OBJECTTYPE_STRING, rFlavor ); + } + break; + case SOT_FORMAT_RTF: + { + SwDoc *const pDoc = lcl_GetDoc(*pClpDocFac); + bOK = SetObject( pDoc, SWTRANSFER_OBJECTTYPE_RTF, rFlavor ); + } + break; + + case SOT_FORMATSTR_ID_HTML: + { + SwDoc *const pDoc = lcl_GetDoc(*pClpDocFac); + bOK = SetObject( pDoc, SWTRANSFER_OBJECTTYPE_HTML, rFlavor ); + } + break; + + case SOT_FORMATSTR_ID_SVXB: + if( eBufferType & TRNSFR_GRAPHIC && pOrigGrf ) + bOK = SetGraphic( *pOrigGrf, rFlavor ); + break; + + case SOT_FORMAT_GDIMETAFILE: + if( eBufferType & TRNSFR_GRAPHIC ) + bOK = SetGDIMetaFile( pClpGraphic->GetGDIMetaFile(), rFlavor ); + break; + case SOT_FORMAT_BITMAP: + // #126398# Neither pClpBitmap nor pClpGraphic are necessarily set + if( (eBufferType & TRNSFR_GRAPHIC) && (pClpBitmap != 0 || pClpGraphic != 0)) + bOK = SetBitmap( (pClpBitmap ? pClpBitmap + : pClpGraphic)->GetBitmap(), + rFlavor ); + break; + + case SOT_FORMATSTR_ID_SVIM: + if( pImageMap ) + bOK = SetImageMap( *pImageMap, rFlavor ); + break; + + case SOT_FORMATSTR_ID_INET_IMAGE: + if( pTargetURL ) + bOK = SetINetImage( *pTargetURL, rFlavor ); + break; + + case SOT_FORMATSTR_ID_SOLK: + case SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK: + case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR: + case SOT_FORMATSTR_ID_FILECONTENT: + case SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR: + case SOT_FORMAT_FILE: + if( (TRNSFR_INETFLD & eBufferType) && pBkmk ) + bOK = SetINetBookmark( *pBkmk, rFlavor ); + break; + + case SOT_FORMATSTR_ID_EMBED_SOURCE: +// default: + if( !aDocShellRef.Is() ) + { + SwDoc *const pDoc = lcl_GetDoc(*pClpDocFac); + SwDocShell* pNewDocSh = new SwDocShell( pDoc, + SFX_CREATE_MODE_EMBEDDED ); + aDocShellRef = pNewDocSh; + aDocShellRef->DoInitNew( NULL ); + SwTransferable::InitOle( aDocShellRef, *pDoc ); + } + bOK = SetObject( &aDocShellRef, SWTRANSFER_OBJECTTYPE_SWOLE, + rFlavor ); + break; + } + } + return bOK; +} + +// ----------------------------------------------------------------------- + +sal_Bool SwTransferable::WriteObject( SotStorageStreamRef& xStream, + void* pObject, sal_uInt32 nObjectType, + const DATA_FLAVOR& /*rFlavor*/ ) +{ + sal_Bool bRet = sal_False; + WriterRef xWrt; + + switch( nObjectType ) + { + case SWTRANSFER_OBJECTTYPE_DRAWMODEL: + { + //JP 28.02.2001: dont change the sequence of commands - Bug 8 + SdrModel *pModel = (SdrModel*)pObject; + xStream->SetBufferSize( 16348 ); + + // #108584# + // for the changed pool defaults from drawing layer pool set those + // attributes as hard attributes to preserve them for saving + const SfxItemPool& rItemPool = pModel->GetItemPool(); + const SvxFontHeightItem& rDefaultFontHeight = (const SvxFontHeightItem&)rItemPool.GetDefaultItem(EE_CHAR_FONTHEIGHT); + + // SW should have no MasterPages + DBG_ASSERT(0L == pModel->GetMasterPageCount(), "SW with MasterPages (!)"); + + for(sal_uInt16 a(0); a < pModel->GetPageCount(); a++) + { + const SdrPage* pPage = pModel->GetPage(a); + SdrObjListIter aIter(*pPage, IM_DEEPNOGROUPS); + + while(aIter.IsMore()) + { + SdrObject* pObj = aIter.Next(); + const SvxFontHeightItem& rItem = (const SvxFontHeightItem&)pObj->GetMergedItem(EE_CHAR_FONTHEIGHT); + + if(rItem.GetHeight() == rDefaultFontHeight.GetHeight()) + { + pObj->SetMergedItem(rDefaultFontHeight); + } + } + } + + { + uno::Reference<io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *xStream ) ); + if( SvxDrawingLayerExport( pModel, xDocOut ) ) + xStream->Commit(); + } + + bRet = ERRCODE_NONE == xStream->GetError(); + } + break; + + case SWTRANSFER_OBJECTTYPE_SWOLE: + { + SfxObjectShell* pEmbObj = (SfxObjectShell*) pObject; + try + { + ::utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + uno::Reference< embed::XStorage > xWorkStore = + ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE ); + + // write document storage + pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, sal_False ); + // mba: no BaseURL for clipboard + SfxMedium aMedium( xWorkStore, String() ); + bRet = pEmbObj->DoSaveObjectAs( aMedium, FALSE ); + pEmbObj->DoSaveCompleted(); + + uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY ); + if ( xTransact.is() ) + xTransact->commit(); + + SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), STREAM_READ ); + if( pSrcStm ) + { + xStream->SetBufferSize( 0xff00 ); + *xStream << *pSrcStm; + delete pSrcStm; + } + + bRet = TRUE; + + xWorkStore->dispose(); + xWorkStore = uno::Reference < embed::XStorage >(); + xStream->Commit(); + } + catch ( uno::Exception& ) + {} + + bRet = ( xStream->GetError() == ERRCODE_NONE ); + } + break; + + + case SWTRANSFER_OBJECTTYPE_DDE: + { + xStream->SetBufferSize( 1024 ); + SwTrnsfrDdeLink* pDdeLnk = (SwTrnsfrDdeLink*)pObject; + if( pDdeLnk->WriteData( *xStream ) ) + { + xStream->Commit(); + bRet = ERRCODE_NONE == xStream->GetError(); + } + } + break; + + case SWTRANSFER_OBJECTTYPE_HTML: + GetHTMLWriter( aEmptyStr, String(), xWrt ); + break; + + case SWTRANSFER_OBJECTTYPE_RTF: + GetRTFWriter( aEmptyStr, String(), xWrt ); + break; + + case SWTRANSFER_OBJECTTYPE_STRING: + GetASCWriter( aEmptyStr, String(), xWrt ); + if( xWrt.Is() ) + { + SwAsciiOptions aAOpt; + aAOpt.SetCharSet( RTL_TEXTENCODING_UTF8 ); + xWrt->SetAsciiOptions( aAOpt ); + + // #102841# no start char for clipboard + xWrt->bUCS2_WithStartChar = FALSE; + } + break; + } + + if( xWrt.Is() ) + { + SwDoc* pDoc = (SwDoc*)pObject; + xWrt->bWriteClipboardDoc = TRUE; + xWrt->bWriteOnlyFirstTable = 0 != (TRNSFR_TABELLE & eBufferType); + xWrt->SetShowProgress( FALSE ); + SwWriter aWrt( *xStream, *pDoc ); + if( !IsError( aWrt.Write( xWrt )) ) + { + *xStream << '\0'; // terminate with a zero + xStream->Commit(); + bRet = sal_True; + } + } + + return bRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::Cut() +{ + int nRet = Copy( TRUE ); + if( nRet ) + DeleteSelection(); + return nRet; +} + +// ----------------------------------------------------------------------- + +void SwTransferable::DeleteSelection() +{ + if(!pWrtShell) + return; + // Selektionsart vor Action-Klammerung erfragen + const int nSelection = pWrtShell->GetSelectionType(); + pWrtShell->StartUndo( UNDO_DELETE ); + if( ( nsSelectionType::SEL_TXT | nsSelectionType::SEL_TBL ) & nSelection ) + pWrtShell->IntelligentCut( nSelection ); + pWrtShell->DelRight(); + pWrtShell->EndUndo( UNDO_DELETE ); +} + +// ----------------------------------------------------------------------- + +int SwTransferable::PrepareForCopy( BOOL bIsCut ) +{ + int nRet = 1; + if(!pWrtShell) + return 0;; + + String sGrfNm; + const int nSelection = pWrtShell->GetSelectionType(); + if( nSelection == nsSelectionType::SEL_GRF ) + { + pClpGraphic = new Graphic; + if( !pWrtShell->GetDrawObjGraphic( FORMAT_GDIMETAFILE, *pClpGraphic )) + pOrigGrf = pClpGraphic; + pClpBitmap = new Graphic; + if( !pWrtShell->GetDrawObjGraphic( FORMAT_BITMAP, *pClpBitmap )) + pOrigGrf = pClpBitmap; + + pClpDocFac = new SwDocFac; + SwDoc *const pDoc = lcl_GetDoc(*pClpDocFac); + pWrtShell->Copy( pDoc ); + + if (pOrigGrf && !pOrigGrf->GetBitmap().IsEmpty()) + AddFormat( SOT_FORMATSTR_ID_SVXB ); + + PrepareOLE( aObjDesc ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + + // --> OD 2005-02-09 #119353# - robust + const Graphic* pGrf = pWrtShell->GetGraphic(); + if( pGrf && pGrf->IsSupportedGraphic() ) + // <-- + { + AddFormat( FORMAT_GDIMETAFILE ); + AddFormat( FORMAT_BITMAP ); + } + eBufferType = TRNSFR_GRAPHIC; + pWrtShell->GetGrfNms( &sGrfNm, 0 ); + } + else if ( nSelection == nsSelectionType::SEL_OLE ) + { + pClpDocFac = new SwDocFac; + SwDoc *const pDoc = lcl_GetDoc(*pClpDocFac); + aDocShellRef = new SwDocShell( pDoc, SFX_CREATE_MODE_EMBEDDED); + aDocShellRef->DoInitNew( NULL ); + pWrtShell->Copy( pDoc ); + + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + + PrepareOLE( aObjDesc ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + + AddFormat( FORMAT_GDIMETAFILE ); + eBufferType = TRNSFR_OLE; + } + //Gibt es ueberhaupt etwas zum bereitstellen? + else if ( pWrtShell->IsSelection() || pWrtShell->IsFrmSelected() || + pWrtShell->IsObjSelected() ) + { + SwWait *pWait = 0; + if( pWrtShell->ShouldWait() ) + pWait = new SwWait( *pWrtShell->GetView().GetDocShell(), TRUE ); + + pClpDocFac = new SwDocFac; + + // zusaetzlichen Cursor erzeugen, damit eine Gleichbehandlung + // von Tastatur- und Mausselektion moeglich ist. + // Im AddMode wird bei Tastaturselektion der neue Cursor erst + // beim Bewegen des Cursors nach Selektionsende erzeugt. + if( pWrtShell->IsAddMode() && pWrtShell->SwCrsrShell::HasSelection() ) + pWrtShell->CreateCrsr(); + + SwDoc *const pTmpDoc = lcl_GetDoc(*pClpDocFac); + + pTmpDoc->SetRefForDocShell( boost::addressof(aDocShellRef) ); + pTmpDoc->LockExpFlds(); // nie die Felder updaten - Text so belassen + pWrtShell->Copy( pTmpDoc ); + + { + IDocumentMarkAccess* const pMarkAccess = pTmpDoc->getIDocumentMarkAccess(); + ::std::vector< ::sw::mark::IMark* > vDdeMarks; + // find all DDE-Bookmarks + for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin(); + ppMark != pMarkAccess->getMarksEnd(); + ppMark++) + { + if(IDocumentMarkAccess::DDE_BOOKMARK == IDocumentMarkAccess::GetType(**ppMark)) + vDdeMarks.push_back(ppMark->get()); + } + // remove all DDE-Bookmarks, they are invalid inside the clipdoc! + for(::std::vector< ::sw::mark::IMark* >::iterator ppMark = vDdeMarks.begin(); + ppMark != vDdeMarks.end(); + ppMark++) + pMarkAccess->deleteMark(*ppMark); + } + + // es wurde in der CORE eine neu angelegt (OLE-Objekte kopiert!) + if( aDocShellRef.Is() ) + SwTransferable::InitOle( aDocShellRef, *pTmpDoc ); + pTmpDoc->SetRefForDocShell( 0 ); + + if( pWrtShell->IsObjSelected() ) + eBufferType = TRNSFR_DRAWING; + else + { + eBufferType = TRNSFR_DOCUMENT; + if (pWrtShell->IntelligentCut(nSelection, FALSE) != SwWrtShell::NO_WORD) + eBufferType = (TransferBufferType)(TRNSFR_DOCUMENT_WORD | eBufferType); + } + + int bDDELink = pWrtShell->IsSelection(); + if( nSelection & nsSelectionType::SEL_TBL_CELLS ) + { + eBufferType = (TransferBufferType)(TRNSFR_TABELLE | eBufferType); + bDDELink = pWrtShell->HasWholeTabSelection(); + } + + //Wenn's einer braucht OLE'n wir ihm was. + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + + //RTF vor das Metafile von OLE stellen, weil mit weniger verlusten + //behaftet. + if( !pWrtShell->IsObjSelected() ) + { + AddFormat( FORMAT_RTF ); + AddFormat( SOT_FORMATSTR_ID_HTML ); + } + if( pWrtShell->IsSelection() ) + AddFormat( FORMAT_STRING ); + + if( nSelection & ( nsSelectionType::SEL_DRW | nsSelectionType::SEL_DRW_FORM )) + { + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + if ( nSelection & nsSelectionType::SEL_DRW ) + { + AddFormat( FORMAT_GDIMETAFILE ); + AddFormat( FORMAT_BITMAP ); + } + eBufferType = (TransferBufferType)( TRNSFR_GRAPHIC | eBufferType ); + + pClpGraphic = new Graphic; + if( !pWrtShell->GetDrawObjGraphic( FORMAT_GDIMETAFILE, *pClpGraphic )) + pOrigGrf = pClpGraphic; + pClpBitmap = new Graphic; + if( !pWrtShell->GetDrawObjGraphic( FORMAT_BITMAP, *pClpBitmap )) + pOrigGrf = pClpBitmap; + + // ist es ein URL-Button ? + String sURL, sDesc; + if( pWrtShell->GetURLFromButton( sURL, sDesc ) ) + { + AddFormat( FORMAT_STRING ); + AddFormat( SOT_FORMATSTR_ID_SOLK ); + AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); + AddFormat( SOT_FORMATSTR_ID_FILECONTENT ); + AddFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); + eBufferType = (TransferBufferType)( TRNSFR_INETFLD | eBufferType ); + nRet = sal_True; + } + } + + // beim Cut hat DDE-Link keinen Sinn!! + SwDocShell* pDShell; + if( !bIsCut && bDDELink && + 0 != ( pDShell = pWrtShell->GetDoc()->GetDocShell()) && + SFX_CREATE_MODE_STANDARD == pDShell->GetCreateMode() ) + { + AddFormat( SOT_FORMATSTR_ID_LINK ); + refDdeLink = new SwTrnsfrDdeLink( *this, *pWrtShell ); + } + + //ObjectDescriptor wurde bereits aus der alten DocShell gefuellt. + //Jetzt noch anpassen. Dadurch kann im GetData die erste Anfrage + //auch noch mit delayed rendering beantwortet werden. + aObjDesc.mbCanLink = FALSE; + Size aSz( OLESIZE ); + aObjDesc.maSize = OutputDevice::LogicToLogic( aSz, MAP_TWIP, MAP_100TH_MM ); + + PrepareOLE( aObjDesc ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + + delete pWait; + } + else + nRet = 0; + + if( pWrtShell->IsFrmSelected() ) + { + SfxItemSet aSet( pWrtShell->GetAttrPool(), RES_URL, RES_URL ); + pWrtShell->GetFlyFrmAttr( aSet ); + const SwFmtURL& rURL = (SwFmtURL&)aSet.Get( RES_URL ); + if( rURL.GetMap() ) + { + pImageMap = new ImageMap( *rURL.GetMap() ); + AddFormat( SOT_FORMATSTR_ID_SVIM ); + } + else if( rURL.GetURL().Len() ) + { + pTargetURL = new INetImage( sGrfNm, rURL.GetURL(), + rURL.GetTargetFrameName(), + aEmptyStr, Size() ); + AddFormat( SOT_FORMATSTR_ID_INET_IMAGE ); + } + } + + return nRet; +} + +int SwTransferable::Copy( BOOL bIsCut ) +{ + int nRet = PrepareForCopy( bIsCut ); + if ( nRet ) + { + SW_MOD()->pClipboard = this; + CopyToClipboard( &pWrtShell->GetView().GetEditWin() ); + } + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::CalculateAndCopy() +{ + if(!pWrtShell) + return 0; + SwWait aWait( *pWrtShell->GetView().GetDocShell(), TRUE ); + + String aStr( pWrtShell->Calculate() ); + + pClpDocFac = new SwDocFac; + SwDoc *const pDoc = lcl_GetDoc(*pClpDocFac); + pWrtShell->Copy(pDoc, & aStr); + eBufferType = TRNSFR_DOCUMENT; + AddFormat( FORMAT_STRING ); + + SW_MOD()->pClipboard = this; + CopyToClipboard( &pWrtShell->GetView().GetEditWin() ); + + return 1; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::CopyGlossary( SwTextBlocks& rGlossary, + const String& rStr ) +{ + if(!pWrtShell) + return 0; + SwWait aWait( *pWrtShell->GetView().GetDocShell(), TRUE ); + + pClpDocFac = new SwDocFac; + SwDoc *const pCDoc = lcl_GetDoc(*pClpDocFac); + + SwNodes& rNds = pCDoc->GetNodes(); + SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() ); + SwCntntNode* pCNd = rNds.GoNext( &aNodeIdx ); // gehe zum 1. ContentNode + SwPaM aPam( *pCNd ); + + pCDoc->SetRefForDocShell( boost::addressof(aDocShellRef) ); + pCDoc->LockExpFlds(); // nie die Felder updaten - Text so belassen + + pCDoc->InsertGlossary( rGlossary, rStr, aPam, 0 ); + + // es wurde in der CORE eine neu angelegt (OLE-Objekte kopiert!) + if( aDocShellRef.Is() ) + SwTransferable::InitOle( aDocShellRef, *pCDoc ); + pCDoc->SetRefForDocShell( 0 ); + + eBufferType = TRNSFR_DOCUMENT; + + //Wenn's einer braucht OLE'n wir ihm was. + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + AddFormat( FORMAT_RTF ); + AddFormat( SOT_FORMATSTR_ID_HTML ); + AddFormat( FORMAT_STRING ); + + //ObjectDescriptor wurde bereits aus der alten DocShell gefuellt. + //Jetzt noch anpassen. Dadurch kann im GetData die erste Anfrage + //auch noch mit delayed rendering beantwortet werden. + aObjDesc.mbCanLink = FALSE; + Size aSz( OLESIZE ); + aObjDesc.maSize = OutputDevice::LogicToLogic( aSz, MAP_TWIP, MAP_100TH_MM ); + + PrepareOLE( aObjDesc ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + + SW_MOD()->pClipboard = this; + CopyToClipboard( &pWrtShell->GetView().GetEditWin() ); + + return 1; +} + +static inline uno::Reference < XTransferable > * lcl_getTransferPointer ( uno::Reference < XTransferable > &xRef ) +{ + return &xRef; +} +// ----------------------------------------------------------------------- + +BOOL SwTransferable::IsPaste( const SwWrtShell& rSh, + const TransferableDataHelper& rData ) +{ + // Check the common case first: We can always paste our own data! + // #106503#: If _only_ the internal format can be pasted, this check will + // yield 'true', while the one below would give a (wrong) result 'false'. + bool bIsPaste = ( SW_MOD()->pClipboard != NULL ); + + // if it's not our own data, we need to have a closer look: + if( ! bIsPaste ) + { + // determine the proper paste action, and return true if we find one + uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() ); + uno::Reference<XUnoTunnel> xTunnel( xTransferable, UNO_QUERY ); + if ( xTunnel.is() ) + { + sal_Int64 nHandle = xTunnel->getSomething( getUnoTunnelId() ); + if ( nHandle ) + return TRUE; + } + + USHORT nDestination = SwTransferable::GetSotDestination( rSh ); + USHORT nSourceOptions = + (( EXCHG_DEST_DOC_TEXTFRAME == nDestination || + EXCHG_DEST_SWDOC_FREE_AREA == nDestination || + EXCHG_DEST_DOC_TEXTFRAME_WEB == nDestination || + EXCHG_DEST_SWDOC_FREE_AREA_WEB == nDestination ) + ? EXCHG_IN_ACTION_COPY + : EXCHG_IN_ACTION_MOVE); + + ULONG nFormat; // output param for GetExchangeAction + USHORT nEventAction; // output param for GetExchangeAction + USHORT nAction = SotExchange::GetExchangeAction( + rData.GetDataFlavorExVector(), + nDestination, + nSourceOptions, /* ?? */ + EXCHG_IN_ACTION_DEFAULT, /* ?? */ + nFormat, nEventAction, 0, + lcl_getTransferPointer ( xTransferable ) ); + + // if we find a suitable action, we can paste! + bIsPaste = (EXCHG_INOUT_ACTION_NONE != nAction); + } + + return bIsPaste; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::Paste( SwWrtShell& rSh, TransferableDataHelper& rData ) +{ + USHORT nEventAction, nAction=0, + nDestination = SwTransferable::GetSotDestination( rSh ); + ULONG nFormat = 0; + + if( SW_MOD()->pClipboard ) + nAction = EXCHG_OUT_ACTION_INSERT_PRIVATE; + else + { + uno::Reference<XUnoTunnel> xTunnel( rData.GetTransferable(), UNO_QUERY ); + if ( xTunnel.is() ) + { + sal_Int64 nHandle = xTunnel->getSomething( getUnoTunnelId() ); + if ( nHandle ) + nAction = EXCHG_OUT_ACTION_INSERT_PRIVATE; + } + + if ( !nAction ) + { + USHORT nSourceOptions = + (( EXCHG_DEST_DOC_TEXTFRAME == nDestination || + EXCHG_DEST_SWDOC_FREE_AREA == nDestination || + EXCHG_DEST_DOC_TEXTFRAME_WEB == nDestination || + EXCHG_DEST_SWDOC_FREE_AREA_WEB == nDestination ) + ? EXCHG_IN_ACTION_COPY + : EXCHG_IN_ACTION_MOVE); + uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() ); + nAction = SotExchange::GetExchangeAction( + rData.GetDataFlavorExVector(), + nDestination, + nSourceOptions, /* ?? */ + EXCHG_IN_ACTION_DEFAULT, /* ?? */ + nFormat, nEventAction, 0, + lcl_getTransferPointer ( xTransferable ) ); + } + } + + // special case for tables from draw application + if( EXCHG_OUT_ACTION_INSERT_DRAWOBJ == (nAction & EXCHG_ACTION_MASK) ) + { + if( rData.HasFormat( SOT_FORMAT_RTF ) ) + { + nAction = EXCHG_OUT_ACTION_INSERT_STRING | (nAction & !EXCHG_ACTION_MASK); + nFormat = SOT_FORMAT_RTF; + } + } + + return EXCHG_INOUT_ACTION_NONE != nAction && + SwTransferable::PasteData( rData, rSh, nAction, nFormat, + nDestination, FALSE, FALSE ); +} + +// ----------------------------------------------------------------------- + +int SwTransferable::PasteData( TransferableDataHelper& rData, + SwWrtShell& rSh, USHORT nAction, ULONG nFormat, + USHORT nDestination, BOOL bIsPasteFmt, + sal_Bool bIsDefault, + const Point* pPt, sal_Int8 nDropAction, + BOOL bPasteSelection ) +{ + SwWait aWait( *rSh.GetView(). + GetDocShell(), FALSE ); + SwTrnsfrActionAndUndo* pAction = 0; + SwModule* pMod = SW_MOD(); + + int nRet = 0; + bool bCallAutoCaption = false; + + if( pPt ) + { + // external Drop + if( bPasteSelection ? !pMod->pXSelection : !pMod->pDragDrop ) + { + switch( nDestination ) + { + case EXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP: + case EXCHG_DEST_DOC_LNKD_GRAPHOBJ: + case EXCHG_DEST_DOC_GRAPH_W_IMAP: + case EXCHG_DEST_DOC_GRAPHOBJ: + case EXCHG_DEST_DOC_OLEOBJ: + case EXCHG_DEST_DOC_DRAWOBJ: + case EXCHG_DEST_DOC_URLBUTTON: + case EXCHG_DEST_DOC_GROUPOBJ: + // Rahmen/Objecte selektieren + SwTransferable::SetSelInShell( rSh, TRUE, pPt ); + break; + + // case EXCHG_DEST_DOC_TEXTFRAME: + // case EXCHG_DEST_SWDOC_FREE_AREA: + // case EXCHG_DEST_DOC_URLFIELD: + default: + SwTransferable::SetSelInShell( rSh, FALSE, pPt ); + break; + } + } + } + else if( ( !pMod->pClipboard || bIsPasteFmt ) && + !rSh.IsTableMode() && rSh.HasSelection() ) + { + // dann die Selektionen loeschen + + //Selektierten Inhalt loeschen, + // - nicht bei Tabellen-Selektion + // - nicht bei ReRead einer Grafik/DDEDaten + // - nicht bei D&D, fuer die richtige Selektion wurde im + // Drop-Handler gesorgt + BOOL bDelSel = FALSE; + switch( nDestination ) + { + case EXCHG_DEST_DOC_TEXTFRAME: + case EXCHG_DEST_SWDOC_FREE_AREA: + case EXCHG_DEST_DOC_TEXTFRAME_WEB: + case EXCHG_DEST_SWDOC_FREE_AREA_WEB: + bDelSel = TRUE; + break; + } + + if( bDelSel ) + // --> FME 2004-10-19 #i34830# + pAction = new SwTrnsfrActionAndUndo( &rSh, UNDO_PASTE_CLIPBOARD, NULL, + TRUE ); + // <-- + } + + SwTransferable *pTrans=0, *pTunneledTrans=0; + uno::Reference<XUnoTunnel> xTunnel( rData.GetTransferable(), UNO_QUERY ); + if ( xTunnel.is() ) + { + sal_Int64 nHandle = xTunnel->getSomething( getUnoTunnelId() ); + if ( nHandle ) + pTunneledTrans = (SwTransferable*) (sal_IntPtr) nHandle; + } + + if( pPt && ( bPasteSelection ? 0 != ( pTrans = pMod->pXSelection ) + : 0 != ( pTrans = pMod->pDragDrop) )) + { + // then internal Drag & Drop or XSelection + nRet = pTrans->PrivateDrop( rSh, *pPt, DND_ACTION_MOVE == nDropAction, + bPasteSelection ); + } + else if( !pPt && ( pTunneledTrans || 0 != ( pTunneledTrans = pMod->pClipboard ) ) && + EXCHG_OUT_ACTION_INSERT_PRIVATE == nAction ) + { + // then internal paste + nRet = pTunneledTrans->PrivatePaste( rSh ); + } + else if( EXCHG_INOUT_ACTION_NONE != nAction ) + { + if( !pAction ) + { + // #111827# + pAction = new SwTrnsfrActionAndUndo( &rSh, UNDO_PASTE_CLIPBOARD); + } + + // im Drag&Drop duerfen keine MessageBoxen angezeigt werden + BOOL bMsg = 0 == pPt; + BYTE nActionFlags = static_cast< BYTE >(( nAction >> 8 ) & 0xFF); + + USHORT nClearedAction = ( nAction & EXCHG_ACTION_MASK ); + // Selektionen loeschen + + switch( nClearedAction ) + { + case EXCHG_OUT_ACTION_INSERT_PRIVATE: +ASSERT( pPt, "EXCHG_OUT_ACTION_INSERT_PRIVATE: was soll hier passieren?" ); + break; + + case EXCHG_OUT_ACTION_MOVE_PRIVATE: +ASSERT( pPt, "EXCHG_OUT_ACTION_MOVE_PRIVATE: was soll hier passieren?" ); + break; + + + case EXCHG_IN_ACTION_MOVE: + case EXCHG_IN_ACTION_COPY: + case EXCHG_IN_ACTION_LINK: + case EXCHG_OUT_ACTION_INSERT_HTML: + case EXCHG_OUT_ACTION_INSERT_STRING: + case EXCHG_OUT_ACTION_INSERT_IMAGEMAP: + case EXCHG_OUT_ACTION_REPLACE_IMAGEMAP: + + // dann muss ueber das Format gegangen werden + switch( nFormat ) + { + case SOT_FORMATSTR_ID_DRAWING: + nRet = SwTransferable::_PasteSdrFormat( rData, rSh, + SW_PASTESDR_INSERT, pPt, + nActionFlags ); + break; + + case SOT_FORMATSTR_ID_HTML: + case SOT_FORMATSTR_ID_HTML_SIMPLE: + case SOT_FORMATSTR_ID_HTML_NO_COMMENT: + case SOT_FORMAT_RTF: + case SOT_FORMAT_STRING: + nRet = SwTransferable::_PasteFileContent( rData, rSh, + nFormat, bMsg ); + break; + + case SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK: + { + INetBookmark aBkmk; + if( rData.GetINetBookmark( nFormat, aBkmk ) ) + { + SwFmtINetFmt aFmt( aBkmk.GetURL(), aEmptyStr ); + rSh.InsertURL( aFmt, aBkmk.GetDescription() ); + nRet = 1; + } + } + break; + + case SOT_FORMATSTR_ID_SD_OLE: + nRet = SwTransferable::_PasteOLE( rData, rSh, nFormat, + nActionFlags, bMsg ); + break; + + case SOT_FORMATSTR_ID_SVIM: + nRet = SwTransferable::_PasteImageMap( rData, rSh ); + break; + + case SOT_FORMATSTR_ID_SVXB: + case SOT_FORMAT_BITMAP: + case SOT_FORMAT_GDIMETAFILE: + nRet = SwTransferable::_PasteGrf( rData, rSh, nFormat, + SW_PASTESDR_INSERT,pPt, + nActionFlags, bMsg ); + break; + + case SOT_FORMATSTR_ID_XFORMS: + case SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE: + case SOT_FORMATSTR_ID_SBA_DATAEXCHANGE: + case SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE: + nRet = SwTransferable::_PasteDBData( rData, rSh, nFormat, + EXCHG_IN_ACTION_LINK == nClearedAction, + pPt, bMsg ); + break; + + case SOT_FORMAT_FILE: + nRet = SwTransferable::_PasteFileName( rData, rSh, nFormat, + ( EXCHG_IN_ACTION_MOVE == nClearedAction + ? SW_PASTESDR_REPLACE + : EXCHG_IN_ACTION_LINK == nClearedAction + ? SW_PASTESDR_SETATTR + : SW_PASTESDR_INSERT), + pPt, nActionFlags, bMsg ); + break; + + case SOT_FORMAT_FILE_LIST: + // dann nur als Grafiken einfuegen + nRet = SwTransferable::_PasteFileList( rData, rSh, + EXCHG_IN_ACTION_LINK == nClearedAction, + pPt, bMsg ); + break; + + case SOT_FORMATSTR_ID_SONLK: + if( pPt ) + { + NaviContentBookmark aBkmk; + if( aBkmk.Paste( rData ) ) + { + if(bIsDefault) + { + switch(aBkmk.GetDefaultDragType()) + { + case REGION_MODE_NONE: nClearedAction = EXCHG_IN_ACTION_COPY; break; + case REGION_MODE_EMBEDDED: nClearedAction = EXCHG_IN_ACTION_MOVE; break; + case REGION_MODE_LINK: nClearedAction = EXCHG_IN_ACTION_LINK; break; + } + } + rSh.NavigatorPaste( aBkmk, nClearedAction ); + nRet = 1; + } + } + break; + + case SOT_FORMATSTR_ID_INET_IMAGE: + case SOT_FORMATSTR_ID_NETSCAPE_IMAGE: + nRet = SwTransferable::_PasteTargetURL( rData, rSh, + SW_PASTESDR_INSERT, + pPt, TRUE ); + break; + + default: + ASSERT( pPt, "unbekanntes Format" ); + } + break; + + case EXCHG_OUT_ACTION_INSERT_FILE: + nRet = SwTransferable::_PasteFileName( rData, rSh, nFormat, + SW_PASTESDR_INSERT, pPt, + nActionFlags, bMsg ); + if( nRet & SWTRANSFER_GRAPHIC_INSERTED ) + bCallAutoCaption = true; + break; + + case EXCHG_OUT_ACTION_INSERT_OLE: + nRet = SwTransferable::_PasteOLE( rData, rSh, nFormat, + nActionFlags,bMsg ); + break; + + case EXCHG_OUT_ACTION_INSERT_DDE: + { + BOOL bReRead = 0 != CNT_HasGrf( rSh.GetCntType() ); + nRet = SwTransferable::_PasteDDE( rData, rSh, bReRead, bMsg ); + } + break; + + case EXCHG_OUT_ACTION_INSERT_HYPERLINK: + { + String sURL, sDesc; + if( SOT_FORMAT_FILE == nFormat ) + { + if( rData.GetString( nFormat, sURL ) && sURL.Len() ) + { + SwTransferable::_CheckForURLOrLNKFile( rData, sURL, &sDesc ); + if( !sDesc.Len() ) + sDesc = sURL; + nRet = 1; + } + } + else + { + INetBookmark aBkmk; + if( rData.GetINetBookmark( nFormat, aBkmk ) ) + { + sURL = aBkmk.GetURL(); + sDesc = aBkmk.GetDescription(); + nRet = 1; + } + } + + if( nRet ) + { + SwFmtINetFmt aFmt( sURL, aEmptyStr ); + rSh.InsertURL( aFmt, sDesc ); + } + } + break; + + case EXCHG_OUT_ACTION_GET_ATTRIBUTES: + switch( nFormat ) + { + case SOT_FORMATSTR_ID_DRAWING: + nRet = SwTransferable::_PasteSdrFormat( rData, rSh, + SW_PASTESDR_SETATTR, pPt, + nActionFlags ); + break; + case SOT_FORMATSTR_ID_SVXB: + case SOT_FORMAT_GDIMETAFILE: + case SOT_FORMAT_BITMAP: + case SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK: + case SOT_FORMAT_FILE: + case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR: + case SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR: + nRet = SwTransferable::_PasteGrf( rData, rSh, nFormat, + SW_PASTESDR_SETATTR, pPt, + nActionFlags, bMsg ); + break; + default: + ASSERT( FALSE, "unbekanntes Format" ); + } + + break; + + case EXCHG_OUT_ACTION_INSERT_DRAWOBJ: + nRet = SwTransferable::_PasteSdrFormat( rData, rSh, + SW_PASTESDR_INSERT, pPt, + nActionFlags ); + break; + case EXCHG_OUT_ACTION_INSERT_SVXB: + case EXCHG_OUT_ACTION_INSERT_GDIMETAFILE: + case EXCHG_OUT_ACTION_INSERT_BITMAP: + case EXCHG_OUT_ACTION_INSERT_GRAPH: + nRet = SwTransferable::_PasteGrf( rData, rSh, nFormat, + SW_PASTESDR_INSERT, pPt, + nActionFlags, bMsg ); + break; + + case EXCHG_OUT_ACTION_REPLACE_DRAWOBJ: + nRet = SwTransferable::_PasteSdrFormat( rData, rSh, + SW_PASTESDR_REPLACE, pPt, + nActionFlags ); + break; + + case EXCHG_OUT_ACTION_REPLACE_SVXB: + case EXCHG_OUT_ACTION_REPLACE_GDIMETAFILE: + case EXCHG_OUT_ACTION_REPLACE_BITMAP: + case EXCHG_OUT_ACTION_REPLACE_GRAPH: + nRet = SwTransferable::_PasteGrf( rData, rSh, nFormat, + SW_PASTESDR_REPLACE,pPt, + nActionFlags, bMsg ); + break; + + case EXCHG_OUT_ACTION_INSERT_INTERACTIVE: + nRet = SwTransferable::_PasteAsHyperlink( rData, rSh, nFormat ); + break; + + default: + ASSERT( FALSE, "unbekannte Action" ); + } + } + + if( !bPasteSelection && rSh.IsFrmSelected() ) + { + rSh.EnterSelFrmMode(); + //force ::SelectShell + rSh.GetView().StopShellTimer(); + } + + if( pAction ) + delete pAction; + if( bCallAutoCaption ) + rSh.GetView().AutoCaption( GRAPHIC_CAP ); + + return nRet; +} + +// ----------------------------------------------------------------------- + +USHORT SwTransferable::GetSotDestination( const SwWrtShell& rSh, + const Point* pPt ) +{ + USHORT nRet = EXCHG_INOUT_ACTION_NONE; + + ObjCntType eOType; + if( pPt ) + { + SdrObject *pObj = 0; + eOType = rSh.GetObjCntType( *pPt, pObj ); + } + else + eOType = rSh.GetObjCntTypeOfSelection(); + + switch( eOType ) + { + case OBJCNT_GRF: + { + BOOL bIMap, bLink; + if( pPt ) + { + bIMap = 0 != rSh.GetFmtFromObj( *pPt )->GetURL().GetMap(); + String aDummy; + rSh.GetGrfAtPos( *pPt, aDummy, bLink ); + } + else + { + bIMap = 0 != rSh.GetFlyFrmFmt()->GetURL().GetMap(); + String aDummy; + rSh.GetGrfNms( &aDummy, 0 ); + bLink = 0 != aDummy.Len(); + } + + if( bLink && bIMap ) + nRet = EXCHG_DEST_DOC_LNKD_GRAPH_W_IMAP; + else if( bLink ) + nRet = EXCHG_DEST_DOC_LNKD_GRAPHOBJ; + else if( bIMap ) + nRet = EXCHG_DEST_DOC_GRAPH_W_IMAP; + else + nRet = EXCHG_DEST_DOC_GRAPHOBJ; + } + break; + + case OBJCNT_FLY: + if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell) ) + nRet = EXCHG_DEST_DOC_TEXTFRAME_WEB; + else + nRet = EXCHG_DEST_DOC_TEXTFRAME; + break; + case OBJCNT_OLE: nRet = EXCHG_DEST_DOC_OLEOBJ; break; + + case OBJCNT_CONTROL: /* no Action avail */ + case OBJCNT_SIMPLE: nRet = EXCHG_DEST_DOC_DRAWOBJ; break; + case OBJCNT_URLBUTTON: nRet = EXCHG_DEST_DOC_URLBUTTON; break; + case OBJCNT_GROUPOBJ: nRet = EXCHG_DEST_DOC_GROUPOBJ; break; + +// was mmchen wir bei Mehrfachselektion??? +// case OBJCNT_DONTCARE: + default: + { +/* +JP 13.07.98: Bug 52637: es wird ein URL-Feld erkannt also werden nur die + Inhalte zugelassen. Das ist aber bestimmt nicht das + gewollte. + SwContentAtPos aCntntAtPos( SwContentAtPos::SW_INETATTR ); + SfxItemSet aSet( (SfxItemPool&)rSh.GetAttrPool(), + RES_TXTATR_INETFMT, RES_TXTATR_INETFMT ); + if( pPt ? ((SwWrtShell&)rSh).GetContentAtPos( *pPt, aCntntAtPos, FALSE ) + : (rSh.GetAttr( aSet ) && aSet.Count()) ) + nRet = EXCHG_DEST_DOC_URLFIELD; + else +*/ + if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell) ) + nRet = EXCHG_DEST_SWDOC_FREE_AREA_WEB; + else + nRet = EXCHG_DEST_SWDOC_FREE_AREA; + } + } + + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteFileContent( TransferableDataHelper& rData, + SwWrtShell& rSh, ULONG nFmt, BOOL bMsg ) +{ + USHORT nResId = MSG_CLPBRD_FORMAT_ERROR; + int nRet = 0; + + MSE40HTMLClipFormatObj aMSE40ClpObj; + + SotStorageStreamRef xStrm; + SvStream* pStream = 0; + SwRead pRead = 0; + rtl::OUString sData; + switch( nFmt ) + { + case SOT_FORMAT_STRING: + { + pRead = ReadAscii; + if( rData.GetString( nFmt, sData ) ) + { + pStream = new SvMemoryStream( (void*)sData.getStr(), + sData.getLength() * sizeof( sal_Unicode ), + STREAM_READ ); +#ifdef OSL_BIGENDIAN + pStream->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); +#else + pStream->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); +#endif + + SwAsciiOptions aAOpt; + aAOpt.SetCharSet( RTL_TEXTENCODING_UCS2 ); + pRead->GetReaderOpt().SetASCIIOpts( aAOpt ); + break; + } + } + // no break - because then test if we get a stream + + default: + if( rData.GetSotStorageStream( nFmt, xStrm ) ) + { + if( ( SOT_FORMATSTR_ID_HTML_SIMPLE == nFmt ) || + ( SOT_FORMATSTR_ID_HTML_NO_COMMENT == nFmt ) ) + { + pStream = aMSE40ClpObj.IsValid( *xStrm ); + pRead = ReadHTML; + pRead->SetReadUTF8( TRUE ); + //pRead->SetBaseURL( aMSE40ClpObj.GetBaseURL() ); + + BOOL bNoComments = + ( nFmt == SOT_FORMATSTR_ID_HTML_NO_COMMENT ); + pRead->SetIgnoreHTMLComments( bNoComments ); + } + else + { + pStream = &xStrm; + if( SOT_FORMAT_RTF == nFmt ) + pRead = SwReaderWriter::GetReader( READER_WRITER_RTF ); + else if( !pRead ) + { + pRead = ReadHTML; + pRead->SetReadUTF8( TRUE ); + } + } + } + break; + } + + if( pStream && pRead ) + { + Link aOldLink( rSh.GetChgLnk() ); + rSh.SetChgLnk( Link() ); + + SwReader aReader( *pStream, aEmptyStr, String(), *rSh.GetCrsr() ); + if( IsError( aReader.Read( *pRead )) ) + nResId = ERR_CLPBRD_READ; + else + nResId = 0, nRet = 1; + + rSh.SetChgLnk( aOldLink ); + if( nRet ) + rSh.CallChgLnk(); + } + else + nResId = MSG_CLPBRD_FORMAT_ERROR; + + // Exist a SvMemoryStream? (data in the OUString and xStrm is empty) + if( pStream && !xStrm.Is() ) + delete pStream; + + if( bMsg && nResId ) + { + InfoBox( 0, SW_RES( nResId )).Execute(); + } + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteOLE( TransferableDataHelper& rData, SwWrtShell& rSh, + ULONG nFmt, BYTE nActionFlags, BOOL bMsg ) +{ + int nRet = 0; + TransferableObjectDescriptor aObjDesc; + uno::Reference < io::XInputStream > xStrm; + uno::Reference < embed::XStorage > xStore; + Reader* pRead = 0; + + // Get the preferred format + SotFormatStringId nId; + if( rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ ) ) + nId = SOT_FORMATSTR_ID_EMBEDDED_OBJ; + else if( rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) && + rData.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )) + nId = SOT_FORMATSTR_ID_EMBED_SOURCE; + else + nId = 0; + + if( nId && rData.GetInputStream( nId, xStrm ) && xStrm.is() ) + { + // if there is an embedded object, first try if it's a writer object + // this will be inserted into the document by using a Reader + try + { + xStore = comphelper::OStorageHelper::GetStorageFromInputStream( xStrm ); + switch( SotStorage::GetFormatID( xStore ) ) + { + case SOT_FORMATSTR_ID_STARWRITER_60: + case SOT_FORMATSTR_ID_STARWRITERWEB_60: + case SOT_FORMATSTR_ID_STARWRITERGLOB_60: + case SOT_FORMATSTR_ID_STARWRITER_8: + case SOT_FORMATSTR_ID_STARWRITERWEB_8: + case SOT_FORMATSTR_ID_STARWRITERGLOB_8: + pRead = ReadXML; + break; + default: + try + { + uno::Reference < lang::XComponent > xComp( xStore, uno::UNO_QUERY ); + xComp->dispose(); + xStore = 0; + } + catch ( uno::Exception& ) + { + } + + break; + } + } + catch ( uno::Exception& ) + { + // it wasn't a storage, but maybe it's a useful stream + } + + nFmt = nId; + } + + if( pRead ) + { + SwPaM &rPAM = *rSh.GetCrsr(); + SwReader aReader( xStore, aEmptyStr, rPAM ); + if( !IsError( aReader.Read( *pRead )) ) + nRet = 1; + else if( bMsg ) + InfoBox( 0, SW_RES(ERR_CLPBRD_READ) ).Execute(); + } + else + { + // temporary storage until the object is inserted + uno::Reference< embed::XStorage > xTmpStor; + uno::Reference < embed::XEmbeddedObject > xObj; + ::rtl::OUString aName; + comphelper::EmbeddedObjectContainer aCnt; + + if ( xStrm.is() ) + { + if ( !rData.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) ) + { + DBG_ASSERT( !xStrm.is(), "An object without descriptor in clipboard!"); + } + } + else + { + if( rData.HasFormat( nFmt = SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE ) && rData.GetTransferableObjectDescriptor( nFmt, aObjDesc ) ) + { + if ( !rData.GetInputStream( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, xStrm ) ) + rData.GetInputStream( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, xStrm ); + + if ( !xStrm.is() ) + { + // This is MSOLE object that should be created by direct using of system clipboard + try + { + xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage(); + uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator( + ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.MSOLEObjectSystemCreator")) ), + uno::UNO_QUERY_THROW ); + + embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard( + xTmpStor, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DummyName" ) ), + uno::Sequence< beans::PropertyValue >() ); + + // TODO/LATER: in future InsertedObjectInfo will be used to get container related information + // for example whether the object should be an iconified one + xObj = aInfo.Object; + } + catch( uno::Exception& ) + {} + } + } + } + + if ( xStrm.is() && !xObj.is() ) + xObj = aCnt.InsertEmbeddedObject( xStrm, aName ); + + if( xObj.is() ) + { + svt::EmbeddedObjectRef xObjRef( xObj, aObjDesc.mnViewAspect ); + + // try to get the replacement image from the clipboard + Graphic aGraphic; + ULONG nGrFormat = 0; + +// (wg. Selection Manager bei Trustet Solaris) +#ifndef SOLARIS +/* + if( rData.GetGraphic( SOT_FORMATSTR_ID_SVXB, aGraphic ) ) + nGrFormat = SOT_FORMATSTR_ID_SVXB; + else if( rData.GetGraphic( FORMAT_GDIMETAFILE, aGraphic ) ) + nGrFormat = SOT_FORMAT_GDIMETAFILE; + else if( rData.GetGraphic( FORMAT_BITMAP, aGraphic ) ) + nGrFormat = SOT_FORMAT_BITMAP; +*/ +#endif + + // insert replacement image ( if there is one ) into the object helper + if ( nGrFormat ) + { + datatransfer::DataFlavor aDataFlavor; + SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor ); + xObjRef.SetGraphic( aGraphic, aDataFlavor.MimeType ); + } + else if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON ) + { + // it is important to have an icon, let an empty graphic be used + // if no other graphic is provided + // TODO/LATER: in future a default bitmap could be used + ::rtl::OUString aMimeType; + MapMode aMapMode( MAP_100TH_MM ); + aGraphic.SetPrefSize( Size( 2500, 2500 ) ); + aGraphic.SetPrefMapMode( aMapMode ); + xObjRef.SetGraphic( aGraphic, aMimeType ); + } + + //Size einstellen. Ist ein Hack wg. Auslieferung, die Size sollte + //an das InsertOle uebergeben werden!!!!!!!!!! + Size aSize; + if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON ) + { + if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() ) + aSize = aObjDesc.maSize; + else + { + MapMode aMapMode( MAP_100TH_MM ); + aSize = xObjRef.GetSize( &aMapMode ); + } + } + else if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() ) + { + aSize = Size( aObjDesc.maSize ); //immer 100TH_MM + MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) ); + aSize = OutputDevice::LogicToLogic( aSize, MAP_100TH_MM, aUnit ); + awt::Size aSz; + try + { + aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect ); + } + catch( embed::NoVisualAreaSizeException& ) + { + // in this case the provided size is used + } + + if ( aSz.Width != aSize.Width() || aSz.Height != aSize.Height() ) + { + aSz.Width = aSize.Width(); + aSz.Height = aSize.Height(); + xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz ); + } + } + else + { + // the descriptor contains the wrong object size + // the following call will let the MSOLE objects cache the size if it is possible + // it should be done while the object is running + try + { + xObj->getVisualAreaSize( aObjDesc.mnViewAspect ); + } + catch( uno::Exception& ) + { + } + } + //Ende mit Hack! + + rSh.InsertOleObject( xObjRef ); + nRet = 1; + + if( nRet && ( nActionFlags & + ( EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL >> 8) )) + SwTransferable::_PasteTargetURL( rData, rSh, 0, 0, FALSE ); + + // let the object be unloaded if possible + SwOLEObj::UnloadObject( xObj, rSh.GetDoc(), embed::Aspects::MSOLE_CONTENT ); + } + } + return nRet; +} + +// ----------------------------------------------------------------------- + + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteTargetURL( TransferableDataHelper& rData, + SwWrtShell& rSh, USHORT nAction, + const Point* pPt, BOOL bInsertGRF ) +{ + int nRet = 0; + INetImage aINetImg; + if( ( rData.HasFormat( SOT_FORMATSTR_ID_INET_IMAGE ) && + rData.GetINetImage( SOT_FORMATSTR_ID_INET_IMAGE, aINetImg )) || + ( rData.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_IMAGE ) && + rData.GetINetImage( SOT_FORMATSTR_ID_NETSCAPE_IMAGE, aINetImg )) ) + { + if( aINetImg.GetImageURL().Len() && bInsertGRF ) + { + String sURL( aINetImg.GetImageURL() ); + SwTransferable::_CheckForURLOrLNKFile( rData, sURL ); + + //!!! auf FileSystem abpruefen - nur dann ist es sinnvoll die + // Grafiken zu testen !!!! + Graphic aGrf; + GraphicFilter *pFlt = GraphicFilter::GetGraphicFilter(); + nRet = GRFILTER_OK == GraphicFilter::LoadGraphic( sURL, aEmptyStr, aGrf, pFlt ); + if( nRet ) + { + switch( nAction ) + { + case SW_PASTESDR_INSERT: + SwTransferable::SetSelInShell( rSh, FALSE, pPt ); + rSh.Insert( sURL, aEmptyStr, aGrf ); + break; + + case SW_PASTESDR_REPLACE: + if( rSh.IsObjSelected() ) + { + rSh.ReplaceSdrObj( sURL, aEmptyStr, &aGrf ); + Point aPt( pPt ? *pPt : rSh.GetCrsrDocPos() ); + SwTransferable::SetSelInShell( rSh, TRUE, &aPt ); + } + else + rSh.ReRead( sURL, aEmptyStr, &aGrf ); + break; + + case SW_PASTESDR_SETATTR: + if( rSh.IsObjSelected() ) + rSh.Paste( aGrf ); + else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() ) + rSh.ReRead( sURL, aEmptyStr, &aGrf ); + else + { + SwTransferable::SetSelInShell( rSh, FALSE, pPt ); + rSh.Insert( sURL, aEmptyStr, aGrf ); + } + break; + default: + nRet = 0; + } + } + } + else + nRet = 1; + } + + if( nRet ) + { + SfxItemSet aSet( rSh.GetAttrPool(), RES_URL, RES_URL ); + rSh.GetFlyFrmAttr( aSet ); + SwFmtURL aURL( (SwFmtURL&)aSet.Get( RES_URL ) ); + + if( aURL.GetURL() != aINetImg.GetTargetURL() || + aURL.GetTargetFrameName() != aINetImg.GetTargetFrame() ) + { + aURL.SetURL( aINetImg.GetTargetURL(), FALSE ); + aURL.SetTargetFrameName( aINetImg.GetTargetFrame() ); + aSet.Put( aURL ); + rSh.SetFlyFrmAttr( aSet ); + } + } + return nRet; +} + + +// ----------------------------------------------------------------------- + +void SwTransferable::SetSelInShell( SwWrtShell& rSh, BOOL bSelectFrm, + const Point* pPt ) +{ + if( bSelectFrm ) + { + // Rahmen/Objecte selektieren + if( pPt && !rSh.GetView().GetViewFrame()->GetDispatcher()->IsLocked() ) + { + rSh.GetView().NoRotate(); + if( rSh.SelectObj( *pPt )) + { + rSh.HideCrsr(); + rSh.EnterSelFrmMode( pPt ); + bFrmDrag = TRUE; + } + } + } + else + { + if( rSh.IsFrmSelected() || rSh.IsObjSelected() ) + { + rSh.UnSelectFrm(); + rSh.LeaveSelFrmMode(); + rSh.GetView().GetEditWin().StopInsFrm(); + bFrmDrag = FALSE; + } + else if( rSh.GetView().GetDrawFuncPtr() ) + rSh.GetView().GetEditWin().StopInsFrm(); + + rSh.EnterStdMode(); + if( pPt ) + rSh.SwCrsrShell::SetCrsr( *pPt, TRUE ); + } +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteDDE( TransferableDataHelper& rData, + SwWrtShell& rWrtShell, BOOL bReReadGrf, + BOOL bMsg ) +{ + // Daten aus dem Clipboardformat + String aApp, aTopic, aItem; + + { + SotStorageStreamRef xStrm; + if( !rData.GetSotStorageStream( SOT_FORMATSTR_ID_LINK, xStrm )) + { + ASSERT( !&rWrtShell, "DDE Data not found." ); + return 0; + } //sinnvollen Fehler melden!! + + rtl_TextEncoding eEncoding = DDE_TXT_ENCODING; + xStrm->ReadCString( aApp, eEncoding ); + xStrm->ReadCString( aTopic, eEncoding ); + xStrm->ReadCString( aItem, eEncoding ); + } + + String aCmd; + sfx2::MakeLnkName( aCmd, &aApp, aTopic, aItem ); + + // wollen wir jetzt eine Grafik einlesen ? + ULONG nFormat; + if( !rData.HasFormat( FORMAT_RTF ) && + !rData.HasFormat( SOT_FORMATSTR_ID_HTML ) && + !rData.HasFormat( FORMAT_STRING ) && + (rData.HasFormat( nFormat = FORMAT_GDIMETAFILE ) || + rData.HasFormat( nFormat = FORMAT_BITMAP )) ) + { + Graphic aGrf; + int nRet = rData.GetGraphic( nFormat, aGrf ); + if( nRet ) + { + String sLnkTyp( String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "DDE" ))); + if ( bReReadGrf ) + rWrtShell.ReRead( aCmd, sLnkTyp, &aGrf ); + else + rWrtShell.Insert( aCmd, sLnkTyp, aGrf ); + } + return nRet; + } + + SwFieldType* pTyp = 0; + USHORT i = 1,j; + String aName; + BOOL bAlreadyThere = FALSE, bDoublePaste = FALSE; + USHORT nSize = rWrtShell.GetFldTypeCount(); + const ::utl::TransliterationWrapper& rColl = ::GetAppCmpStrIgnore(); + + do { + aName = aApp; + aName += String::CreateFromInt32( i ); + for( j = INIT_FLDTYPES; j < nSize; j++ ) + { + pTyp = rWrtShell.GetFldType( j ); + if( RES_DDEFLD == pTyp->Which() ) + { + String sTmp( ((SwDDEFieldType*)pTyp)->GetCmd() ); + if( rColl.isEqual( sTmp, aCmd ) && + sfx2::LINKUPDATE_ALWAYS == ((SwDDEFieldType*)pTyp)->GetType() ) + { + aName = pTyp->GetName(); + bDoublePaste = TRUE; + break; + } + else if( rColl.isEqual( aName, pTyp->GetName() ) ) + break; + } + } + if( j == nSize ) + bAlreadyThere = FALSE; + else + { + bAlreadyThere = TRUE; + i++; + } + } + while( bAlreadyThere && !bDoublePaste ); + + if( !bDoublePaste ) + { + SwDDEFieldType aType( aName, aCmd, sfx2::LINKUPDATE_ALWAYS ); + pTyp = rWrtShell.InsertFldType( aType ); + } + + + SwDDEFieldType* pDDETyp = (SwDDEFieldType*)pTyp; + + String aExpand; + if( rData.GetString( FORMAT_STRING, aExpand )) + { + do { // middle checked loop + + // Wenn die Daten von einer Tabellenkalkulation kommen + // fuegen wir eine DDE-Tabelle ein + if( ( rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) || + rData.HasFormat( SOT_FORMATSTR_ID_SYLK_BIGCAPS ) ) && + aExpand.Len() && + ( 1 < aExpand.GetTokenCount( '\n' ) || + aExpand.GetTokenCount( '\t' )) ) + { + String sTmp( aExpand ); + xub_StrLen nRows = sTmp.GetTokenCount( '\n' ); + if( nRows ) + --nRows; + sTmp = sTmp.GetToken( 0, '\n' ); + xub_StrLen nCols = sTmp.GetTokenCount( '\t' ); + + // mindestens eine Spalte & Zeile muss vorhanden sein + if( !nRows || !nCols ) + { + if( bMsg ) + InfoBox(0, SW_RESSTR(STR_NO_TABLE)).Execute(); + pDDETyp = 0; + break; + } + + rWrtShell.InsertDDETable( + SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ), // TODO MULTIHEADER + pDDETyp, nRows, nCols ); + } + else if( 1 < aExpand.GetTokenCount( '\n' ) ) + { + // mehrere Absaetze -> eine geschuetzte Section einfuegen + if( rWrtShell.HasSelection() ) + rWrtShell.DelRight(); + + SwSectionData aSect( DDE_LINK_SECTION, aName ); + aSect.SetLinkFileName( aCmd ); + aSect.SetProtectFlag(true); + rWrtShell.InsertSection( aSect ); + + pDDETyp = 0; // FeldTypen wieder entfernen + } + else + { + // Einfuegen + SwDDEField aSwDDEField( pDDETyp ); + rWrtShell.Insert( aSwDDEField ); + } + + } while( FALSE ); + } + else + pDDETyp = 0; // FeldTypen wieder entfernen + + if( !pDDETyp && !bDoublePaste ) + { + // FeldTyp wieder entfernen - Fehler aufgetreten! + for( j = nSize; j >= INIT_FLDTYPES; --j ) + if( pTyp == rWrtShell.GetFldType( j ) ) + { + rWrtShell.RemoveFldType( j ); + break; + } + } + + return 1; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteSdrFormat( TransferableDataHelper& rData, + SwWrtShell& rSh, USHORT nAction, + const Point* pPt, BYTE nActionFlags ) +{ + int nRet = 0; + SotStorageStreamRef xStrm; + if( rData.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStrm )) + { + xStrm->SetVersion( SOFFICE_FILEFORMAT_50 ); + rSh.Paste( *xStrm, nAction, pPt ); + nRet = 1; + + if( nRet && ( nActionFlags & + ( EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL >> 8) )) + SwTransferable::_PasteTargetURL( rData, rSh, 0, 0, FALSE ); + } + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteGrf( TransferableDataHelper& rData, SwWrtShell& rSh, + ULONG nFmt, USHORT nAction, const Point* pPt, + BYTE nActionFlags, BOOL /*bMsg*/ ) +{ + int nRet = 0; + + Graphic aGrf; + INetBookmark aBkmk; + BOOL bCheckForGrf = FALSE, bCheckForImageMap = FALSE; + + switch( nFmt ) + { + case SOT_FORMAT_BITMAP: + case SOT_FORMAT_GDIMETAFILE: + nRet = rData.GetGraphic( nFmt, aGrf ); + break; + + case SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK: + case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR: + case SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR: + if( 0 != ( nRet = rData.GetINetBookmark( nFmt, aBkmk ) )) + { +/* if( SW_PASTESDR_SETATTR != nAction ) + { + INetURLObject aURL( aBkmk.GetURL() ); + bCheckForGrf = INET_PROT_FILE == aURL.GetProtocol(); + nRet = 0 != bCheckForGrf; + } +*/ + if( SW_PASTESDR_SETATTR == nAction ) + nFmt = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK; + else + bCheckForGrf = TRUE; + } + break; + + case SOT_FORMAT_FILE: + { + String sTxt; + if( 0 != ( nRet = rData.GetString( nFmt, sTxt ) ) ) + { + String sDesc; + SwTransferable::_CheckForURLOrLNKFile( rData, sTxt, &sDesc ); + + aBkmk = INetBookmark( + URIHelper::SmartRel2Abs(INetURLObject(), sTxt, Link(), false ), + sDesc ); + bCheckForGrf = TRUE; + bCheckForImageMap = SW_PASTESDR_REPLACE == nAction; + } + } + break; + + default: + nRet = rData.GetGraphic( nFmt, aGrf ); + break; + } + + if( bCheckForGrf ) + { + //!!! auf FileSystem abpruefen - nur dann ist es sinnvoll die + // Grafiken zu testen !!!! + GraphicFilter *pFlt = GraphicFilter::GetGraphicFilter(); + nRet = GRFILTER_OK == GraphicFilter::LoadGraphic( aBkmk.GetURL(), aEmptyStr, + aGrf, pFlt ); + if( !nRet && SW_PASTESDR_SETATTR == nAction && + SOT_FORMAT_FILE == nFmt && + // Bug 63031 - nur bei Rahmenselektion + rSh.IsFrmSelected() ) + { + // dann als Hyperlink hinter die Grafik setzen + nFmt = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK; + nRet = TRUE; + } + } + + if( nRet ) + { + String sURL; + if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell) ) + sURL = aBkmk.GetURL(); + + switch( nAction ) + { + case SW_PASTESDR_INSERT: + SwTransferable::SetSelInShell( rSh, FALSE, pPt ); + rSh.Insert( sURL, aEmptyStr, aGrf ); + break; + + case SW_PASTESDR_REPLACE: + if( rSh.IsObjSelected() ) + { + rSh.ReplaceSdrObj( sURL, aEmptyStr, &aGrf ); + Point aPt( pPt ? *pPt : rSh.GetCrsrDocPos() ); + SwTransferable::SetSelInShell( rSh, TRUE, &aPt ); + } + else + rSh.ReRead( sURL, aEmptyStr, &aGrf ); + break; + + case SW_PASTESDR_SETATTR: + if( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK == nFmt ) + { + if( rSh.IsFrmSelected() ) + { + SfxItemSet aSet( rSh.GetAttrPool(), RES_URL, RES_URL ); + rSh.GetFlyFrmAttr( aSet ); + SwFmtURL aURL( (SwFmtURL&)aSet.Get( RES_URL ) ); + aURL.SetURL( aBkmk.GetURL(), FALSE ); + aSet.Put( aURL ); + rSh.SetFlyFrmAttr( aSet ); + } + } + else if( rSh.IsObjSelected() ) + rSh.Paste( aGrf ); + else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() ) + rSh.ReRead( sURL, aEmptyStr, &aGrf ); + else + { + SwTransferable::SetSelInShell( rSh, FALSE, pPt ); + rSh.Insert( aBkmk.GetURL(), aEmptyStr, aGrf ); + } + break; + default: + nRet = 0; + } + } + + if( nRet ) + { + + if( nActionFlags & + (( EXCHG_OUT_ACTION_FLAG_INSERT_IMAGEMAP | + EXCHG_OUT_ACTION_FLAG_REPLACE_IMAGEMAP ) >> 8) ) + SwTransferable::_PasteImageMap( rData, rSh ); + + if( nActionFlags & + ( EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL >> 8) ) + SwTransferable::_PasteTargetURL( rData, rSh, 0, 0, FALSE ); + } + else if( bCheckForImageMap ) + { + // oder sollte das File ein ImageMap-File sein? + ImageMap aMap; + SfxMedium aMed( INetURLObject(aBkmk.GetURL()).GetFull(), + STREAM_STD_READ, FALSE ); + SvStream* pStream = aMed.GetInStream(); + if( pStream != NULL && + !pStream->GetError() && + // mba: no BaseURL for clipboard functionality + aMap.Read( *pStream, IMAP_FORMAT_DETECT, String() ) == IMAP_ERR_OK && + aMap.GetIMapObjectCount() ) + { + SfxItemSet aSet( rSh.GetAttrPool(), RES_URL, RES_URL ); + rSh.GetFlyFrmAttr( aSet ); + SwFmtURL aURL( (SwFmtURL&)aSet.Get( RES_URL ) ); + aURL.SetMap( &aMap ); + aSet.Put( aURL ); + rSh.SetFlyFrmAttr( aSet ); + nRet = 1; + } + } + + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteImageMap( TransferableDataHelper& rData, + SwWrtShell& rSh ) +{ + int nRet = 0; + if( rData.HasFormat( SOT_FORMATSTR_ID_SVIM )) + { + SfxItemSet aSet( rSh.GetAttrPool(), RES_URL, RES_URL ); + rSh.GetFlyFrmAttr( aSet ); + SwFmtURL aURL( (SwFmtURL&)aSet.Get( RES_URL ) ); + const ImageMap* pOld = aURL.GetMap(); + + // setzen oder ersetzen ist hier die Frage + ImageMap aImageMap; + if( rData.GetImageMap( SOT_FORMATSTR_ID_SVIM, aImageMap ) && + ( !pOld || aImageMap != *pOld )) + { + aURL.SetMap( &aImageMap ); + aSet.Put( aURL ); + rSh.SetFlyFrmAttr( aSet ); + } + nRet = 1; + } + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteAsHyperlink( TransferableDataHelper& rData, + SwWrtShell& rSh, ULONG nFmt ) +{ + int nRet = 0; + String sFile; + if( rData.GetString( nFmt, sFile ) && sFile.Len() ) + { + String sDesc; + SwTransferable::_CheckForURLOrLNKFile( rData, sFile, &sDesc ); + + //#41801# ersteinmal die URL absolut machen + INetURLObject aURL; + aURL.SetSmartProtocol( INET_PROT_FILE ); + aURL.SetSmartURL( sFile ); + sFile = aURL.GetMainURL( INetURLObject::NO_DECODE ); + + switch( rSh.GetObjCntTypeOfSelection() ) + { + case OBJCNT_FLY: + case OBJCNT_GRF: + case OBJCNT_OLE: + { + SfxItemSet aSet( rSh.GetAttrPool(), RES_URL, RES_URL ); + rSh.GetFlyFrmAttr( aSet ); + SwFmtURL aURL2( (SwFmtURL&)aSet.Get( RES_URL ) ); + aURL2.SetURL( sFile, FALSE ); + if( !aURL2.GetName().Len() ) + aURL2.SetName( sFile ); + aSet.Put( aURL2 ); + rSh.SetFlyFrmAttr( aSet ); + } + break; + + default: + { + rSh.InsertURL( SwFmtINetFmt( sFile, aEmptyStr ), + sDesc.Len() ? sDesc : sFile ); + } + } + nRet = TRUE; + } + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteFileName( TransferableDataHelper& rData, + SwWrtShell& rSh, ULONG nFmt, + USHORT nAction, const Point* pPt, + BYTE nActionFlags, BOOL bMsg ) +{ + int nRet = SwTransferable::_PasteGrf( rData, rSh, nFmt, nAction, + pPt, nActionFlags, bMsg ); + if( nRet ) + nRet |= SWTRANSFER_GRAPHIC_INSERTED; + if( !nRet ) + { + String sFile, sDesc; + if( rData.GetString( nFmt, sFile ) && sFile.Len() ) + { + INetURLObject aMediaURL; + + aMediaURL.SetSmartURL( sFile ); + const String aMediaURLStr( aMediaURL.GetMainURL( INetURLObject::NO_DECODE ) ); + + if( ::avmedia::MediaWindow::isMediaURL( aMediaURLStr ) ) + { + const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aMediaURLStr ); + rSh.GetView().GetViewFrame()->GetDispatcher()->Execute( + SID_INSERT_AVMEDIA, SFX_CALLMODE_SYNCHRON, + &aMediaURLItem, 0L ); + } + else + { + BOOL bIsURLFile = SwTransferable::_CheckForURLOrLNKFile( rData, sFile, &sDesc ); + + //Eigenes FileFormat? -->Einfuegen, nicht fuer StarWriter/Web + String sFileURL = URIHelper::SmartRel2Abs(INetURLObject(), sFile, Link(), false ); + const SfxFilter* pFlt = SW_PASTESDR_SETATTR == nAction + ? 0 : SwIoSystem::GetFileFilter( + sFileURL, aEmptyStr ); + if( pFlt && !rSh.GetView().GetDocShell()->ISA(SwWebDocShell) + /* + JP 02.07.98: warum nur fuer die Formate ?? + && ( pFlt->GetUserData() == FILTER_SW5 || + pFlt->GetUserData() == FILTER_SW4 || + pFlt->GetUserData() == FILTER_SW3 || + pFlt->GetUserData() == FILTER_SWG ) + */ + ) + { + // und dann per PostUser Event den Bereich-Einfuegen-Dialog hochreissen + SwSectionData * pSect = new SwSectionData( + FILE_LINK_SECTION, + rSh.GetDoc()->GetUniqueSectionName() ); + pSect->SetLinkFileName( sFileURL ); + pSect->SetProtectFlag( true ); + + Application::PostUserEvent( STATIC_LINK( &rSh, SwWrtShell, + InsertRegionDialog ), pSect ); + nRet = 1; + } + else if( SW_PASTESDR_SETATTR == nAction || + ( bIsURLFile && SW_PASTESDR_INSERT == nAction )) + { + //Fremde Files koennen wir immerhin noch als Links + //Einfuegen. + + //#41801# ersteinmal die URL absolut machen + INetURLObject aURL; + aURL.SetSmartProtocol( INET_PROT_FILE ); + aURL.SetSmartURL( sFile ); + sFile = aURL.GetMainURL( INetURLObject::NO_DECODE ); + + switch( rSh.GetObjCntTypeOfSelection() ) + { + case OBJCNT_FLY: + case OBJCNT_GRF: + case OBJCNT_OLE: + { + SfxItemSet aSet( rSh.GetAttrPool(), RES_URL, RES_URL ); + rSh.GetFlyFrmAttr( aSet ); + SwFmtURL aURL2( (SwFmtURL&)aSet.Get( RES_URL ) ); + aURL2.SetURL( sFile, FALSE ); + if( !aURL2.GetName().Len() ) + aURL2.SetName( sFile ); + aSet.Put( aURL2 ); + rSh.SetFlyFrmAttr( aSet ); + } + break; + + default: + { + rSh.InsertURL( SwFmtINetFmt( sFile, aEmptyStr ), + sDesc.Len() ? sDesc : sFile ); + } + } + nRet = TRUE; + } + } + } + } + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteDBData( TransferableDataHelper& rData, + SwWrtShell& rSh, ULONG nFmt, BOOL bLink, + const Point* pDragPt, BOOL bMsg ) +{ + int nRet = 0; + String sTxt; + if( rData.GetString( nFmt, sTxt ) && sTxt.Len() ) + { + USHORT nWh = SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE == nFmt + ? 0 + : SOT_FORMATSTR_ID_SBA_DATAEXCHANGE == nFmt + ? (bLink + ? FN_QRY_MERGE_FIELD + : FN_QRY_INSERT) + : (bLink + ? 0 + : FN_QRY_INSERT_FIELD ); + DataFlavorExVector& rVector = rData.GetDataFlavorExVector(); + sal_Bool bHaveColumnDescriptor = OColumnTransferable::canExtractColumnDescriptor(rVector, CTF_COLUMN_DESCRIPTOR | CTF_CONTROL_EXCHANGE); + if ( SOT_FORMATSTR_ID_XFORMS == nFmt ) + { + SdrObject* pObj; + rSh.MakeDrawView(); + FmFormView* pFmView = PTR_CAST( FmFormView, rSh.GetDrawView() ); + if(pFmView) { + const OXFormsDescriptor &rDesc = OXFormsTransferable::extractDescriptor(rData); + if(0 != (pObj = pFmView->CreateXFormsControl(rDesc))) + { + rSh.SwFEShell::InsertDrawObj( *pObj, *pDragPt ); + } + } + } + else if( nWh ) + { + SfxUsrAnyItem* pConnectionItem = 0; + SfxUsrAnyItem* pCursorItem = 0; + SfxUsrAnyItem* pColumnItem = 0; + SfxUsrAnyItem* pSourceItem = 0; + SfxUsrAnyItem* pCommandItem = 0; + SfxUsrAnyItem* pCommandTypeItem = 0; + SfxUsrAnyItem* pColumnNameItem = 0; + SfxUsrAnyItem* pSelectionItem = 0; + + BOOL bDataAvailable = TRUE; + ODataAccessDescriptor aDesc; + if(bHaveColumnDescriptor) + aDesc = OColumnTransferable::extractColumnDescriptor(rData); + else if(ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) ) + aDesc = ODataAccessObjectTransferable::extractObjectDescriptor(rData); + else + bDataAvailable = FALSE; + + if ( bDataAvailable ) + { + pConnectionItem = new SfxUsrAnyItem(FN_DB_CONNECTION_ANY, aDesc[daConnection]); + pColumnItem = new SfxUsrAnyItem(FN_DB_COLUMN_ANY, aDesc[daColumnObject]); + pSourceItem = new SfxUsrAnyItem(FN_DB_DATA_SOURCE_ANY, makeAny(aDesc.getDataSource())); + pCommandItem = new SfxUsrAnyItem(FN_DB_DATA_COMMAND_ANY, aDesc[daCommand]); + pCommandTypeItem = new SfxUsrAnyItem(FN_DB_DATA_COMMAND_TYPE_ANY, aDesc[daCommandType]); + pColumnNameItem = new SfxUsrAnyItem(FN_DB_DATA_COLUMN_NAME_ANY, aDesc[daColumnName]); + pSelectionItem = new SfxUsrAnyItem(FN_DB_DATA_SELECTION_ANY, aDesc[daSelection]); + pCursorItem = new SfxUsrAnyItem(FN_DB_DATA_CURSOR_ANY, aDesc[daCursor]); + } + + SwView& rView = rSh.GetView(); + //force ::SelectShell + rView.StopShellTimer(); + + SfxStringItem aDataDesc( nWh, sTxt ); + rView.GetViewFrame()->GetDispatcher()->Execute( + nWh, SFX_CALLMODE_ASYNCHRON, &aDataDesc, + pConnectionItem, pColumnItem, + pSourceItem, pCommandItem, pCommandTypeItem, + pColumnNameItem, pSelectionItem, pCursorItem,0L); + delete pConnectionItem; + delete pColumnItem; + delete pSourceItem; + delete pCommandItem; + delete pCommandTypeItem; + delete pColumnNameItem; + delete pCursorItem; + } + else + { + SdrObject* pObj; + rSh.MakeDrawView(); + FmFormView* pFmView = PTR_CAST( FmFormView, rSh.GetDrawView() ); + if (pFmView && bHaveColumnDescriptor) + { + if ( 0 != (pObj = pFmView->CreateFieldControl( OColumnTransferable::extractColumnDescriptor(rData) ) ) ) + rSh.SwFEShell::InsertDrawObj( *pObj, *pDragPt ); + } + } + nRet = 1; + } + else if( bMsg ) + { + InfoBox( 0, SW_RES(MSG_CLPBRD_FORMAT_ERROR)).Execute(); + } + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_PasteFileList( TransferableDataHelper& rData, + SwWrtShell& rSh, BOOL bLink, + const Point* pPt, BOOL bMsg ) +{ + int nRet = 0; + FileList aFileList; + if( rData.GetFileList( SOT_FORMAT_FILE_LIST, aFileList ) && + aFileList.Count() ) + { + USHORT nAct = bLink ? SW_PASTESDR_SETATTR : SW_PASTESDR_INSERT; + String sFlyNm; + // iterate over the filelist + for( ULONG n = 0, nEnd = aFileList.Count(); n < nEnd; ++n ) + { + TransferDataContainer* pHlp = new TransferDataContainer; + pHlp->CopyString( FORMAT_FILE, aFileList.GetFile( n )); + TransferableDataHelper aData( pHlp ); + + if( SwTransferable::_PasteFileName( aData, rSh, SOT_FORMAT_FILE, nAct, + pPt, FALSE, bMsg )) + { + if( bLink ) + { + sFlyNm = rSh.GetFlyName(); + SwTransferable::SetSelInShell( rSh, FALSE, pPt ); + } + nRet = 1; + } + } + if( sFlyNm.Len() ) + rSh.GotoFly( sFlyNm ); + } + else if( bMsg ) + { + InfoBox( 0, SW_RES(MSG_CLPBRD_FORMAT_ERROR)).Execute(); + } + return nRet; +} + +// ----------------------------------------------------------------------- + +BOOL SwTransferable::_CheckForURLOrLNKFile( TransferableDataHelper& rData, + String& rFileName, String* pTitle ) +{ + BOOL bIsURLFile = FALSE; + INetBookmark aBkmk; + if( rData.GetINetBookmark( SOT_FORMATSTR_ID_SOLK, aBkmk ) ) + { + rFileName = aBkmk.GetURL(); + if( pTitle ) + *pTitle = aBkmk.GetDescription(); + bIsURLFile = TRUE; + } + else + { + xub_StrLen nLen = rFileName.Len(); + if( 4 < nLen && '.' == rFileName.GetChar( nLen - 4 )) + { + String sExt( rFileName.Copy( nLen - 3 )); + if( sExt.EqualsIgnoreCaseAscii( "url" )) + { +ASSERT( !&rFileName, "how do we read today .URL - Files?" ); + } + } + } + return bIsURLFile; +} + +// ----------------------------------------------------------------------- + +BOOL SwTransferable::IsPasteSpecial( const SwWrtShell& rWrtShell, + const TransferableDataHelper& rData ) +{ + // we can paste-special if there's an entry in the paste-special-format list + SvxClipboardFmtItem aClipboardFmtItem(0); + FillClipFmtItem( rWrtShell, rData, aClipboardFmtItem); + return aClipboardFmtItem.Count() > 0; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::PasteFormat( SwWrtShell& rSh, + TransferableDataHelper& rData, + ULONG nFormat ) +{ + SwWait aWait( *rSh.GetView().GetDocShell(), FALSE ); + int nRet = 0; + + ULONG nPrivateFmt = FORMAT_PRIVATE; + SwTransferable *pClipboard = SW_MOD()->pClipboard; + if( pClipboard && + ((TRNSFR_DOCUMENT|TRNSFR_GRAPHIC|TRNSFR_OLE) & pClipboard->eBufferType )) + nPrivateFmt = SOT_FORMATSTR_ID_EMBED_SOURCE; + + if( pClipboard && nPrivateFmt == nFormat ) + nRet = pClipboard->PrivatePaste( rSh ); + else if( rData.HasFormat( nFormat ) ) + { + uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() ); + USHORT nEventAction, + nDestination = SwTransferable::GetSotDestination( rSh ), + nSourceOptions = + (( EXCHG_DEST_DOC_TEXTFRAME == nDestination || + EXCHG_DEST_SWDOC_FREE_AREA == nDestination || + EXCHG_DEST_DOC_TEXTFRAME_WEB == nDestination || + EXCHG_DEST_SWDOC_FREE_AREA_WEB == nDestination ) + ? EXCHG_IN_ACTION_COPY + : EXCHG_IN_ACTION_MOVE), + nAction = SotExchange::GetExchangeAction( + rData.GetDataFlavorExVector(), + nDestination, + nSourceOptions, /* ?? */ + EXCHG_IN_ACTION_DEFAULT, /* ?? */ + nFormat, nEventAction, nFormat, + lcl_getTransferPointer ( xTransferable ) ); + + if( EXCHG_INOUT_ACTION_NONE != nAction ) + nRet = SwTransferable::PasteData( rData, rSh, nAction, nFormat, + nDestination, TRUE, FALSE ); + } + return nRet; +} + +// ----------------------------------------------------------------------- + +int SwTransferable::_TestAllowedFormat( const TransferableDataHelper& rData, + ULONG nFormat, USHORT nDestination ) +{ + USHORT nAction = EXCHG_INOUT_ACTION_NONE, nEventAction; + if( rData.HasFormat( nFormat )) { + uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() ); + nAction = SotExchange::GetExchangeAction( + rData.GetDataFlavorExVector(), + nDestination, EXCHG_IN_ACTION_COPY, + EXCHG_IN_ACTION_COPY, nFormat, + nEventAction, nFormat, + lcl_getTransferPointer ( xTransferable ) ); + } + return EXCHG_INOUT_ACTION_NONE != nAction; +} + +// ----------------------------------------------------------------------- + +/** + * the list of formats which will be offered to the user in the 'Paste + * Special...' dialog and the paste button menu + */ +static USHORT aPasteSpecialIds[] = +{ + SOT_FORMATSTR_ID_HTML, + SOT_FORMATSTR_ID_HTML_SIMPLE, + SOT_FORMATSTR_ID_HTML_NO_COMMENT, + FORMAT_RTF, + FORMAT_STRING, + SOT_FORMATSTR_ID_SONLK, + SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK, + SOT_FORMATSTR_ID_DRAWING, + SOT_FORMATSTR_ID_SVXB, + FORMAT_GDIMETAFILE, + FORMAT_BITMAP, + SOT_FORMATSTR_ID_SVIM, + SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR, + 0 +}; + + +int SwTransferable::PasteUnformatted( SwWrtShell& rSh, TransferableDataHelper& rData ) +{ + // Plain text == unformatted + return SwTransferable::PasteFormat( rSh, rData, SOT_FORMAT_STRING ); +} + +// ----------------------------------------------------------------------- + +int SwTransferable::PasteSpecial( SwWrtShell& rSh, TransferableDataHelper& rData, ULONG& rFormatUsed ) +{ + int nRet = 0; + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + SfxAbstractPasteDialog* pDlg = pFact->CreatePasteDialog( &rSh.GetView().GetEditWin() ); + + DataFlavorExVector aFormats( rData.GetDataFlavorExVector() ); + TransferableObjectDescriptor aDesc; + + USHORT nDest = SwTransferable::GetSotDestination( rSh ); + + SwTransferable *pClipboard = SW_MOD()->pClipboard; + if( pClipboard ) + { + aDesc = pClipboard->aObjDesc; + USHORT nResId; + if( pClipboard->eBufferType & TRNSFR_DOCUMENT ) + nResId = STR_PRIVATETEXT; + else if( pClipboard->eBufferType & TRNSFR_GRAPHIC ) + nResId = STR_PRIVATEGRAPHIC; + else if( pClipboard->eBufferType == TRNSFR_OLE ) + nResId = STR_PRIVATEOLE; + else + nResId = 0; + + if( nResId ) + { + if( STR_PRIVATEOLE == nResId || STR_PRIVATEGRAPHIC == nResId ) + { + // add SOT_FORMATSTR_ID_EMBED_SOURCE to the formats. This + // format display then the private format name. + DataFlavorEx aFlavorEx; + aFlavorEx.mnSotId = SOT_FORMATSTR_ID_EMBED_SOURCE; + aFormats.insert( aFormats.begin(), aFlavorEx ); + } + pDlg->SetObjName( pClipboard->aObjDesc.maClassName, + SW_RES( nResId ) ); + pDlg->Insert( SOT_FORMATSTR_ID_EMBED_SOURCE, aEmptyStr ); + } + } + else + { + if( rData.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) ) + rData.GetTransferableObjectDescriptor( + SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ); + + if( SwTransferable::_TestAllowedFormat( rData, SOT_FORMATSTR_ID_EMBED_SOURCE, nDest )) + pDlg->Insert( SOT_FORMATSTR_ID_EMBED_SOURCE, aEmptyStr ); + if( SwTransferable::_TestAllowedFormat( rData, SOT_FORMATSTR_ID_LINK_SOURCE, nDest )) + pDlg->Insert( SOT_FORMATSTR_ID_LINK_SOURCE, aEmptyStr ); + } + + if( SwTransferable::_TestAllowedFormat( rData, SOT_FORMATSTR_ID_LINK, nDest )) + pDlg->Insert( SOT_FORMATSTR_ID_LINK, SW_RES(STR_DDEFORMAT) ); + + for( USHORT* pIds = aPasteSpecialIds; *pIds; ++pIds ) + if( SwTransferable::_TestAllowedFormat( rData, *pIds, nDest )) + pDlg->Insert( *pIds, aEmptyStr ); + + ULONG nFormat = pDlg->GetFormat( rData.GetTransferable() ); + + if( nFormat ) + nRet = SwTransferable::PasteFormat( rSh, rData, nFormat ); + + if ( nRet ) + rFormatUsed = nFormat; + + delete pDlg; + return nRet; +} + + +void SwTransferable::FillClipFmtItem( const SwWrtShell& rSh, + const TransferableDataHelper& rData, + SvxClipboardFmtItem & rToFill ) +{ + USHORT nDest = SwTransferable::GetSotDestination( rSh ); + SwTransferable *pClipboard = SW_MOD()->pClipboard; + if( pClipboard ) + { + USHORT nResId; + if( pClipboard->eBufferType & TRNSFR_DOCUMENT ) + nResId = STR_PRIVATETEXT; + else if( pClipboard->eBufferType & TRNSFR_GRAPHIC ) + nResId = STR_PRIVATEGRAPHIC; + else if( pClipboard->eBufferType == TRNSFR_OLE ) + nResId = STR_PRIVATEOLE; + else + nResId = 0; + + if( nResId ) + rToFill.AddClipbrdFormat( SOT_FORMATSTR_ID_EMBED_SOURCE, + SW_RES( nResId ) ); + } + else + { + TransferableObjectDescriptor aDesc; + if( rData.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) ) + ((TransferableDataHelper&)rData).GetTransferableObjectDescriptor( + SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ); + + if( SwTransferable::_TestAllowedFormat( rData, SOT_FORMATSTR_ID_EMBED_SOURCE, nDest )) + rToFill.AddClipbrdFormat( SOT_FORMATSTR_ID_EMBED_SOURCE, + aDesc.maTypeName ); + if( SwTransferable::_TestAllowedFormat( rData, SOT_FORMATSTR_ID_LINK_SOURCE, nDest )) + rToFill.AddClipbrdFormat( SOT_FORMATSTR_ID_LINK_SOURCE ); + + SotFormatStringId nFormat; + if ( rData.HasFormat(nFormat = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE) || rData.HasFormat(nFormat = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE) ) + { + String sName,sSource; + if ( SvPasteObjectHelper::GetEmbeddedName(rData,sName,sSource,nFormat) ) + rToFill.AddClipbrdFormat( nFormat, sName ); + } + } + + if( SwTransferable::_TestAllowedFormat( rData, SOT_FORMATSTR_ID_LINK, nDest )) + rToFill.AddClipbrdFormat( SOT_FORMATSTR_ID_LINK, SW_RES(STR_DDEFORMAT) ); + + for( USHORT* pIds = aPasteSpecialIds; *pIds; ++pIds ) + if( SwTransferable::_TestAllowedFormat( rData, *pIds, nDest )) + rToFill.AddClipbrdFormat( *pIds, aEmptyStr ); +} + +void SwTransferable::SetDataForDragAndDrop( const Point& rSttPos ) +{ + if(!pWrtShell) + return; + String sGrfNm; + const int nSelection = pWrtShell->GetSelectionType(); + if( nsSelectionType::SEL_GRF == nSelection) + { + AddFormat( SOT_FORMATSTR_ID_SVXB ); + // --> OD 2005-02-09 #119353# - robust + const Graphic* pGrf = pWrtShell->GetGraphic(); + if ( pGrf && pGrf->IsSupportedGraphic() ) + // <-- + { + AddFormat( FORMAT_GDIMETAFILE ); + AddFormat( FORMAT_BITMAP ); + } + eBufferType = TRNSFR_GRAPHIC; + pWrtShell->GetGrfNms( &sGrfNm, 0 ); + } + else if( nsSelectionType::SEL_OLE == nSelection ) + { + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + PrepareOLE( aObjDesc ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + AddFormat( FORMAT_GDIMETAFILE ); + eBufferType = TRNSFR_OLE; + } + //Gibt es ueberhaupt etwas zum bereitstellen? + else if ( pWrtShell->IsSelection() || pWrtShell->IsFrmSelected() || + pWrtShell->IsObjSelected() ) + { + if( pWrtShell->IsObjSelected() ) + eBufferType = TRNSFR_DRAWING; + else + { + eBufferType = TRNSFR_DOCUMENT; + if( SwWrtShell::NO_WORD != + pWrtShell->IntelligentCut( nSelection, FALSE )) + eBufferType = TransferBufferType( TRNSFR_DOCUMENT_WORD + | eBufferType); + } + + if( nSelection & nsSelectionType::SEL_TBL_CELLS ) + eBufferType = (TransferBufferType)(TRNSFR_TABELLE | eBufferType); + + AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); + + //RTF vor das Metafile von OLE stellen, weil mit weniger verlusten + //behaftet. + if( !pWrtShell->IsObjSelected() ) + { + AddFormat( FORMAT_RTF ); + AddFormat( SOT_FORMATSTR_ID_HTML ); + } + if( pWrtShell->IsSelection() ) + AddFormat( FORMAT_STRING ); + + if( nSelection & ( nsSelectionType::SEL_DRW | nsSelectionType::SEL_DRW_FORM )) + { + AddFormat( SOT_FORMATSTR_ID_DRAWING ); + if ( nSelection & nsSelectionType::SEL_DRW ) + { + AddFormat( FORMAT_GDIMETAFILE ); + AddFormat( FORMAT_BITMAP ); + } + eBufferType = (TransferBufferType)( TRNSFR_GRAPHIC | eBufferType ); + + pClpGraphic = new Graphic; + if( !pWrtShell->GetDrawObjGraphic( FORMAT_GDIMETAFILE, *pClpGraphic )) + pOrigGrf = pClpGraphic; + pClpBitmap = new Graphic; + if( !pWrtShell->GetDrawObjGraphic( FORMAT_BITMAP, *pClpBitmap )) + pOrigGrf = pClpBitmap; + + // ist es ein URL-Button ? + String sURL, sDesc; + if( pWrtShell->GetURLFromButton( sURL, sDesc ) ) + { + AddFormat( FORMAT_STRING ); + AddFormat( SOT_FORMATSTR_ID_SOLK ); + AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); + AddFormat( SOT_FORMATSTR_ID_FILECONTENT ); + AddFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); + eBufferType = (TransferBufferType)( TRNSFR_INETFLD | eBufferType ); + } + } + + //ObjectDescriptor wurde bereits aus der alten DocShell gefuellt. + //Jetzt noch anpassen. Dadurch kann im GetData die erste Anfrage + //auch noch mit delayed rendering beantwortet werden. + aObjDesc.mbCanLink = FALSE; + aObjDesc.maDragStartPos = rSttPos; + aObjDesc.maSize = OutputDevice::LogicToLogic( Size( OLESIZE ), + MAP_TWIP, MAP_100TH_MM ); + PrepareOLE( aObjDesc ); + AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); + } + else if( nSelection & nsSelectionType::SEL_TXT && !pWrtShell->HasMark() ) + { + // ist nur ein Feld - Selektiert? + SwContentAtPos aCntntAtPos( SwContentAtPos::SW_INETATTR ); + Point aPos( SwEditWin::GetDDStartPosX(), SwEditWin::GetDDStartPosY()); + + if( pWrtShell->GetContentAtPos( aPos, aCntntAtPos ) ) + { + AddFormat( FORMAT_STRING ); + AddFormat( SOT_FORMATSTR_ID_SOLK ); + AddFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ); + AddFormat( SOT_FORMATSTR_ID_FILECONTENT ); + AddFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ); + AddFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ); + eBufferType = TRNSFR_INETFLD; + } + } + + if( pWrtShell->IsFrmSelected() ) + { + SfxItemSet aSet( pWrtShell->GetAttrPool(), RES_URL, RES_URL ); + pWrtShell->GetFlyFrmAttr( aSet ); + const SwFmtURL& rURL = (SwFmtURL&)aSet.Get( RES_URL ); + if( rURL.GetMap() ) + { + pImageMap = new ImageMap( *rURL.GetMap() ); + AddFormat( SOT_FORMATSTR_ID_SVIM ); + } + else if( rURL.GetURL().Len() ) + { + pTargetURL = new INetImage( sGrfNm, rURL.GetURL(), + rURL.GetTargetFrameName(), + aEmptyStr, Size() ); + AddFormat( SOT_FORMATSTR_ID_INET_IMAGE ); + } + } +} + +void SwTransferable::StartDrag( Window* pWin, const Point& rPos ) +{ + if(!pWrtShell) + return; + bOldIdle = pWrtShell->GetViewOptions()->IsIdle(); + bCleanUp = TRUE; + + ((SwViewOption *)pWrtShell->GetViewOptions())->SetIdle( FALSE ); + + if( pWrtShell->IsSelFrmMode() ) + pWrtShell->ShowCrsr(); + + SW_MOD()->pDragDrop = this; + + SetDataForDragAndDrop( rPos ); + + sal_Int8 nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK; + SwDocShell* pDShell = pWrtShell->GetView().GetDocShell(); + if( ( pDShell && pDShell->IsReadOnly() ) || pWrtShell->HasReadonlySel() ) + nDragOptions &= ~DND_ACTION_MOVE; + + TransferableHelper::StartDrag( pWin, nDragOptions ); +} + +void SwTransferable::DragFinished( sal_Int8 nAction ) +{ + //Und noch die letzten Nacharbeiten damit alle Stati stimmen. + if( DND_ACTION_MOVE == nAction ) + { + if( bCleanUp ) + { + //Es wurde auserhalb des Writers gedroped. Wir muessen noch + //loeschen. + + pWrtShell->StartAllAction(); + pWrtShell->StartUndo( UNDO_UI_DRAG_AND_MOVE ); + if ( pWrtShell->IsTableMode() ) + pWrtShell->DeleteTblSel(); + else + { + if ( !(pWrtShell->IsSelFrmMode() || pWrtShell->IsObjSelected()) ) + //SmartCut, eines der Blanks mitnehmen. + pWrtShell->IntelligentCut( pWrtShell->GetSelectionType(), TRUE ); + pWrtShell->DelRight(); + } + pWrtShell->EndUndo( UNDO_UI_DRAG_AND_MOVE ); + pWrtShell->EndAllAction(); + } + else + { + const int nSelection = pWrtShell->GetSelectionType(); + if( ( nsSelectionType::SEL_FRM | nsSelectionType::SEL_GRF | + nsSelectionType::SEL_OLE | nsSelectionType::SEL_DRW ) & nSelection ) + { + pWrtShell->EnterSelFrmMode(); + } + } + } + pWrtShell->GetView().GetEditWin().DragFinished(); + + if( pWrtShell->IsSelFrmMode() ) + pWrtShell->HideCrsr(); + else + pWrtShell->ShowCrsr(); +//!! else if( DND_ACTION_NONE != nAction ) +//!! pWrtShell->ShowCrsr(); +//!! else +//!! { +//!! //Muss wohl sein weil gescrollt wurde und ?...? +//!! pWrtShell->StartAction(); +//!! pWrtShell->EndAction(); +//!! } + + ((SwViewOption *)pWrtShell->GetViewOptions())->SetIdle( bOldIdle ); +} + + +/* */ + +int SwTransferable::PrivatePaste( SwWrtShell& rShell ) +{ + // erst den SelectionType erfragen, dann Action-Klammerung !!!! + // (sonst wird nicht in eine TabellenSelektion gepastet!!!) + ASSERT( !rShell.ActionPend(), "Paste darf nie eine Actionklammerung haben" ); + if ( !pClpDocFac ) + return sal_False; // the return value of the SwFEShell::Paste also is BOOL! + + const int nSelection = rShell.GetSelectionType(); + + // #111827# + SwRewriter aRewriter; + + SwTrnsfrActionAndUndo aAction( &rShell, UNDO_PASTE_CLIPBOARD); + + bool bKillPaMs = false; + + //Selektierten Inhalt loeschen, nicht bei Tabellen-Selektion und + //Tabelle im Clipboard + if( rShell.HasSelection() && !( nSelection & nsSelectionType::SEL_TBL_CELLS)) + { + bKillPaMs = true; + rShell.SetRetainSelection( true ); + rShell.DelRight(); + // war ein Fly selektiert, so muss jetzt fuer eine gueltige + // Cursor-Position gesorgt werden! (geparkter Cursor!) + if( ( nsSelectionType::SEL_FRM | nsSelectionType::SEL_GRF | + nsSelectionType::SEL_OLE | nsSelectionType::SEL_DRW | + nsSelectionType::SEL_DRW_FORM ) & nSelection ) + { + // den Cursor wieder positionieren + Point aPt( rShell.GetCharRect().Pos() ); + rShell.SwCrsrShell::SetCrsr( aPt, TRUE ); + } + rShell.SetRetainSelection( false ); + } + + BOOL bInWrd = FALSE, bEndWrd = FALSE, bSttWrd = FALSE, + bSmart = 0 != (TRNSFR_DOCUMENT_WORD & eBufferType); + if( bSmart ) + { +// #108491# Why not for other Scripts? If TRNSFR_DOCUMENT_WORD is set, we have +// a word in the buffer, word in this context means 'something with spaces at +// beginning and end'. In this case we definitely want these spaces to be inserted +// here. +// if( SCRIPTTYPE_LATIN != rShell.GetScriptType() ) +// bSmart = FALSE; +// else +// { + bInWrd = rShell.IsInWrd(); + bEndWrd = rShell.IsEndWrd(); + bSmart = bInWrd || bEndWrd; + if( bSmart ) + { + bSttWrd = rShell.IsSttWrd(); + if( bSmart && !bSttWrd && (bInWrd || bEndWrd) ) + rShell.SwEditShell::Insert(' '); + } +// } + } + + int nRet = rShell.Paste( pClpDocFac->GetDoc() ); + + if( bKillPaMs ) + rShell.KillPams(); + + // Wenn Smart Paste dann Leerzeichen einfuegen + if( nRet && bSmart && ((bInWrd && !bEndWrd )|| bSttWrd) ) + rShell.SwEditShell::Insert(' '); + + return nRet; +} + +int SwTransferable::PrivateDrop( SwWrtShell& rSh, const Point& rDragPt, + BOOL bMove, BOOL bIsXSelection ) +{ + int cWord = 0; + BOOL bInWrd = FALSE; + BOOL bEndWrd = FALSE; + BOOL bSttWrd = FALSE; + BOOL bSttPara= FALSE; + BOOL bTblSel = FALSE; + BOOL bFrmSel = FALSE; + + SwWrtShell& rSrcSh = *GetShell(); + + rSh.UnSetVisCrsr(); + + if( TRNSFR_INETFLD == eBufferType ) + { + if( rSh.GetFmtFromObj( rDragPt ) ) + { + INetBookmark aTmp; + if( (TRNSFR_INETFLD & eBufferType) && pBkmk ) + aTmp = *pBkmk; + + // Zielgrafik selektieren + if( rSh.SelectObj( rDragPt ) ) + { + rSh.HideCrsr(); + rSh.EnterSelFrmMode( &rDragPt ); + bFrmDrag = TRUE; + } + + const int nSelection = rSh.GetSelectionType(); + + // Draw-Objekte erstmal noch nicht beruecksichtigen + if( nsSelectionType::SEL_GRF & nSelection ) + { + SfxItemSet aSet( rSh.GetAttrPool(), RES_URL, RES_URL ); + rSh.GetFlyFrmAttr( aSet ); + SwFmtURL aURL( (SwFmtURL&)aSet.Get( RES_URL ) ); + aURL.SetURL( aTmp.GetURL(), FALSE ); + aSet.Put( aURL ); + rSh.SetFlyFrmAttr( aSet ); + return 1; + } + + if( nsSelectionType::SEL_DRW & nSelection ) + { + rSh.LeaveSelFrmMode(); + rSh.UnSelectFrm(); + rSh.ShowCrsr(); + bFrmDrag = FALSE; + } + } + } + + if( &rSh != &rSrcSh && (nsSelectionType::SEL_GRF & rSh.GetSelectionType()) && + TRNSFR_GRAPHIC == eBufferType ) + { + // ReRead auf die Grafik + String sGrfNm, sFltNm; + rSrcSh.GetGrfNms( &sGrfNm, &sFltNm ); + rSh.ReRead( sGrfNm, sFltNm, rSrcSh.GetGraphic() ); + return 1; + } + + //Nicht in Selektionen oder selektierten Rahmen + if( rSh.ChgCurrPam( rDragPt ) || + ( rSh.IsSelFrmMode() && rSh.IsInsideSelectedObj( rDragPt )) ) + return 0; + + if( rSrcSh.IsTableMode() ) + bTblSel = TRUE; + else if( rSrcSh.IsSelFrmMode() || rSrcSh.IsObjSelected() ) + { + // keine positionsgeschuetzten Objecte verschieben! + if( bMove && rSrcSh.IsSelObjProtected( FLYPROTECT_POS ) ) + return 0; + + bFrmSel = TRUE; + } + + const int nSel = rSrcSh.GetSelectionType(); + + SwUndoId eUndoId = bMove ? UNDO_UI_DRAG_AND_MOVE : UNDO_UI_DRAG_AND_COPY; + + // #111827# + SwRewriter aRewriter; + + aRewriter.AddRule(UNDO_ARG1, rSrcSh.GetSelDescr()); + + if(rSrcSh.GetDoc() != rSh.GetDoc()) + rSrcSh.StartUndo( eUndoId, &aRewriter ); + rSh.StartUndo( eUndoId, &aRewriter ); + + rSh.StartAction(); + rSrcSh.StartAction(); + + if( &rSrcSh != &rSh ) + { + rSh.EnterStdMode(); + rSh.SwCrsrShell::SetCrsr( rDragPt, TRUE ); + cWord = rSrcSh.IntelligentCut( nSel, FALSE ); + } + else if( !bTblSel && !bFrmSel ) + { + if( !rSh.IsAddMode() ) + { + // --> OD 2008-03-19 #i87233# + if ( rSh.IsBlockMode() ) + { + // preserve order of cursors for block mode + rSh.GoPrevCrsr(); + } + // <-- + rSh.SwCrsrShell::CreateCrsr(); + } + rSh.SwCrsrShell::SetCrsr( rDragPt, TRUE, false ); + rSh.GoPrevCrsr(); + cWord = rSh.IntelligentCut( rSh.GetSelectionType(), FALSE ); + rSh.GoNextCrsr(); + } + + bInWrd = rSh.IsInWrd(); + bEndWrd = rSh.IsEndWrd(); + bSttWrd = !bEndWrd && rSh.IsSttWrd(); + bSttPara= rSh.IsSttPara(); + + Point aSttPt( SwEditWin::GetDDStartPosX(), SwEditWin::GetDDStartPosY() ); + + //JP 05.03.96: INetFelder erstmal selektieren ! + if( TRNSFR_INETFLD == eBufferType ) + { + if( &rSrcSh == &rSh ) + { + rSh.GoPrevCrsr(); + rSh.SwCrsrShell::SetCrsr( aSttPt, TRUE ); + rSh.SelectTxtAttr( RES_TXTATR_INETFMT ); + if( rSh.ChgCurrPam( rDragPt ) ) + { + // nicht in sich selbst kopieren/verschieben + rSh.DestroyCrsr(); + rSh.EndUndo( eUndoId ); + rSh.EndAction(); + rSh.EndAction(); + return 0; + } + rSh.GoNextCrsr(); + } + else + { + rSrcSh.SwCrsrShell::SetCrsr( aSttPt, TRUE ); + rSrcSh.SelectTxtAttr( RES_TXTATR_INETFMT ); + } + + // ist am Einfuege Punkt ein URL-Attribut? Dann das ersetzen, + // also einfach eine Selektion aufspannen? + rSh.DelINetAttrWithText(); + bDDINetAttr = TRUE; + } + + if ( rSrcSh.IsSelFrmMode() ) + { + //Hack: Spezialbehandlung austricksen + aSttPt -= aSttPt - rSrcSh.GetObjRect().Pos(); + } + + BOOL bRet = rSrcSh.SwFEShell::Copy( &rSh, aSttPt, rDragPt, bMove, + !bIsXSelection ); + + if( !bIsXSelection ) + { + rSrcSh.Push(); + if ( bRet && bMove && !bFrmSel ) + { + if ( bTblSel ) + { + /* #109590# delete table contents not cells */ + rSrcSh.Delete(); + } + else + { + //SmartCut, eines der Blank mitnehmen. + rSh.SwCrsrShell::DestroyCrsr(); + if ( cWord == SwWrtShell::WORD_SPACE_BEFORE ) + rSh.ExtendSelection( FALSE ); + else if ( cWord == SwWrtShell::WORD_SPACE_AFTER ) + rSh.ExtendSelection(); + rSrcSh.DelRight(); + } + } + rSrcSh.KillPams(); + rSrcSh.Pop( FALSE ); + + /* #109590# after dragging a table selection inside one shell + set cursor to the drop position. */ + if( &rSh == &rSrcSh && ( bTblSel || rSh.IsBlockMode() ) ) + { + rSrcSh.SwCrsrShell::SetCrsr(rDragPt); + rSrcSh.GetSwCrsr()->SetMark(); + } + } + + if( bRet && !bTblSel && !bFrmSel ) + { + if( (bInWrd || bEndWrd) && + (cWord == SwWrtShell::WORD_SPACE_AFTER || + cWord == SwWrtShell::WORD_SPACE_BEFORE) ) + { + if ( bSttWrd || (bInWrd && !bEndWrd)) + rSh.SwEditShell::Insert(' ', bIsXSelection); + if ( !bSttWrd || (bInWrd && !bSttPara) ) + { + rSh.SwapPam(); + if ( !bSttWrd ) + rSh.SwEditShell::Insert(' ', bIsXSelection); + rSh.SwapPam(); + } + } + + if( bIsXSelection ) + { + if( &rSrcSh == &rSh && !rSh.IsAddMode() ) + { + rSh.SwCrsrShell::DestroyCrsr(); + rSh.GoPrevCrsr(); + } + else + { + rSh.SwapPam(); + rSh.SwCrsrShell::ClearMark(); + } + } + else + { + if( rSh.IsAddMode() ) + rSh.SwCrsrShell::CreateCrsr(); + else + { + // Selektionsmodus einschalten + rSh.SttSelect(); + rSh.EndSelect(); + } + } + } + + if( bRet && bMove && bFrmSel ) + rSrcSh.LeaveSelFrmMode(); + + if( rSrcSh.GetDoc() != rSh.GetDoc() ) + rSrcSh.EndUndo( eUndoId ); + rSh.EndUndo( eUndoId ); + + // Shell in den richtigen Status versetzen + if( &rSrcSh != &rSh && ( rSh.IsFrmSelected() || rSh.IsObjSelected() )) + rSh.EnterSelFrmMode(); + + rSrcSh.EndAction(); + rSh.EndAction(); + return 1; +} + +// Interfaces for Selection +void SwTransferable::CreateSelection( SwWrtShell& rSh, + const ViewShell * _pCreatorView ) +{ + SwModule *pMod = SW_MOD(); + SwTransferable* pNew = new SwTransferable( rSh ); + + /* #96392#*/ + pNew->pCreatorView = _pCreatorView; + + uno::Reference< + datatransfer::XTransferable > xRef( pNew ); + pMod->pXSelection = pNew; + pNew->CopyToSelection( rSh.GetWin() ); +} + +void SwTransferable::ClearSelection( SwWrtShell& rSh, + const ViewShell * _pCreatorView) +{ + SwModule *pMod = SW_MOD(); + if( pMod->pXSelection && + ((!pMod->pXSelection->pWrtShell) || (pMod->pXSelection->pWrtShell == &rSh)) && + /* #96392# */ + (!_pCreatorView || (pMod->pXSelection->pCreatorView == _pCreatorView)) ) + { + TransferableHelper::ClearSelection( rSh.GetWin() ); + } +} +/* -----------------3/31/2003 11:46AM---------------- + + --------------------------------------------------*/ +const Sequence< sal_Int8 >& SwTransferable::getUnoTunnelId() +{ + static Sequence< sal_Int8 > aSeq; + if( !aSeq.getLength() ) + { + static osl::Mutex aCreateMutex; + osl::Guard< osl::Mutex > aGuard( aCreateMutex ); + aSeq.realloc( 16 ); + rtl_createUuid( reinterpret_cast< sal_uInt8* >( aSeq.getArray() ), 0, sal_True ); + } + return aSeq; +} +/* -----------------3/31/2003 11:46AM---------------- + + --------------------------------------------------*/ +sal_Int64 SwTransferable::getSomething( const Sequence< sal_Int8 >& rId ) throw( RuntimeException ) +{ + sal_Int64 nRet; + if( ( rId.getLength() == 16 ) && + ( 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) ) + { + nRet = sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ) ); + } + else + nRet = TransferableHelper::getSomething(rId); + return nRet; +} + +/* */ + +// ----------------------------------------------------------------------- + +SwTrnsfrDdeLink::SwTrnsfrDdeLink( SwTransferable& rTrans, SwWrtShell& rSh ) + : rTrnsfr( rTrans ), pDocShell( 0 ), + bDelBookmrk( FALSE ), bInDisconnect( FALSE ) +{ + // hier kommen wir nur bei Tabellen- oder Text-Selection an + const int nSelection = rSh.GetSelectionType(); + if( nsSelectionType::SEL_TBL_CELLS & nSelection ) + { + SwFrmFmt* pFmt = rSh.GetTableFmt(); + if( pFmt ) + sName = pFmt->GetName(); + } + else + { + // creating a temp. bookmark without undo + BOOL bUndo = rSh.DoesUndo(); + rSh.DoUndo( FALSE ); + BOOL bIsModified = rSh.IsModified(); + + ::sw::mark::IMark* pMark = rSh.SetBookmark( + KeyCode(), + ::rtl::OUString(), + ::rtl::OUString(), + IDocumentMarkAccess::DDE_BOOKMARK); + if(pMark) + { + sName = pMark->GetName(); + bDelBookmrk = TRUE; + if( !bIsModified ) + rSh.ResetModified(); + } + else + sName.Erase(); + rSh.DoUndo( bUndo ); + } + + if( sName.Len() && + 0 != ( pDocShell = rSh.GetDoc()->GetDocShell() ) ) + { + // dann erzeugen wir uns mal unseren "Server" und connecten uns + // zu diesem + refObj = pDocShell->DdeCreateLinkSource( sName ); + if( refObj.Is() ) + { + refObj->AddConnectAdvise( this ); + refObj->AddDataAdvise( this, +// SotExchange::GetFormatMimeType( FORMAT_RTF ), + aEmptyStr, + ADVISEMODE_NODATA | ADVISEMODE_ONLYONCE ); + nOldTimeOut = refObj->GetUpdateTimeout(); + refObj->SetUpdateTimeout( 0 ); + } + } +} + +// ----------------------------------------------------------------------- + +SwTrnsfrDdeLink::~SwTrnsfrDdeLink() +{ + if( refObj.Is() ) + Disconnect( TRUE ); +} + +// ----------------------------------------------------------------------- + +void SwTrnsfrDdeLink::DataChanged( const String& , + const uno::Any& ) +{ + // tja das wars dann mit dem Link + if( !bInDisconnect ) + { + if( FindDocShell() && pDocShell->GetView() ) + rTrnsfr.RemoveDDELinkFormat( pDocShell->GetView()->GetEditWin() ); + Disconnect( FALSE ); + } +} + +// ----------------------------------------------------------------------- + +BOOL SwTrnsfrDdeLink::WriteData( SvStream& rStrm ) +{ + if( !refObj.Is() || !FindDocShell() ) + return FALSE; + + rtl_TextEncoding eEncoding = DDE_TXT_ENCODING; + const ByteString aAppNm( GetpApp()->GetAppName(), eEncoding ); + const ByteString aTopic( pDocShell->GetTitle( SFX_TITLE_FULLNAME ), + eEncoding ); + const ByteString aName( sName, eEncoding ); + + sal_Char* pMem = new char[ aAppNm.Len() + aTopic.Len() + aName.Len() + 4 ]; + + xub_StrLen nLen = aAppNm.Len(); + memcpy( pMem, aAppNm.GetBuffer(), nLen ); + pMem[ nLen++ ] = 0; + memcpy( pMem + nLen, aTopic.GetBuffer(), aTopic.Len() ); + nLen = nLen + aTopic.Len(); + pMem[ nLen++ ] = 0; + memcpy( pMem + nLen, aName.GetBuffer(), aName.Len() ); + nLen = nLen + aName.Len(); + pMem[ nLen++ ] = 0; + pMem[ nLen++ ] = 0; + + rStrm.Write( pMem, nLen ); + delete[] pMem; + + //if( bDelBookmrk ) + //{ + // // er wird das erstemal abgeholt, also ins Undo mitaufnehmen + // // aber wie?? + //} + + IDocumentMarkAccess* const pMarkAccess = pDocShell->GetDoc()->getIDocumentMarkAccess(); + IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(sName); + if(ppMark != pMarkAccess->getMarksEnd() + && IDocumentMarkAccess::GetType(**ppMark) != IDocumentMarkAccess::BOOKMARK) + { + // the mark is still a DdeBookmark + // we replace it with a Bookmark, so it will get saved etc. + ::sw::mark::IMark* const pMark = ppMark->get(); + SwServerObject* const pServerObject = dynamic_cast<SwServerObject *>(&refObj); + + // collecting state of old mark + SwPaM aPaM(pMark->GetMarkStart()); + *aPaM.GetPoint() = pMark->GetMarkStart(); + if(pMark->IsExpanded()) + { + aPaM.SetMark(); + *aPaM.GetMark() = pMark->GetMarkEnd(); + } + ::rtl::OUString sMarkName = pMark->GetName(); + + // remove mark + pServerObject->SetNoServer(); // this removes the connection between SwServerObject and mark + // N.B. ppMark was not loaded from file and cannot have xml:id + pMarkAccess->deleteMark(ppMark); + + // recreate as Bookmark + ::sw::mark::IMark* const pNewMark = pMarkAccess->makeMark( + aPaM, + sMarkName, + IDocumentMarkAccess::BOOKMARK); + pServerObject->SetDdeBookmark(*pNewMark); + } + + bDelBookmrk = false; + return true; +} + +// ----------------------------------------------------------------------- + +void SwTrnsfrDdeLink::Disconnect( BOOL bRemoveDataAdvise ) +{ + //JP 29.01.96 Bug 24432: + // kein DataChanged mehr entgegen nehmen, wenn man + // sich schon im Disconnet befindet! + // (DTOR vom Bookmark verschickt einen DataChanged!) + BOOL bOldDisconnect = bInDisconnect; + bInDisconnect = TRUE; + + // den nicht verwendeten Bookmark wieder zerstoeren (ohne Undo!)? + if( bDelBookmrk && refObj.Is() && FindDocShell() ) + { + SwDoc* pDoc = pDocShell->GetDoc(); + BOOL bUndo = pDoc->DoesUndo(); + pDoc->DoUndo( FALSE ); + + // --> OD, CD, OS 2005-11-25 #i58448# + Link aSavedOle2Link( pDoc->GetOle2Link() ); + pDoc->SetOle2Link( Link() ); + // <-- + BOOL bIsModified = pDoc->IsModified(); + + IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); + pMarkAccess->deleteMark(pMarkAccess->findMark(sName)); + + if( !bIsModified ) + pDoc->ResetModified(); + // --> OD, CD, OS 2005-11-25 #i58448# + pDoc->SetOle2Link( aSavedOle2Link ); + // <-- + + pDoc->DoUndo( bUndo ); + bDelBookmrk = FALSE; + } + + if( refObj.Is() ) + { + refObj->SetUpdateTimeout( nOldTimeOut ); + refObj->RemoveConnectAdvise( this ); + if( bRemoveDataAdvise ) + // in einem DataChanged darf das SelectionObject NIE geloescht + // werden; wird schon von der Basisklasse erledigt + // (ADVISEMODE_ONLYONCE!!!!) + // Im normalen Disconnet aber schon! + refObj->RemoveAllDataAdvise( this ); + refObj.Clear(); + } + bInDisconnect = bOldDisconnect; +} + +// ----------------------------------------------------------------------- + +BOOL SwTrnsfrDdeLink::FindDocShell() +{ + TypeId aType( TYPE( SwDocShell ) ); + SfxObjectShell* pTmpSh = SfxObjectShell::GetFirst( &aType ); + while( pTmpSh ) + { + if( pTmpSh == pDocShell ) // die wollen wir haben + { + if( pDocShell->GetDoc() ) + return TRUE; + break; // das Doc ist nicht mehr vorhanden, also raus! + } + pTmpSh = SfxObjectShell::GetNext( *pTmpSh, &aType ); + } + + pDocShell = 0; + return FALSE; +} + +// ----------------------------------------------------------------------- + +void SwTrnsfrDdeLink::Closed() +{ + if( !bInDisconnect && refObj.Is() ) + { + refObj->RemoveAllDataAdvise( this ); + refObj->RemoveConnectAdvise( this ); + refObj.Clear(); + } +} |