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>
24 #include <svx/unomodel.hxx>
25 #include <unotools/streamwrap.hxx>
27 #include <svx/fmmodel.hxx>
28 #include <svx/svdetc.hxx>
29 #include <svx/svditer.hxx>
30 #include <svx/svdobj.hxx>
31 #include <svx/svdogrp.hxx>
32 #include <svx/svdouno.hxx>
33 #include <svx/svdoole2.hxx>
34 #include <svx/svdpage.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/docfile.hxx>
37 #include <comphelper/classids.hxx>
38 #include <sot/formats.hxx>
39 #include <sot/filelist.hxx>
40 #include <sot/storage.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/lok.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <comphelper/storagehelper.hxx>
50 #include <comphelper/string.hxx>
52 #include <viewfunc.hxx>
54 #include <drawview.hxx>
60 #include <globstr.hrc>
62 #include <scextopt.hxx>
63 #include <tabvwsh.hxx>
64 #include <compiler.hxx>
66 #include <asciiopt.hxx>
67 #include <scabstdlg.hxx>
68 #include <clipparam.hxx>
69 #include <markdata.hxx>
70 #include <vcl/msgbox.hxx>
71 #include <sfx2/viewfrm.hxx>
72 #include <svx/dbaexchange.hxx>
75 using namespace com::sun::star
;
77 bool ScViewFunc::PasteDataFormat( SotClipboardFormatId nFormatId
,
78 const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
,
79 SCCOL nPosX
, SCROW nPosY
, const Point
* pLogicPos
, bool bLink
, bool bAllowDialogs
)
81 ScDocument
* pDoc
= GetViewData().GetDocument();
82 pDoc
->SetPastingDrawFromOtherDoc( true );
84 Point aPos
; // inserting position (1/100 mm)
89 // inserting position isn't needed for text formats
90 bool bIsTextFormat
= ( ScImportExport::IsFormatSupported( nFormatId
) ||
91 nFormatId
== SotClipboardFormatId::RTF
);
94 // Window MapMode isn't drawing MapMode if DrawingLayer hasn't been created yet
96 SCTAB nTab
= GetViewData().GetTabNo();
98 for (SCCOL i
=0; i
<nPosX
; i
++)
99 nXT
+= pDoc
->GetColWidth(i
,nTab
);
100 if (pDoc
->IsNegativePage(nTab
))
102 sal_uLong nYT
= pDoc
->GetRowHeight( 0, nPosY
-1, nTab
);
103 aPos
= Point( (long)(nXT
* HMM_PER_TWIPS
), (long)(nYT
* HMM_PER_TWIPS
) );
107 TransferableDataHelper
aDataHelper( rxTransferable
);
110 // handle individual formats
112 if ( nFormatId
== SotClipboardFormatId::EMBED_SOURCE
||
113 nFormatId
== SotClipboardFormatId::LINK_SOURCE
||
114 nFormatId
== SotClipboardFormatId::EMBED_SOURCE_OLE
||
115 nFormatId
== SotClipboardFormatId::LINK_SOURCE_OLE
||
116 nFormatId
== SotClipboardFormatId::EMBEDDED_OBJ_OLE
)
118 uno::Reference
< io::XInputStream
> xStm
;
119 TransferableObjectDescriptor aObjDesc
;
121 if (aDataHelper
.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR
, aObjDesc
))
122 xStm
= aDataHelper
.GetInputStream(nFormatId
, OUString());
126 if ( aObjDesc
.maClassName
== SvGlobalName( SO3_SC_CLASSID_60
) )
128 uno::Reference
< embed::XStorage
> xStore
= ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm
);
130 // mba: BaseURL doesn't make sense for clipboard
131 // #i43716# Medium must be allocated with "new".
132 // DoLoad stores the pointer and deletes it with the SfxObjectShell.
133 SfxMedium
* pMedium
= new SfxMedium( xStore
, OUString() );
135 // TODO/LATER: is it a problem that we don't support binary formats here?
136 ScDocShellRef xDocShRef
= new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT
);
137 if (xDocShRef
->DoLoad(pMedium
))
139 ScDocument
& rSrcDoc
= xDocShRef
->GetDocument();
140 SCTAB nSrcTab
= rSrcDoc
.GetVisibleTab();
141 if (!rSrcDoc
.HasTable(nSrcTab
))
145 aSrcMark
.SelectOneTable( nSrcTab
); // for CopyToClip
146 ScDocumentUniquePtr
pClipDoc(new ScDocument( SCDOCMODE_CLIP
));
148 SCCOL nFirstCol
, nLastCol
;
149 SCROW nFirstRow
, nLastRow
;
150 if ( rSrcDoc
.GetDataStart( nSrcTab
, nFirstCol
, nFirstRow
) )
151 rSrcDoc
.GetCellArea( nSrcTab
, nLastCol
, nLastRow
);
154 nFirstCol
= nLastCol
= 0;
155 nFirstRow
= nLastRow
= 0;
157 ScClipParam
aClipParam(ScRange(nFirstCol
, nFirstRow
, nSrcTab
, nLastCol
, nLastRow
, nSrcTab
), false);
158 rSrcDoc
.CopyToClip(aClipParam
, pClipDoc
.get(), &aSrcMark
, false, false);
159 ScGlobal::SetClipDocName( xDocShRef
->GetTitle( SFX_TITLE_FULLNAME
) );
161 SetCursor( nPosX
, nPosY
);
163 PasteFromClip( InsertDeleteFlags::ALL
, pClipDoc
.get(),
164 ScPasteFunc::NONE
, false, false, false, INS_NONE
, InsertDeleteFlags::NONE
,
169 xDocShRef
->DoClose();
175 uno::Reference
< embed::XEmbeddedObject
> xObj
= GetViewData().GetViewShell()->GetObjectShell()->
176 GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
179 // try to get the replacement image from the clipboard
181 SotClipboardFormatId nGrFormat
= SotClipboardFormatId::NONE
;
183 // limit the size of the preview metafile to 100000 actions
184 GDIMetaFile aMetafile
;
185 if (aDataHelper
.GetGDIMetaFile(SotClipboardFormatId::GDIMETAFILE
, aMetafile
, 100000))
187 nGrFormat
= SotClipboardFormatId::GDIMETAFILE
;
188 aGraphic
= aMetafile
;
191 // insert replacement image ( if there is one ) into the object helper
192 if ( nGrFormat
!= SotClipboardFormatId::NONE
)
194 datatransfer::DataFlavor aDataFlavor
;
195 SotExchange::GetFormatDataFlavor( nGrFormat
, aDataFlavor
);
196 PasteObject( aPos
, xObj
, &aObjDesc
.maSize
, &aGraphic
, aDataFlavor
.MimeType
, aObjDesc
.mnViewAspect
);
199 PasteObject( aPos
, xObj
, &aObjDesc
.maSize
);
205 OSL_FAIL("Error in CreateAndLoad");
211 if ( aDataHelper
.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE
, aObjDesc
) )
214 uno::Reference
< embed::XEmbeddedObject
> xObj
;
215 xStm
= aDataHelper
.GetInputStream(SotClipboardFormatId::EMBED_SOURCE_OLE
, OUString());
217 aDataHelper
.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE
, OUString());
221 xObj
= GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
227 uno::Reference
< embed::XStorage
> xTmpStor
= ::comphelper::OStorageHelper::GetTemporaryStorage();
228 uno::Reference
< embed::XEmbedObjectClipboardCreator
> xClipboardCreator
=
229 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
231 embed::InsertedObjectInfo aInfo
= xClipboardCreator
->createInstanceInitFromClipboard(
234 uno::Sequence
< beans::PropertyValue
>() );
236 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
237 // for example whether the object should be an iconified one
240 GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj
, aName
);
242 catch( uno::Exception
& )
248 // try to get the replacement image from the clipboard
250 SotClipboardFormatId nGrFormat
= SotClipboardFormatId::NONE
;
252 // (for Selection Manager in Trusted Solaris)
254 if( aDataHelper
.GetGraphic( SotClipboardFormatId::SVXB
, aGraphic
) )
255 nGrFormat
= SotClipboardFormatId::SVXB
;
256 else if( aDataHelper
.GetGraphic( SotClipboardFormatId::GDIMETAFILE
, aGraphic
) )
257 nGrFormat
= SotClipboardFormatId::GDIMETAFILE
;
258 else if( aDataHelper
.GetGraphic( SotClipboardFormatId::BITMAP
, aGraphic
) )
259 nGrFormat
= SotClipboardFormatId::BITMAP
;
262 // insert replacement image ( if there is one ) into the object helper
263 if ( nGrFormat
!= SotClipboardFormatId::NONE
)
265 datatransfer::DataFlavor aDataFlavor
;
266 SotExchange::GetFormatDataFlavor( nGrFormat
, aDataFlavor
);
267 PasteObject( aPos
, xObj
, &aObjDesc
.maSize
, &aGraphic
, aDataFlavor
.MimeType
, aObjDesc
.mnViewAspect
);
270 PasteObject( aPos
, xObj
, &aObjDesc
.maSize
);
272 // let object stay in loaded state after insertion
273 SdrOle2Obj::Unload( xObj
, embed::Aspects::MSOLE_CONTENT
);
278 OSL_FAIL("Error creating external OLE object");
281 //TODO/LATER: if format is not available, create picture
284 else if ( nFormatId
== SotClipboardFormatId::LINK
) // LINK is also in ScImportExport
286 bRet
= PasteLink( rxTransferable
);
288 else if ( ScImportExport::IsFormatSupported( nFormatId
) || nFormatId
== SotClipboardFormatId::RTF
||
289 nFormatId
== SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT
)
291 if ( nFormatId
== SotClipboardFormatId::RTF
&& ( aDataHelper
.HasFormat( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT
) ) )
293 // use EditView's PasteSpecial / Drop
294 PasteRTF( nPosX
, nPosY
, rxTransferable
);
299 ScAddress
aCellPos( nPosX
, nPosY
, GetViewData().GetTabNo() );
300 std::shared_ptr
<ScImportExport
> pObj(new ScImportExport(GetViewData().GetDocument(), aCellPos
));
301 pObj
->SetOverwriting( true );
304 std::shared_ptr
<OUString
> pStrBuffer(new OUString());
305 tools::SvRef
<SotStorageStream
> xStream
;
306 if ( aDataHelper
.GetSotStorageStream( nFormatId
, xStream
) && xStream
.is() )
308 if (nFormatId
== SotClipboardFormatId::HTML
)
310 // Launch the text import options dialog. For now, we do
311 // this for html pasting only, but in the future it may
312 // make sense to do it for other data types too.
313 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
314 ScopedVclPtr
<AbstractScTextImportOptionsDlg
> pDlg(
315 pFact
->CreateScTextImportOptionsDlg());
317 if (pDlg
->Execute() == RET_OK
)
319 ScAsciiOptions aOptions
;
320 aOptions
.SetLanguage(pDlg
->GetLanguageType());
321 aOptions
.SetDetectSpecialNumber(pDlg
->IsDateConversionSet());
322 pObj
->SetExtOptions(aOptions
);
326 // prevent error dialog for user cancel action
331 bRet
= pObj
->ImportStream( *xStream
, OUString(), nFormatId
);
332 // mba: clipboard always must contain absolute URLs (could be from alien source)
334 else if ((nFormatId
== SotClipboardFormatId::STRING
|| nFormatId
== SotClipboardFormatId::STRING_TSVC
)
335 && aDataHelper
.GetString( nFormatId
, *pStrBuffer
))
337 // Do CSV dialog if more than one line.
338 sal_Int32 nDelim
= pStrBuffer
->indexOf('\n');
339 if (nDelim
>= 0 && nDelim
!= pStrBuffer
->getLength () - 1)
341 vcl::Window
* pParent
= comphelper::LibreOfficeKit::isActive() ? GetActiveWin() : nullptr;
343 std::shared_ptr
<ScImportStringStream
> pStrm(new ScImportStringStream(*pStrBuffer
));
345 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
346 VclPtr
<AbstractScImportAsciiDlg
> pDlg(
347 pFact
->CreateScImportAsciiDlg(pParent
, OUString(), pStrm
.get(), SC_PASTETEXT
));
349 bAllowDialogs
= bAllowDialogs
&& !SC_MOD()->IsInExecuteDrop();
351 pDlg
->StartExecuteAsync([this, pDlg
, pDoc
, pStrm
, nFormatId
, pStrBuffer
, pObj
, bAllowDialogs
](sal_Int32 nResult
){
352 bool bShowErrorDialog
= bAllowDialogs
;
353 if (RET_OK
== nResult
)
355 ScAsciiOptions aOptions
;
356 pDlg
->GetOptions( aOptions
);
357 pDlg
->SaveParameters();
358 pObj
->SetExtOptions( aOptions
);
359 pObj
->ImportString( *pStrBuffer
, nFormatId
);
361 // TODO: what if (aObj.IsOverflow())
362 // Content was partially pasted, which can be undone by
364 bShowErrorDialog
= bShowErrorDialog
&& pObj
->IsOverflow();
368 bShowErrorDialog
= false;
369 // Yes, no failure, don't raise a "couldn't paste"
370 // dialog if user cancelled.
374 GetViewData().UpdateInputHandler();
376 pDoc
->SetPastingDrawFromOtherDoc( false );
378 if (bShowErrorDialog
)
379 ErrorMessage(STR_PASTE_ERROR
);
384 bRet
= pObj
->ImportString( *pStrBuffer
, nFormatId
);
386 else if ((nFormatId
!= SotClipboardFormatId::STRING
&& nFormatId
!= SotClipboardFormatId::STRING_TSVC
)
387 && aDataHelper
.GetString( nFormatId
, *pStrBuffer
))
388 bRet
= pObj
->ImportString( *pStrBuffer
, nFormatId
);
391 GetViewData().UpdateInputHandler();
394 else if (nFormatId
== SotClipboardFormatId::SBA_DATAEXCHANGE
)
396 // import of database data into table
398 const DataFlavorExVector
& rVector
= aDataHelper
.GetDataFlavorExVector();
399 if ( svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector
) )
401 // transport the whole ODataAccessDescriptor as slot parameter
402 svx::ODataAccessDescriptor aDesc
= svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper
);
404 uno::Sequence
<beans::PropertyValue
> aProperties
= aDesc
.createPropertyValueSequence();
405 aDescAny
<<= aProperties
;
406 SfxUsrAnyItem
aDataDesc(SID_SBA_IMPORT
, aDescAny
);
408 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
409 SCTAB nTab
= GetViewData().GetTabNo();
411 ClickCursor(nPosX
, nPosY
, false); // set cursor position
413 // Creation of database area "Import1" isn't here, but in the DocShell
414 // slot execute, so it can be added to the undo action
416 ScDBData
* pDBData
= pDocSh
->GetDBData( ScRange(nPosX
,nPosY
,nTab
), SC_DB_OLD
, ScGetDBSelection::Keep
);
419 sTarget
= pDBData
->GetName();
422 ScAddress
aCellPos( nPosX
,nPosY
,nTab
);
423 sTarget
= aCellPos
.Format(ScRefFlags::ADDR_ABS_3D
, pDoc
, pDoc
->GetAddressConvention());
425 SfxStringItem
aTarget(FN_PARAM_1
, sTarget
);
427 bool bAreaIsNew
= !pDBData
;
428 SfxBoolItem
aAreaNew(FN_PARAM_2
, bAreaIsNew
);
430 // asynchronous, to avoid doing the whole import in drop handler
431 SfxDispatcher
& rDisp
= GetViewData().GetDispatcher();
432 rDisp
.ExecuteList(SID_SBA_IMPORT
, SfxCallMode::ASYNCHRON
,
433 { &aDataDesc
, &aTarget
, &aAreaNew
});
438 else if (nFormatId
== SotClipboardFormatId::SBA_FIELDDATAEXCHANGE
)
440 // insert database field control
442 if ( svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper
.GetDataFlavorExVector(), ColumnTransferFormatFlags::COLUMN_DESCRIPTOR
| ColumnTransferFormatFlags::CONTROL_EXCHANGE
) )
445 ScDrawView
* pScDrawView
= GetScDrawView();
446 SdrObject
* pObj
= pScDrawView
->CreateFieldControl( svx::OColumnTransferable::extractColumnDescriptor( aDataHelper
) );
449 Point aInsPos
= aPos
;
450 tools::Rectangle
aRect(pObj
->GetLogicRect());
451 aInsPos
.X() -= aRect
.GetSize().Width() / 2;
452 aInsPos
.Y() -= aRect
.GetSize().Height() / 2;
453 if ( aInsPos
.X() < 0 ) aInsPos
.X() = 0;
454 if ( aInsPos
.Y() < 0 ) aInsPos
.Y() = 0;
455 aRect
.SetPos(aInsPos
);
456 pObj
->SetLogicRect(aRect
);
458 if ( dynamic_cast<const SdrUnoObj
*>( pObj
) != nullptr )
459 pObj
->NbcSetLayer(SC_LAYER_CONTROLS
);
461 pObj
->NbcSetLayer(SC_LAYER_FRONT
);
462 if (dynamic_cast<const SdrObjGroup
*>( pObj
) != nullptr)
464 SdrObjListIter
aIter( *pObj
, SdrIterMode::DeepWithGroups
);
465 SdrObject
* pSubObj
= aIter
.Next();
468 if ( dynamic_cast<const SdrUnoObj
*>( pSubObj
) != nullptr )
469 pSubObj
->NbcSetLayer(SC_LAYER_CONTROLS
);
471 pSubObj
->NbcSetLayer(SC_LAYER_FRONT
);
472 pSubObj
= aIter
.Next();
476 pScDrawView
->InsertObjectSafe(pObj
, *pScDrawView
->GetSdrPageView());
478 GetViewData().GetViewShell()->SetDrawShell( true );
483 else if (nFormatId
== SotClipboardFormatId::BITMAP
|| nFormatId
== SotClipboardFormatId::PNG
)
486 if( aDataHelper
.GetBitmapEx( SotClipboardFormatId::BITMAP
, aBmpEx
) )
487 bRet
= PasteBitmapEx( aPos
, aBmpEx
);
489 else if (nFormatId
== SotClipboardFormatId::GDIMETAFILE
)
492 if( aDataHelper
.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE
, aMtf
) )
493 bRet
= PasteMetaFile( aPos
, aMtf
);
495 else if (nFormatId
== SotClipboardFormatId::SVXB
)
497 tools::SvRef
<SotStorageStream
> xStm
;
498 if( aDataHelper
.GetSotStorageStream( SotClipboardFormatId::SVXB
, xStm
) )
501 ReadGraphic( *xStm
, aGraphic
);
502 bRet
= PasteGraphic( aPos
, aGraphic
, EMPTY_OUSTRING
, EMPTY_OUSTRING
);
505 else if ( nFormatId
== SotClipboardFormatId::DRAWING
)
507 tools::SvRef
<SotStorageStream
> xStm
;
508 if( aDataHelper
.GetSotStorageStream( SotClipboardFormatId::DRAWING
, xStm
) )
510 MakeDrawLayer(); // before loading model, so 3D factory has been created
512 SvtPathOptions aPathOpt
;
513 OUString aPath
= aPathOpt
.GetPalettePath();
515 ScDocShellRef
aDragShellRef( new ScDocShell
);
516 aDragShellRef
->DoInitNew();
517 std::unique_ptr
<FmFormModel
> pModel(new FmFormModel( aPath
, nullptr, aDragShellRef
.get() ));
519 pModel
->GetItemPool().FreezeIdRanges();
522 css::uno::Reference
< css::io::XInputStream
> xInputStream( new utl::OInputStreamWrapper( *xStm
) );
523 SvxDrawingLayerImport( pModel
.get(), xInputStream
);
525 // set everything to right layer:
526 size_t nObjCount
= 0;
527 sal_uInt16 nPages
= pModel
->GetPageCount();
528 for (sal_uInt16 i
=0; i
<nPages
; i
++)
530 SdrPage
* pPage
= pModel
->GetPage(i
);
531 SdrObjListIter
aIter( *pPage
, SdrIterMode::DeepWithGroups
);
532 SdrObject
* pObject
= aIter
.Next();
535 if ( dynamic_cast<const SdrUnoObj
*>( pObject
) != nullptr )
536 pObject
->NbcSetLayer(SC_LAYER_CONTROLS
);
538 pObject
->NbcSetLayer(SC_LAYER_FRONT
);
539 pObject
= aIter
.Next();
542 nObjCount
+= pPage
->GetObjCount(); // count group object only once
545 PasteDraw(aPos
, pModel
.get(), (nObjCount
> 1), "A", "B"); // grouped if more than 1 object
547 aDragShellRef
->DoClose();
551 else if ( (nFormatId
== SotClipboardFormatId::BIFF_5
) || (nFormatId
== SotClipboardFormatId::BIFF_8
) )
553 // do excel import into a clipboard document
555 uno::Reference
<io::XInputStream
> xStm
= aDataHelper
.GetInputStream(nFormatId
, OUString());
558 ScDocument
* pInsDoc
= new ScDocument( SCDOCMODE_CLIP
);
559 SCTAB nSrcTab
= 0; // Biff5 in clipboard: always sheet 0
560 pInsDoc
->ResetClip( pDoc
, nSrcTab
);
563 aMed
.GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM
, uno::makeAny( xStm
) ) );
564 ErrCode eErr
= ScFormatFilter::Get().ScImportExcel( aMed
, pInsDoc
, EIF_AUTO
);
565 if ( eErr
== ERRCODE_NONE
)
568 const ScExtDocOptions
* pExtOpt
= pInsDoc
->GetExtDocOptions();
569 const ScExtTabSettings
* pTabSett
= pExtOpt
? pExtOpt
->GetTabSettings( nSrcTab
) : nullptr;
570 if( pTabSett
&& pTabSett
->maUsedArea
.IsValid() )
572 aSource
= pTabSett
->maUsedArea
;
573 // ensure correct sheet indexes
574 aSource
.aStart
.SetTab( nSrcTab
);
575 aSource
.aEnd
.SetTab( nSrcTab
);
576 // don't use selection area: if cursor is moved in Excel after Copy, selection
577 // represents the new cursor position and not the copied area
581 OSL_FAIL("no dimension"); //! possible?
582 SCCOL nFirstCol
, nLastCol
;
583 SCROW nFirstRow
, nLastRow
;
584 if ( pInsDoc
->GetDataStart( nSrcTab
, nFirstCol
, nFirstRow
) )
585 pInsDoc
->GetCellArea( nSrcTab
, nLastCol
, nLastRow
);
588 nFirstCol
= nLastCol
= 0;
589 nFirstRow
= nLastRow
= 0;
591 aSource
= ScRange( nFirstCol
, nFirstRow
, nSrcTab
,
592 nLastCol
, nLastRow
, nSrcTab
);
597 // position specified (Drag&Drop) - change selection
598 MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, false, false );
602 pInsDoc
->SetClipArea( aSource
);
603 PasteFromClip( InsertDeleteFlags::ALL
, pInsDoc
,
604 ScPasteFunc::NONE
, false, false, false, INS_NONE
, InsertDeleteFlags::NONE
,
612 else if ( nFormatId
== SotClipboardFormatId::SIMPLE_FILE
)
615 if ( aDataHelper
.GetString( nFormatId
, aFile
) )
616 bRet
= PasteFile( aPos
, aFile
, bLink
);
618 else if ( nFormatId
== SotClipboardFormatId::FILE_LIST
)
621 if ( aDataHelper
.GetFileList( nFormatId
, aFileList
) )
623 sal_uLong nCount
= aFileList
.Count();
624 for( sal_uLong i
= 0; i
< nCount
; i
++ )
626 OUString aFile
= aFileList
.GetFile( i
);
628 PasteFile( aPos
, aFile
, bLink
);
636 else if ( nFormatId
== SotClipboardFormatId::SOLK
||
637 nFormatId
== SotClipboardFormatId::UNIFORMRESOURCELOCATOR
||
638 nFormatId
== SotClipboardFormatId::NETSCAPE_BOOKMARK
||
639 nFormatId
== SotClipboardFormatId::FILEGRPDESCRIPTOR
)
641 bRet
= PasteBookmark( nFormatId
, rxTransferable
, nPosX
, nPosY
);
644 pDoc
->SetPastingDrawFromOtherDoc( false );
649 bool ScViewFunc::PasteLink( const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
)
651 TransferableDataHelper
aDataHelper( rxTransferable
);
653 // get link data from transferable before string data,
654 // so the source knows it will be used for a link
656 uno::Sequence
<sal_Int8
> aSequence
= aDataHelper
.GetSequence(SotClipboardFormatId::LINK
, OUString());
657 if (!aSequence
.getLength())
659 OSL_FAIL("DDE Data not found.");
663 // check size (only if string is available in transferable)
665 sal_uInt16 nCols
= 1;
666 sal_uInt16 nRows
= 1;
667 if ( aDataHelper
.HasFormat( SotClipboardFormatId::STRING
) )
670 if ( aDataHelper
.GetString( SotClipboardFormatId::STRING
, aDataStr
) )
672 // get size from string the same way as in ScDdeLink::DataChanged
674 aDataStr
= convertLineEnd(aDataStr
, LINEEND_LF
);
675 sal_Int32 nLen
= aDataStr
.getLength();
676 if (nLen
&& aDataStr
[nLen
-1] == '\n')
677 aDataStr
= aDataStr
.copy(0, nLen
-1);
679 if (!aDataStr
.isEmpty())
681 nRows
= comphelper::string::getTokenCount(aDataStr
, '\n');
682 OUString aLine
= aDataStr
.getToken( 0, '\n' );
683 if (!aLine
.isEmpty())
684 nCols
= comphelper::string::getTokenCount(aLine
, '\t');
691 sal_Int32 nSeqLen
= aSequence
.getLength();
692 const char* p
= reinterpret_cast<const char*>(aSequence
.getConstArray());
694 rtl_TextEncoding eSysEnc
= osl_getThreadTextEncoding();
696 // char array delimited by \0.
697 // app \0 topic \0 item \0 (extra \0) where the extra is optional.
698 ::std::vector
<OUString
> aStrs
;
699 const char* pStart
= p
;
700 sal_Int32 nStart
= 0;
701 for (sal_Int32 i
= 0; i
< nSeqLen
; ++i
, ++p
)
705 sal_Int32 nLen
= i
- nStart
;
706 aStrs
.emplace_back(pStart
, nLen
, eSysEnc
);
712 if (aStrs
.size() < 3)
715 const OUString
* pApp
= &aStrs
[0];
716 const OUString
* pTopic
= &aStrs
[1];
717 const OUString
* pItem
= &aStrs
[2];
718 const OUString
* pExtra
= nullptr;
719 if (aStrs
.size() > 3)
722 if ( pExtra
&& *pExtra
== "calc:extref" )
724 // Paste this as an external reference. Note that paste link always
725 // uses Calc A1 syntax even when another formula syntax is specified
728 + ScGlobal::GetAbsDocName(*pTopic
, GetViewData().GetDocument()->GetDocumentShell())
730 , ::formula::FormulaGrammar::GRAM_NATIVE
);
735 // DDE in all other cases.
737 // TODO: we could define ocQuote for "
738 EnterMatrix("=" + ScCompiler::GetNativeSymbol(ocDde
)
739 + ScCompiler::GetNativeSymbol(ocOpen
)
740 + "\"" + *pApp
+ "\""
741 + ScCompiler::GetNativeSymbol(ocSep
)
742 + "\"" + *pTopic
+ "\""
743 + ScCompiler::GetNativeSymbol(ocSep
)
744 + "\"" + *pItem
+ "\""
745 + ScCompiler::GetNativeSymbol(ocClose
)
746 , ::formula::FormulaGrammar::GRAM_NATIVE
);
751 SCTAB nTab
= GetViewData().GetTabNo();
752 SCCOL nCurX
= GetViewData().GetCurX();
753 SCROW nCurY
= GetViewData().GetCurY();
756 InitBlockMode( nCurX
, nCurY
, nTab
);
757 MarkCursor( nCurX
+static_cast<SCCOL
>(nCols
)-1, nCurY
+static_cast<SCROW
>(nRows
)-1, nTab
);
764 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */