1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
21 #include <com/sun/star/embed/Aspects.hpp>
22 #include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
25 #include <svx/unomodel.hxx>
26 #include <unotools/streamwrap.hxx>
28 #include <svx/fmmodel.hxx>
29 #include <svx/svdetc.hxx>
30 #include <svx/svditer.hxx>
31 #include <svx/svdobj.hxx>
32 #include <svx/svdogrp.hxx>
33 #include <svx/svdouno.hxx>
34 #include <svx/svdoole2.hxx>
35 #include <svx/svdpage.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <comphelper/classids.hxx>
39 #include <sot/formats.hxx>
40 #include <sot/filelist.hxx>
41 #include <unotools/pathoptions.hxx>
42 #include <svl/ptitem.hxx>
43 #include <svl/stritem.hxx>
44 #include <svtools/transfer.hxx>
45 #include <vcl/graph.hxx>
47 #include <comphelper/processfactory.hxx>
48 #include <comphelper/storagehelper.hxx>
49 #include <comphelper/string.hxx>
51 #include "viewfunc.hxx"
53 #include "drawview.hxx"
59 #include "scextopt.hxx"
60 #include "tabvwsh.hxx"
61 #include "compiler.hxx"
63 #include "asciiopt.hxx"
64 #include "scabstdlg.hxx"
65 #include "clipparam.hxx"
66 #include "markdata.hxx"
67 #include <vcl/msgbox.hxx>
68 #include <sfx2/viewfrm.hxx>
69 #include <svx/dbaexchange.hxx>
70 #include <boost/scoped_ptr.hpp>
72 using namespace com::sun::star
;
74 bool ScViewFunc::PasteDataFormat( sal_uLong nFormatId
,
75 const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
,
76 SCCOL nPosX
, SCROW nPosY
, Point
* pLogicPos
, bool bLink
, bool bAllowDialogs
)
78 ScDocument
* pDoc
= GetViewData()->GetDocument();
79 pDoc
->SetPastingDrawFromOtherDoc( true );
81 Point aPos
; // inserting position (1/100 mm)
86 // inserting position isn't needed for text formats
87 bool bIsTextFormat
= ( ScImportExport::IsFormatSupported( nFormatId
) ||
88 nFormatId
== FORMAT_RTF
);
91 // Window MapMode isn't drawing MapMode if DrawingLayer hasn't been created yet
93 SCTAB nTab
= GetViewData()->GetTabNo();
95 for (SCCOL i
=0; i
<nPosX
; i
++)
96 nXT
+= pDoc
->GetColWidth(i
,nTab
);
97 if (pDoc
->IsNegativePage(nTab
))
99 sal_uLong nYT
= pDoc
->GetRowHeight( 0, nPosY
-1, nTab
);
100 aPos
= Point( (long)(nXT
* HMM_PER_TWIPS
), (long)(nYT
* HMM_PER_TWIPS
) );
104 TransferableDataHelper
aDataHelper( rxTransferable
);
108 // handle individual formats
111 if ( nFormatId
== SOT_FORMATSTR_ID_EMBED_SOURCE
||
112 nFormatId
== SOT_FORMATSTR_ID_LINK_SOURCE
||
113 nFormatId
== SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
||
114 nFormatId
== SOT_FORMATSTR_ID_LINK_SOURCE_OLE
||
115 nFormatId
== SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
)
117 uno::Reference
< io::XInputStream
> xStm
;
118 TransferableObjectDescriptor aObjDesc
;
120 if (aDataHelper
.GetTransferableObjectDescriptor(SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aObjDesc
))
121 xStm
= aDataHelper
.GetInputStream(nFormatId
, OUString());
125 if ( aObjDesc
.maClassName
== SvGlobalName( SO3_SC_CLASSID_60
) )
127 uno::Reference
< embed::XStorage
> xStore
= ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm
);
129 // mba: BaseURL doesn't make sense for clipboard
130 // #i43716# Medium must be allocated with "new".
131 // DoLoad stores the pointer and deletes it with the SfxObjectShell.
132 SfxMedium
* pMedium
= new SfxMedium( xStore
, OUString() );
134 // TODO/LATER: is it a problem that we don't support binary formats here?
135 ScDocShellRef xDocShRef
= new ScDocShell(SFX_CREATE_MODE_EMBEDDED
);
136 if (xDocShRef
->DoLoad(pMedium
))
138 ScDocument
* pSrcDoc
= xDocShRef
->GetDocument();
139 SCTAB nSrcTab
= pSrcDoc
->GetVisibleTab();
140 if (!pSrcDoc
->HasTable(nSrcTab
))
144 aSrcMark
.SelectOneTable( nSrcTab
); // for CopyToClip
145 boost::scoped_ptr
<ScDocument
> pClipDoc(new ScDocument( SCDOCMODE_CLIP
));
147 SCCOL nFirstCol
, nLastCol
;
148 SCROW nFirstRow
, nLastRow
;
149 if ( pSrcDoc
->GetDataStart( nSrcTab
, nFirstCol
, nFirstRow
) )
150 pSrcDoc
->GetCellArea( nSrcTab
, nLastCol
, nLastRow
);
153 nFirstCol
= nLastCol
= 0;
154 nFirstRow
= nLastRow
= 0;
156 ScClipParam
aClipParam(ScRange(nFirstCol
, nFirstRow
, nSrcTab
, nLastCol
, nLastRow
, nSrcTab
), false);
157 pSrcDoc
->CopyToClip(aClipParam
, pClipDoc
.get(), &aSrcMark
);
158 ScGlobal::SetClipDocName( xDocShRef
->GetTitle( SFX_TITLE_FULLNAME
) );
160 SetCursor( nPosX
, nPosY
);
162 PasteFromClip( IDF_ALL
, pClipDoc
.get(),
163 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
168 xDocShRef
->DoClose();
174 uno::Reference
< embed::XEmbeddedObject
> xObj
= GetViewData()->GetViewShell()->GetObjectShell()->
175 GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
178 // try to get the replacement image from the clipboard
180 sal_uLong nGrFormat
= 0;
182 // limit the size of the preview metafile to 100000 actions
183 GDIMetaFile aMetafile
;
184 if (aDataHelper
.GetGDIMetaFile(FORMAT_GDIMETAFILE
, aMetafile
, 100000))
186 nGrFormat
= SOT_FORMAT_GDIMETAFILE
;
187 aGraphic
= aMetafile
;
190 // insert replacement image ( if there is one ) into the object helper
193 datatransfer::DataFlavor aDataFlavor
;
194 SotExchange::GetFormatDataFlavor( nGrFormat
, aDataFlavor
);
195 PasteObject( aPos
, xObj
, &aObjDesc
.maSize
, &aGraphic
, aDataFlavor
.MimeType
, aObjDesc
.mnViewAspect
);
198 PasteObject( aPos
, xObj
, &aObjDesc
.maSize
);
204 OSL_FAIL("Error in CreateAndLoad");
210 if ( aDataHelper
.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE
, aObjDesc
) )
213 uno::Reference
< embed::XEmbeddedObject
> xObj
;
214 xStm
= aDataHelper
.GetInputStream(SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
, OUString());
216 aDataHelper
.GetInputStream(SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE
, OUString());
220 xObj
= GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
226 uno::Reference
< embed::XStorage
> xTmpStor
= ::comphelper::OStorageHelper::GetTemporaryStorage();
227 uno::Reference
< embed::XEmbedObjectClipboardCreator
> xClipboardCreator
=
228 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
230 embed::InsertedObjectInfo aInfo
= xClipboardCreator
->createInstanceInitFromClipboard(
232 OUString( "DummyName" ),
233 uno::Sequence
< beans::PropertyValue
>() );
235 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
236 // for example whether the object should be an iconified one
239 GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj
, aName
);
241 catch( uno::Exception
& )
247 // try to get the replacement image from the clipboard
249 sal_uLong nGrFormat
= 0;
251 // (wg. Selection Manager bei Trustet Solaris)
253 if( aDataHelper
.GetGraphic( SOT_FORMATSTR_ID_SVXB
, aGraphic
) )
254 nGrFormat
= SOT_FORMATSTR_ID_SVXB
;
255 else if( aDataHelper
.GetGraphic( FORMAT_GDIMETAFILE
, aGraphic
) )
256 nGrFormat
= SOT_FORMAT_GDIMETAFILE
;
257 else if( aDataHelper
.GetGraphic( FORMAT_BITMAP
, aGraphic
) )
258 nGrFormat
= SOT_FORMAT_BITMAP
;
261 // insert replacement image ( if there is one ) into the object helper
264 datatransfer::DataFlavor aDataFlavor
;
265 SotExchange::GetFormatDataFlavor( nGrFormat
, aDataFlavor
);
266 PasteObject( aPos
, xObj
, &aObjDesc
.maSize
, &aGraphic
, aDataFlavor
.MimeType
, aObjDesc
.mnViewAspect
);
269 PasteObject( aPos
, xObj
, &aObjDesc
.maSize
);
271 // let object stay in loaded state after insertion
272 SdrOle2Obj::Unload( xObj
, embed::Aspects::MSOLE_CONTENT
);
277 OSL_FAIL("Error creating external OLE object");
280 //TODO/LATER: if format is not available, create picture
283 else if ( nFormatId
== SOT_FORMATSTR_ID_LINK
) // LINK is also in ScImportExport
285 bRet
= PasteLink( rxTransferable
);
287 else if ( ScImportExport::IsFormatSupported( nFormatId
) || nFormatId
== SOT_FORMAT_RTF
)
289 if ( nFormatId
== SOT_FORMAT_RTF
&& aDataHelper
.HasFormat( SOT_FORMATSTR_ID_EDITENGINE
) )
291 // use EditView's PasteSpecial / Drop
292 PasteRTF( nPosX
, nPosY
, rxTransferable
);
297 ScAddress
aCellPos( nPosX
, nPosY
, GetViewData()->GetTabNo() );
298 ScImportExport
aObj( GetViewData()->GetDocument(), aCellPos
);
299 aObj
.SetOverwriting( true );
302 SotStorageStreamRef xStream
;
303 if ( aDataHelper
.GetSotStorageStream( nFormatId
, xStream
) && xStream
.Is() )
305 if (nFormatId
== SOT_FORMATSTR_ID_HTML
)
307 // Launch the text import options dialog. For now, we do
308 // this for html pasting only, but in the future it may
309 // make sense to do it for other data types too.
310 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
311 boost::scoped_ptr
<AbstractScTextImportOptionsDlg
> pDlg(
312 pFact
->CreateScTextImportOptionsDlg(NULL
));
314 if (pDlg
->Execute() == RET_OK
)
316 ScAsciiOptions aOptions
;
317 aOptions
.SetLanguage(pDlg
->GetLanguageType());
318 aOptions
.SetDetectSpecialNumber(pDlg
->IsDateConversionSet());
319 aObj
.SetExtOptions(aOptions
);
323 // prevent error dialog for user cancel action
328 bRet
= aObj
.ImportStream( *xStream
, OUString(), nFormatId
);
329 // mba: clipboard always must contain absolute URLs (could be from alien source)
331 else if (nFormatId
== FORMAT_STRING
&& aDataHelper
.GetString( nFormatId
, aStr
))
333 // Do CSV dialog if more than one line.
334 sal_Int32 nDelim
= aStr
.indexOf('\n');
335 if (nDelim
>= 0 && nDelim
!= aStr
.getLength () - 1)
337 ScImportStringStream
aStrm( aStr
);
338 ScAbstractDialogFactory
* pFact
=
339 ScAbstractDialogFactory::Create();
340 boost::scoped_ptr
<AbstractScImportAsciiDlg
> pDlg(
341 pFact
->CreateScImportAsciiDlg( NULL
, OUString(), &aStrm
,
344 if (pDlg
->Execute() == RET_OK
)
346 ScAsciiOptions aOptions
;
347 pDlg
->GetOptions( aOptions
);
348 pDlg
->SaveParameters();
349 aObj
.SetExtOptions( aOptions
);
351 bRet
= aObj
.ImportString( aStr
, nFormatId
);
353 // TODO: what if (aObj.IsOverflow())
354 // Content was partially pasted, which can be undone by
356 if (aObj
.IsOverflow())
361 // Yes, no failure, don't raise a "couldn't paste"
362 // dialog if user cancelled.
365 bRet
= aObj
.ImportString( aStr
, nFormatId
);
367 else if (nFormatId
!= FORMAT_STRING
&& aDataHelper
.GetString( nFormatId
, aStr
))
368 bRet
= aObj
.ImportString( aStr
, nFormatId
);
371 GetViewData()->UpdateInputHandler();
374 else if (nFormatId
== SOT_FORMATSTR_ID_SBA_DATAEXCHANGE
)
376 // import of database data into table
378 const DataFlavorExVector
& rVector
= aDataHelper
.GetDataFlavorExVector();
379 if ( svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector
) )
381 // transport the whole ODataAccessDescriptor as slot parameter
382 svx::ODataAccessDescriptor aDesc
= svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper
);
384 uno::Sequence
<beans::PropertyValue
> aProperties
= aDesc
.createPropertyValueSequence();
385 aDescAny
<<= aProperties
;
386 SfxUsrAnyItem
aDataDesc(SID_SBA_IMPORT
, aDescAny
);
388 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
389 SCTAB nTab
= GetViewData()->GetTabNo();
391 ClickCursor(nPosX
, nPosY
, false); // set cursor position
393 // Creation of database area "Import1" isn't here, but in the DocShell
394 // slot execute, so it can be added to the undo action
396 ScDBData
* pDBData
= pDocSh
->GetDBData( ScRange(nPosX
,nPosY
,nTab
), SC_DB_OLD
, SC_DBSEL_KEEP
);
399 sTarget
= pDBData
->GetName();
402 ScAddress
aCellPos( nPosX
,nPosY
,nTab
);
403 sTarget
= aCellPos
.Format(SCA_ABS_3D
, pDoc
, pDoc
->GetAddressConvention());
405 SfxStringItem
aTarget(FN_PARAM_1
, sTarget
);
407 bool bAreaIsNew
= !pDBData
;
408 SfxBoolItem
aAreaNew(FN_PARAM_2
, bAreaIsNew
);
410 // asynchronous, to avoid doing the whole import in drop handler
411 SfxDispatcher
& rDisp
= GetViewData()->GetDispatcher();
412 rDisp
.Execute(SID_SBA_IMPORT
, SFX_CALLMODE_ASYNCHRON
,
413 &aDataDesc
, &aTarget
, &aAreaNew
, (void*)0 );
418 else if (nFormatId
== SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE
)
420 // insert database field control
422 if ( ::svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper
.GetDataFlavorExVector(), CTF_COLUMN_DESCRIPTOR
| CTF_CONTROL_EXCHANGE
) )
425 ScDrawView
* pScDrawView
= GetScDrawView();
426 SdrObject
* pObj
= pScDrawView
->CreateFieldControl( ::svx::OColumnTransferable::extractColumnDescriptor( aDataHelper
) );
429 Point aInsPos
= aPos
;
430 Rectangle
aRect(pObj
->GetLogicRect());
431 aInsPos
.X() -= aRect
.GetSize().Width() / 2;
432 aInsPos
.Y() -= aRect
.GetSize().Height() / 2;
433 if ( aInsPos
.X() < 0 ) aInsPos
.X() = 0;
434 if ( aInsPos
.Y() < 0 ) aInsPos
.Y() = 0;
435 aRect
.SetPos(aInsPos
);
436 pObj
->SetLogicRect(aRect
);
438 if ( pObj
->ISA(SdrUnoObj
) )
439 pObj
->NbcSetLayer(SC_LAYER_CONTROLS
);
441 pObj
->NbcSetLayer(SC_LAYER_FRONT
);
442 if (pObj
->ISA(SdrObjGroup
))
444 SdrObjListIter
aIter( *pObj
, IM_DEEPWITHGROUPS
);
445 SdrObject
* pSubObj
= aIter
.Next();
448 if ( pSubObj
->ISA(SdrUnoObj
) )
449 pSubObj
->NbcSetLayer(SC_LAYER_CONTROLS
);
451 pSubObj
->NbcSetLayer(SC_LAYER_FRONT
);
452 pSubObj
= aIter
.Next();
456 pScDrawView
->InsertObjectSafe(pObj
, *pScDrawView
->GetSdrPageView());
458 GetViewData()->GetViewShell()->SetDrawShell( true );
463 else if (nFormatId
== SOT_FORMAT_BITMAP
|| nFormatId
== SOT_FORMATSTR_ID_PNG
)
466 if( aDataHelper
.GetBitmapEx( FORMAT_BITMAP
, aBmpEx
) )
467 bRet
= PasteBitmapEx( aPos
, aBmpEx
);
469 else if (nFormatId
== SOT_FORMAT_GDIMETAFILE
)
472 if( aDataHelper
.GetGDIMetaFile( FORMAT_GDIMETAFILE
, aMtf
) )
473 bRet
= PasteMetaFile( aPos
, aMtf
);
475 else if (nFormatId
== SOT_FORMATSTR_ID_SVXB
)
477 SotStorageStreamRef xStm
;
478 if( aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB
, xStm
) )
481 ReadGraphic( *xStm
, aGraphic
);
482 bRet
= PasteGraphic( aPos
, aGraphic
, EMPTY_OUSTRING
, EMPTY_OUSTRING
);
485 else if ( nFormatId
== SOT_FORMATSTR_ID_DRAWING
)
487 SotStorageStreamRef xStm
;
488 if( aDataHelper
.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING
, xStm
) )
490 MakeDrawLayer(); // before loading model, so 3D factory has been created
492 SvtPathOptions aPathOpt
;
493 OUString aPath
= aPathOpt
.GetPalettePath();
495 ScDocShellRef
aDragShellRef( new ScDocShell
);
496 aDragShellRef
->DoInitNew(NULL
);
497 boost::scoped_ptr
<FmFormModel
> pModel(new FmFormModel( aPath
, NULL
, aDragShellRef
));
499 pModel
->GetItemPool().FreezeIdRanges();
502 com::sun::star::uno::Reference
< com::sun::star::io::XInputStream
> xInputStream( new utl::OInputStreamWrapper( *xStm
) );
503 SvxDrawingLayerImport( pModel
.get(), xInputStream
);
505 // set everything to right layer:
506 sal_uLong nObjCount
= 0;
507 sal_uInt16 nPages
= pModel
->GetPageCount();
508 for (sal_uInt16 i
=0; i
<nPages
; i
++)
510 SdrPage
* pPage
= pModel
->GetPage(i
);
511 SdrObjListIter
aIter( *pPage
, IM_DEEPWITHGROUPS
);
512 SdrObject
* pObject
= aIter
.Next();
515 if ( pObject
->ISA(SdrUnoObj
) )
516 pObject
->NbcSetLayer(SC_LAYER_CONTROLS
);
518 pObject
->NbcSetLayer(SC_LAYER_FRONT
);
519 pObject
= aIter
.Next();
522 nObjCount
+= pPage
->GetObjCount(); // count group object only once
525 PasteDraw(aPos
, pModel
.get(), (nObjCount
> 1), "A", "B"); // grouped if more than 1 object
527 aDragShellRef
->DoClose();
531 else if ( (nFormatId
== SOT_FORMATSTR_ID_BIFF_5
) || (nFormatId
== SOT_FORMATSTR_ID_BIFF_8
) )
533 // do excel import into a clipboard document
535 uno::Reference
<io::XInputStream
> xStm
= aDataHelper
.GetInputStream(nFormatId
, OUString());
538 ScDocument
* pInsDoc
= new ScDocument( SCDOCMODE_CLIP
);
539 SCTAB nSrcTab
= 0; // Biff5 in clipboard: always sheet 0
540 pInsDoc
->ResetClip( pDoc
, nSrcTab
);
543 aMed
.GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM
, uno::makeAny( xStm
) ) );
544 FltError eErr
= ScFormatFilter::Get().ScImportExcel( aMed
, pInsDoc
, EIF_AUTO
);
545 if ( eErr
== eERR_OK
)
548 const ScExtDocOptions
* pExtOpt
= pInsDoc
->GetExtDocOptions();
549 const ScExtTabSettings
* pTabSett
= pExtOpt
? pExtOpt
->GetTabSettings( nSrcTab
) : 0;
550 if( pTabSett
&& pTabSett
->maUsedArea
.IsValid() )
552 aSource
= pTabSett
->maUsedArea
;
553 // ensure correct sheet indexes
554 aSource
.aStart
.SetTab( nSrcTab
);
555 aSource
.aEnd
.SetTab( nSrcTab
);
556 // don't use selection area: if cursor is moved in Excel after Copy, selection
557 // represents the new cursor position and not the copied area
561 OSL_FAIL("no dimension"); //! possible?
562 SCCOL nFirstCol
, nLastCol
;
563 SCROW nFirstRow
, nLastRow
;
564 if ( pInsDoc
->GetDataStart( nSrcTab
, nFirstCol
, nFirstRow
) )
565 pInsDoc
->GetCellArea( nSrcTab
, nLastCol
, nLastRow
);
568 nFirstCol
= nLastCol
= 0;
569 nFirstRow
= nLastRow
= 0;
571 aSource
= ScRange( nFirstCol
, nFirstRow
, nSrcTab
,
572 nLastCol
, nLastRow
, nSrcTab
);
577 // position specified (Drag&Drop) - change selection
578 MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, false, false );
582 pInsDoc
->SetClipArea( aSource
);
583 PasteFromClip( IDF_ALL
, pInsDoc
,
584 PASTE_NOFUNC
, false, false, false, INS_NONE
, IDF_NONE
,
592 else if ( nFormatId
== SOT_FORMAT_FILE
)
595 if ( aDataHelper
.GetString( nFormatId
, aFile
) )
596 bRet
= PasteFile( aPos
, aFile
, bLink
);
598 else if ( nFormatId
== SOT_FORMAT_FILE_LIST
)
601 if ( aDataHelper
.GetFileList( nFormatId
, aFileList
) )
603 sal_uLong nCount
= aFileList
.Count();
604 for( sal_uLong i
= 0; i
< nCount
; i
++ )
606 OUString aFile
= aFileList
.GetFile( i
);
608 PasteFile( aPos
, aFile
, bLink
);
616 else if ( nFormatId
== SOT_FORMATSTR_ID_SOLK
||
617 nFormatId
== SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR
||
618 nFormatId
== SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK
||
619 nFormatId
== SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR
)
621 bRet
= PasteBookmark( nFormatId
, rxTransferable
, nPosX
, nPosY
);
624 pDoc
->SetPastingDrawFromOtherDoc( false );
629 bool ScViewFunc::PasteLink( const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
)
631 TransferableDataHelper
aDataHelper( rxTransferable
);
633 // get link data from transferable before string data,
634 // so the source knows it will be used for a link
636 uno::Sequence
<sal_Int8
> aSequence
= aDataHelper
.GetSequence(SOT_FORMATSTR_ID_LINK
, OUString());
637 if (!aSequence
.getLength())
639 OSL_FAIL("DDE Data not found.");
643 // check size (only if string is available in transferable)
645 sal_uInt16 nCols
= 1;
646 sal_uInt16 nRows
= 1;
647 if ( aDataHelper
.HasFormat( SOT_FORMAT_STRING
) )
650 if ( aDataHelper
.GetString( SOT_FORMAT_STRING
, aDataStr
) )
652 // get size from string the same way as in ScDdeLink::DataChanged
654 aDataStr
= convertLineEnd(aDataStr
, LINEEND_LF
);
655 sal_Int32 nLen
= aDataStr
.getLength();
656 if (nLen
&& aDataStr
[nLen
-1] == '\n')
657 aDataStr
= aDataStr
.copy(0, nLen
-1);
659 if (!aDataStr
.isEmpty())
661 nRows
= comphelper::string::getTokenCount(aDataStr
, '\n');
662 OUString aLine
= aDataStr
.getToken( 0, '\n' );
663 if (!aLine
.isEmpty())
664 nCols
= comphelper::string::getTokenCount(aLine
, '\t');
671 sal_Int32 nSeqLen
= aSequence
.getLength();
672 const char* p
= reinterpret_cast<const char*>(aSequence
.getConstArray());
674 rtl_TextEncoding eSysEnc
= osl_getThreadTextEncoding();
676 // char array delimited by \0.
677 // app \0 topic \0 item \0 (extra \0) where the extra is optional.
678 ::std::vector
<OUString
> aStrs
;
679 const char* pStart
= p
;
680 sal_Int32 nStart
= 0;
681 for (sal_Int32 i
= 0; i
< nSeqLen
; ++i
, ++p
)
685 sal_Int32 nLen
= i
- nStart
;
686 aStrs
.push_back(OUString(pStart
, nLen
, eSysEnc
));
692 if (aStrs
.size() < 3)
695 const OUString
* pApp
= &aStrs
[0];
696 const OUString
* pTopic
= &aStrs
[1];
697 const OUString
* pItem
= &aStrs
[2];
698 const OUString
* pExtra
= NULL
;
699 if (aStrs
.size() > 3)
702 if ( pExtra
&& *pExtra
== "calc:extref" )
704 // Paste this as an external reference. Note that paste link always
705 // uses Calc A1 syntax even when another formula syntax is specified
708 + OUString(ScGlobal::GetAbsDocName(*pTopic
, GetViewData()->GetDocument()->GetDocumentShell()))
710 , ::formula::FormulaGrammar::GRAM_NATIVE
);
715 // DDE in all other cases.
717 // TODO: we could define ocQuote for "
718 EnterMatrix("=" + OUString(ScCompiler::GetNativeSymbol(ocDde
))
719 + ScCompiler::GetNativeSymbol(ocOpen
)
720 + "\"" + *pApp
+ "\""
721 + ScCompiler::GetNativeSymbol(ocSep
)
722 + "\"" + *pTopic
+ "\""
723 + ScCompiler::GetNativeSymbol(ocSep
)
724 + "\"" + *pItem
+ "\""
725 + ScCompiler::GetNativeSymbol(ocClose
)
726 , ::formula::FormulaGrammar::GRAM_NATIVE
);
731 SCTAB nTab
= GetViewData()->GetTabNo();
732 SCCOL nCurX
= GetViewData()->GetCurX();
733 SCROW nCurY
= GetViewData()->GetCurY();
736 InitBlockMode( nCurX
, nCurY
, nTab
);
737 MarkCursor( nCurX
+static_cast<SCCOL
>(nCols
)-1, nCurY
+static_cast<SCROW
>(nRows
)-1, nTab
);
745 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */