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