tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / viewfun5.cxx
blob3786db72362965f307dfe69782d45d4994d58938
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
54 #include <docsh.hxx>
55 #include <drawview.hxx>
56 #include <impex.hxx>
57 #include <dbdata.hxx>
58 #include <sc.hrc>
59 #include <filter.hxx>
60 #include <globstr.hrc>
61 #include <global.hxx>
62 #include <scextopt.hxx>
63 #include <tabvwsh.hxx>
64 #include <compiler.hxx>
65 #include <scmod.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>
73 #include <memory>
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)
85 if (pLogicPos)
86 aPos = *pLogicPos;
87 else
89 // inserting position isn't needed for text formats
90 bool bIsTextFormat = ( ScImportExport::IsFormatSupported( nFormatId ) ||
91 nFormatId == SotClipboardFormatId::RTF );
92 if ( !bIsTextFormat )
94 // Window MapMode isn't drawing MapMode if DrawingLayer hasn't been created yet
96 SCTAB nTab = GetViewData().GetTabNo();
97 tools::Long nXT = 0;
98 for (SCCOL i=0; i<nPosX; i++)
99 nXT += rDoc.GetColWidth(i,nTab);
100 if (rDoc.IsNegativePage(nTab))
101 nXT = -nXT;
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 );
109 bool bRet = false;
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);
140 uno::Any aDescAny;
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 );
154 OUString sTarget;
155 if (pDBData)
156 sTarget = pDBData->GetName();
157 else
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 });
172 bRet = true;
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 ) )
181 MakeDrawLayer();
182 ScDrawView* pScDrawView = GetScDrawView();
183 rtl::Reference<SdrObject> pObj = pScDrawView->CreateFieldControl( svx::OColumnTransferable::extractColumnDescriptor( aDataHelper ) );
184 if (pObj)
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);
197 else
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();
203 while (pSubObj)
205 if ( dynamic_cast<const SdrUnoObj*>( pSubObj) != nullptr )
206 pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
207 else
208 pSubObj->NbcSetLayer(SC_LAYER_FRONT);
209 pSubObj = aIter.Next();
213 pScDrawView->InsertObjectSafe(pObj.get(), *pScDrawView->GetSdrPageView());
215 GetViewData().GetViewShell()->SetDrawShell( true );
216 bRet = true;
220 else if (nFormatId == SotClipboardFormatId::BITMAP || nFormatId == SotClipboardFormatId::PNG || nFormatId == SotClipboardFormatId::JPEG)
222 BitmapEx aBmpEx;
223 if( aDataHelper.GetBitmapEx( SotClipboardFormatId::BITMAP, aBmpEx ) )
224 bRet = PasteBitmapEx( aPos, aBmpEx );
226 else if (nFormatId == SotClipboardFormatId::GDIMETAFILE)
228 GDIMetaFile aMtf;
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 ) )
236 Graphic aGraphic;
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();
254 xStm->Seek(0);
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();
267 while (pObject)
269 if ( dynamic_cast<const SdrUnoObj*>( pObject) != nullptr )
270 pObject->NbcSetLayer(SC_LAYER_CONTROLS);
271 else
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();
281 bRet = true;
284 else if ( (nFormatId == SotClipboardFormatId::BIFF_5) || (nFormatId == SotClipboardFormatId::BIFF_8) )
286 // do excel import into a clipboard document
287 //TODO/MBA: testing
288 uno::Reference <io::XInputStream> xStm = aDataHelper.GetInputStream(nFormatId, OUString());
289 if (xStm.is())
291 ScDocument aInsDoc( SCDOCMODE_CLIP );
292 SCTAB nSrcTab = 0; // Biff5 in clipboard: always sheet 0
293 aInsDoc.ResetClip( &rDoc, nSrcTab );
295 SfxMedium aMed;
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 )
300 ScRange aSource;
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
312 else
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 );
319 else
321 nFirstCol = nLastCol = 0;
322 nFirstRow = nLastRow = 0;
324 aSource = ScRange( nFirstCol, nFirstRow, nSrcTab,
325 nLastCol, nLastRow, nSrcTab );
328 if ( pLogicPos )
330 // position specified (Drag&Drop) - change selection
331 MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, false, false );
332 Unmark();
335 aInsDoc.SetClipArea( aSource );
336 PasteFromClip( InsertDeleteFlags::ALL, &aInsDoc,
337 ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
338 bAllowDialogs );
339 bRet = true;
343 else if ( nFormatId == SotClipboardFormatId::SIMPLE_FILE )
345 OUString aFile;
346 if ( aDataHelper.GetString( nFormatId, aFile ) )
347 bRet = PasteFile( aPos, aFile, bLink );
349 else if ( nFormatId == SotClipboardFormatId::FILE_LIST )
351 FileList aFileList;
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 );
361 aPos.AdjustX(400 );
362 aPos.AdjustY(400 );
364 bRet = true;
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 );
377 return bRet;
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))
389 return false;
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 ) )
397 OUString aDataStr;
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' );
411 if (!aLine.empty())
412 nCols = comphelper::string::getTokenCount(aLine, '\t');
417 // create formula
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
422 // in the UI.
423 EnterMatrix("='"
424 + ScGlobal::GetAbsDocName(sTopic, GetViewData().GetDocument().GetDocumentShell())
425 + "'#" + sItem
426 , ::formula::FormulaGrammar::GRAM_NATIVE);
427 return true;
429 else
431 // DDE in all other cases.
433 // TODO: we could define ocQuote for "
434 EnterMatrix("=" + ScCompiler::GetNativeSymbol(ocDde)
435 + ScCompiler::GetNativeSymbol(ocOpen)
436 + "\"" + sApp + "\""
437 + ScCompiler::GetNativeSymbol(ocSep)
438 + "\"" + sTopic + "\""
439 + ScCompiler::GetNativeSymbol(ocSep)
440 + "\"" + sItem + "\""
441 + ScCompiler::GetNativeSymbol(ocClose)
442 , ::formula::FormulaGrammar::GRAM_NATIVE);
445 // mark range
447 SCTAB nTab = GetViewData().GetTabNo();
448 SCCOL nCurX = GetViewData().GetCurX();
449 SCROW nCurY = GetViewData().GetCurY();
450 HideAllCursors();
451 DoneBlockMode();
452 InitBlockMode( nCurX, nCurY, nTab );
453 MarkCursor( nCurX+static_cast<SCCOL>(nCols)-1, nCurY+static_cast<SCROW>(nRows)-1, nTab );
454 ShowAllCursors();
455 CursorPosChanged();
457 return true;
460 bool ScViewFunc::PasteDataFormatSource( SotClipboardFormatId nFormatId,
461 SCCOL nPosX, SCROW nPosY, bool bAllowDialogs,
462 TransferableDataHelper& rDataHelper, Point& rPos )
464 bool bRet = false;
465 uno::Reference < io::XInputStream > xStm;
466 TransferableObjectDescriptor aObjDesc;
468 if (rDataHelper.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc))
469 xStm = rDataHelper.GetInputStream(nFormatId, OUString());
471 if (xStm.is())
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))
489 nSrcTab = 0;
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;
505 else
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 );
534 Unmark();
535 PasteFromClip( InsertDeleteFlags::ALL, pClipDoc.get(),
536 ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
537 bAllowDialogs );
538 bRet = true;
541 xDocShRef->DoClose();
542 xDocShRef.clear();
544 else
546 OUString aName;
547 uno::Reference < embed::XEmbeddedObject > xObj = GetViewData().GetViewShell()->GetObjectShell()->
548 GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
549 if ( xObj.is() )
551 // try to get the replacement image from the clipboard
552 Graphic aGraphic;
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 );
570 else
571 PasteObject( rPos, xObj, &aObjDesc.maSize );
573 bRet = true;
575 else
577 OSL_FAIL("Error in CreateAndLoad");
581 else
583 if ( rDataHelper.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE, aObjDesc ) )
585 OUString aName;
586 uno::Reference < embed::XEmbeddedObject > xObj;
587 xStm = rDataHelper.GetInputStream(SotClipboardFormatId::EMBED_SOURCE_OLE, OUString());
588 if (!xStm.is())
589 rDataHelper.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE, OUString());
591 if (xStm.is())
593 xObj = GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
595 else
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(
604 xTmpStor,
605 u"DummyName"_ustr,
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
610 xObj = aInfo.Object;
611 if ( xObj.is() )
612 GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
614 catch( uno::Exception& )
618 if ( xObj.is() )
620 // try to get the replacement image from the clipboard
621 Graphic aGraphic;
622 SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
624 // (for Selection Manager in Trusted Solaris)
625 #ifndef __sun
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;
632 #endif
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 );
641 else
642 PasteObject( rPos, xObj, &aObjDesc.maSize );
644 // let object stay in loaded state after insertion
645 SdrOle2Obj::Unload( xObj, embed::Aspects::MSOLE_CONTENT );
646 bRet = true;
648 else
650 OSL_FAIL("Error creating external OLE object");
653 //TODO/LATER: if format is not available, create picture
655 return bRet;
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 );
667 return true;
670 bool bRet = false;
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);
697 else
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);
722 else
724 // prevent error dialog for user cancel action
725 bRet = true;
729 if(!bRet)
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
766 // the user though.
767 bShowErrorDialog = bShowErrorDialog && pObj->IsOverflow();
769 else
771 bShowErrorDialog = false;
772 // Yes, no failure, don't raise a "couldn't paste"
773 // dialog if user cancelled.
776 InvalidateAttribs();
777 GetViewData().UpdateInputHandler();
779 rDoc.SetPastingDrawFromOtherDoc( false );
781 if (bShowErrorDialog)
782 ErrorMessage(STR_PASTE_ERROR);
783 pDlg->disposeOnce();
785 return true;
787 else
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 );
794 InvalidateAttribs();
795 GetViewData().UpdateInputHandler();
796 return bRet;
799 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */