blob: c239ec22a28d3c868041c37e55d096bf83f65899 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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 <IDocumentUndoRedo.hxx>
#include <pagedesc.hxx>
#include <IMark.hxx>
#include <bookmrk.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>
#include <svx/svditer.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <svx/svdpage.hxx>
#include <avmedia/mediawindow.hxx>
#include <swcrsr.hxx>
#include <SwRewriter.hxx>
#include <globals.hrc>
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
#include <swserv.hxx>
#include <switerator.hxx>
extern sal_Bool bFrmDrag;
extern sal_Bool bDDINetAttr;
extern sal_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()
class SwTrnsfrDdeLink : public ::sfx2::SvBaseLink
{
String sName;
::sfx2::SvLinkSourceRef refObj;
SwTransferable& rTrnsfr;
SwDocShell* pDocShell;
sal_uLong nOldTimeOut;
sal_Bool bDelBookmrk : 1;
sal_Bool bInDisconnect : 1;
sal_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();
sal_Bool WriteData( SvStream& rStrm );
void Disconnect( sal_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,
sal_Bool bDelSel = sal_False)
: pSh( pS ), eUndoId( nId )
{
pSh->StartUndo( eUndoId, pRewriter );
if( bDelSel )
pSh->DelRight();
pSh->StartAllAction();
}
~SwTrnsfrActionAndUndo()
{
pSh->EndUndo();
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( sal_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->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->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 )
{
SwIterator<SwCntntNode,SwFmtColl> aIter( *pClpDocFac->GetDoc()->GetDfltGrfFmtColl() );
for( SwCntntNode* pNd = aIter.First(); pNd; pNd = 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 )
{
SwIterator<SwCntntNode,SwFmtColl> aIter( *pClpDocFac->GetDoc()->GetDfltGrfFmtColl() );
for( SwCntntNode* pNd = aIter.First(); pNd; pNd = 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();
// when pending we will not get the correct type, but nsSelectionType::SEL_TXT
// as fallback. This *happens* durning D&D, so we need to check if we are in
// the fallback and just try to get a graphic
const bool bPending(pWrtShell->BasicActionPend());
// SEL_GRF kommt vom ContentType der editsh
if(bPending || ((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->LockExpFlds(); // nie die Felder updaten - Text so belassen
pWrtShell->Copy( pTmpDoc );
// es wurde in der CORE eine neu angelegt (OLE-Objekte kopiert!)
aDocShellRef = pTmpDoc->GetTmpDocShell();
if( aDocShellRef.Is() )
SwTransferable::InitOle( aDocShellRef, *pTmpDoc );
pTmpDoc->SetTmpDocShell( (SfxObjectShell*)NULL );
if( nSelectionType & nsSelectionType::SEL_TXT && !pWrtShell->HasMark() )
{
SwContentAtPos aCntntAtPos( SwContentAtPos::SW_INETATTR );
Point aPos( SwEditWin::GetDDStartPosX(), SwEditWin::GetDDStartPosY());
sal_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:
case SOT_FORMATSTR_ID_PNG:
// #126398# Neither pClpBitmap nor pClpGraphic are necessarily set
if( (eBufferType & TRNSFR_GRAPHIC) && (pClpBitmap != 0 || pClpGraphic != 0))
bOK = SetBitmapEx( (pClpBitmap ? pClpBitmap : pClpGraphic)->GetBitmapEx(), 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, sal_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 = sal_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 = sal_False;
}
break;
}
if( xWrt.Is() )
{
SwDoc* pDoc = (SwDoc*)pObject;
xWrt->bWriteClipboardDoc = sal_True;
xWrt->bWriteOnlyFirstTable = 0 != (TRNSFR_TABELLE & eBufferType);
xWrt->SetShowProgress( sal_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( sal_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( sal_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( SOT_FORMATSTR_ID_PNG );
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 );
// --> OD #i98753#
// set size of embedded object at the object description structure
aObjDesc.maSize = OutputDevice::LogicToLogic( pWrtShell->GetObjSize(), MAP_TWIP, MAP_100TH_MM );
// <--
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->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->getAllMarksBegin();
ppMark != pMarkAccess->getAllMarksEnd();
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!)
aDocShellRef = pTmpDoc->GetTmpDocShell();
if( aDocShellRef.Is() )
SwTransferable::InitOle( aDocShellRef, *pTmpDoc );
pTmpDoc->SetTmpDocShell( (SfxObjectShell*)NULL );
if( pWrtShell->IsObjSelected() )
eBufferType = TRNSFR_DRAWING;
else
{
eBufferType = TRNSFR_DOCUMENT;
if (pWrtShell->IntelligentCut(nSelection, sal_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( SOT_FORMATSTR_ID_PNG );
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 = sal_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( sal_Bool bIsCut )
{
int nRet = PrepareForCopy( bIsCut );
if ( nRet )
{
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 );
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->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!)
aDocShellRef = pCDoc->GetTmpDocShell();
if( aDocShellRef.Is() )
SwTransferable::InitOle( aDocShellRef, *pCDoc );
pCDoc->SetTmpDocShell( (SfxObjectShell*)NULL );
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 = sal_False;
Size aSz( OLESIZE );
aObjDesc.maSize = OutputDevice::LogicToLogic( aSz, MAP_TWIP, MAP_100TH_MM );
PrepareOLE( aObjDesc );
AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
CopyToClipboard( &pWrtShell->GetView().GetEditWin() );
return 1;
}
static inline uno::Reference < XTransferable > * lcl_getTransferPointer ( uno::Reference < XTransferable > &xRef )
{
return &xRef;
}
// -----------------------------------------------------------------------
sal_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 = ( GetSwTransferable( rData ) != 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() );
sal_uInt16 nDestination = SwTransferable::GetSotDestination( rSh );
sal_uInt16 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);
sal_uLong nFormat; // output param for GetExchangeAction
sal_uInt16 nEventAction; // output param for GetExchangeAction
sal_uInt16 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 )
{
sal_uInt16 nEventAction, nAction=0,
nDestination = SwTransferable::GetSotDestination( rSh );
sal_uLong nFormat = 0;
if( GetSwTransferable( rData ) )
{
nAction = EXCHG_OUT_ACTION_INSERT_PRIVATE;
}
else
{
sal_uInt16 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, sal_False, sal_False );
}
// -----------------------------------------------------------------------
int SwTransferable::PasteData( TransferableDataHelper& rData,
SwWrtShell& rSh, sal_uInt16 nAction, sal_uLong nFormat,
sal_uInt16 nDestination, sal_Bool bIsPasteFmt,
sal_Bool bIsDefault,
const Point* pPt, sal_Int8 nDropAction,
sal_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, sal_True, pPt );
break;
// case EXCHG_DEST_DOC_TEXTFRAME:
// case EXCHG_DEST_SWDOC_FREE_AREA:
// case EXCHG_DEST_DOC_URLFIELD:
default:
SwTransferable::SetSelInShell( rSh, sal_False, pPt );
break;
}
}
}
else if( ( !GetSwTransferable( rData ) || 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
sal_Bool bDelSel = sal_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 = sal_True;
break;
}
if( bDelSel )
// --> FME 2004-10-19 #i34830#
pAction = new SwTrnsfrActionAndUndo( &rSh, UNDO_PASTE_CLIPBOARD, NULL,
sal_True );
// <--
}
SwTransferable *pTrans=0, *pTunneledTrans=GetSwTransferable( rData );
// uno::Reference<XUnoTunnel> xTunnel( rData.GetTransferable(), UNO_QUERY );
// if ( xTunnel.is() )
// {
// sal_Int64 nHandle = xTunnel->getSomething( getUnoTunnelId() );
// if ( nHandle )
// pTunneledTrans = (SwTransferable*) (sal_IntPtr) nHandle;
// }
// check for private drop
bool bPrivateDrop(pPt && (bPasteSelection ? 0 != (pTrans = pMod->pXSelection) : 0 != (pTrans = pMod->pDragDrop)));
bool bNeedToSelectBeforePaste(false);
if(bPrivateDrop && DND_ACTION_LINK == nDropAction)
{
// internal drop on object, suppress bPrivateDrop to change internal fill
bPrivateDrop = false;
bNeedToSelectBeforePaste = true;
}
if(bPrivateDrop && pPt && DND_ACTION_MOVE == nDropAction)
{
// check if dragged over a useful target. If yes, use as content exchange
// drop as if from external
const SwFrmFmt* pSwFrmFmt = rSh.GetFmtFromObj(*pPt);
if(pSwFrmFmt && 0 != dynamic_cast< const SwDrawFrmFmt* >(pSwFrmFmt))
{
bPrivateDrop = false;
bNeedToSelectBeforePaste = true;
}
}
if(bPrivateDrop)
{
// then internal Drag & Drop or XSelection
nRet = pTrans->PrivateDrop( rSh, *pPt, DND_ACTION_MOVE == nDropAction,
bPasteSelection );
}
else if( !pPt && pTunneledTrans &&
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
sal_Bool bMsg = 0 == pPt;
sal_uInt8 nActionFlags = static_cast< sal_uInt8 >(( nAction >> 8 ) & 0xFF);
sal_uInt16 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, bNeedToSelectBeforePaste);
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_FORMATSTR_ID_PNG:
case SOT_FORMAT_GDIMETAFILE:
nRet = SwTransferable::_PasteGrf( rData, rSh, nFormat,
SW_PASTESDR_INSERT,pPt,
nActionFlags, nDropAction, bNeedToSelectBeforePaste);
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, sal_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:
{
sal_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, bNeedToSelectBeforePaste);
break;
case SOT_FORMATSTR_ID_SVXB:
case SOT_FORMAT_GDIMETAFILE:
case SOT_FORMAT_BITMAP:
case SOT_FORMATSTR_ID_PNG:
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, nDropAction, bNeedToSelectBeforePaste);
break;
default:
ASSERT( sal_False, "unbekanntes Format" );
}
break;
case EXCHG_OUT_ACTION_INSERT_DRAWOBJ:
nRet = SwTransferable::_PasteSdrFormat( rData, rSh,
SW_PASTESDR_INSERT, pPt,
nActionFlags, bNeedToSelectBeforePaste);
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, nDropAction, bNeedToSelectBeforePaste);
break;
case EXCHG_OUT_ACTION_REPLACE_DRAWOBJ:
nRet = SwTransferable::_PasteSdrFormat( rData, rSh,
SW_PASTESDR_REPLACE, pPt,
nActionFlags, bNeedToSelectBeforePaste);
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, nDropAction, bNeedToSelectBeforePaste);
break;
case EXCHG_OUT_ACTION_INSERT_INTERACTIVE:
nRet = SwTransferable::_PasteAsHyperlink( rData, rSh, nFormat );
break;
default:
ASSERT( sal_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;
}
// -----------------------------------------------------------------------
sal_uInt16 SwTransferable::GetSotDestination( const SwWrtShell& rSh,
const Point* pPt )
{
sal_uInt16 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:
{
sal_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, sal_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, sal_uLong nFmt, sal_Bool bMsg )
{
sal_uInt16 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( sal_True );
//pRead->SetBaseURL( aMSE40ClpObj.GetBaseURL() );
sal_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( sal_True );
}
}
}
break;
}
if( pStream && pRead )
{
Link aOldLink( rSh.GetChgLnk() );
rSh.SetChgLnk( Link() );
const SwPosition& rInsPos = *rSh.GetCrsr()->Start();
SwReader aReader( *pStream, aEmptyStr, String(), *rSh.GetCrsr() );
rSh.SaveTblBoxCntnt( &rInsPos );
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,
sal_uLong nFmt, sal_uInt8 nActionFlags, sal_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;
sal_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, sal_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, sal_uInt16 nAction,
const Point* pPt, sal_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, sal_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, sal_True, &aPt );
}
else
rSh.ReRead( sURL, aEmptyStr, &aGrf );
break;
case SW_PASTESDR_SETATTR:
if( rSh.IsObjSelected() )
rSh.Paste( aGrf, String() );
else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() )
rSh.ReRead( sURL, aEmptyStr, &aGrf );
else
{
SwTransferable::SetSelInShell( rSh, sal_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(), sal_False );
aURL.SetTargetFrameName( aINetImg.GetTargetFrame() );
aSet.Put( aURL );
rSh.SetFlyFrmAttr( aSet );
}
}
return nRet;
}
// -----------------------------------------------------------------------
void SwTransferable::SetSelInShell( SwWrtShell& rSh, sal_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 = sal_True;
}
}
}
else
{
if( rSh.IsFrmSelected() || rSh.IsObjSelected() )
{
rSh.UnSelectFrm();
rSh.LeaveSelFrmMode();
rSh.GetView().GetEditWin().StopInsFrm();
bFrmDrag = sal_False;
}
else if( rSh.GetView().GetDrawFuncPtr() )
rSh.GetView().GetEditWin().StopInsFrm();
rSh.EnterStdMode();
if( pPt )
rSh.SwCrsrShell::SetCrsr( *pPt, sal_True );
}
}
// -----------------------------------------------------------------------
int SwTransferable::_PasteDDE( TransferableDataHelper& rData,
SwWrtShell& rWrtShell, sal_Bool bReReadGrf,
sal_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 ?
sal_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;
sal_uInt16 i = 1,j;
String aName;
sal_Bool bAlreadyThere = sal_False, bDoublePaste = sal_False;
sal_uInt16 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 = sal_True;
break;
}
else if( rColl.isEqual( aName, pTyp->GetName() ) )
break;
}
}
if( j == nSize )
bAlreadyThere = sal_False;
else
{
bAlreadyThere = sal_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( sal_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, sal_uInt16 nAction,
const Point* pPt, sal_uInt8 nActionFlags, bool bNeedToSelectBeforePaste)
{
int nRet = 0;
SotStorageStreamRef xStrm;
if( rData.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStrm ))
{
xStrm->SetVersion( SOFFICE_FILEFORMAT_50 );
if(bNeedToSelectBeforePaste && pPt)
{
// if this is an internal drag, need to set the target right (select it), else
// still the source will be selected
SwTransferable::SetSelInShell( rSh, sal_True, pPt );
}
rSh.Paste( *xStrm, nAction, pPt );
nRet = 1;
if( nRet && ( nActionFlags &
( EXCHG_OUT_ACTION_FLAG_INSERT_TARGETURL >> 8) ))
SwTransferable::_PasteTargetURL( rData, rSh, 0, 0, sal_False );
}
return nRet;
}
// -----------------------------------------------------------------------
int SwTransferable::_PasteGrf( TransferableDataHelper& rData, SwWrtShell& rSh,
sal_uLong nFmt, sal_uInt16 nAction, const Point* pPt,
sal_uInt8 nActionFlags, sal_Int8 nDropAction, bool bNeedToSelectBeforePaste)
{
int nRet = 0;
Graphic aGrf;
INetBookmark aBkmk;
sal_Bool bCheckForGrf = sal_False, bCheckForImageMap = sal_False;
switch( nFmt )
{
case SOT_FORMAT_BITMAP:
case SOT_FORMATSTR_ID_PNG:
case SOT_FORMAT_GDIMETAFILE:
nRet = rData.GetGraphic( nFmt, aGrf );
break;
case SOT_FORMATSTR_ID_SVXB:
{
SotStorageStreamRef xStm;
if(rData.GetSotStorageStream(SOT_FORMATSTR_ID_SVXB, xStm))
{
*xStm >> aGrf;
nRet = (GRAPHIC_NONE != aGrf.GetType() && GRAPHIC_DEFAULT != aGrf.GetType());
}
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 = sal_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 = sal_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 = sal_True;
}
}
if(pPt && bNeedToSelectBeforePaste)
{
// when using internal D&Ds, still the source object is selected and
// this is necessary to get the correct source data which is also
// dependent from selection. After receiving the drag data it is
// now tiime to select the correct target object
SwTransferable::SetSelInShell( rSh, sal_True, pPt );
}
if( nRet )
{
String sURL;
if( rSh.GetView().GetDocShell()->ISA(SwWebDocShell)
// #123922# if link action is noted, also take URL
|| DND_ACTION_LINK == nDropAction)
{
sURL = aBkmk.GetURL();
}
switch( nAction )
{
case SW_PASTESDR_INSERT:
{
SwTransferable::SetSelInShell( rSh, sal_False, pPt );
rSh.Insert( sURL, aEmptyStr, aGrf );
break;
}
case SW_PASTESDR_REPLACE:
{
if( rSh.IsObjSelected() )
{
// #123922# for D&D on draw objects, do for now the same for
// SW_PASTESDR_REPLACE (D&D) as for SW_PASTESDR_SETATTR (D&D and
// CTRL+SHIFT). The code below replaces the draw object with
// a writer graphic; maybe this is an option later again if wanted
rSh.Paste( aGrf, sURL );
// rSh.ReplaceSdrObj( sURL, aEmptyStr, &aGrf );
// Point aPt( pPt ? *pPt : rSh.GetCrsrDocPos() );
// SwTransferable::SetSelInShell( rSh, sal_True, &aPt );
}
else
{
// set graphic at writer graphic without link
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(), sal_False );
aSet.Put( aURL );
rSh.SetFlyFrmAttr( aSet );
}
}
else if( rSh.IsObjSelected() )
{
// set as attribute at DrawObject
rSh.Paste( aGrf, sURL );
}
else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() )
{
// set as linked graphic at writer graphic frame
rSh.ReRead( sURL, aEmptyStr, &aGrf );
}
else
{
SwTransferable::SetSelInShell( rSh, sal_False, pPt );
rSh.Insert( aBkmk.GetURL(), aEmptyStr, aGrf );
}
break;
}
default:
{
nRet = 0;
break;
}
}
}
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, sal_False );
}
else if( bCheckForImageMap )
{
// oder sollte das File ein ImageMap-File sein?
ImageMap aMap;
SfxMedium aMed( INetURLObject(aBkmk.GetURL()).GetFull(),
STREAM_STD_READ, sal_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, sal_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, sal_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 = sal_True;
}
return nRet;
}
// -----------------------------------------------------------------------
int SwTransferable::_PasteFileName( TransferableDataHelper& rData,
SwWrtShell& rSh, sal_uLong nFmt,
sal_uInt16 nAction, const Point* pPt,
sal_uInt8 nActionFlags, sal_Bool /* bMsg */)
{
int nRet = SwTransferable::_PasteGrf( rData, rSh, nFmt, nAction,
pPt, nActionFlags, 0, false);
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
{
sal_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, sal_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 = sal_True;
}
}
}
}
return nRet;
}
// -----------------------------------------------------------------------
int SwTransferable::_PasteDBData( TransferableDataHelper& rData,
SwWrtShell& rSh, sal_uLong nFmt, sal_Bool bLink,
const Point* pDragPt, sal_Bool bMsg )
{
int nRet = 0;
String sTxt;
if( rData.GetString( nFmt, sTxt ) && sTxt.Len() )
{
sal_uInt16 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;
sal_Bool bDataAvailable = sal_True;
ODataAccessDescriptor aDesc;
if(bHaveColumnDescriptor)
aDesc = OColumnTransferable::extractColumnDescriptor(rData);
else if(ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
aDesc = ODataAccessObjectTransferable::extractObjectDescriptor(rData);
else
bDataAvailable = sal_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, sal_Bool bLink,
const Point* pPt, sal_Bool bMsg )
{
int nRet = 0;
FileList aFileList;
if( rData.GetFileList( SOT_FORMAT_FILE_LIST, aFileList ) &&
aFileList.Count() )
{
sal_uInt16 nAct = bLink ? SW_PASTESDR_SETATTR : SW_PASTESDR_INSERT;
String sFlyNm;
// iterate over the filelist
for( sal_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, sal_False, bMsg ))
{
if( bLink )
{
sFlyNm = rSh.GetFlyName();
SwTransferable::SetSelInShell( rSh, sal_False, pPt );
}
nRet = 1;
}
}
if( sFlyNm.Len() )
rSh.GotoFly( sFlyNm );
}
else if( bMsg )
{
InfoBox( 0, SW_RES(MSG_CLPBRD_FORMAT_ERROR)).Execute();
}
return nRet;
}
// -----------------------------------------------------------------------
sal_Bool SwTransferable::_CheckForURLOrLNKFile( TransferableDataHelper& rData,
String& rFileName, String* pTitle )
{
sal_Bool bIsURLFile = sal_False;
INetBookmark aBkmk;
if( rData.GetINetBookmark( SOT_FORMATSTR_ID_SOLK, aBkmk ) )
{
rFileName = aBkmk.GetURL();
if( pTitle )
*pTitle = aBkmk.GetDescription();
bIsURLFile = sal_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;
}
// -----------------------------------------------------------------------
sal_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,
sal_uLong nFormat )
{
SwWait aWait( *rSh.GetView().GetDocShell(), false );
int nRet = 0;
sal_uLong nPrivateFmt = FORMAT_PRIVATE;
SwTransferable *pClipboard = GetSwTransferable( rData );
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() );
sal_uInt16 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, sal_True, sal_False );
}
return nRet;
}
// -----------------------------------------------------------------------
int SwTransferable::_TestAllowedFormat( const TransferableDataHelper& rData,
sal_uLong nFormat, sal_uInt16 nDestination )
{
sal_uInt16 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 sal_uInt16 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, sal_uLong& rFormatUsed )
{
int nRet = 0;
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
SfxAbstractPasteDialog* pDlg = pFact->CreatePasteDialog( &rSh.GetView().GetEditWin() );
DataFlavorExVector aFormats( rData.GetDataFlavorExVector() );
TransferableObjectDescriptor aDesc;
sal_uInt16 nDest = SwTransferable::GetSotDestination( rSh );
SwTransferable *pClipboard = GetSwTransferable( rData );
if( pClipboard )
{
aDesc = pClipboard->aObjDesc;
sal_uInt16 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( sal_uInt16* pIds = aPasteSpecialIds; *pIds; ++pIds )
if( SwTransferable::_TestAllowedFormat( rData, *pIds, nDest ))
pDlg->Insert( *pIds, aEmptyStr );
sal_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 )
{
sal_uInt16 nDest = SwTransferable::GetSotDestination( rSh );
SwTransferable *pClipboard = GetSwTransferable( rData );
if( pClipboard )
{
sal_uInt16 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( sal_uInt16* 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( SOT_FORMATSTR_ID_PNG );
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, sal_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( SOT_FORMATSTR_ID_PNG );
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 = sal_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 = sal_True;
((SwViewOption *)pWrtShell->GetViewOptions())->SetIdle( sal_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(), sal_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 sal_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, sal_True );
}
rShell.SetRetainSelection( false );
}
sal_Bool bInWrd = sal_False, bEndWrd = sal_False, bSttWrd = sal_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 = sal_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,
sal_Bool bMove, sal_Bool bIsXSelection )
{
int cWord = 0;
sal_Bool bInWrd = sal_False;
sal_Bool bEndWrd = sal_False;
sal_Bool bSttWrd = sal_False;
sal_Bool bSttPara= sal_False;
sal_Bool bTblSel = sal_False;
sal_Bool bFrmSel = sal_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 = sal_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(), sal_False );
aSet.Put( aURL );
rSh.SetFlyFrmAttr( aSet );
return 1;
}
if( nsSelectionType::SEL_DRW & nSelection )
{
rSh.LeaveSelFrmMode();
rSh.UnSelectFrm();
rSh.ShowCrsr();
bFrmDrag = sal_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 = sal_True;
else if( rSrcSh.IsSelFrmMode() || rSrcSh.IsObjSelected() )
{
// keine positionsgeschuetzten Objecte verschieben!
if( bMove && rSrcSh.IsSelObjProtected( FLYPROTECT_POS ) )
return 0;
bFrmSel = sal_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, sal_True );
cWord = rSrcSh.IntelligentCut( nSel, sal_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, sal_True, false );
rSh.GoPrevCrsr();
cWord = rSh.IntelligentCut( rSh.GetSelectionType(), sal_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, sal_True );
rSh.SelectTxtAttr( RES_TXTATR_INETFMT );
if( rSh.ChgCurrPam( rDragPt ) )
{
// nicht in sich selbst kopieren/verschieben
rSh.DestroyCrsr();
rSh.EndUndo();
rSh.EndAction();
rSh.EndAction();
return 0;
}
rSh.GoNextCrsr();
}
else
{
rSrcSh.SwCrsrShell::SetCrsr( aSttPt, sal_True );
rSrcSh.SelectTxtAttr( RES_TXTATR_INETFMT );
}
// ist am Einfuege Punkt ein URL-Attribut? Dann das ersetzen,
// also einfach eine Selektion aufspannen?
rSh.DelINetAttrWithText();
bDDINetAttr = sal_True;
}
if ( rSrcSh.IsSelFrmMode() )
{
//Hack: Spezialbehandlung austricksen
aSttPt -= aSttPt - rSrcSh.GetObjRect().Pos();
}
sal_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( sal_False );
else if ( cWord == SwWrtShell::WORD_SPACE_AFTER )
rSh.ExtendSelection();
rSrcSh.DelRight();
}
}
rSrcSh.KillPams();
rSrcSh.Pop( sal_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();
rSh.EndUndo();
// 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;
}
SwTransferable* SwTransferable::GetSwTransferable( const TransferableDataHelper& rData )
{
SwTransferable* pSwTransferable = NULL;
uno::Reference<XUnoTunnel> xTunnel( rData.GetTransferable(), UNO_QUERY );
if ( xTunnel.is() )
{
sal_Int64 nHandle = xTunnel->getSomething( getUnoTunnelId() );
if ( nHandle )
pSwTransferable = (SwTransferable*) (sal_IntPtr) nHandle;
}
return pSwTransferable;
}
/* */
// -----------------------------------------------------------------------
SwTrnsfrDdeLink::SwTrnsfrDdeLink( SwTransferable& rTrans, SwWrtShell& rSh )
: rTrnsfr( rTrans ), pDocShell( 0 ),
bDelBookmrk( sal_False ), bInDisconnect( sal_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
sal_Bool bUndo = rSh.DoesUndo();
rSh.DoUndo( sal_False );
sal_Bool bIsModified = rSh.IsModified();
::sw::mark::IMark* pMark = rSh.SetBookmark(
KeyCode(),
::rtl::OUString(),
::rtl::OUString(),
IDocumentMarkAccess::DDE_BOOKMARK);
if(pMark)
{
sName = pMark->GetName();
bDelBookmrk = sal_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( sal_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( sal_False );
}
}
// -----------------------------------------------------------------------
sal_Bool SwTrnsfrDdeLink::WriteData( SvStream& rStrm )
{
if( !refObj.Is() || !FindDocShell() )
return sal_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;
IDocumentMarkAccess* const pMarkAccess = pDocShell->GetDoc()->getIDocumentMarkAccess();
IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(sName);
if(ppMark != pMarkAccess->getAllMarksEnd()
&& 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( sal_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!)
const sal_Bool bOldDisconnect = bInDisconnect;
bInDisconnect = sal_True;
// den nicht verwendeten Bookmark wieder zerstoeren (ohne Undo!)?
if( bDelBookmrk && refObj.Is() && FindDocShell() )
{
SwDoc* pDoc = pDocShell->GetDoc();
::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
// --> OD, CD, OS 2005-11-25 #i58448#
Link aSavedOle2Link( pDoc->GetOle2Link() );
pDoc->SetOle2Link( Link() );
// <--
sal_Bool bIsModified = pDoc->IsModified();
IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
// check, if DdeBookmark is already in its desctruction
IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(sName);
if ( ppMark != pMarkAccess->getAllMarksEnd() )
{
::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(ppMark->get());
if ( pDdeBookmark && !pDdeBookmark->IsInDestruction() )
{
pMarkAccess->deleteMark(ppMark);
}
}
if( !bIsModified )
pDoc->ResetModified();
pDoc->SetOle2Link( aSavedOle2Link );
bDelBookmrk = sal_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;
}
// -----------------------------------------------------------------------
sal_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 sal_True;
break; // das Doc ist nicht mehr vorhanden, also raus!
}
pTmpSh = SfxObjectShell::GetNext( *pTmpSh, &aType );
}
pDocShell = 0;
return sal_False;
}
// -----------------------------------------------------------------------
void SwTrnsfrDdeLink::Closed()
{
if( !bInDisconnect && refObj.Is() )
{
refObj->RemoveAllDataAdvise( this );
refObj->RemoveConnectAdvise( this );
refObj.Clear();
}
}