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