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/svditer.hxx>
28 #include <svx/svdobj.hxx>
29 #include <svx/svdogrp.hxx>
30 #include <svx/svdouno.hxx>
31 #include <svx/svdoole2.hxx>
32 #include <svx/svdpage.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <comphelper/classids.hxx>
36 #include <sot/formats.hxx>
37 #include <sot/filelist.hxx>
38 #include <sot/storage.hxx>
39 #include <svl/stritem.hxx>
40 #include <vcl/transfer.hxx>
41 #include <vcl/graph.hxx>
42 #include <vcl/TypeSerializer.hxx>
43 #include <osl/thread.h>
44 #include <o3tl/unit_conversion.hxx>
45 #include <o3tl/string_view.hxx>
47 #include <comphelper/automationinvokedzone.hxx>
48 #include <comphelper/lok.hxx>
49 #include <comphelper/processfactory.hxx>
50 #include <comphelper/storagehelper.hxx>
51 #include <comphelper/string.hxx>
53 #include <viewfunc.hxx>
55 #include <drawview.hxx>
60 #include <globstr.hrc>
62 #include <scextopt.hxx>
63 #include <tabvwsh.hxx>
64 #include <compiler.hxx>
67 #include <asciiopt.hxx>
68 #include <scabstdlg.hxx>
69 #include <clipparam.hxx>
70 #include <markdata.hxx>
71 #include <sfx2/frame.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
& rDoc
= GetViewData().GetDocument();
82 rDoc
.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
+= rDoc
.GetColWidth(i
,nTab
);
100 if (rDoc
.IsNegativePage(nTab
))
102 tools::Long nYT
= rDoc
.GetRowHeight( 0, nPosY
-1, nTab
);
103 aPos
= Point(o3tl::convert(nXT
, o3tl::Length::twip
, o3tl::Length::mm100
),
104 o3tl::convert(nYT
, o3tl::Length::twip
, o3tl::Length::mm100
));
108 TransferableDataHelper
aDataHelper( rxTransferable
);
111 // handle individual formats
113 if ( nFormatId
== SotClipboardFormatId::EMBED_SOURCE
||
114 nFormatId
== SotClipboardFormatId::LINK_SOURCE
||
115 nFormatId
== SotClipboardFormatId::EMBED_SOURCE_OLE
||
116 nFormatId
== SotClipboardFormatId::LINK_SOURCE_OLE
||
117 nFormatId
== SotClipboardFormatId::EMBEDDED_OBJ_OLE
)
119 bRet
= PasteDataFormatSource(nFormatId
, nPosX
, nPosY
, bAllowDialogs
, aDataHelper
, aPos
);
121 else if ( nFormatId
== SotClipboardFormatId::LINK
) // LINK is also in ScImportExport
123 bRet
= PasteLink( rxTransferable
);
125 else if ( ScImportExport::IsFormatSupported( nFormatId
) || nFormatId
== SotClipboardFormatId::RTF
||
126 nFormatId
== SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT
)
128 bRet
= PasteDataFormatFormattedText(nFormatId
, rxTransferable
, nPosX
, nPosY
,
129 bAllowDialogs
, aDataHelper
);
131 else if (nFormatId
== SotClipboardFormatId::SBA_DATAEXCHANGE
)
133 // import of database data into table
135 const DataFlavorExVector
& rVector
= aDataHelper
.GetDataFlavorExVector();
136 if ( svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector
) )
138 // transport the whole ODataAccessDescriptor as slot parameter
139 svx::ODataAccessDescriptor aDesc
= svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper
);
141 uno::Sequence
<beans::PropertyValue
> aProperties
= aDesc
.createPropertyValueSequence();
142 aDescAny
<<= aProperties
;
143 SfxUnoAnyItem
aDataDesc(SID_SBA_IMPORT
, aDescAny
);
145 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
146 SCTAB nTab
= GetViewData().GetTabNo();
148 ClickCursor(nPosX
, nPosY
, false); // set cursor position
150 // Creation of database area "Import1" isn't here, but in the DocShell
151 // slot execute, so it can be added to the undo action
153 ScDBData
* pDBData
= pDocSh
->GetDBData( ScRange(nPosX
,nPosY
,nTab
), SC_DB_OLD
, ScGetDBSelection::Keep
);
156 sTarget
= pDBData
->GetName();
159 ScAddress
aCellPos( nPosX
,nPosY
,nTab
);
160 sTarget
= aCellPos
.Format(ScRefFlags::ADDR_ABS_3D
, &rDoc
, rDoc
.GetAddressConvention());
162 SfxStringItem
aTarget(FN_PARAM_1
, sTarget
);
164 bool bAreaIsNew
= !pDBData
;
165 SfxBoolItem
aAreaNew(FN_PARAM_2
, bAreaIsNew
);
167 // asynchronous, to avoid doing the whole import in drop handler
168 SfxDispatcher
& rDisp
= GetViewData().GetDispatcher();
169 rDisp
.ExecuteList(SID_SBA_IMPORT
, SfxCallMode::ASYNCHRON
,
170 { &aDataDesc
, &aTarget
, &aAreaNew
});
175 else if (nFormatId
== SotClipboardFormatId::SBA_FIELDDATAEXCHANGE
)
177 // insert database field control
179 if ( svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper
.GetDataFlavorExVector(), ColumnTransferFormatFlags::COLUMN_DESCRIPTOR
| ColumnTransferFormatFlags::CONTROL_EXCHANGE
) )
182 ScDrawView
* pScDrawView
= GetScDrawView();
183 rtl::Reference
<SdrObject
> pObj
= pScDrawView
->CreateFieldControl( svx::OColumnTransferable::extractColumnDescriptor( aDataHelper
) );
186 Point aInsPos
= aPos
;
187 tools::Rectangle
aRect(pObj
->GetLogicRect());
188 aInsPos
.AdjustX( -(aRect
.GetSize().Width() / 2) );
189 aInsPos
.AdjustY( -(aRect
.GetSize().Height() / 2) );
190 if ( aInsPos
.X() < 0 ) aInsPos
.setX( 0 );
191 if ( aInsPos
.Y() < 0 ) aInsPos
.setY( 0 );
192 aRect
.SetPos(aInsPos
);
193 pObj
->SetLogicRect(aRect
);
195 if ( dynamic_cast<const SdrUnoObj
*>( pObj
.get() ) != nullptr )
196 pObj
->NbcSetLayer(SC_LAYER_CONTROLS
);
198 pObj
->NbcSetLayer(SC_LAYER_FRONT
);
199 if (dynamic_cast<const SdrObjGroup
*>( pObj
.get() ) != nullptr)
201 SdrObjListIter
aIter( *pObj
, SdrIterMode::DeepWithGroups
);
202 SdrObject
* pSubObj
= aIter
.Next();
205 if ( dynamic_cast<const SdrUnoObj
*>( pSubObj
) != nullptr )
206 pSubObj
->NbcSetLayer(SC_LAYER_CONTROLS
);
208 pSubObj
->NbcSetLayer(SC_LAYER_FRONT
);
209 pSubObj
= aIter
.Next();
213 pScDrawView
->InsertObjectSafe(pObj
.get(), *pScDrawView
->GetSdrPageView());
215 GetViewData().GetViewShell()->SetDrawShell( true );
220 else if (nFormatId
== SotClipboardFormatId::BITMAP
|| nFormatId
== SotClipboardFormatId::PNG
|| nFormatId
== SotClipboardFormatId::JPEG
)
223 if( aDataHelper
.GetBitmapEx( SotClipboardFormatId::BITMAP
, aBmpEx
) )
224 bRet
= PasteBitmapEx( aPos
, aBmpEx
);
226 else if (nFormatId
== SotClipboardFormatId::GDIMETAFILE
)
229 if( aDataHelper
.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE
, aMtf
) )
230 bRet
= PasteMetaFile( aPos
, aMtf
);
232 else if (nFormatId
== SotClipboardFormatId::SVXB
)
234 if (std::unique_ptr
<SvStream
> xStm
= aDataHelper
.GetSotStorageStream( SotClipboardFormatId::SVXB
) )
237 TypeSerializer
aSerializer(*xStm
);
238 aSerializer
.readGraphic(aGraphic
);
239 bRet
= PasteGraphic( aPos
, aGraphic
, OUString() );
242 else if ( nFormatId
== SotClipboardFormatId::DRAWING
)
244 if (std::unique_ptr
<SvStream
> xStm
= aDataHelper
.GetSotStorageStream( SotClipboardFormatId::DRAWING
))
246 MakeDrawLayer(); // before loading model, so 3D factory has been created
248 ScDocShellRef
aDragShellRef( new ScDocShell
);
249 aDragShellRef
->MakeDrawLayer();
250 aDragShellRef
->DoInitNew();
252 ScDrawLayer
* pModel
= aDragShellRef
->GetDocument().GetDrawLayer();
256 css::uno::Reference
< css::io::XInputStream
> xInputStream( new utl::OInputStreamWrapper( *xStm
) );
257 SvxDrawingLayerImport( pModel
, xInputStream
);
259 // set everything to right layer:
260 size_t nObjCount
= 0;
261 sal_uInt16 nPages
= pModel
->GetPageCount();
262 for (sal_uInt16 i
=0; i
<nPages
; i
++)
264 SdrPage
* pPage
= pModel
->GetPage(i
);
265 SdrObjListIter
aIter( pPage
, SdrIterMode::DeepWithGroups
);
266 SdrObject
* pObject
= aIter
.Next();
269 if ( dynamic_cast<const SdrUnoObj
*>( pObject
) != nullptr )
270 pObject
->NbcSetLayer(SC_LAYER_CONTROLS
);
272 pObject
->NbcSetLayer(SC_LAYER_FRONT
);
273 pObject
= aIter
.Next();
276 nObjCount
+= pPage
->GetObjCount(); // count group object only once
279 PasteDraw(aPos
, pModel
, (nObjCount
> 1), u
"A", u
"B"); // grouped if more than 1 object
280 aDragShellRef
->DoClose();
284 else if ( (nFormatId
== SotClipboardFormatId::BIFF_5
) || (nFormatId
== SotClipboardFormatId::BIFF_8
) )
286 // do excel import into a clipboard document
288 uno::Reference
<io::XInputStream
> xStm
= aDataHelper
.GetInputStream(nFormatId
, OUString());
291 ScDocument
aInsDoc( SCDOCMODE_CLIP
);
292 SCTAB nSrcTab
= 0; // Biff5 in clipboard: always sheet 0
293 aInsDoc
.ResetClip( &rDoc
, nSrcTab
);
296 aMed
.GetItemSet().Put( SfxUnoAnyItem( SID_INPUTSTREAM
, uno::Any( xStm
) ) );
297 ErrCode eErr
= ScFormatFilter::Get().ScImportExcel( aMed
, &aInsDoc
, EIF_AUTO
);
298 if ( eErr
== ERRCODE_NONE
)
301 const ScExtDocOptions
* pExtOpt
= aInsDoc
.GetExtDocOptions();
302 const ScExtTabSettings
* pTabSett
= pExtOpt
? pExtOpt
->GetTabSettings( nSrcTab
) : nullptr;
303 if( pTabSett
&& pTabSett
->maUsedArea
.IsValid() )
305 aSource
= pTabSett
->maUsedArea
;
306 // ensure correct sheet indexes
307 aSource
.aStart
.SetTab( nSrcTab
);
308 aSource
.aEnd
.SetTab( nSrcTab
);
309 // don't use selection area: if cursor is moved in Excel after Copy, selection
310 // represents the new cursor position and not the copied area
314 OSL_FAIL("no dimension"); //! possible?
315 SCCOL nFirstCol
, nLastCol
;
316 SCROW nFirstRow
, nLastRow
;
317 if ( aInsDoc
.GetDataStart( nSrcTab
, nFirstCol
, nFirstRow
) )
318 aInsDoc
.GetCellArea( nSrcTab
, nLastCol
, nLastRow
);
321 nFirstCol
= nLastCol
= 0;
322 nFirstRow
= nLastRow
= 0;
324 aSource
= ScRange( nFirstCol
, nFirstRow
, nSrcTab
,
325 nLastCol
, nLastRow
, nSrcTab
);
330 // position specified (Drag&Drop) - change selection
331 MoveCursorAbs( nPosX
, nPosY
, SC_FOLLOW_NONE
, false, false );
335 aInsDoc
.SetClipArea( aSource
);
336 PasteFromClip( InsertDeleteFlags::ALL
, &aInsDoc
,
337 ScPasteFunc::NONE
, false, false, false, INS_NONE
, InsertDeleteFlags::NONE
,
343 else if ( nFormatId
== SotClipboardFormatId::SIMPLE_FILE
)
346 if ( aDataHelper
.GetString( nFormatId
, aFile
) )
347 bRet
= PasteFile( aPos
, aFile
, bLink
);
349 else if ( nFormatId
== SotClipboardFormatId::FILE_LIST
)
352 if ( aDataHelper
.GetFileList( nFormatId
, aFileList
) )
354 sal_uLong nCount
= aFileList
.Count();
355 for( sal_uLong i
= 0; i
< nCount
; i
++ )
357 OUString aFile
= aFileList
.GetFile( i
);
359 PasteFile( aPos
, aFile
, bLink
);
367 else if ( nFormatId
== SotClipboardFormatId::SOLK
||
368 nFormatId
== SotClipboardFormatId::UNIFORMRESOURCELOCATOR
||
369 nFormatId
== SotClipboardFormatId::NETSCAPE_BOOKMARK
||
370 nFormatId
== SotClipboardFormatId::FILEGRPDESCRIPTOR
)
372 bRet
= PasteBookmark( nFormatId
, rxTransferable
, nPosX
, nPosY
);
375 rDoc
.SetPastingDrawFromOtherDoc( false );
380 bool ScViewFunc::PasteLink( const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
)
382 TransferableDataHelper
aDataHelper( rxTransferable
);
384 // get link data from transferable before string data,
385 // so the source knows it will be used for a link
387 OUString sApp
, sTopic
, sItem
, sExtra
;
388 if (!aDataHelper
.ReadDDELink(sApp
, sTopic
, sItem
, sExtra
))
391 // check size (only if string is available in transferable)
393 sal_uInt16 nCols
= 1;
394 sal_uInt16 nRows
= 1;
395 if ( aDataHelper
.HasFormat( SotClipboardFormatId::STRING
) )
398 if ( aDataHelper
.GetString( SotClipboardFormatId::STRING
, aDataStr
) )
400 // get size from string the same way as in ScDdeLink::DataChanged
402 aDataStr
= convertLineEnd(aDataStr
, LINEEND_LF
);
403 sal_Int32 nLen
= aDataStr
.getLength();
404 if (nLen
&& aDataStr
[nLen
-1] == '\n')
405 aDataStr
= aDataStr
.copy(0, nLen
-1);
407 if (!aDataStr
.isEmpty())
409 nRows
= comphelper::string::getTokenCount(aDataStr
, '\n');
410 std::u16string_view aLine
= o3tl::getToken(aDataStr
, 0, '\n' );
412 nCols
= comphelper::string::getTokenCount(aLine
, '\t');
418 if ( sExtra
== "calc:extref" )
420 // Paste this as an external reference. Note that paste link always
421 // uses Calc A1 syntax even when another formula syntax is specified
424 + ScGlobal::GetAbsDocName(sTopic
, GetViewData().GetDocument().GetDocumentShell())
426 , ::formula::FormulaGrammar::GRAM_NATIVE
);
431 // DDE in all other cases.
433 // TODO: we could define ocQuote for "
434 EnterMatrix("=" + ScCompiler::GetNativeSymbol(ocDde
)
435 + ScCompiler::GetNativeSymbol(ocOpen
)
437 + ScCompiler::GetNativeSymbol(ocSep
)
438 + "\"" + sTopic
+ "\""
439 + ScCompiler::GetNativeSymbol(ocSep
)
440 + "\"" + sItem
+ "\""
441 + ScCompiler::GetNativeSymbol(ocClose
)
442 , ::formula::FormulaGrammar::GRAM_NATIVE
);
447 SCTAB nTab
= GetViewData().GetTabNo();
448 SCCOL nCurX
= GetViewData().GetCurX();
449 SCROW nCurY
= GetViewData().GetCurY();
452 InitBlockMode( nCurX
, nCurY
, nTab
);
453 MarkCursor( nCurX
+static_cast<SCCOL
>(nCols
)-1, nCurY
+static_cast<SCROW
>(nRows
)-1, nTab
);
460 bool ScViewFunc::PasteDataFormatSource( SotClipboardFormatId nFormatId
,
461 SCCOL nPosX
, SCROW nPosY
, bool bAllowDialogs
,
462 TransferableDataHelper
& rDataHelper
, Point
& rPos
)
465 uno::Reference
< io::XInputStream
> xStm
;
466 TransferableObjectDescriptor aObjDesc
;
468 if (rDataHelper
.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR
, aObjDesc
))
469 xStm
= rDataHelper
.GetInputStream(nFormatId
, OUString());
473 if ( aObjDesc
.maClassName
== SvGlobalName( SO3_SC_CLASSID_60
) )
475 uno::Reference
< embed::XStorage
> xStore
= ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm
);
477 // mba: BaseURL doesn't make sense for clipboard
478 // #i43716# Medium must be allocated with "new".
479 // DoLoad stores the pointer and deletes it with the SfxObjectShell.
480 SfxMedium
* pMedium
= new SfxMedium( xStore
, OUString() );
482 // TODO/LATER: is it a problem that we don't support binary formats here?
483 ScDocShellRef xDocShRef
= new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT
);
484 if (xDocShRef
->DoLoad(pMedium
))
486 ScDocument
& rSrcDoc
= xDocShRef
->GetDocument();
487 SCTAB nSrcTab
= rSrcDoc
.GetVisibleTab();
488 if (!rSrcDoc
.HasTable(nSrcTab
))
491 ScMarkData
aSrcMark(rSrcDoc
.GetSheetLimits());
492 aSrcMark
.SelectOneTable( nSrcTab
); // for CopyToClip
493 ScDocumentUniquePtr
pClipDoc(new ScDocument( SCDOCMODE_CLIP
));
495 SCCOL nFirstCol
, nLastCol
;
496 SCROW nFirstRow
, nLastRow
;
497 if ( rSrcDoc
.GetDataStart( nSrcTab
, nFirstCol
, nFirstRow
) )
499 rSrcDoc
.GetCellArea( nSrcTab
, nLastCol
, nLastRow
);
500 if (nLastCol
< nFirstCol
)
501 nLastCol
= nFirstCol
;
502 if (nLastRow
< nFirstRow
)
503 nLastRow
= nFirstRow
;
507 nFirstCol
= nLastCol
= 0;
508 nFirstRow
= nLastRow
= 0;
511 bool bIncludeObjects
= false; // include drawing layer objects in CopyToClip ?
513 if (nFormatId
== SotClipboardFormatId::EMBED_SOURCE
)
515 const ScDrawLayer
* pDraw
= rSrcDoc
.GetDrawLayer();
516 SCCOL nPrintEndCol
= nFirstCol
;
517 SCROW nPrintEndRow
= nFirstRow
;
518 bool bHasObjects
= pDraw
&& pDraw
->HasObjects();
519 // Extend the range to include the drawing layer objects.
520 if (bHasObjects
&& rSrcDoc
.GetPrintArea(nSrcTab
, nPrintEndCol
, nPrintEndRow
, true))
522 nLastCol
= std::max
<SCCOL
>(nLastCol
, nPrintEndCol
);
523 nLastRow
= std::max
<SCROW
>(nLastRow
, nPrintEndRow
);
526 bIncludeObjects
= bHasObjects
;
529 ScClipParam
aClipParam(ScRange(nFirstCol
, nFirstRow
, nSrcTab
, nLastCol
, nLastRow
, nSrcTab
), false);
530 rSrcDoc
.CopyToClip(aClipParam
, pClipDoc
.get(), &aSrcMark
, false, bIncludeObjects
);
531 ScGlobal::SetClipDocName( xDocShRef
->GetTitle( SFX_TITLE_FULLNAME
) );
533 SetCursor( nPosX
, nPosY
);
535 PasteFromClip( InsertDeleteFlags::ALL
, pClipDoc
.get(),
536 ScPasteFunc::NONE
, false, false, false, INS_NONE
, InsertDeleteFlags::NONE
,
541 xDocShRef
->DoClose();
547 uno::Reference
< embed::XEmbeddedObject
> xObj
= GetViewData().GetViewShell()->GetObjectShell()->
548 GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
551 // try to get the replacement image from the clipboard
553 SotClipboardFormatId nGrFormat
= SotClipboardFormatId::NONE
;
555 // limit the size of the preview metafile to 100000 actions
556 GDIMetaFile aMetafile
;
557 if (rDataHelper
.GetGDIMetaFile(SotClipboardFormatId::GDIMETAFILE
, aMetafile
, 100000))
559 nGrFormat
= SotClipboardFormatId::GDIMETAFILE
;
560 aGraphic
= aMetafile
;
563 // insert replacement image ( if there is one ) into the object helper
564 if ( nGrFormat
!= SotClipboardFormatId::NONE
)
566 datatransfer::DataFlavor aDataFlavor
;
567 SotExchange::GetFormatDataFlavor( nGrFormat
, aDataFlavor
);
568 PasteObject( rPos
, xObj
, &aObjDesc
.maSize
, &aGraphic
, aDataFlavor
.MimeType
, aObjDesc
.mnViewAspect
);
571 PasteObject( rPos
, xObj
, &aObjDesc
.maSize
);
577 OSL_FAIL("Error in CreateAndLoad");
583 if ( rDataHelper
.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE
, aObjDesc
) )
586 uno::Reference
< embed::XEmbeddedObject
> xObj
;
587 xStm
= rDataHelper
.GetInputStream(SotClipboardFormatId::EMBED_SOURCE_OLE
, OUString());
589 rDataHelper
.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE
, OUString());
593 xObj
= GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
599 uno::Reference
< embed::XStorage
> xTmpStor
= ::comphelper::OStorageHelper::GetTemporaryStorage();
600 uno::Reference
< embed::XEmbedObjectClipboardCreator
> xClipboardCreator
=
601 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
603 embed::InsertedObjectInfo aInfo
= xClipboardCreator
->createInstanceInitFromClipboard(
606 uno::Sequence
< beans::PropertyValue
>() );
608 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
609 // for example whether the object should be an iconified one
612 GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj
, aName
);
614 catch( uno::Exception
& )
620 // try to get the replacement image from the clipboard
622 SotClipboardFormatId nGrFormat
= SotClipboardFormatId::NONE
;
624 // (for Selection Manager in Trusted Solaris)
626 if( rDataHelper
.GetGraphic( SotClipboardFormatId::SVXB
, aGraphic
) )
627 nGrFormat
= SotClipboardFormatId::SVXB
;
628 else if( rDataHelper
.GetGraphic( SotClipboardFormatId::GDIMETAFILE
, aGraphic
) )
629 nGrFormat
= SotClipboardFormatId::GDIMETAFILE
;
630 else if( rDataHelper
.GetGraphic( SotClipboardFormatId::BITMAP
, aGraphic
) )
631 nGrFormat
= SotClipboardFormatId::BITMAP
;
634 // insert replacement image ( if there is one ) into the object helper
635 if ( nGrFormat
!= SotClipboardFormatId::NONE
)
637 datatransfer::DataFlavor aDataFlavor
;
638 SotExchange::GetFormatDataFlavor( nGrFormat
, aDataFlavor
);
639 PasteObject( rPos
, xObj
, &aObjDesc
.maSize
, &aGraphic
, aDataFlavor
.MimeType
, aObjDesc
.mnViewAspect
);
642 PasteObject( rPos
, xObj
, &aObjDesc
.maSize
);
644 // let object stay in loaded state after insertion
645 SdrOle2Obj::Unload( xObj
, embed::Aspects::MSOLE_CONTENT
);
650 OSL_FAIL("Error creating external OLE object");
653 //TODO/LATER: if format is not available, create picture
658 bool ScViewFunc::PasteDataFormatFormattedText( SotClipboardFormatId nFormatId
,
659 const uno::Reference
<datatransfer::XTransferable
>& rxTransferable
,
660 SCCOL nPosX
, SCROW nPosY
, bool bAllowDialogs
,
661 TransferableDataHelper
& rDataHelper
)
663 if ( nFormatId
== SotClipboardFormatId::RTF
&& rDataHelper
.HasFormat( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT
) )
665 // use EditView's PasteSpecial / Drop
666 PasteRTF( nPosX
, nPosY
, rxTransferable
);
671 ScDocument
& rDoc
= GetViewData().GetDocument();
672 ScAddress
aCellPos( nPosX
, nPosY
, GetViewData().GetTabNo() );
673 auto pObj
= std::make_shared
<ScImportExport
>(GetViewData().GetDocument(), aCellPos
);
674 pObj
->SetOverwriting( true );
676 auto pStrBuffer
= std::make_shared
<OUString
>();
677 if (std::unique_ptr
<SvStream
> xStream
= rDataHelper
.GetSotStorageStream( nFormatId
) )
679 // Static variables for per-session storage. This could be
680 // changed to longer-term storage in future.
681 static bool bHaveSavedPreferences
= false;
682 static LanguageType eSavedLanguage
;
683 static bool bSavedDateConversion
;
684 static bool bSavedScientificConversion
;
686 if (nFormatId
== SotClipboardFormatId::HTML
&&
687 !comphelper::LibreOfficeKit::isActive())
689 if (bHaveSavedPreferences
)
691 ScAsciiOptions aOptions
;
692 aOptions
.SetLanguage(eSavedLanguage
);
693 aOptions
.SetDetectSpecialNumber(bSavedDateConversion
);
694 aOptions
.SetDetectScientificNumber(bSavedScientificConversion
);
695 pObj
->SetExtOptions(aOptions
);
699 // Launch the text import options dialog. For now, we do
700 // this for html pasting only, but in the future it may
701 // make sense to do it for other data types too.
702 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
703 vcl::Window
* pParent
= GetActiveWin();
704 ScopedVclPtr
<AbstractScTextImportOptionsDlg
> pDlg(
705 pFact
->CreateScTextImportOptionsDlg(pParent
? pParent
->GetFrameWeld() : nullptr));
707 if (pDlg
->Execute() == RET_OK
)
709 ScAsciiOptions aOptions
;
710 aOptions
.SetLanguage(pDlg
->GetLanguageType());
711 aOptions
.SetDetectSpecialNumber(pDlg
->IsDateConversionSet());
712 aOptions
.SetDetectScientificNumber(pDlg
->IsScientificConversionSet());
713 if (!pDlg
->IsKeepAskingSet())
715 bHaveSavedPreferences
= true;
716 eSavedLanguage
= pDlg
->GetLanguageType();
717 bSavedDateConversion
= pDlg
->IsDateConversionSet();
718 bSavedScientificConversion
= pDlg
->IsScientificConversionSet();
720 pObj
->SetExtOptions(aOptions
);
724 // prevent error dialog for user cancel action
730 bRet
= pObj
->ImportStream( *xStream
, OUString(), nFormatId
);
731 // mba: clipboard always must contain absolute URLs (could be from alien source)
733 else if ((nFormatId
== SotClipboardFormatId::STRING
|| nFormatId
== SotClipboardFormatId::STRING_TSVC
)
734 && rDataHelper
.GetString( nFormatId
, *pStrBuffer
))
736 // Do CSV dialog if more than one line. But not if invoked from Automation.
737 const SfxViewShell
* pViewShell
= SfxViewShell::Current();
738 sal_Int32 nDelim
= pStrBuffer
->indexOf('\n');
739 if (!(pViewShell
&& pViewShell
->isLOKMobilePhone()) && !comphelper::Automation::AutomationInvokedZone::isActive()
740 && nDelim
>= 0 && nDelim
!= pStrBuffer
->getLength () - 1)
742 vcl::Window
* pParent
= GetActiveWin();
744 auto pStrm
= std::make_shared
<ScImportStringStream
>(*pStrBuffer
);
746 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
747 VclPtr
<AbstractScImportAsciiDlg
> pDlg(
748 pFact
->CreateScImportAsciiDlg(pParent
? pParent
->GetFrameWeld() : nullptr, OUString(), pStrm
.get(), SC_PASTETEXT
));
750 bAllowDialogs
= bAllowDialogs
&& !ScModule::get()->IsInExecuteDrop();
752 pDlg
->StartExecuteAsync([this, pDlg
, &rDoc
, pStrm
=std::move(pStrm
),
753 nFormatId
, pStrBuffer
=std::move(pStrBuffer
),
754 pObj
=std::move(pObj
), bAllowDialogs
](sal_Int32 nResult
){
755 bool bShowErrorDialog
= bAllowDialogs
;
756 if (RET_OK
== nResult
)
758 ScAsciiOptions aOptions
;
759 pDlg
->GetOptions( aOptions
);
760 pDlg
->SaveParameters();
761 pObj
->SetExtOptions( aOptions
);
762 pObj
->ImportString( *pStrBuffer
, nFormatId
);
764 // TODO: what if (aObj.IsOverflow())
765 // Content was partially pasted, which can be undone by
767 bShowErrorDialog
= bShowErrorDialog
&& pObj
->IsOverflow();
771 bShowErrorDialog
= false;
772 // Yes, no failure, don't raise a "couldn't paste"
773 // dialog if user cancelled.
777 GetViewData().UpdateInputHandler();
779 rDoc
.SetPastingDrawFromOtherDoc( false );
781 if (bShowErrorDialog
)
782 ErrorMessage(STR_PASTE_ERROR
);
788 bRet
= pObj
->ImportString( *pStrBuffer
, nFormatId
);
790 else if ((nFormatId
!= SotClipboardFormatId::STRING
&& nFormatId
!= SotClipboardFormatId::STRING_TSVC
)
791 && rDataHelper
.GetString( nFormatId
, *pStrBuffer
))
792 bRet
= pObj
->ImportString( *pStrBuffer
, nFormatId
);
795 GetViewData().UpdateInputHandler();
799 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */