LibreOffice Module sc (master)  1
viewfun5.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
21 #include <com/sun/star/embed/Aspects.hpp>
22 #include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
23 
24 #include <svx/unomodel.hxx>
25 #include <unotools/streamwrap.hxx>
26 
27 #include <svx/fmmodel.hxx>
28 #include <svx/svditer.hxx>
29 #include <svx/svdobj.hxx>
30 #include <svx/svdogrp.hxx>
31 #include <svx/svdouno.hxx>
32 #include <svx/svdoole2.hxx>
33 #include <svx/svdpage.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <comphelper/classids.hxx>
37 #include <sot/formats.hxx>
38 #include <sot/filelist.hxx>
39 #include <sot/storage.hxx>
40 #include <svl/stritem.hxx>
41 #include <vcl/transfer.hxx>
42 #include <vcl/graph.hxx>
43 #include <vcl/TypeSerializer.hxx>
44 #include <osl/thread.h>
45 #include <o3tl/unit_conversion.hxx>
46 #include <o3tl/string_view.hxx>
47 
49 #include <comphelper/lok.hxx>
52 #include <comphelper/string.hxx>
53 
54 #include <viewfunc.hxx>
55 #include <docsh.hxx>
56 #include <drawview.hxx>
57 #include <impex.hxx>
58 #include <dbdata.hxx>
59 #include <sc.hrc>
60 #include <filter.hxx>
61 #include <globstr.hrc>
62 #include <global.hxx>
63 #include <scextopt.hxx>
64 #include <tabvwsh.hxx>
65 #include <compiler.hxx>
66 #include <scmod.hxx>
67 
68 #include <asciiopt.hxx>
69 #include <scabstdlg.hxx>
70 #include <clipparam.hxx>
71 #include <markdata.hxx>
72 #include <sfx2/frame.hxx>
73 #include <svx/dbaexchange.hxx>
74 #include <memory>
75 
76 using namespace com::sun::star;
77 
79  const uno::Reference<datatransfer::XTransferable>& rxTransferable,
80  SCCOL nPosX, SCROW nPosY, const Point* pLogicPos, bool bLink, bool bAllowDialogs )
81 {
82  ScDocument& rDoc = GetViewData().GetDocument();
83  rDoc.SetPastingDrawFromOtherDoc( true );
84 
85  Point aPos; // inserting position (1/100 mm)
86  if (pLogicPos)
87  aPos = *pLogicPos;
88  else
89  {
90  // inserting position isn't needed for text formats
91  bool bIsTextFormat = ( ScImportExport::IsFormatSupported( nFormatId ) ||
92  nFormatId == SotClipboardFormatId::RTF );
93  if ( !bIsTextFormat )
94  {
95  // Window MapMode isn't drawing MapMode if DrawingLayer hasn't been created yet
96 
97  SCTAB nTab = GetViewData().GetTabNo();
98  tools::Long nXT = 0;
99  for (SCCOL i=0; i<nPosX; i++)
100  nXT += rDoc.GetColWidth(i,nTab);
101  if (rDoc.IsNegativePage(nTab))
102  nXT = -nXT;
103  tools::Long nYT = rDoc.GetRowHeight( 0, nPosY-1, nTab);
106  }
107  }
108 
109  TransferableDataHelper aDataHelper( rxTransferable );
110  bool bRet = false;
111 
112  // handle individual formats
113 
114  if ( nFormatId == SotClipboardFormatId::EMBED_SOURCE ||
115  nFormatId == SotClipboardFormatId::LINK_SOURCE ||
116  nFormatId == SotClipboardFormatId::EMBED_SOURCE_OLE ||
117  nFormatId == SotClipboardFormatId::LINK_SOURCE_OLE ||
118  nFormatId == SotClipboardFormatId::EMBEDDED_OBJ_OLE )
119  {
120  uno::Reference < io::XInputStream > xStm;
122 
123  if (aDataHelper.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc))
124  xStm = aDataHelper.GetInputStream(nFormatId, OUString());
125 
126  if (xStm.is())
127  {
128  if ( aObjDesc.maClassName == SvGlobalName( SO3_SC_CLASSID_60 ) )
129  {
130  uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm );
131 
132  // mba: BaseURL doesn't make sense for clipboard
133  // #i43716# Medium must be allocated with "new".
134  // DoLoad stores the pointer and deletes it with the SfxObjectShell.
135  SfxMedium* pMedium = new SfxMedium( xStore, OUString() );
136 
137  // TODO/LATER: is it a problem that we don't support binary formats here?
138  ScDocShellRef xDocShRef = new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT);
139  if (xDocShRef->DoLoad(pMedium))
140  {
141  ScDocument& rSrcDoc = xDocShRef->GetDocument();
142  SCTAB nSrcTab = rSrcDoc.GetVisibleTab();
143  if (!rSrcDoc.HasTable(nSrcTab))
144  nSrcTab = 0;
145 
146  ScMarkData aSrcMark(rSrcDoc.GetSheetLimits());
147  aSrcMark.SelectOneTable( nSrcTab ); // for CopyToClip
149 
150  SCCOL nFirstCol, nLastCol;
151  SCROW nFirstRow, nLastRow;
152  if ( rSrcDoc.GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
153  {
154  rSrcDoc.GetCellArea( nSrcTab, nLastCol, nLastRow );
155  if (nLastCol < nFirstCol)
156  nLastCol = nFirstCol;
157  if (nLastRow < nFirstRow)
158  nLastRow = nFirstRow;
159  }
160  else
161  {
162  nFirstCol = nLastCol = 0;
163  nFirstRow = nLastRow = 0;
164  }
165 
166  bool bIncludeObjects = false; // include drawing layer objects in CopyToClip ?
167 
168  if (nFormatId == SotClipboardFormatId::EMBED_SOURCE)
169  {
170  const ScDrawLayer* pDraw = rSrcDoc.GetDrawLayer();
171  SCCOL nPrintEndCol = nFirstCol;
172  SCROW nPrintEndRow = nFirstRow;
173  bool bHasObjects = pDraw && pDraw->HasObjects();
174  // Extend the range to include the drawing layer objects.
175  if (bHasObjects && rSrcDoc.GetPrintArea(nSrcTab, nPrintEndCol, nPrintEndRow, true))
176  {
177  nLastCol = std::max<SCCOL>(nLastCol, nPrintEndCol);
178  nLastRow = std::max<SCROW>(nLastRow, nPrintEndRow);
179  }
180 
181  bIncludeObjects = bHasObjects;
182  }
183 
184  ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, nSrcTab, nLastCol, nLastRow, nSrcTab), false);
185  rSrcDoc.CopyToClip(aClipParam, pClipDoc.get(), &aSrcMark, false, bIncludeObjects);
187 
188  SetCursor( nPosX, nPosY );
189  Unmark();
190  PasteFromClip( InsertDeleteFlags::ALL, pClipDoc.get(),
191  ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
192  bAllowDialogs );
193  bRet = true;
194  }
195 
196  xDocShRef->DoClose();
197  xDocShRef.clear();
198  }
199  else
200  {
201  OUString aName;
202  uno::Reference < embed::XEmbeddedObject > xObj = GetViewData().GetViewShell()->GetObjectShell()->
203  GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
204  if ( xObj.is() )
205  {
206  // try to get the replacement image from the clipboard
207  Graphic aGraphic;
208  SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
209 
210  // limit the size of the preview metafile to 100000 actions
211  GDIMetaFile aMetafile;
212  if (aDataHelper.GetGDIMetaFile(SotClipboardFormatId::GDIMETAFILE, aMetafile, 100000))
213  {
214  nGrFormat = SotClipboardFormatId::GDIMETAFILE;
215  aGraphic = aMetafile;
216  }
217 
218  // insert replacement image ( if there is one ) into the object helper
219  if ( nGrFormat != SotClipboardFormatId::NONE )
220  {
221  datatransfer::DataFlavor aDataFlavor;
222  SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
223  PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
224  }
225  else
226  PasteObject( aPos, xObj, &aObjDesc.maSize );
227 
228  bRet = true;
229  }
230  else
231  {
232  OSL_FAIL("Error in CreateAndLoad");
233  }
234  }
235  }
236  else
237  {
238  if ( aDataHelper.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE, aObjDesc ) )
239  {
240  OUString aName;
241  uno::Reference < embed::XEmbeddedObject > xObj;
242  xStm = aDataHelper.GetInputStream(SotClipboardFormatId::EMBED_SOURCE_OLE, OUString());
243  if (!xStm.is())
244  aDataHelper.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE, OUString());
245 
246  if (xStm.is())
247  {
248  xObj = GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
249  }
250  else
251  {
252  try
253  {
254  uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
255  uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator =
256  embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
257 
258  embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
259  xTmpStor,
260  "DummyName",
261  uno::Sequence< beans::PropertyValue >() );
262 
263  // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
264  // for example whether the object should be an iconified one
265  xObj = aInfo.Object;
266  if ( xObj.is() )
267  GetViewData().GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
268  }
269  catch( uno::Exception& )
270  {}
271  }
272 
273  if ( xObj.is() )
274  {
275  // try to get the replacement image from the clipboard
276  Graphic aGraphic;
277  SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
278 
279 // (for Selection Manager in Trusted Solaris)
280 #ifndef __sun
281  if( aDataHelper.GetGraphic( SotClipboardFormatId::SVXB, aGraphic ) )
282  nGrFormat = SotClipboardFormatId::SVXB;
283  else if( aDataHelper.GetGraphic( SotClipboardFormatId::GDIMETAFILE, aGraphic ) )
284  nGrFormat = SotClipboardFormatId::GDIMETAFILE;
285  else if( aDataHelper.GetGraphic( SotClipboardFormatId::BITMAP, aGraphic ) )
286  nGrFormat = SotClipboardFormatId::BITMAP;
287 #endif
288 
289  // insert replacement image ( if there is one ) into the object helper
290  if ( nGrFormat != SotClipboardFormatId::NONE )
291  {
292  datatransfer::DataFlavor aDataFlavor;
293  SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
294  PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
295  }
296  else
297  PasteObject( aPos, xObj, &aObjDesc.maSize );
298 
299  // let object stay in loaded state after insertion
300  SdrOle2Obj::Unload( xObj, embed::Aspects::MSOLE_CONTENT );
301  bRet = true;
302  }
303  else
304  {
305  OSL_FAIL("Error creating external OLE object");
306  }
307  }
308  //TODO/LATER: if format is not available, create picture
309  }
310  }
311  else if ( nFormatId == SotClipboardFormatId::LINK ) // LINK is also in ScImportExport
312  {
313  bRet = PasteLink( rxTransferable );
314  }
315  else if ( ScImportExport::IsFormatSupported( nFormatId ) || nFormatId == SotClipboardFormatId::RTF ||
316  nFormatId == SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT )
317  {
318  if ( nFormatId == SotClipboardFormatId::RTF && ( aDataHelper.HasFormat( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT ) ) )
319  {
320  // use EditView's PasteSpecial / Drop
321  PasteRTF( nPosX, nPosY, rxTransferable );
322  bRet = true;
323  }
324  else
325  {
326  ScAddress aCellPos( nPosX, nPosY, GetViewData().GetTabNo() );
327  auto pObj = std::make_shared<ScImportExport>(GetViewData().GetDocument(), aCellPos);
328  pObj->SetOverwriting( true );
329 
330 
331  auto pStrBuffer = std::make_shared<OUString>();
333  if ( aDataHelper.GetSotStorageStream( nFormatId, xStream ) && xStream.is() )
334  {
335  // Static variables for per-session storage. This could be
336  // changed to longer-term storage in future.
337  static bool bHaveSavedPreferences = false;
338  static LanguageType eSavedLanguage;
339  static bool bSavedDateConversion;
340 
341  if (nFormatId == SotClipboardFormatId::HTML &&
343  {
344  if (bHaveSavedPreferences)
345  {
346  ScAsciiOptions aOptions;
347  aOptions.SetLanguage(eSavedLanguage);
348  aOptions.SetDetectSpecialNumber(bSavedDateConversion);
349  pObj->SetExtOptions(aOptions);
350  }
351  else
352  {
353  // Launch the text import options dialog. For now, we do
354  // this for html pasting only, but in the future it may
355  // make sense to do it for other data types too.
357  vcl::Window* pParent = GetActiveWin();
359  pFact->CreateScTextImportOptionsDlg(pParent ? pParent->GetFrameWeld() : nullptr));
360 
361  if (pDlg->Execute() == RET_OK)
362  {
363  ScAsciiOptions aOptions;
364  aOptions.SetLanguage(pDlg->GetLanguageType());
366  if (!pDlg->IsKeepAskingSet())
367  {
368  bHaveSavedPreferences = true;
369  eSavedLanguage = pDlg->GetLanguageType();
370  bSavedDateConversion = pDlg->IsDateConversionSet();
371  }
372  pObj->SetExtOptions(aOptions);
373  }
374  else
375  {
376  // prevent error dialog for user cancel action
377  bRet = true;
378  }
379  }
380  }
381  if(!bRet)
382  bRet = pObj->ImportStream( *xStream, OUString(), nFormatId );
383  // mba: clipboard always must contain absolute URLs (could be from alien source)
384  }
385  else if ((nFormatId == SotClipboardFormatId::STRING || nFormatId == SotClipboardFormatId::STRING_TSVC)
386  && aDataHelper.GetString( nFormatId, *pStrBuffer ))
387  {
388  // Do CSV dialog if more than one line. But not if invoked from Automation.
389  const SfxViewShell* pViewShell = SfxViewShell::Current();
390  sal_Int32 nDelim = pStrBuffer->indexOf('\n');
391  if (!(pViewShell && pViewShell->isLOKMobilePhone()) && !comphelper::Automation::AutomationInvokedZone::isActive()
392  && nDelim >= 0 && nDelim != pStrBuffer->getLength () - 1)
393  {
394  vcl::Window* pParent = GetActiveWin();
395 
396  auto pStrm = std::make_shared<ScImportStringStream>(*pStrBuffer);
397 
400  pFact->CreateScImportAsciiDlg(pParent ? pParent->GetFrameWeld() : nullptr, OUString(), pStrm.get(), SC_PASTETEXT));
401 
402  bAllowDialogs = bAllowDialogs && !SC_MOD()->IsInExecuteDrop();
403 
404  pDlg->StartExecuteAsync([this, pDlg, &rDoc, pStrm, nFormatId, pStrBuffer, pObj, bAllowDialogs](sal_Int32 nResult){
405  bool bShowErrorDialog = bAllowDialogs;
406  if (RET_OK == nResult)
407  {
408  ScAsciiOptions aOptions;
409  pDlg->GetOptions( aOptions );
410  pDlg->SaveParameters();
411  pObj->SetExtOptions( aOptions );
412  pObj->ImportString( *pStrBuffer, nFormatId );
413 
414  // TODO: what if (aObj.IsOverflow())
415  // Content was partially pasted, which can be undone by
416  // the user though.
417  bShowErrorDialog = bShowErrorDialog && pObj->IsOverflow();
418  }
419  else
420  {
421  bShowErrorDialog = false;
422  // Yes, no failure, don't raise a "couldn't paste"
423  // dialog if user cancelled.
424  }
425 
426  InvalidateAttribs();
427  GetViewData().UpdateInputHandler();
428 
429  rDoc.SetPastingDrawFromOtherDoc( false );
430 
431  if (bShowErrorDialog)
432  ErrorMessage(STR_PASTE_ERROR);
433  pDlg->disposeOnce();
434  });
435  return true;
436  }
437  else
438  bRet = pObj->ImportString( *pStrBuffer, nFormatId );
439  }
440  else if ((nFormatId != SotClipboardFormatId::STRING && nFormatId != SotClipboardFormatId::STRING_TSVC)
441  && aDataHelper.GetString( nFormatId, *pStrBuffer ))
442  bRet = pObj->ImportString( *pStrBuffer, nFormatId );
443 
444  InvalidateAttribs();
445  GetViewData().UpdateInputHandler();
446  }
447  }
448  else if (nFormatId == SotClipboardFormatId::SBA_DATAEXCHANGE)
449  {
450  // import of database data into table
451 
452  const DataFlavorExVector& rVector = aDataHelper.GetDataFlavorExVector();
454  {
455  // transport the whole ODataAccessDescriptor as slot parameter
457  uno::Any aDescAny;
458  uno::Sequence<beans::PropertyValue> aProperties = aDesc.createPropertyValueSequence();
459  aDescAny <<= aProperties;
460  SfxUnoAnyItem aDataDesc(SID_SBA_IMPORT, aDescAny);
461 
462  ScDocShell* pDocSh = GetViewData().GetDocShell();
463  SCTAB nTab = GetViewData().GetTabNo();
464 
465  ClickCursor(nPosX, nPosY, false); // set cursor position
466 
467  // Creation of database area "Import1" isn't here, but in the DocShell
468  // slot execute, so it can be added to the undo action
469 
470  ScDBData* pDBData = pDocSh->GetDBData( ScRange(nPosX,nPosY,nTab), SC_DB_OLD, ScGetDBSelection::Keep );
471  OUString sTarget;
472  if (pDBData)
473  sTarget = pDBData->GetName();
474  else
475  {
476  ScAddress aCellPos( nPosX,nPosY,nTab );
477  sTarget = aCellPos.Format(ScRefFlags::ADDR_ABS_3D, &rDoc, rDoc.GetAddressConvention());
478  }
479  SfxStringItem aTarget(FN_PARAM_1, sTarget);
480 
481  bool bAreaIsNew = !pDBData;
482  SfxBoolItem aAreaNew(FN_PARAM_2, bAreaIsNew);
483 
484  // asynchronous, to avoid doing the whole import in drop handler
485  SfxDispatcher& rDisp = GetViewData().GetDispatcher();
486  rDisp.ExecuteList(SID_SBA_IMPORT, SfxCallMode::ASYNCHRON,
487  { &aDataDesc, &aTarget, &aAreaNew });
488 
489  bRet = true;
490  }
491  }
492  else if (nFormatId == SotClipboardFormatId::SBA_FIELDDATAEXCHANGE)
493  {
494  // insert database field control
495 
496  if ( svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper.GetDataFlavorExVector(), ColumnTransferFormatFlags::COLUMN_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE ) )
497  {
498  MakeDrawLayer();
499  ScDrawView* pScDrawView = GetScDrawView();
501  if (pObj)
502  {
503  Point aInsPos = aPos;
504  tools::Rectangle aRect(pObj->GetLogicRect());
505  aInsPos.AdjustX( -(aRect.GetSize().Width() / 2) );
506  aInsPos.AdjustY( -(aRect.GetSize().Height() / 2) );
507  if ( aInsPos.X() < 0 ) aInsPos.setX( 0 );
508  if ( aInsPos.Y() < 0 ) aInsPos.setY( 0 );
509  aRect.SetPos(aInsPos);
510  pObj->SetLogicRect(aRect);
511 
512  if ( dynamic_cast<const SdrUnoObj*>( pObj.get() ) != nullptr )
513  pObj->NbcSetLayer(SC_LAYER_CONTROLS);
514  else
515  pObj->NbcSetLayer(SC_LAYER_FRONT);
516  if (dynamic_cast<const SdrObjGroup*>( pObj.get() ) != nullptr)
517  {
518  SdrObjListIter aIter( *pObj, SdrIterMode::DeepWithGroups );
519  SdrObject* pSubObj = aIter.Next();
520  while (pSubObj)
521  {
522  if ( dynamic_cast<const SdrUnoObj*>( pSubObj) != nullptr )
523  pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
524  else
525  pSubObj->NbcSetLayer(SC_LAYER_FRONT);
526  pSubObj = aIter.Next();
527  }
528  }
529 
530  pScDrawView->InsertObjectSafe(pObj.release(), *pScDrawView->GetSdrPageView());
531 
532  GetViewData().GetViewShell()->SetDrawShell( true );
533  bRet = true;
534  }
535  }
536  }
537  else if (nFormatId == SotClipboardFormatId::BITMAP || nFormatId == SotClipboardFormatId::PNG || nFormatId == SotClipboardFormatId::JPEG)
538  {
539  BitmapEx aBmpEx;
540  if( aDataHelper.GetBitmapEx( SotClipboardFormatId::BITMAP, aBmpEx ) )
541  bRet = PasteBitmapEx( aPos, aBmpEx );
542  }
543  else if (nFormatId == SotClipboardFormatId::GDIMETAFILE)
544  {
545  GDIMetaFile aMtf;
546  if( aDataHelper.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE, aMtf ) )
547  bRet = PasteMetaFile( aPos, aMtf );
548  }
549  else if (nFormatId == SotClipboardFormatId::SVXB)
550  {
552  if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::SVXB, xStm ) )
553  {
554  Graphic aGraphic;
555  TypeSerializer aSerializer(*xStm);
556  aSerializer.readGraphic(aGraphic);
557  bRet = PasteGraphic( aPos, aGraphic, OUString() );
558  }
559  }
560  else if ( nFormatId == SotClipboardFormatId::DRAWING )
561  {
563  if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::DRAWING, xStm ) )
564  {
565  MakeDrawLayer(); // before loading model, so 3D factory has been created
566 
567  ScDocShellRef aDragShellRef( new ScDocShell );
568  aDragShellRef->DoInitNew();
569 
570  std::unique_ptr<FmFormModel> pModel(
571  new FmFormModel(
572  nullptr,
573  aDragShellRef.get()));
574 
575  pModel->GetItemPool().FreezeIdRanges();
576  xStm->Seek(0);
577 
578  css::uno::Reference< css::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
579  SvxDrawingLayerImport( pModel.get(), xInputStream );
580 
581  // set everything to right layer:
582  size_t nObjCount = 0;
583  sal_uInt16 nPages = pModel->GetPageCount();
584  for (sal_uInt16 i=0; i<nPages; i++)
585  {
586  SdrPage* pPage = pModel->GetPage(i);
587  SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
588  SdrObject* pObject = aIter.Next();
589  while (pObject)
590  {
591  if ( dynamic_cast<const SdrUnoObj*>( pObject) != nullptr )
592  pObject->NbcSetLayer(SC_LAYER_CONTROLS);
593  else
594  pObject->NbcSetLayer(SC_LAYER_FRONT);
595  pObject = aIter.Next();
596  }
597 
598  nObjCount += pPage->GetObjCount(); // count group object only once
599  }
600 
601  PasteDraw(aPos, pModel.get(), (nObjCount > 1), u"A", u"B"); // grouped if more than 1 object
602  pModel.reset();
603  aDragShellRef->DoClose();
604  bRet = true;
605  }
606  }
607  else if ( (nFormatId == SotClipboardFormatId::BIFF_5) || (nFormatId == SotClipboardFormatId::BIFF_8) )
608  {
609  // do excel import into a clipboard document
610  //TODO/MBA: testing
611  uno::Reference <io::XInputStream> xStm = aDataHelper.GetInputStream(nFormatId, OUString());
612  if (xStm.is())
613  {
614  ScDocument aInsDoc( SCDOCMODE_CLIP );
615  SCTAB nSrcTab = 0; // Biff5 in clipboard: always sheet 0
616  aInsDoc.ResetClip( &rDoc, nSrcTab );
617 
618  SfxMedium aMed;
619  aMed.GetItemSet()->Put( SfxUnoAnyItem( SID_INPUTSTREAM, uno::Any( xStm ) ) );
620  ErrCode eErr = ScFormatFilter::Get().ScImportExcel( aMed, &aInsDoc, EIF_AUTO );
621  if ( eErr == ERRCODE_NONE )
622  {
623  ScRange aSource;
624  const ScExtDocOptions* pExtOpt = aInsDoc.GetExtDocOptions();
625  const ScExtTabSettings* pTabSett = pExtOpt ? pExtOpt->GetTabSettings( nSrcTab ) : nullptr;
626  if( pTabSett && pTabSett->maUsedArea.IsValid() )
627  {
628  aSource = pTabSett->maUsedArea;
629  // ensure correct sheet indexes
630  aSource.aStart.SetTab( nSrcTab );
631  aSource.aEnd.SetTab( nSrcTab );
632 // don't use selection area: if cursor is moved in Excel after Copy, selection
633 // represents the new cursor position and not the copied area
634  }
635  else
636  {
637  OSL_FAIL("no dimension");
638  SCCOL nFirstCol, nLastCol;
639  SCROW nFirstRow, nLastRow;
640  if ( aInsDoc.GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
641  aInsDoc.GetCellArea( nSrcTab, nLastCol, nLastRow );
642  else
643  {
644  nFirstCol = nLastCol = 0;
645  nFirstRow = nLastRow = 0;
646  }
647  aSource = ScRange( nFirstCol, nFirstRow, nSrcTab,
648  nLastCol, nLastRow, nSrcTab );
649  }
650 
651  if ( pLogicPos )
652  {
653  // position specified (Drag&Drop) - change selection
654  MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, false, false );
655  Unmark();
656  }
657 
658  aInsDoc.SetClipArea( aSource );
659  PasteFromClip( InsertDeleteFlags::ALL, &aInsDoc,
660  ScPasteFunc::NONE, false, false, false, INS_NONE, InsertDeleteFlags::NONE,
661  bAllowDialogs );
662  bRet = true;
663  }
664  }
665  }
666  else if ( nFormatId == SotClipboardFormatId::SIMPLE_FILE )
667  {
668  OUString aFile;
669  if ( aDataHelper.GetString( nFormatId, aFile ) )
670  bRet = PasteFile( aPos, aFile, bLink );
671  }
672  else if ( nFormatId == SotClipboardFormatId::FILE_LIST )
673  {
674  FileList aFileList;
675  if ( aDataHelper.GetFileList( nFormatId, aFileList ) )
676  {
677  sal_uLong nCount = aFileList.Count();
678  for( sal_uLong i = 0; i < nCount ; i++ )
679  {
680  OUString aFile = aFileList.GetFile( i );
681 
682  PasteFile( aPos, aFile, bLink );
683 
684  aPos.AdjustX(400 );
685  aPos.AdjustY(400 );
686  }
687  bRet = true;
688  }
689  }
690  else if ( nFormatId == SotClipboardFormatId::SOLK ||
691  nFormatId == SotClipboardFormatId::UNIFORMRESOURCELOCATOR ||
692  nFormatId == SotClipboardFormatId::NETSCAPE_BOOKMARK ||
693  nFormatId == SotClipboardFormatId::FILEGRPDESCRIPTOR )
694  {
695  bRet = PasteBookmark( nFormatId, rxTransferable, nPosX, nPosY );
696  }
697 
698  rDoc.SetPastingDrawFromOtherDoc( false );
699 
700  return bRet;
701 }
702 
703 bool ScViewFunc::PasteLink( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
704 {
705  TransferableDataHelper aDataHelper( rxTransferable );
706 
707  // get link data from transferable before string data,
708  // so the source knows it will be used for a link
709 
710  uno::Sequence<sal_Int8> aSequence = aDataHelper.GetSequence(SotClipboardFormatId::LINK, OUString());
711  if (!aSequence.hasElements())
712  {
713  OSL_FAIL("DDE Data not found.");
714  return false;
715  }
716 
717  // check size (only if string is available in transferable)
718 
719  sal_uInt16 nCols = 1;
720  sal_uInt16 nRows = 1;
721  if ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) )
722  {
723  OUString aDataStr;
724  if ( aDataHelper.GetString( SotClipboardFormatId::STRING, aDataStr ) )
725  {
726  // get size from string the same way as in ScDdeLink::DataChanged
727 
728  aDataStr = convertLineEnd(aDataStr, LINEEND_LF);
729  sal_Int32 nLen = aDataStr.getLength();
730  if (nLen && aDataStr[nLen-1] == '\n')
731  aDataStr = aDataStr.copy(0, nLen-1);
732 
733  if (!aDataStr.isEmpty())
734  {
735  nRows = comphelper::string::getTokenCount(aDataStr, '\n');
736  std::u16string_view aLine = o3tl::getToken(aDataStr, 0, '\n' );
737  if (!aLine.empty())
738  nCols = comphelper::string::getTokenCount(aLine, '\t');
739  }
740  }
741  }
742 
743  // create formula
744 
745  sal_Int32 nSeqLen = aSequence.getLength();
746  const char* p = reinterpret_cast<const char*>(aSequence.getConstArray());
747 
748  rtl_TextEncoding eSysEnc = osl_getThreadTextEncoding();
749 
750  // char array delimited by \0.
751  // app \0 topic \0 item \0 (extra \0) where the extra is optional.
752  ::std::vector<OUString> aStrs;
753  const char* pStart = p;
754  sal_Int32 nStart = 0;
755  for (sal_Int32 i = 0; i < nSeqLen; ++i, ++p)
756  {
757  if (*p == '\0')
758  {
759  sal_Int32 nLen = i - nStart;
760  aStrs.emplace_back(pStart, nLen, eSysEnc);
761  nStart = ++i;
762  pStart = ++p;
763  }
764  }
765 
766  if (aStrs.size() < 3)
767  return false;
768 
769  const OUString& pApp = aStrs[0];
770  const OUString& pTopic = aStrs[1];
771  const OUString& pItem = aStrs[2];
772  const OUString* pExtra = nullptr;
773  if (aStrs.size() > 3)
774  pExtra = &aStrs[3];
775 
776  if ( pExtra && *pExtra == "calc:extref" )
777  {
778  // Paste this as an external reference. Note that paste link always
779  // uses Calc A1 syntax even when another formula syntax is specified
780  // in the UI.
781  EnterMatrix("='"
782  + ScGlobal::GetAbsDocName(pTopic, GetViewData().GetDocument().GetDocumentShell())
783  + "'#" + pItem
785  return true;
786  }
787  else
788  {
789  // DDE in all other cases.
790 
791  // TODO: we could define ocQuote for "
792  EnterMatrix("=" + ScCompiler::GetNativeSymbol(ocDde)
794  + "\"" + pApp + "\""
796  + "\"" + pTopic + "\""
798  + "\"" + pItem + "\""
801  }
802 
803  // mark range
804 
805  SCTAB nTab = GetViewData().GetTabNo();
806  SCCOL nCurX = GetViewData().GetCurX();
807  SCROW nCurY = GetViewData().GetCurY();
808  HideAllCursors();
809  DoneBlockMode();
810  InitBlockMode( nCurX, nCurY, nTab );
811  MarkCursor( nCurX+static_cast<SCCOL>(nCols)-1, nCurY+static_cast<SCROW>(nRows)-1, nTab );
812  ShowAllCursors();
813  CursorPosChanged();
814 
815  return true;
816 }
817 
818 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SC_DLLPUBLIC bool GetPrintArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow, bool bNotes=true) const
Definition: documen2.cxx:594
void SetPos(const Point &rPoint)
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
ScAddress aStart
Definition: address.hxx:497
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
SC_DLLPUBLIC bool GetDataStart(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow) const
Definition: documen2.cxx:662
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:42
bool isLOKMobilePhone() const
void readGraphic(Graphic &rGraphic)
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
Definition: document.cxx:997
bool GetBitmapEx(SotClipboardFormatId nFormat, BitmapEx &rBmp) const
OUString GetTitle(sal_uInt16 nMaxLen=0) const
static css::uno::Reference< css::embed::XStorage > GetStorageFromInputStream(const css::uno::Reference< css::io::XInputStream > &xStream, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
static bool IsFormatSupported(SotClipboardFormatId nFormat)
Definition: impex.cxx:223
virtual ErrCode ScImportExcel(SfxMedium &, ScDocument *, const EXCIMPFORMAT)=0
::std::vector< DataFlavorEx > DataFlavorExVector
sal_uIntPtr sal_uLong
long Long
virtual void GetOptions(ScAsciiOptions &rOpt)=0
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
ocOpen
don't create
Definition: global.hxx:384
ScRange maUsedArea
Used area in the sheet (columns/rows only).
Definition: scextopt.hxx:49
size_t GetObjCount() const
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
static SC_DLLPUBLIC ScFormatFilterPlugin & Get()
Definition: impex.cxx:2622
ScAddress aEnd
Definition: address.hxx:498
Extended options held by an ScDocument containing additional settings for filters.
Definition: scextopt.hxx:76
css::uno::Sequence< css::beans::PropertyValue > const & createPropertyValueSequence()
ScDBData * GetDBData(const ScRange &rMarked, ScGetDBMode eMode, ScGetDBSelection eSel)
Definition: docsh5.cxx:114
virtual short Execute()=0
EmbeddedObjectRef * pObject
bool HasFormat(SotClipboardFormatId nFormat) const
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:494
bool PasteLink(const css::uno::Reference< css::datatransfer::XTransferable > &rxTransferable)
Definition: viewfun5.cxx:703
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4211
weld::Window * GetFrameWeld() const
Keep selection as is, expand to used data area if no selection.
void SetDetectSpecialNumber(bool bSet)
Definition: asciiopt.hxx:79
Reference< XInputStream > xStream
PropertiesInfo aProperties
int nCount
static SfxViewShell * Current()
virtual bool IsKeepAskingSet() const =0
bool GetFileList(SotClipboardFormatId nFormat, FileList &rFileList) const
static bool extractColumnDescriptor(const TransferableDataHelper &_rData, OUString &_rDatasource, OUString &_rDatabaseLocation, OUString &_rConnectionResource, sal_Int32 &_nCommandType, OUString &_rCommand, OUString &_rFieldName)
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:193
SotClipboardFormatId
#define SO3_SC_CLASSID_60
SC_DLLPUBLIC void ResetClip(ScDocument *pSourceDoc, const ScMarkData *pMarks)
Definition: documen2.cxx:506
bool HasObjects() const
Definition: drwlayer.cxx:358
static bool canExtractColumnDescriptor(const DataFlavorExVector &_rFlavors, ColumnTransferFormatFlags _nFormats)
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
css::uno::Sequence< sal_Int8 > GetSequence(SotClipboardFormatId nFormat, const OUString &rDestDoc) const
ocSep
SC_DLLPUBLIC bool GetCellArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow) const
Definition: document.cxx:1013
ocDde
static SC_DLLPUBLIC OUString GetAbsDocName(const OUString &rFileName, const SfxObjectShell *pShell)
Definition: global2.cxx:287
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
#define SFX_TITLE_FULLNAME
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1081
void SetClipArea(const ScRange &rArea, bool bCut=false)
Definition: document.cxx:3154
T * get() const
static css::uno::Reference< css::embed::XStorage > GetTemporaryStorage(const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
LINEEND_LF
static void SetClipDocName(const OUString &rNew)
Definition: global.cxx:493
static const OUString & GetNativeSymbol(OpCode eOp)
int i
bool PasteDataFormat(SotClipboardFormatId nFormatId, const css::uno::Reference< css::datatransfer::XTransferable > &rxTransferable, SCCOL nPosX, SCROW nPosY, const Point *pLogicPos, bool bLink=false, bool bAllowDialogs=false)
Definition: viewfun5.cxx:78
static bool canExtractObjectDescriptor(const DataFlavorExVector &_rFlavors)
void SetLanguage(LanguageType e)
Definition: asciiopt.hxx:84
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2715
sal_Int16 SCCOL
Definition: types.hxx:21
#define SC_MOD()
Definition: scmod.hxx:249
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:896
void SelectOneTable(SCTAB nTab)
Definition: markdata.cxx:174
float u
const OUString & GetName() const
Definition: dbdata.hxx:121
OUString GetFile(size_t nIndex) const
SfxItemSet * GetItemSet() const
SdrObjectUniquePtr CreateFieldControl(std::u16string_view rFieldDesc) const
size_t Count() const
bool GetString(SotClipboardFormatId nFormat, OUString &rStr) const
const ScExtTabSettings * GetTabSettings(SCTAB nTab) const
Definition: scextopt.cxx:180
bool StartExecuteAsync(const std::function< void(sal_Int32)> &rEndDialogFn)
bool IsValid() const
Definition: address.hxx:544
bool GetGraphic(SotClipboardFormatId nFormat, Graphic &rGraphic) const
Extended settings for a sheet, used in import/export filters.
Definition: scextopt.hxx:47
virtual VclPtr< AbstractScTextImportOptionsDlg > CreateScTextImportOptionsDlg(weld::Window *pParent)=0
virtual LanguageType GetLanguageType() const =0
bool Unload()
bool InsertObjectSafe(SdrObject *pObj, SdrPageView &rPV)
Definition: drawview.cxx:806
virtual bool IsDateConversionSet() const =0
SdrObject * Next()
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_Int32 SCROW
Definition: types.hxx:17
bool GetSotStorageStream(SotClipboardFormatId nFormat, tools::SvRef< SotTempStream > &rStreamRef) const
virtual VclPtr< AbstractScImportAsciiDlg > CreateScImportAsciiDlg(weld::Window *pParent, const OUString &aDatName, SvStream *pInStream, ScImportAsciiCall eCall)=0
#define ERRCODE_NONE
constexpr SdrLayerID SC_LAYER_FRONT(0)
OUString aName
bool GetGDIMetaFile(SotClipboardFormatId nFormat, GDIMetaFile &rMtf, size_t nMaxActions=0) const
static SC_DLLPUBLIC ScAbstractDialogFactory * Create()
Definition: scabstdlg.cxx:37
RET_OK
ScExtDocOptions * GetExtDocOptions()
Definition: document.hxx:642
css::uno::Reference< css::io::XInputStream > GetInputStream(SotClipboardFormatId nFormat, const OUString &rDestDoc) const
void * p
Reference< XComponentContext > getProcessComponentContext()
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
SdrPageView * GetSdrPageView() const
SVXCORE_DLLPUBLIC bool SvxDrawingLayerImport(SdrModel *pModel, const css::uno::Reference< css::io::XInputStream > &xInputStream)
bool GetTransferableObjectDescriptor(SotClipboardFormatId nFormat, TransferableObjectDescriptor &rDesc)
bool DoLoad(SfxMedium *pMedium)
virtual void SaveParameters()=0
This struct stores general clipboard parameters associated with a ScDocument instance created in clip...
Definition: clipparam.hxx:30
SCTAB GetVisibleTab() const
Definition: document.hxx:877
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4170
static ODataAccessDescriptor extractObjectDescriptor(const TransferableDataHelper &_rData)
constexpr SdrLayerID SC_LAYER_CONTROLS(3)
ocClose
sal_Int16 SCTAB
Definition: types.hxx:22
SC_DLLPUBLIC void CopyToClip(const ScClipParam &rClipParam, ScDocument *pClipDoc, const ScMarkData *pMarks, bool bKeepScenarioFlags, bool bIncludeObjects)
Definition: document.cxx:2164
void SetPastingDrawFromOtherDoc(bool bVal)
Definition: document.hxx:2514
virtual void NbcSetLayer(SdrLayerID nLayer)
static bool GetFormatDataFlavor(SotClipboardFormatId nFormat, css::datatransfer::DataFlavor &rFlavor)
const DataFlavorExVector & GetDataFlavorExVector() const