LibreOffice Module sw (master)  1
swdtflvr.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 <config_features.h>
21 
22 #include <com/sun/star/embed/XTransactedObject.hpp>
23 #include <com/sun/star/embed/Aspects.hpp>
24 #include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
25 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
26 #include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
27 #include <com/sun/star/text/XPasteListener.hpp>
28 
30 #include <svtools/insdlg.hxx>
31 #include <unotools/tempfile.hxx>
32 #include <comphelper/fileformat.h>
36 #include <comphelper/string.hxx>
37 #include <o3tl/deleter.hxx>
39 #include <sot/filelist.hxx>
40 #include <svx/svxdlg.hxx>
42 #include <osl/endian.h>
43 #include <sfx2/linkmgr.hxx>
44 #include <tools/urlobj.hxx>
45 #include <vcl/wrkwin.hxx>
46 #include <vcl/weld.hxx>
47 #include <sfx2/dispatch.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <svl/stritem.hxx>
50 #include <vcl/imap.hxx>
51 #include <sot/storage.hxx>
52 #include <vcl/graph.hxx>
53 #include <svl/urihelper.hxx>
54 #include <svx/svdmodel.hxx>
55 #include <svx/xmlexchg.hxx>
56 #include <svx/dbaexchange.hxx>
57 #include <svx/clipfmtitem.hxx>
58 #include <svx/svxids.hrc>
59 #include <sfx2/mieclip.hxx>
60 #include <svx/svdetc.hxx>
61 #include <svx/xoutbmp.hxx>
62 #include <svl/urlbmk.hxx>
63 #include <svtools/htmlout.hxx>
64 #include <svx/hlnkitem.hxx>
65 #include <vcl/inetimg.hxx>
66 #include <editeng/paperinf.hxx>
67 #include <svx/fmview.hxx>
69 #include <sfx2/docfilt.hxx>
70 #include <vcl/imapobj.hxx>
71 #include <sfx2/docfile.hxx>
73 #include <unotools/streamwrap.hxx>
74 #include <vcl/graphicfilter.hxx>
75 
76 #ifdef _WIN32
77 #define WIN32_LEAN_AND_MEAN
78 #include <prewin.h>
79 #include <windows.h>
80 #include <postwin.h>
82 #include <osl/file.hxx>
83 #endif
84 
85 #include <svx/unomodel.hxx>
86 #include <fmturl.hxx>
87 #include <fmtinfmt.hxx>
88 #include <fmtfsize.hxx>
89 #include <swdtflvr.hxx>
90 #include <shellio.hxx>
91 #include <ddefld.hxx>
92 #include <doc.hxx>
93 #include <IDocumentUndoRedo.hxx>
98 #include <IDocumentState.hxx>
99 #include <pagedesc.hxx>
100 #include <IMark.hxx>
101 #include <docary.hxx>
102 #include <section.hxx>
103 #include <ndtxt.hxx>
104 #include <edtdd.hxx>
105 #include <edtwin.hxx>
106 #include <navicont.hxx>
107 #include <swcont.hxx>
108 #include <wrtsh.hxx>
109 #include <swmodule.hxx>
110 #include <view.hxx>
111 #include <docsh.hxx>
112 #include <wdocsh.hxx>
113 #include <fldbas.hxx>
114 #include <swundo.hxx>
115 #include <pam.hxx>
116 #include <ndole.hxx>
117 #include <swwait.hxx>
118 #include <viewopt.hxx>
119 #include <swerror.h>
120 #include <SwCapObjType.hxx>
121 #include <cmdid.h>
122 #include <strings.hrc>
123 #include <sot/stg.hxx>
124 #include <svx/svditer.hxx>
125 #include <editeng/eeitem.hxx>
126 #include <editeng/fhgtitem.hxx>
127 #include <svx/svdpage.hxx>
128 #include <avmedia/mediawindow.hxx>
129 #include <swcrsr.hxx>
130 #include <SwRewriter.hxx>
131 #include <globals.hrc>
132 #include <app.hrc>
133 #include <vcl/svapp.hxx>
134 #include <swserv.hxx>
135 #include <calbck.hxx>
136 #include <fmtmeta.hxx>
137 #include <itabenum.hxx>
138 #include <iodetect.hxx>
139 #include <unotextrange.hxx>
140 #include <unoframe.hxx>
141 
144 #include <comphelper/lok.hxx>
146 #include <sfx2/sfxdlg.hxx>
147 
148 #include <memory>
149 
150 #define OLESIZE 11905 - 2 * lMinBorder, 6 * MM50
151 
152 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_DRAWMODEL = 0x00000001;
153 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_HTML = 0x00000002;
154 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_RTF = 0x00000004;
155 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_STRING = 0x00000008;
156 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_SWOLE = 0x00000010;
157 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_DDE = 0x00000020;
158 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_RICHTEXT = 0x00000040;
159 
160 using namespace ::svx;
161 using namespace ::com::sun::star;
162 using namespace ::com::sun::star::uno;
163 using namespace ::com::sun::star::datatransfer;
164 
165 #define DDE_TXT_ENCODING osl_getThreadTextEncoding()
166 
168 {
169  OUString sName;
174  bool bDelBookmrk : 1;
175  bool bInDisconnect : 1;
176 
177  bool FindDocShell();
178 
180 
181 protected:
182  virtual ~SwTrnsfrDdeLink() override;
183 
184 public:
185  SwTrnsfrDdeLink( SwTransferable& rTrans, SwWrtShell& rSh );
186 
187  virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
188  const OUString& rMimeType, const css::uno::Any & rValue ) override;
189  virtual void Closed() override;
190 
191  bool WriteData( SvStream& rStrm );
192 
193  void Disconnect( bool bRemoveDataAdvise );
194 };
195 
198 {
199 public:
200  SwPasteContext(SwWrtShell& rWrtShell);
201  ~SwPasteContext();
202 
203  void remember();
204  void forget();
205 
206 private:
208  std::unique_ptr<SwPaM> m_pPaM;
209  sal_Int32 m_nStartContent = 0;
210 };
211 
212 // helper class for Action and Undo enclosing
214 {
216 public:
217  SwTrnsfrActionAndUndo( SwWrtShell *pS, bool bDelSel = false, SwPasteContext* pContext = nullptr)
218  : pSh( pS )
219  {
221  if( bDelSel )
222  {
223  if (pContext)
224  pContext->forget();
225  pSh->DelRight();
226  if (pContext)
227  pContext->remember();
228  }
229  pSh->StartAllAction();
230  }
231  ~SwTrnsfrActionAndUndo() COVERITY_NOEXCEPT_FALSE
232  {
233  pSh->EndUndo();
234  pSh->EndAllAction();
235  }
236 };
237 
239  : m_pWrtShell( &rSh ),
240  m_pCreatorView( nullptr ),
241  m_pOrigGraphic( nullptr ),
242  m_eBufferType( TransferBufferType::NONE )
243 {
244  rSh.GetView().AddTransferable(*this);
245  SwDocShell* pDShell = rSh.GetDoc()->GetDocShell();
246  if( pDShell )
247  {
249  if( pDShell->GetMedium() )
250  {
251  const INetURLObject& rURLObj = pDShell->GetMedium()->GetURLObject();
256  }
257 
259  }
260 }
261 
263 {
264  SolarMutexGuard aSolarGuard;
265 
266  // the DDELink still needs the WrtShell!
267  if( m_xDdeLink.is() )
268  {
269  static_cast<SwTrnsfrDdeLink*>( m_xDdeLink.get() )->Disconnect( true );
270  m_xDdeLink.clear();
271  }
272 
273  m_pWrtShell = nullptr;
274 
275  // release reference to the document so that aDocShellRef will delete
276  // it (if aDocShellRef is set). Otherwise, the OLE nodes keep references
277  // to their sub-storage when the storage is already dead.
278  m_pClpDocFac.reset();
279 
280  // first close, then the Ref. can be cleared as well, so that
281  // the DocShell really gets deleted!
282  if( m_aDocShellRef.Is() )
283  {
285  SwDocShell* pDocSh = static_cast<SwDocShell*>(pObj);
286  pDocSh->DoClose();
287  }
289 
290  SwModule* pMod = SW_MOD();
291  if(pMod)
292  {
293  if ( pMod->m_pDragDrop == this )
294  pMod->m_pDragDrop = nullptr;
295  else if ( pMod->m_pXSelection == this )
296  pMod->m_pXSelection = nullptr;
297  }
298 
300 }
301 
302 static SwDoc * lcl_GetDoc(SwDocFac & rDocFac)
303 {
304  SwDoc *const pDoc = rDocFac.GetDoc();
305  OSL_ENSURE( pDoc, "Document not found" );
306  if (pDoc)
307  {
308  pDoc->SetClipBoard( true );
309  }
310  return pDoc;
311 }
312 
314 {
315  SwModule *pMod = SW_MOD();
316  if( this == pMod->m_pDragDrop )
317  pMod->m_pDragDrop = nullptr;
318  else if( this == pMod->m_pXSelection )
319  pMod->m_pXSelection = nullptr;
320 }
321 
323 {
324  // only need if we are the current XSelection Object
325  SwModule *pMod = SW_MOD();
327  {
328  SetDataForDragAndDrop( Point( 0,0) );
329  }
330 }
331 
333 {
334  //set OleVisArea. Upper left corner of the page and size of
335  //RealSize in Twips.
336  const Size aSz( OLESIZE );
337  SwRect aVis( Point( DOCUMENTBORDER, DOCUMENTBORDER ), aSz );
338  pDoc->SetVisArea( aVis.SVRect() );
339 }
340 
341 uno::Reference < embed::XEmbeddedObject > SwTransferable::FindOLEObj( sal_Int64& nAspect ) const
342 {
343  uno::Reference < embed::XEmbeddedObject > xObj;
344  if( m_pClpDocFac )
345  {
346  SwIterator<SwContentNode,SwFormatColl> aIter( *m_pClpDocFac->GetDoc()->GetDfltGrfFormatColl() );
347  for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
348  if( SwNodeType::Ole == pNd->GetNodeType() )
349  {
350  xObj = static_cast<SwOLENode*>(pNd)->GetOLEObj().GetOleRef();
351  nAspect = static_cast<SwOLENode*>(pNd)->GetAspect();
352  break;
353  }
354  }
355  return xObj;
356 }
357 
359 {
360  if( m_pClpDocFac )
361  {
362  SwIterator<SwContentNode,SwFormatColl> aIter( *m_pClpDocFac->GetDoc()->GetDfltGrfFormatColl() );
363  for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
364  if( SwNodeType::Ole == pNd->GetNodeType() )
365  {
366  return static_cast<SwOLENode*>(pNd)->GetGraphic();
367  }
368  }
369 
370  return nullptr;
371 }
372 
374 {
375  RemoveFormat( SotClipboardFormatId::LINK );
376  CopyToClipboard( const_cast<vcl::Window*>(&rWin) );
377 }
378 
379 namespace
380 {
381  //Resolves: fdo#40717 surely when we create a clipboard document we should
382  //overwrite the clipboard documents styles and settings with that of the
383  //source, so that we can WYSIWYG paste. If we want that the destinations
384  //styles are used over the source styles, that's a matter of the
385  //destination paste code to handle, not the source paste code.
386  void lclOverWriteDoc(SwWrtShell &rSrcWrtShell, SwDoc &rDest)
387  {
388  const SwDoc &rSrc = *rSrcWrtShell.GetDoc();
389 
390  rDest.ReplaceCompatibilityOptions(rSrc);
391  rDest.ReplaceDefaults(rSrc);
392 
393  //It would probably make most sense here to only insert the styles used
394  //by the selection, e.g. apply SwDoc::IsUsed on styles ?
395  rDest.ReplaceStyles(rSrc, false);
396 
397  rSrcWrtShell.Copy(&rDest);
398 
400  }
401 
402  void lclCheckAndPerformRotation(Graphic& aGraphic)
403  {
404  GraphicNativeMetadata aMetadata;
405  if ( aMetadata.read(aGraphic) )
406  {
407  sal_uInt16 aRotation = aMetadata.getRotation();
408  if (aRotation != 0)
409  {
410  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "modules/swriter/ui/queryrotateintostandarddialog.ui"));
411  std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("QueryRotateIntoStandardOrientationDialog"));
412  if (xQueryBox->run() == RET_YES)
413  {
414  GraphicNativeTransform aTransform( aGraphic );
415  aTransform.rotate( aRotation );
416  }
417  }
418  }
419  }
420 }
421 
422 bool SwTransferable::GetData( const DataFlavor& rFlavor, const OUString& rDestDoc )
423 {
424  SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
425 
426  // we can only fulfil the request if
427  // 1) we have data for this format
428  // 2) we have either a clipboard document (pClpDocFac), or
429  // we have a SwWrtShell (so we can generate a new clipboard document)
430  if( !HasFormat( nFormat ) || ( m_pClpDocFac == nullptr && m_pWrtShell == nullptr ) )
431  return false;
432 
433  if( !m_pClpDocFac )
434  {
435  SelectionType nSelectionType = m_pWrtShell->GetSelectionType();
436 
437  // when pending we will not get the correct type, but SelectionType::Text
438  // as fallback. This *happens* during D&D, so we need to check if we are in
439  // the fallback and just try to get a graphic
440  const bool bPending(m_pWrtShell->ActionPend());
441 
442  // SEL_GRF is from ContentType of editsh
443  if(bPending || ((SelectionType::Graphic | SelectionType::DbForm) & nSelectionType))
444  {
445  m_pClpGraphic.reset(new Graphic);
446  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_pClpGraphic ))
448  m_pClpBitmap.reset(new Graphic);
449  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_pClpBitmap ))
451 
452  // is it a URL-Button ?
453  OUString sURL;
454  OUString sDesc;
455  if( m_pWrtShell->GetURLFromButton( sURL, sDesc ) )
456  {
457  m_pBookmark.reset(new INetBookmark( sURL, sDesc ));
459  }
460  }
461 
462  m_pClpDocFac.reset(new SwDocFac);
463  SwDoc *const pTmpDoc = lcl_GetDoc(*m_pClpDocFac);
464 
465  pTmpDoc->getIDocumentFieldsAccess().LockExpFields(); // never update fields - leave text as it is
466  lclOverWriteDoc(*m_pWrtShell, *pTmpDoc);
467 
468  // in CORE a new one was created (OLE-objects copied!)
469  m_aDocShellRef = pTmpDoc->GetTmpDocShell();
470  if( m_aDocShellRef.Is() )
472  pTmpDoc->SetTmpDocShell( nullptr );
473 
474  if( nSelectionType & SelectionType::Text && !m_pWrtShell->HasMark() )
475  {
476  SwContentAtPos aContentAtPos( IsAttrAtPos::InetAttr );
477 
479 
480  bool bSelect = g_bExecuteDrag &&
483  if( m_pWrtShell->GetContentAtPos( aPos, aContentAtPos, bSelect ) )
484  {
485  m_pBookmark.reset(new INetBookmark(
486  static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr)->GetValue(),
487  aContentAtPos.sStr ));
489  if( bSelect )
491  }
492  }
494  {
496  m_pWrtShell->GetFlyFrameAttr( aSet );
497  const SwFormatURL& rURL = aSet.Get( RES_URL );
498  if( rURL.GetMap() )
499  m_pImageMap.reset(new ImageMap( *rURL.GetMap() ));
500  else if( !rURL.GetURL().isEmpty() )
501  m_pTargetURL.reset(new INetImage(OUString(), rURL.GetURL(),
502  rURL.GetTargetFrameName() ));
503  }
504  }
505 
506  bool bOK = false;
508  {
509  //TODO/MBA: testing - is this the "single OLE object" case?!
510  // get OLE-Object from ClipDoc and get the data from that.
511  sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT; // will be set in the next statement
512  uno::Reference < embed::XEmbeddedObject > xObj = FindOLEObj( nAspect );
513  const Graphic* pOLEGraph = FindOLEReplacementGraphic();
514  if( xObj.is() )
515  {
516  TransferableDataHelper aD( new SvEmbedTransferHelper( xObj, pOLEGraph, nAspect ) );
517  uno::Any aAny = aD.GetAny(rFlavor, rDestDoc);
518  if( aAny.hasValue() )
519  bOK = SetAny( aAny );
520  }
521 
522  // the following solution will be used in the case when the object can not generate the image
523  // TODO/LATER: in future the transferhelper must probably be created based on object and the replacement stream
524  // TODO: Block not required now, SvEmbedTransferHelper should be able to handle GDIMetaFile format
525  if ( nFormat == SotClipboardFormatId::GDIMETAFILE )
526  {
527  pOLEGraph = FindOLEReplacementGraphic();
528  if ( pOLEGraph )
529  bOK = SetGDIMetaFile( pOLEGraph->GetGDIMetaFile() );
530  }
531  }
532  else
533  {
534  switch( nFormat )
535  {
536  case SotClipboardFormatId::LINK:
537  if( m_xDdeLink.is() )
538  bOK = SetObject( m_xDdeLink.get(), SWTRANSFER_OBJECTTYPE_DDE, rFlavor );
539  break;
540 
541  case SotClipboardFormatId::OBJECTDESCRIPTOR:
542  case SotClipboardFormatId::LINKSRCDESCRIPTOR:
544  break;
545 
546  case SotClipboardFormatId::DRAWING:
547  {
548  SwDoc *const pDoc = lcl_GetDoc(*m_pClpDocFac);
551  }
552  break;
553 
554  case SotClipboardFormatId::STRING:
555  {
556  SwDoc *const pDoc = lcl_GetDoc(*m_pClpDocFac);
557  bOK = SetObject( pDoc, SWTRANSFER_OBJECTTYPE_STRING, rFlavor );
558  }
559  break;
560  case SotClipboardFormatId::RTF:
561  {
562  SwDoc *const pDoc = lcl_GetDoc(*m_pClpDocFac);
563  bOK = SetObject( pDoc, SWTRANSFER_OBJECTTYPE_RTF, rFlavor );
564  }
565  break;
566  case SotClipboardFormatId::RICHTEXT:
567  {
568  SwDoc *const pDoc = lcl_GetDoc(*m_pClpDocFac);
569  bOK = SetObject( pDoc, SWTRANSFER_OBJECTTYPE_RICHTEXT, rFlavor );
570  }
571  break;
572 
573  case SotClipboardFormatId::HTML:
574  {
575  SwDoc *const pDoc = lcl_GetDoc(*m_pClpDocFac);
576  bOK = SetObject( pDoc, SWTRANSFER_OBJECTTYPE_HTML, rFlavor );
577  }
578  break;
579 
580  case SotClipboardFormatId::SVXB:
582  bOK = SetGraphic( *m_pOrigGraphic );
583  break;
584 
585  case SotClipboardFormatId::GDIMETAFILE:
587  bOK = SetGDIMetaFile( m_pClpGraphic->GetGDIMetaFile() );
588  break;
589  case SotClipboardFormatId::BITMAP:
590  case SotClipboardFormatId::PNG:
591  // Neither pClpBitmap nor pClpGraphic are necessarily set
592  if( (m_eBufferType & TransferBufferType::Graphic) && (m_pClpBitmap != nullptr || m_pClpGraphic != nullptr))
593  bOK = SetBitmapEx( (m_pClpBitmap ? m_pClpBitmap : m_pClpGraphic)->GetBitmapEx(), rFlavor );
594  break;
595 
596  case SotClipboardFormatId::SVIM:
597  if( m_pImageMap )
598  bOK = SetImageMap( *m_pImageMap );
599  break;
600 
601  case SotClipboardFormatId::INET_IMAGE:
602  if( m_pTargetURL )
603  bOK = SetINetImage( *m_pTargetURL, rFlavor );
604  break;
605 
606  case SotClipboardFormatId::SOLK:
607  case SotClipboardFormatId::NETSCAPE_BOOKMARK:
608  case SotClipboardFormatId::FILEGRPDESCRIPTOR:
609  case SotClipboardFormatId::FILECONTENT:
610  case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
611  case SotClipboardFormatId::SIMPLE_FILE:
613  bOK = SetINetBookmark( *m_pBookmark, rFlavor );
614  break;
615 
616  case SotClipboardFormatId::EMBED_SOURCE:
617  if( !m_aDocShellRef.Is() )
618  {
619  SwDoc *const pDoc = lcl_GetDoc(*m_pClpDocFac);
620  SwDocShell* pNewDocSh = new SwDocShell( pDoc,
621  SfxObjectCreateMode::EMBEDDED );
622  m_aDocShellRef = pNewDocSh;
625  }
627  rFlavor );
628  break;
629  default: break;
630  }
631  }
632  return bOK;
633 }
634 
636  void* pObject, sal_uInt32 nObjectType,
637  const DataFlavor& /*rFlavor*/ )
638 {
639  bool bRet = false;
640  WriterRef xWrt;
641 
642  switch( nObjectType )
643  {
645  {
646  // don't change the sequence of commands
647  SdrModel *pModel = static_cast<SdrModel*>(pObject);
648  xStream->SetBufferSize( 16348 );
649 
650  // for the changed pool defaults from drawing layer pool set those
651  // attributes as hard attributes to preserve them for saving
652  const SfxItemPool& rItemPool = pModel->GetItemPool();
653  const SvxFontHeightItem& rDefaultFontHeight = rItemPool.GetDefaultItem(EE_CHAR_FONTHEIGHT);
654 
655  // SW should have no MasterPages
656  OSL_ENSURE(0 == pModel->GetMasterPageCount(), "SW with MasterPages (!)");
657 
658  for(sal_uInt16 a(0); a < pModel->GetPageCount(); a++)
659  {
660  const SdrPage* pPage = pModel->GetPage(a);
661  SdrObjListIter aIter(pPage, SdrIterMode::DeepNoGroups);
662 
663  while(aIter.IsMore())
664  {
665  SdrObject* pObj = aIter.Next();
666  const SvxFontHeightItem& rItem = pObj->GetMergedItem(EE_CHAR_FONTHEIGHT);
667 
668  if(rItem.GetHeight() == rDefaultFontHeight.GetHeight())
669  {
670  pObj->SetMergedItem(rDefaultFontHeight);
671  }
672  }
673  }
674 
675  {
676  uno::Reference<io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *xStream ) );
677  if( SvxDrawingLayerExport( pModel, xDocOut ) )
678  xStream->Commit();
679  }
680 
681  bRet = ERRCODE_NONE == xStream->GetError();
682  }
683  break;
684 
686  {
687  SfxObjectShell* pEmbObj = static_cast<SfxObjectShell*>(pObject);
688  try
689  {
690  ::utl::TempFile aTempFile;
691  aTempFile.EnableKillingFile();
692  uno::Reference< embed::XStorage > xWorkStore =
693  ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
694 
695  // write document storage
696  pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
697  // mba: no BaseURL for clipboard
698  SfxMedium aMedium( xWorkStore, OUString() );
699  pEmbObj->DoSaveObjectAs( aMedium, false );
700  pEmbObj->DoSaveCompleted();
701 
702  uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
703  if ( xTransact.is() )
704  xTransact->commit();
705 
706  std::unique_ptr<SvStream> pSrcStm(::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), StreamMode::READ ));
707  if( pSrcStm )
708  {
709  xStream->SetBufferSize( 0xff00 );
710  xStream->WriteStream( *pSrcStm );
711  pSrcStm.reset();
712  }
713 
714  xWorkStore->dispose();
715  xWorkStore.clear();
716  xStream->Commit();
717  }
718  catch (const uno::Exception&)
719  {
720  }
721 
722  bRet = ( xStream->GetError() == ERRCODE_NONE );
723  }
724  break;
725 
727  {
728  xStream->SetBufferSize( 1024 );
729  SwTrnsfrDdeLink* pDdeLnk = static_cast<SwTrnsfrDdeLink*>(pObject);
730  if( pDdeLnk->WriteData( *xStream ) )
731  {
732  xStream->Commit();
733  bRet = ERRCODE_NONE == xStream->GetError();
734  }
735  }
736  break;
737 
739  GetHTMLWriter(OUString(), OUString(), xWrt);
740  break;
741 
744  GetRTFWriter(OUString(), OUString(), xWrt);
745  break;
746 
748  GetASCWriter(OUString(), OUString(), xWrt);
749  if( xWrt.is() )
750  {
751  SwAsciiOptions aAOpt;
752  aAOpt.SetCharSet( RTL_TEXTENCODING_UTF8 );
753  xWrt->SetAsciiOptions( aAOpt );
754 
755  // no start char for clipboard
756  xWrt->m_bUCS2_WithStartChar = false;
757  }
758  break;
759  default: break;
760  }
761 
762  if( xWrt.is() )
763  {
764  SwDoc* pDoc = static_cast<SwDoc*>(pObject);
765  xWrt->m_bWriteClipboardDoc = true;
766  xWrt->m_bWriteOnlyFirstTable = bool(TransferBufferType::Table & m_eBufferType);
767  xWrt->SetShowProgress(false);
768 
769 #if defined(DEBUGPASTE)
770  SvFileStream aPasteDebug(OUString(
771  "PASTEBUFFER.debug"), StreamMode::WRITE|StreamMode::TRUNC);
772  SwWriter aDbgWrt( aPasteDebug, *pDoc );
773  aDbgWrt.Write( xWrt );
774 #endif
775 
776  SwWriter aWrt( *xStream, *pDoc );
777  if( ! aWrt.Write( xWrt ).IsError() )
778  {
779  xStream->WriteChar( '\0' ); // terminate with a zero
780  xStream->Commit();
781  bRet = true;
782  }
783  }
784 
785  return bRet;
786 }
787 
789 {
790  int nRet = Copy( true );
791  if( nRet )
792  DeleteSelection();
793  return nRet;
794 }
795 
797 {
798  if(!m_pWrtShell)
799  return;
800  // ask for type of selection before action-bracketing
801  const SelectionType nSelection = m_pWrtShell->GetSelectionType();
803  if( ( SelectionType::Text | SelectionType::Table ) & nSelection )
804  m_pWrtShell->IntelligentCut( nSelection );
807 }
808 
810 {
811  int nRet = 1;
812  if(!m_pWrtShell)
813  return 0;
814 
815  OUString sGrfNm;
816  const SelectionType nSelection = m_pWrtShell->GetSelectionType();
817  if( nSelection == SelectionType::Graphic )
818  {
819  m_pClpGraphic.reset(new Graphic);
820  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_pClpGraphic ))
822  m_pClpBitmap.reset(new Graphic);
823  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_pClpBitmap ))
825 
826  m_pClpDocFac.reset(new SwDocFac);
827  SwDoc *const pDoc = lcl_GetDoc(*m_pClpDocFac);
828  m_pWrtShell->Copy( pDoc );
829 
830 #if HAVE_FEATURE_DESKTOP
832  AddFormat( SotClipboardFormatId::SVXB );
833 #endif
834 
836  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
837 
838  const Graphic* pGrf = m_pWrtShell->GetGraphic();
839  if( pGrf && pGrf->IsSupportedGraphic() )
840  {
841  AddFormat( SotClipboardFormatId::PNG );
842 #if HAVE_FEATURE_DESKTOP
843  AddFormat( SotClipboardFormatId::GDIMETAFILE );
844  AddFormat( SotClipboardFormatId::BITMAP );
845 #endif
846  }
848  m_pWrtShell->GetGrfNms( &sGrfNm, nullptr );
849  }
850  else if ( nSelection == SelectionType::Ole )
851  {
852  m_pClpDocFac.reset(new SwDocFac);
853  SwDoc *const pDoc = lcl_GetDoc(*m_pClpDocFac);
854  m_aDocShellRef = new SwDocShell( pDoc, SfxObjectCreateMode::EMBEDDED);
856  m_pWrtShell->Copy( pDoc );
857 
858  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
859 
860  // --> OD #i98753#
861  // set size of embedded object at the object description structure
862  m_aObjDesc.maSize = OutputDevice::LogicToLogic(m_pWrtShell->GetObjSize(), MapMode(MapUnit::MapTwip), MapMode(MapUnit::Map100thMM));
863  // <--
865 
866 #if HAVE_FEATURE_DESKTOP
867  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
868  AddFormat( SotClipboardFormatId::GDIMETAFILE );
869 
870  // Fetch the formats supported via embedtransferhelper as well
871  sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
872  uno::Reference < embed::XEmbeddedObject > xObj = FindOLEObj( nAspect );
873  const Graphic* pOLEGraph = FindOLEReplacementGraphic();
874  if( xObj.is() )
875  {
876  TransferableDataHelper aD( new SvEmbedTransferHelper( xObj, pOLEGraph, nAspect ) );
877  if ( aD.GetTransferable().is() )
878  {
880 
881  for( const auto& rItem : aVector )
882  AddFormat( rItem );
883  }
884  }
885 #endif
887  }
888  // Is there anything to provide anyway?
889  else if ( m_pWrtShell->IsSelection() || m_pWrtShell->IsFrameSelected() ||
891  {
892  std::unique_ptr<SwWait> pWait;
893  if( m_pWrtShell->ShouldWait() )
894  pWait.reset(new SwWait( *m_pWrtShell->GetView().GetDocShell(), true ));
895 
896  m_pClpDocFac.reset(new SwDocFac);
897 
898  // create additional cursor so that equal treatment of keyboard
899  // and mouse selection is possible.
900  // In AddMode with keyboard selection, the new cursor is not created
901  // before the cursor is moved after end of selection.
902  if( m_pWrtShell->IsAddMode() && m_pWrtShell->SwCursorShell::HasSelection() )
904 
905  SwDoc *const pTmpDoc = lcl_GetDoc(*m_pClpDocFac);
906 
907  pTmpDoc->getIDocumentFieldsAccess().LockExpFields(); // Never update fields - leave text as is
908  lclOverWriteDoc(*m_pWrtShell, *pTmpDoc);
909 
910  {
911  IDocumentMarkAccess* const pMarkAccess = pTmpDoc->getIDocumentMarkAccess();
912  std::vector< ::sw::mark::IMark* > vDdeMarks;
913  // find all DDE-Bookmarks
914  for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
915  ppMark != pMarkAccess->getAllMarksEnd();
916  ++ppMark)
917  {
919  vDdeMarks.push_back(*ppMark);
920  }
921  // remove all DDE-Bookmarks, they are invalid inside the clipdoc!
922  for(const auto& rpMark : vDdeMarks)
923  pMarkAccess->deleteMark(rpMark);
924  }
925 
926  // a new one was created in CORE (OLE objects copied!)
927  m_aDocShellRef = pTmpDoc->GetTmpDocShell();
928  if( m_aDocShellRef.Is() )
930  pTmpDoc->SetTmpDocShell( nullptr );
931 
932  if( m_pWrtShell->IsObjSelected() )
934  else
935  {
937  if (m_pWrtShell->IntelligentCut(nSelection, false) != SwWrtShell::NO_WORD)
939  }
940 
941  bool bDDELink = m_pWrtShell->IsSelection();
942  if( nSelection & SelectionType::TableCell )
943  {
945  bDDELink = m_pWrtShell->HasWholeTabSelection();
946  }
947 
948 #if HAVE_FEATURE_DESKTOP
949  //When someone needs it, we 'OLE' him something
950  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
951 #endif
952 
953  //put RTF ahead of the OLE's Metafile to have less loss
954  if( !m_pWrtShell->IsObjSelected() )
955  {
956  AddFormat( SotClipboardFormatId::RTF );
957 #if HAVE_FEATURE_DESKTOP
958  AddFormat( SotClipboardFormatId::RICHTEXT );
959  AddFormat( SotClipboardFormatId::HTML );
960 #endif
961  }
962  if( m_pWrtShell->IsSelection() )
963  AddFormat( SotClipboardFormatId::STRING );
964 
965  if( nSelection & ( SelectionType::DrawObject | SelectionType::DbForm ))
966  {
967  AddFormat( SotClipboardFormatId::DRAWING );
968  if ( nSelection & SelectionType::DrawObject )
969  {
970 #if HAVE_FEATURE_DESKTOP
971  AddFormat( SotClipboardFormatId::GDIMETAFILE );
972  AddFormat( SotClipboardFormatId::BITMAP );
973 #endif
974  AddFormat( SotClipboardFormatId::PNG );
975  }
977 
978  m_pClpGraphic.reset(new Graphic);
979  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_pClpGraphic ))
981  m_pClpBitmap.reset(new Graphic);
982  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_pClpBitmap ))
984 
985  // is it a URL-Button ?
986  OUString sURL;
987  OUString sDesc;
988  if( m_pWrtShell->GetURLFromButton( sURL, sDesc ) )
989  {
990  AddFormat( SotClipboardFormatId::STRING );
991 #if HAVE_FEATURE_DESKTOP
992  AddFormat( SotClipboardFormatId::SOLK );
993  AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
994  AddFormat( SotClipboardFormatId::FILECONTENT );
995  AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
996 #endif
997  AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
999  nRet = 1;
1000  }
1001  }
1002 
1003  // at Cut, DDE-Link doesn't make sense!!
1004  SwDocShell* pDShell;
1005  if( !bIsCut && bDDELink &&
1006  nullptr != ( pDShell = m_pWrtShell->GetDoc()->GetDocShell()) &&
1007  SfxObjectCreateMode::STANDARD == pDShell->GetCreateMode() )
1008  {
1009 #if HAVE_FEATURE_DESKTOP
1010  AddFormat( SotClipboardFormatId::LINK );
1011 #endif
1012  m_xDdeLink = new SwTrnsfrDdeLink( *this, *m_pWrtShell );
1013  }
1014 
1015  //ObjectDescriptor was already filly from the old DocShell.
1016  //Now adjust it. Thus in GetData the first query can still
1017  //be answered with delayed rendering.
1018  Size aSz( OLESIZE );
1019  m_aObjDesc.maSize = OutputDevice::LogicToLogic(aSz, MapMode(MapUnit::MapTwip), MapMode(MapUnit::Map100thMM));
1020 
1022 #if HAVE_FEATURE_DESKTOP
1023  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
1024 #endif
1025  }
1026  else
1027  nRet = 0;
1028 
1029  if( m_pWrtShell->IsFrameSelected() )
1030  {
1032  m_pWrtShell->GetFlyFrameAttr( aSet );
1033  const SwFormatURL& rURL = aSet.Get( RES_URL );
1034  if( rURL.GetMap() )
1035  {
1036  m_pImageMap.reset( new ImageMap( *rURL.GetMap() ) );
1037  AddFormat( SotClipboardFormatId::SVIM );
1038  }
1039  else if( !rURL.GetURL().isEmpty() )
1040  {
1041  m_pTargetURL.reset(new INetImage( sGrfNm, rURL.GetURL(),
1042  rURL.GetTargetFrameName() ));
1043  AddFormat( SotClipboardFormatId::INET_IMAGE );
1044  }
1045  }
1046 
1047  return nRet;
1048 }
1049 
1050 int SwTransferable::Copy( bool bIsCut )
1051 {
1052  int nRet = PrepareForCopy( bIsCut );
1053  if ( nRet )
1054  {
1056  }
1057  return nRet;
1058 }
1059 
1061 {
1062  if(!m_pWrtShell)
1063  return;
1064  SwWait aWait( *m_pWrtShell->GetView().GetDocShell(), true );
1065 
1066  OUString aStr( m_pWrtShell->Calculate() );
1067 
1068  m_pClpDocFac.reset(new SwDocFac);
1069  SwDoc *const pDoc = lcl_GetDoc(*m_pClpDocFac);
1070  m_pWrtShell->Copy(pDoc, & aStr);
1072  AddFormat( SotClipboardFormatId::STRING );
1073 
1075 }
1076 
1077 bool SwTransferable::CopyGlossary( SwTextBlocks& rGlossary, const OUString& rStr )
1078 {
1079  if(!m_pWrtShell)
1080  return false;
1081  SwWait aWait( *m_pWrtShell->GetView().GetDocShell(), true );
1082 
1083  m_pClpDocFac.reset(new SwDocFac);
1084  SwDoc *const pCDoc = lcl_GetDoc(*m_pClpDocFac);
1085 
1086  SwNodes& rNds = pCDoc->GetNodes();
1087  SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() );
1088  SwContentNode* pCNd = rNds.GoNext( &aNodeIdx ); // go to 1st ContentNode
1089  SwPaM aPam( *pCNd );
1090 
1091  pCDoc->getIDocumentFieldsAccess().LockExpFields(); // never update fields - leave text as it is
1092 
1093  pCDoc->InsertGlossary( rGlossary, rStr, aPam );
1094 
1095  // a new one was created in CORE (OLE-Objects copied!)
1096  m_aDocShellRef = pCDoc->GetTmpDocShell();
1097  if( m_aDocShellRef.Is() )
1099  pCDoc->SetTmpDocShell( nullptr );
1100 
1102 
1103  //When someone needs it, we 'OLE' her something.
1104  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
1105  AddFormat( SotClipboardFormatId::RTF );
1106  AddFormat( SotClipboardFormatId::RICHTEXT );
1107  AddFormat( SotClipboardFormatId::HTML );
1108  AddFormat( SotClipboardFormatId::STRING );
1109 
1110  //ObjectDescriptor was already filled from the old DocShell.
1111  //Now adjust it. Thus in GetData the first query can still
1112  //be answered with delayed rendering.
1113  Size aSz( OLESIZE );
1114  m_aObjDesc.maSize = OutputDevice::LogicToLogic(aSz, MapMode(MapUnit::MapTwip), MapMode(MapUnit::Map100thMM));
1115 
1117  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
1118 
1120 
1121  return true;
1122 }
1123 
1124 static uno::Reference < XTransferable > * lcl_getTransferPointer ( uno::Reference < XTransferable > &xRef )
1125 {
1126  return &xRef;
1127 }
1128 
1130  : m_rWrtShell(rWrtShell)
1131 {
1132  remember();
1133 }
1134 
1136 {
1138  return;
1139 
1140  SwPaM* pCursor = m_rWrtShell.GetCursor();
1141  if (!pCursor)
1142  return;
1143 
1144  // Set point to the previous node, so it is not moved.
1145  const SwNodeIndex& rNodeIndex = pCursor->GetPoint()->nNode;
1146  m_pPaM.reset(new SwPaM(rNodeIndex, rNodeIndex, 0, -1));
1147  m_nStartContent = pCursor->GetPoint()->nContent.GetIndex();
1148 }
1149 
1150 void SwPasteContext::forget() { m_pPaM.reset(); }
1151 
1153 {
1154  try
1155  {
1157  return;
1158 
1159  beans::PropertyValue aPropertyValue;
1160 
1161  switch (m_rWrtShell.GetView().GetShellMode())
1162  {
1163  case ShellMode::Graphic:
1164  {
1166  if (!pFormat)
1167  return;
1168 
1169  aPropertyValue.Name = "TextGraphicObject";
1170  aPropertyValue.Value
1171  <<= SwXTextGraphicObject::CreateXTextGraphicObject(*pFormat->GetDoc(), pFormat);
1172  break;
1173  }
1174 
1175  default:
1176  {
1177  if (!m_pPaM)
1178  return;
1179 
1180  SwPaM* pCursor = m_rWrtShell.GetCursor();
1181  if (!pCursor)
1182  return;
1183 
1184  if (!pCursor->GetPoint()->nNode.GetNode().IsTextNode())
1185  // Non-text was pasted.
1186  return;
1187 
1188  // Update mark after paste.
1189  *m_pPaM->GetMark() = *pCursor->GetPoint();
1190 
1191  // Restore point.
1192  ++m_pPaM->GetPoint()->nNode;
1193  SwNode& rNode = m_pPaM->GetNode();
1194  if (!rNode.IsTextNode())
1195  // Starting point is no longer text.
1196  return;
1197 
1198  m_pPaM->GetPoint()->nContent.Assign(static_cast<SwContentNode*>(&rNode),
1199  m_nStartContent);
1200 
1201  aPropertyValue.Name = "TextRange";
1202  const uno::Reference<text::XTextRange> xTextRange = SwXTextRange::CreateXTextRange(
1203  *m_pPaM->GetDoc(), *m_pPaM->GetPoint(), m_pPaM->GetMark());
1204  aPropertyValue.Value <<= xTextRange;
1205  break;
1206  }
1207  }
1208 
1209  if (aPropertyValue.Name.isEmpty())
1210  return;
1211 
1212  // Invoke the listeners.
1213  uno::Sequence<beans::PropertyValue> aEvent{ aPropertyValue };
1214 
1216  while (it.hasMoreElements())
1217  {
1218  uno::Reference<text::XPasteListener> xListener(it.next(), UNO_QUERY);
1219  if (xListener.is())
1220  xListener->notifyPasteEvent(aEvent);
1221  }
1222  }
1223  catch (const uno::Exception& rException)
1224  {
1225  SAL_WARN("sw",
1226  "SwPasteContext::~SwPasteContext: uncaught exception: " << rException.Message);
1227  }
1228 }
1229 
1231  const TransferableDataHelper& rData )
1232 {
1233  // Check the common case first: We can always paste our own data!
1234  // If _only_ the internal format can be pasted, this check will
1235  // yield 'true', while the one below would give a (wrong) result 'false'.
1236 
1237  bool bIsPaste = ( GetSwTransferable( rData ) != nullptr );
1238 
1239  // if it's not our own data, we need to have a closer look:
1240  if( ! bIsPaste )
1241  {
1242  // determine the proper paste action, and return true if we find one
1243  uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
1244 
1245  SotExchangeDest nDestination = SwTransferable::GetSotDestination( rSh );
1246  sal_uInt16 nSourceOptions =
1247  (( SotExchangeDest::DOC_TEXTFRAME == nDestination ||
1248  SotExchangeDest::SWDOC_FREE_AREA == nDestination ||
1249  SotExchangeDest::DOC_TEXTFRAME_WEB == nDestination ||
1250  SotExchangeDest::SWDOC_FREE_AREA_WEB == nDestination )
1253 
1254  SotClipboardFormatId nFormat; // output param for GetExchangeAction
1255  sal_uInt8 nEventAction; // output param for GetExchangeAction
1257  rData.GetDataFlavorExVector(),
1258  nDestination,
1259  nSourceOptions, /* ?? */
1260  EXCHG_IN_ACTION_DEFAULT, /* ?? */
1261  nFormat, nEventAction, SotClipboardFormatId::NONE,
1262  lcl_getTransferPointer ( xTransferable ) );
1263 
1264  // if we find a suitable action, we can paste!
1265  bIsPaste = (EXCHG_INOUT_ACTION_NONE != nAction);
1266  }
1267 
1268  return bIsPaste;
1269 }
1270 
1271 bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndStdIds nAnchorType, bool bIgnoreComments)
1272 {
1273  SwPasteContext aPasteContext(rSh);
1274 
1275  sal_uInt8 nEventAction, nAction=0;
1276  SotExchangeDest nDestination = SwTransferable::GetSotDestination( rSh );
1277  SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
1278  SotExchangeActionFlags nActionFlags = SotExchangeActionFlags::NONE;
1279  bool bSingleCellTable = false;
1280 
1281  if( GetSwTransferable( rData ) )
1282  {
1284  }
1285  else
1286  {
1287  sal_uInt16 nSourceOptions =
1288  (( SotExchangeDest::DOC_TEXTFRAME == nDestination ||
1289  SotExchangeDest::SWDOC_FREE_AREA == nDestination ||
1290  SotExchangeDest::DOC_TEXTFRAME_WEB == nDestination ||
1291  SotExchangeDest::SWDOC_FREE_AREA_WEB == nDestination )
1294  uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
1296  rData.GetDataFlavorExVector(),
1297  nDestination,
1298  nSourceOptions, /* ?? */
1299  EXCHG_IN_ACTION_DEFAULT, /* ?? */
1300  nFormat, nEventAction, SotClipboardFormatId::NONE,
1301  lcl_getTransferPointer ( xTransferable ),
1302  &nActionFlags );
1303  }
1304 
1305  // tdf#37223 avoid OLE insertion of worksheets in the following cases:
1306  // content of 1-cell worksheets are inserted as simple text using RTF format,
1307  // bigger worksheets within native (Writer) table cells are inserted as native tables,
1308  // ie. cell by cell instead of embedding the worksheet in a single cell of the Writer table
1309  if ( EXCHG_OUT_ACTION_INSERT_OLE == nAction && ( rData.HasFormat( SotClipboardFormatId::SYLK ) ||
1310  rData.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS ) ) )
1311  {
1312  // is it a 1-cell worksheet?
1313  OUString aExpand;
1314  if( rData.GetString( SotClipboardFormatId::STRING, aExpand ))
1315  {
1316  const sal_Int32 nNewlines{comphelper::string::getTokenCount(aExpand, '\n')};
1317  const sal_Int32 nRows = nNewlines ? nNewlines-1 : 0;
1318  if ( nRows == 1 )
1319  {
1320  const sal_Int32 nCols = comphelper::string::getTokenCount(aExpand.getToken(0, '\n'), '\t');
1321  if (nCols == 1)
1322  bSingleCellTable = true;
1323  }
1324  }
1325 
1326  // convert the worksheet to a temporary native table using HTML format, and copy that into the original native table
1327  if (!bSingleCellTable && rData.HasFormat( SotClipboardFormatId::HTML ) &&
1328  rSh.GetDoc()->IsIdxInTable(rSh.GetCursor()->GetNode()) != nullptr && rSh.DoesUndo())
1329  {
1330  SfxDispatcher* pDispatch = rSh.GetView().GetViewFrame()->GetDispatcher();
1331  sal_uInt32 nLevel = 0;
1332  // within Writer table cells, inserting worksheets using HTML format results only plain text, not a native table,
1333  // so remove all outer nested tables temporary to get a working insertion point
1334  // (RTF format has no such problem, but that inserts the hidden rows of the original Calc worksheet, too)
1335  do
1336  {
1337  // insert a random character to redo the place of the insertion at the end
1338  pDispatch->Execute(FN_INSERT_NNBSP, SfxCallMode::SYNCHRON);
1339  pDispatch->Execute(FN_TABLE_DELETE_TABLE, SfxCallMode::SYNCHRON);
1340  nLevel++;
1341  } while (rSh.GetDoc()->IsIdxInTable(rSh.GetCursor()->GetNode()) != nullptr);
1342  if ( SwTransferable::PasteData( rData, rSh, EXCHG_OUT_ACTION_INSERT_STRING, nActionFlags, SotClipboardFormatId::HTML,
1343  nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext ))
1344  {
1345  pDispatch->Execute(FN_CHAR_LEFT, SfxCallMode::SYNCHRON);
1346  pDispatch->Execute(FN_TABLE_SELECT_ALL, SfxCallMode::SYNCHRON);
1347  pDispatch->Execute(SID_COPY, SfxCallMode::SYNCHRON);
1348  for(sal_uInt32 a = 0; a < 1 + (nLevel * 2); a++)
1349  pDispatch->Execute(SID_UNDO, SfxCallMode::SYNCHRON);
1350  pDispatch->Execute(SID_PASTE, SfxCallMode::SYNCHRON);
1351  return true;
1352  } else {
1353  for(sal_uInt32 a = 0; a < (nLevel * 2); a++)
1354  pDispatch->Execute(SID_UNDO, SfxCallMode::SYNCHRON);
1355  }
1356  }
1357  }
1358 
1359  // special case for tables from draw application or 1-cell tables
1360  if( EXCHG_OUT_ACTION_INSERT_DRAWOBJ == nAction || bSingleCellTable )
1361  {
1362  if( rData.HasFormat( SotClipboardFormatId::RTF ) )
1363  {
1365  nFormat = SotClipboardFormatId::RTF;
1366  }
1367  else if( rData.HasFormat( SotClipboardFormatId::RICHTEXT ) )
1368  {
1370  nFormat = SotClipboardFormatId::RICHTEXT;
1371  }
1372  }
1373 
1374  return EXCHG_INOUT_ACTION_NONE != nAction &&
1375  SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat,
1376  nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext );
1377 }
1378 
1380  SwWrtShell& rSh, sal_uInt8 nAction, SotExchangeActionFlags nActionFlags,
1381  SotClipboardFormatId nFormat,
1382  SotExchangeDest nDestination, bool bIsPasteFormat,
1383  bool bIsDefault,
1384  const Point* pPt, sal_Int8 nDropAction,
1385  bool bPasteSelection, RndStdIds nAnchorType,
1386  bool bIgnoreComments,
1387  SwPasteContext* pContext )
1388 {
1389  SwWait aWait( *rSh.GetView().GetDocShell(), false );
1390  std::unique_ptr<SwTrnsfrActionAndUndo, o3tl::default_delete<SwTrnsfrActionAndUndo>> pAction;
1391  SwModule* pMod = SW_MOD();
1392 
1393  bool bRet = false;
1394  bool bCallAutoCaption = false;
1395 
1396  if( pPt )
1397  {
1398  // external Drop
1399  if( bPasteSelection ? !pMod->m_pXSelection : !pMod->m_pDragDrop )
1400  {
1401  switch( nDestination )
1402  {
1403  case SotExchangeDest::DOC_LNKD_GRAPH_W_IMAP:
1404  case SotExchangeDest::DOC_LNKD_GRAPHOBJ:
1405  case SotExchangeDest::DOC_GRAPH_W_IMAP:
1406  case SotExchangeDest::DOC_GRAPHOBJ:
1407  case SotExchangeDest::DOC_OLEOBJ:
1408  case SotExchangeDest::DOC_DRAWOBJ:
1409  case SotExchangeDest::DOC_URLBUTTON:
1410  case SotExchangeDest::DOC_GROUPOBJ:
1411  // select frames/objects
1412  SwTransferable::SetSelInShell( rSh, true, pPt );
1413  break;
1414 
1415  default:
1416  SwTransferable::SetSelInShell( rSh, false, pPt );
1417  break;
1418  }
1419  }
1420  }
1421  else if( ( !GetSwTransferable( rData ) || bIsPasteFormat ) &&
1422  !rSh.IsTableMode() && rSh.HasSelection() )
1423  {
1424  // then delete the selections
1425 
1426  //don't delete selected content
1427  // - at table-selection
1428  // - at ReRead of a graphic/DDEData
1429  // - at D&D, for the right selection was taken care of
1430  // in Drop-Handler
1431  bool bDelSel = false;
1432  switch( nDestination )
1433  {
1434  case SotExchangeDest::DOC_TEXTFRAME:
1435  case SotExchangeDest::SWDOC_FREE_AREA:
1436  case SotExchangeDest::DOC_TEXTFRAME_WEB:
1437  case SotExchangeDest::SWDOC_FREE_AREA_WEB:
1438  bDelSel = true;
1439  break;
1440  default:
1441  break;
1442  }
1443 
1444  if( bDelSel )
1445  // #i34830#
1446  pAction.reset(new SwTrnsfrActionAndUndo(&rSh, true, pContext));
1447  }
1448 
1449  SwTransferable *pTrans=nullptr, *pTunneledTrans=GetSwTransferable( rData );
1450 
1451  // check for private drop
1452  bool bPrivateDrop(pPt);
1453  if (bPrivateDrop)
1454  {
1455  if (bPasteSelection)
1456  pTrans = pMod->m_pXSelection;
1457  else
1458  pTrans = pMod->m_pDragDrop;
1459  bPrivateDrop = nullptr != pTrans;
1460  }
1461  bool bNeedToSelectBeforePaste(false);
1462 
1463  if(bPrivateDrop && DND_ACTION_LINK == nDropAction)
1464  {
1465  // internal drop on object, suppress bPrivateDrop to change internal fill
1466  bPrivateDrop = false;
1467  bNeedToSelectBeforePaste = true;
1468  }
1469 
1470  if(bPrivateDrop && pPt && DND_ACTION_MOVE == nDropAction)
1471  {
1472  // check if dragged over a useful target. If yes, use as content exchange
1473  // drop as if from external
1474  const SwFrameFormat* pSwFrameFormat = rSh.GetFormatFromObj(*pPt);
1475 
1476  if(dynamic_cast< const SwDrawFrameFormat* >(pSwFrameFormat))
1477  {
1478  bPrivateDrop = false;
1479  bNeedToSelectBeforePaste = true;
1480  }
1481  }
1482 
1483  if(bPrivateDrop)
1484  {
1485  // then internal Drag & Drop or XSelection
1486  bRet = pTrans->PrivateDrop( rSh, *pPt, DND_ACTION_MOVE == nDropAction,
1487  bPasteSelection );
1488  }
1489  else if( !pPt && pTunneledTrans &&
1490  EXCHG_OUT_ACTION_INSERT_PRIVATE == nAction )
1491  {
1492  // then internal paste
1493  bRet = pTunneledTrans->PrivatePaste(rSh, pContext);
1494  }
1495  else if( EXCHG_INOUT_ACTION_NONE != nAction )
1496  {
1497  if( !pAction )
1498  {
1499  pAction.reset(new SwTrnsfrActionAndUndo( &rSh ));
1500  }
1501 
1502  // in Drag&Drop MessageBoxes must not be showed
1503  bool bMsg = nullptr == pPt;
1504 
1505  // delete selections
1506 
1507  switch( nAction )
1508  {
1510  OSL_ENSURE( pPt, "EXCHG_OUT_ACTION_INSERT_PRIVATE: what should happen here?" );
1511  break;
1512 
1514  OSL_ENSURE( pPt, "EXCHG_OUT_ACTION_MOVE_PRIVATE: what should happen here?" );
1515  break;
1516 
1517  case EXCHG_IN_ACTION_MOVE:
1518  case EXCHG_IN_ACTION_COPY:
1519  case EXCHG_IN_ACTION_LINK:
1524 
1525  // then we have to use the format
1526  switch( nFormat )
1527  {
1528  case SotClipboardFormatId::DRAWING:
1529  bRet = SwTransferable::PasteSdrFormat( rData, rSh,
1530  SwPasteSdr::Insert, pPt,
1531  nActionFlags, bNeedToSelectBeforePaste);
1532  break;
1533 
1534  case SotClipboardFormatId::HTML:
1535  case SotClipboardFormatId::HTML_SIMPLE:
1536  case SotClipboardFormatId::HTML_NO_COMMENT:
1537  case SotClipboardFormatId::RTF:
1538  case SotClipboardFormatId::RICHTEXT:
1539  case SotClipboardFormatId::STRING:
1540  bRet = SwTransferable::PasteFileContent( rData, rSh,
1541  nFormat, bMsg, bIgnoreComments );
1542  break;
1543 
1544  case SotClipboardFormatId::NETSCAPE_BOOKMARK:
1545  {
1546  INetBookmark aBkmk;
1547  if( rData.GetINetBookmark( nFormat, aBkmk ) )
1548  {
1549  SwFormatINetFormat aFormat( aBkmk.GetURL(), OUString() );
1550  rSh.InsertURL( aFormat, aBkmk.GetDescription() );
1551  bRet = true;
1552  }
1553  }
1554  break;
1555 
1556  case SotClipboardFormatId::SD_OLE:
1557  bRet = SwTransferable::PasteOLE( rData, rSh, nFormat,
1558  nActionFlags, bMsg );
1559  break;
1560 
1561  case SotClipboardFormatId::SVIM:
1562  bRet = SwTransferable::PasteImageMap( rData, rSh );
1563  break;
1564 
1565  case SotClipboardFormatId::SVXB:
1566  case SotClipboardFormatId::BITMAP:
1567  case SotClipboardFormatId::PNG:
1568  case SotClipboardFormatId::GDIMETAFILE:
1569  bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
1570  SwPasteSdr::Insert,pPt,
1571  nActionFlags, nDropAction, bNeedToSelectBeforePaste);
1572  break;
1573 
1574  case SotClipboardFormatId::XFORMS:
1575  case SotClipboardFormatId::SBA_FIELDDATAEXCHANGE:
1576  case SotClipboardFormatId::SBA_DATAEXCHANGE:
1577  case SotClipboardFormatId::SBA_CTRLDATAEXCHANGE:
1578  bRet = SwTransferable::PasteDBData( rData, rSh, nFormat,
1579  EXCHG_IN_ACTION_LINK == nAction,
1580  pPt, bMsg );
1581  break;
1582 
1583  case SotClipboardFormatId::SIMPLE_FILE:
1584  bRet = SwTransferable::PasteFileName( rData, rSh, nFormat,
1585  ( EXCHG_IN_ACTION_MOVE == nAction
1587  : EXCHG_IN_ACTION_LINK == nAction
1589  : SwPasteSdr::Insert),
1590  pPt, nActionFlags, nullptr );
1591  break;
1592 
1593  case SotClipboardFormatId::FILE_LIST:
1594  // then insert as graphics only
1595  bRet = SwTransferable::PasteFileList( rData, rSh,
1596  EXCHG_IN_ACTION_LINK == nAction,
1597  pPt, bMsg );
1598  break;
1599 
1600  case SotClipboardFormatId::SONLK:
1601  if( pPt )
1602  {
1603  NaviContentBookmark aBkmk;
1604  if( aBkmk.Paste( rData ) )
1605  {
1606  if(bIsDefault)
1607  {
1608  switch(aBkmk.GetDefaultDragType())
1609  {
1610  case RegionMode::NONE: nAction = EXCHG_IN_ACTION_COPY; break;
1611  case RegionMode::EMBEDDED: nAction = EXCHG_IN_ACTION_MOVE; break;
1612  case RegionMode::LINK: nAction = EXCHG_IN_ACTION_LINK; break;
1613  }
1614  }
1615  rSh.NavigatorPaste( aBkmk, nAction );
1616  bRet = true;
1617  }
1618  }
1619  break;
1620 
1621  case SotClipboardFormatId::INET_IMAGE:
1622  case SotClipboardFormatId::NETSCAPE_IMAGE:
1623  bRet = SwTransferable::PasteTargetURL( rData, rSh,
1624  SwPasteSdr::Insert,
1625  pPt, true );
1626  break;
1627 
1628  default:
1629  OSL_ENSURE( pPt, "unknown format" );
1630  }
1631  break;
1632 
1634  {
1635  bool graphicInserted;
1636  bRet = SwTransferable::PasteFileName( rData, rSh, nFormat,
1637  SwPasteSdr::Insert, pPt,
1638  nActionFlags,
1639  &graphicInserted );
1640  if( graphicInserted )
1641  bCallAutoCaption = true;
1642  }
1643  break;
1644 
1646  bRet = SwTransferable::PasteOLE( rData, rSh, nFormat,
1647  nActionFlags,bMsg );
1648  break;
1649 
1651  {
1652  bool bReRead = 0 != CNT_HasGrf( rSh.GetCntType() );
1653  bRet = SwTransferable::PasteDDE( rData, rSh, bReRead, bMsg );
1654  }
1655  break;
1656 
1658  {
1659  OUString sURL, sDesc;
1660  if( SotClipboardFormatId::SIMPLE_FILE == nFormat )
1661  {
1662  if( rData.GetString( nFormat, sURL ) && !sURL.isEmpty() )
1663  {
1664  SwTransferable::CheckForURLOrLNKFile( rData, sURL, &sDesc );
1665  if( sDesc.isEmpty() )
1666  sDesc = sURL;
1667  bRet = true;
1668  }
1669  }
1670  else
1671  {
1672  INetBookmark aBkmk;
1673  if( rData.GetINetBookmark( nFormat, aBkmk ) )
1674  {
1675  sURL = aBkmk.GetURL();
1676  sDesc = aBkmk.GetDescription();
1677  bRet = true;
1678  }
1679  }
1680 
1681  if( bRet )
1682  {
1683  SwFormatINetFormat aFormat( sURL, OUString() );
1684  rSh.InsertURL( aFormat, sDesc );
1685  }
1686  }
1687  break;
1688 
1690  switch( nFormat )
1691  {
1692  case SotClipboardFormatId::DRAWING:
1693  bRet = SwTransferable::PasteSdrFormat( rData, rSh,
1694  SwPasteSdr::SetAttr, pPt,
1695  nActionFlags, bNeedToSelectBeforePaste);
1696  break;
1697  case SotClipboardFormatId::SVXB:
1698  case SotClipboardFormatId::GDIMETAFILE:
1699  case SotClipboardFormatId::BITMAP:
1700  case SotClipboardFormatId::PNG:
1701  case SotClipboardFormatId::NETSCAPE_BOOKMARK:
1702  case SotClipboardFormatId::SIMPLE_FILE:
1703  case SotClipboardFormatId::FILEGRPDESCRIPTOR:
1704  case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
1705  bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
1706  SwPasteSdr::SetAttr, pPt,
1707  nActionFlags, nDropAction, bNeedToSelectBeforePaste);
1708  break;
1709  default:
1710  OSL_FAIL( "unknown format" );
1711  }
1712 
1713  break;
1714 
1716  bRet = SwTransferable::PasteSdrFormat( rData, rSh,
1717  SwPasteSdr::Insert, pPt,
1718  nActionFlags, bNeedToSelectBeforePaste);
1719  break;
1724  bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
1725  SwPasteSdr::Insert, pPt,
1726  nActionFlags, nDropAction, bNeedToSelectBeforePaste, nAnchorType );
1727  break;
1728 
1730  bRet = SwTransferable::PasteSdrFormat( rData, rSh,
1731  SwPasteSdr::Replace, pPt,
1732  nActionFlags, bNeedToSelectBeforePaste);
1733  break;
1734 
1739  bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
1740  SwPasteSdr::Replace,pPt,
1741  nActionFlags, nDropAction, bNeedToSelectBeforePaste);
1742  break;
1743 
1745  bRet = SwTransferable::PasteAsHyperlink( rData, rSh, nFormat );
1746  break;
1747 
1748  default:
1749  OSL_FAIL("unknown action" );
1750  }
1751  }
1752 
1753  if( !bPasteSelection && rSh.IsFrameSelected() )
1754  {
1755  rSh.EnterSelFrameMode();
1756  //force ::SelectShell
1757  rSh.GetView().StopShellTimer();
1758  }
1759 
1760  pAction.reset();
1761  if( bCallAutoCaption )
1762  rSh.GetView().AutoCaption( GRAPHIC_CAP );
1763 
1764  return bRet;
1765 }
1766 
1768 {
1769  SotExchangeDest nRet = SotExchangeDest::NONE;
1770 
1771  ObjCntType eOType = rSh.GetObjCntTypeOfSelection();
1772 
1773  switch( eOType )
1774  {
1775  case OBJCNT_GRF:
1776  {
1777  bool bIMap, bLink;
1778  bIMap = nullptr != rSh.GetFlyFrameFormat()->GetURL().GetMap();
1779  OUString aDummy;
1780  rSh.GetGrfNms( &aDummy, nullptr );
1781  bLink = !aDummy.isEmpty();
1782 
1783  if( bLink && bIMap )
1784  nRet = SotExchangeDest::DOC_LNKD_GRAPH_W_IMAP;
1785  else if( bLink )
1786  nRet = SotExchangeDest::DOC_LNKD_GRAPHOBJ;
1787  else if( bIMap )
1788  nRet = SotExchangeDest::DOC_GRAPH_W_IMAP;
1789  else
1790  nRet = SotExchangeDest::DOC_GRAPHOBJ;
1791  }
1792  break;
1793 
1794  case OBJCNT_FLY:
1795  if( dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr )
1796  nRet = SotExchangeDest::DOC_TEXTFRAME_WEB;
1797  else
1798  nRet = SotExchangeDest::DOC_TEXTFRAME;
1799  break;
1800  case OBJCNT_OLE: nRet = SotExchangeDest::DOC_OLEOBJ; break;
1801 
1802  case OBJCNT_CONTROL: /* no Action avail */
1803  case OBJCNT_SIMPLE: nRet = SotExchangeDest::DOC_DRAWOBJ; break;
1804  case OBJCNT_URLBUTTON: nRet = SotExchangeDest::DOC_URLBUTTON; break;
1805  case OBJCNT_GROUPOBJ: nRet = SotExchangeDest::DOC_GROUPOBJ; break;
1806 
1807  // what do we do at multiple selections???
1808  default:
1809  {
1810  if( dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr )
1811  nRet = SotExchangeDest::SWDOC_FREE_AREA_WEB;
1812  else
1813  nRet = SotExchangeDest::SWDOC_FREE_AREA;
1814  }
1815  }
1816 
1817  return nRet;
1818 }
1819 
1821  SwWrtShell& rSh, SotClipboardFormatId nFormat, bool bMsg, bool bIgnoreComments )
1822 {
1823  const char* pResId = STR_CLPBRD_FORMAT_ERROR;
1824  bool bRet = false;
1825 
1826  MSE40HTMLClipFormatObj aMSE40ClpObj;
1827 
1829  SvStream* pStream = nullptr;
1830  Reader* pRead = nullptr;
1831  OUString sData;
1832  switch( nFormat )
1833  {
1834  case SotClipboardFormatId::STRING:
1835  {
1836  pRead = ReadAscii;
1837  if( rData.GetString( nFormat, sData ) )
1838  {
1839  pStream = new SvMemoryStream( const_cast<sal_Unicode *>(sData.getStr()),
1840  sData.getLength() * sizeof( sal_Unicode ),
1841  StreamMode::READ );
1842 #ifdef OSL_BIGENDIAN
1843  pStream->SetEndian( SvStreamEndian::BIG );
1844 #else
1845  pStream->SetEndian( SvStreamEndian::LITTLE );
1846 #endif
1847 
1848  SwAsciiOptions aAOpt;
1849  aAOpt.SetCharSet( RTL_TEXTENCODING_UCS2 );
1850  pRead->GetReaderOpt().SetASCIIOpts( aAOpt );
1851  break;
1852  }
1853  }
1854  [[fallthrough]]; // because then test if we get a stream
1855 
1856  default:
1857  if( rData.GetSotStorageStream( nFormat, xStrm ) )
1858  {
1859  if( ( SotClipboardFormatId::HTML_SIMPLE == nFormat ) ||
1860  ( SotClipboardFormatId::HTML_NO_COMMENT == nFormat ) )
1861  {
1862  pStream = aMSE40ClpObj.IsValid( *xStrm );
1863  pRead = ReadHTML;
1864  pRead->SetReadUTF8( true );
1865 
1866  bool bNoComments =
1867  ( nFormat == SotClipboardFormatId::HTML_NO_COMMENT );
1868  pRead->SetIgnoreHTMLComments( bNoComments );
1869  }
1870  else
1871  {
1872  pStream = xStrm.get();
1873  if( SotClipboardFormatId::RTF == nFormat || SotClipboardFormatId::RICHTEXT == nFormat)
1874  pRead = SwReaderWriter::GetRtfReader();
1875  else if( !pRead )
1876  {
1877  pRead = ReadHTML;
1878  pRead->SetReadUTF8( true );
1879  }
1880  }
1881  }
1882  break;
1883  }
1884 
1885  if( pStream && pRead )
1886  {
1887  Link<SwCursorShell*,void> aOldLink( rSh.GetChgLnk() );
1889 
1890  const SwPosition& rInsPos = *rSh.GetCursor()->Start();
1891  SwReader aReader(*pStream, OUString(), OUString(), *rSh.GetCursor());
1892  rSh.SaveTableBoxContent( &rInsPos );
1893 
1894  if (bIgnoreComments)
1895  pRead->SetIgnoreHTMLComments(true);
1896 
1897  if( aReader.Read( *pRead ).IsError() )
1898  pResId = STR_ERROR_CLPBRD_READ;
1899  else
1900  {
1901  pResId = nullptr;
1902  bRet = true;
1903  }
1904 
1905  rSh.SetChgLnk( aOldLink );
1906  if( bRet )
1907  rSh.CallChgLnk();
1908  }
1909  else
1910  pResId = STR_CLPBRD_FORMAT_ERROR;
1911 
1912  // Exist a SvMemoryStream? (data in the OUString and xStrm is empty)
1913  if( pStream && !xStrm.is() )
1914  delete pStream;
1915 
1916  if (bMsg && pResId)
1917  {
1918  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
1919  VclMessageType::Info, VclButtonsType::Ok,
1920  SwResId(pResId)));
1921  xBox->run();
1922  }
1923  return bRet;
1924 }
1925 
1927  SotClipboardFormatId nFormat, SotExchangeActionFlags nActionFlags, bool bMsg )
1928 {
1929  bool bRet = false;
1931  uno::Reference < io::XInputStream > xStrm;
1932  uno::Reference < embed::XStorage > xStore;
1933  Reader* pRead = nullptr;
1934 
1935  // Get the preferred format
1937  if( rData.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ ) )
1938  nId = SotClipboardFormatId::EMBEDDED_OBJ;
1939  else if( rData.HasFormat( SotClipboardFormatId::EMBED_SOURCE ) &&
1940  rData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ))
1941  nId = SotClipboardFormatId::EMBED_SOURCE;
1942  else
1943  nId = SotClipboardFormatId::NONE;
1944 
1945  if (nId != SotClipboardFormatId::NONE)
1946  {
1947  SwDocShell* pDocSh = rSh.GetDoc()->GetDocShell();
1948  xStrm = rData.GetInputStream(nId, SfxObjectShell::CreateShellID(pDocSh));
1949  }
1950 
1951  if (xStrm.is())
1952  {
1953  // if there is an embedded object, first try if it's a writer object
1954  // this will be inserted into the document by using a Reader
1955  try
1956  {
1958  switch( SotStorage::GetFormatID( xStore ) )
1959  {
1960  case SotClipboardFormatId::STARWRITER_60:
1961  case SotClipboardFormatId::STARWRITERWEB_60:
1962  case SotClipboardFormatId::STARWRITERGLOB_60:
1963  case SotClipboardFormatId::STARWRITER_8:
1964  case SotClipboardFormatId::STARWRITERWEB_8:
1965  case SotClipboardFormatId::STARWRITERGLOB_8:
1966  pRead = ReadXML;
1967  break;
1968  default:
1969  try
1970  {
1971  xStore->dispose();
1972  xStore = nullptr;
1973  }
1974  catch (const uno::Exception&)
1975  {
1976  }
1977 
1978  break;
1979  }
1980  }
1981  catch (const uno::Exception&)
1982  {
1983  // it wasn't a storage, but maybe it's a useful stream
1984  }
1985  }
1986 
1987  if( pRead )
1988  {
1989  SwPaM &rPAM = *rSh.GetCursor();
1990  SwReader aReader(xStore, OUString(), rPAM);
1991  if( ! aReader.Read( *pRead ).IsError() )
1992  bRet = true;
1993  else if( bMsg )
1994  {
1995  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
1996  VclMessageType::Info, VclButtonsType::Ok,
1997  SwResId(STR_ERROR_CLPBRD_READ)));
1998  xBox->run();
1999  }
2000  }
2001  else
2002  {
2003  // temporary storage until the object is inserted
2004  uno::Reference< embed::XStorage > xTmpStor;
2005  uno::Reference < embed::XEmbeddedObject > xObj;
2006  OUString aName;
2008 
2009  if ( xStrm.is() )
2010  {
2011  if ( !rData.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc ) )
2012  {
2013  OSL_ENSURE( !xStrm.is(), "An object without descriptor in clipboard!");
2014  }
2015  }
2016  else
2017  {
2018  if( rData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE ) && rData.GetTransferableObjectDescriptor( nFormat, aObjDesc ) )
2019  {
2020  xStrm = rData.GetInputStream(SotClipboardFormatId::EMBED_SOURCE_OLE, OUString());
2021  if (!xStrm.is())
2022  xStrm = rData.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE, OUString());
2023 
2024  if ( !xStrm.is() )
2025  {
2026  // This is MSOLE object that should be created by direct using of system clipboard
2027  try
2028  {
2030  uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator =
2031  embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
2032 
2033  embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
2034  xTmpStor,
2035  "DummyName",
2036  uno::Sequence< beans::PropertyValue >() );
2037 
2038  // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
2039  // for example whether the object should be an iconified one
2040  xObj = aInfo.Object;
2041  }
2042  catch (const uno::Exception&)
2043  {
2044  }
2045  }
2046  }
2047  }
2048 
2049  if ( xStrm.is() && !xObj.is() )
2050  xObj = aCnt.InsertEmbeddedObject( xStrm, aName );
2051 
2052  if( xObj.is() )
2053  {
2054  svt::EmbeddedObjectRef xObjRef( xObj, aObjDesc.mnViewAspect );
2055 
2056  // try to get the replacement image from the clipboard
2057  Graphic aGraphic;
2058  SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
2059 
2060  // limit the size of the preview metafile to 100000 actions
2061  GDIMetaFile aMetafile;
2062  if (rData.GetGDIMetaFile(SotClipboardFormatId::GDIMETAFILE, aMetafile, 100000))
2063  {
2064  nGrFormat = SotClipboardFormatId::GDIMETAFILE;
2065  aGraphic = aMetafile;
2066  }
2067 
2068  // insert replacement image ( if there is one ) into the object helper
2069  if ( nGrFormat != SotClipboardFormatId::NONE )
2070  {
2071  DataFlavor aDataFlavor;
2072  SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
2073  xObjRef.SetGraphic( aGraphic, aDataFlavor.MimeType );
2074  }
2075  else if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
2076  {
2077  // it is important to have an icon, let an empty graphic be used
2078  // if no other graphic is provided
2079  // TODO/LATER: in future a default bitmap could be used
2080  MapMode aMapMode( MapUnit::Map100thMM );
2081  aGraphic.SetPrefSize( Size( 2500, 2500 ) );
2082  aGraphic.SetPrefMapMode( aMapMode );
2083  xObjRef.SetGraphic( aGraphic, OUString() );
2084  }
2085 
2086  //set size. This is a hack because of handing over, size should be
2087  //passed to the InsertOle!!!!!!!!!!
2088  Size aSize;
2089  if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
2090  {
2091  if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
2092  aSize = aObjDesc.maSize;
2093  else
2094  {
2095  MapMode aMapMode( MapUnit::Map100thMM );
2096  aSize = xObjRef.GetSize( &aMapMode );
2097  }
2098  }
2099  else if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
2100  {
2101  aSize = aObjDesc.maSize; //always 100TH_MM
2102  MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) );
2103  aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(aUnit));
2104  awt::Size aSz;
2105  try
2106  {
2107  aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
2108  }
2109  catch (const embed::NoVisualAreaSizeException&)
2110  {
2111  // in this case the provided size is used
2112  }
2113 
2114  if ( aSz.Width != aSize.Width() || aSz.Height != aSize.Height() )
2115  {
2116  aSz.Width = aSize.Width();
2117  aSz.Height = aSize.Height();
2118  xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
2119  }
2120  }
2121  else
2122  {
2123  // the descriptor contains the wrong object size
2124  // the following call will let the MSOLE objects cache the size if it is possible
2125  // it should be done while the object is running
2126  try
2127  {
2128  xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
2129  }
2130  catch (const uno::Exception&)
2131  {
2132  }
2133  }
2134  //End of Hack!
2135 
2136  rSh.InsertOleObject( xObjRef );
2137  bRet = true;
2138 
2139  if( bRet && ( nActionFlags & SotExchangeActionFlags::InsertTargetUrl) )
2140  SwTransferable::PasteTargetURL( rData, rSh, SwPasteSdr::NONE, nullptr, false );
2141 
2142  // let the object be unloaded if possible
2143  SwOLEObj::UnloadObject( xObj, rSh.GetDoc(), embed::Aspects::MSOLE_CONTENT );
2144  }
2145  }
2146  return bRet;
2147 }
2148 
2150  SwWrtShell& rSh, SwPasteSdr nAction,
2151  const Point* pPt, bool bInsertGRF )
2152 {
2153  bool bRet = false;
2154  INetImage aINetImg;
2155  if( ( rData.HasFormat( SotClipboardFormatId::INET_IMAGE ) &&
2156  rData.GetINetImage( SotClipboardFormatId::INET_IMAGE, aINetImg )) ||
2157  ( rData.HasFormat( SotClipboardFormatId::NETSCAPE_IMAGE ) &&
2158  rData.GetINetImage( SotClipboardFormatId::NETSCAPE_IMAGE, aINetImg )) )
2159  {
2160  if( !aINetImg.GetImageURL().isEmpty() && bInsertGRF )
2161  {
2162  OUString sURL( aINetImg.GetImageURL() );
2163  SwTransferable::CheckForURLOrLNKFile( rData, sURL );
2164 
2166  Graphic aGraphic;
2168  bRet = ERRCODE_NONE == GraphicFilter::LoadGraphic(sURL, OUString(), aGraphic, &rFlt);
2169 
2170  if( bRet )
2171  {
2172  //Check and Perform rotation if needed
2173  lclCheckAndPerformRotation(aGraphic);
2174 
2175  switch( nAction )
2176  {
2177  case SwPasteSdr::Insert:
2178  SwTransferable::SetSelInShell( rSh, false, pPt );
2179  rSh.Insert(sURL, OUString(), aGraphic);
2180  break;
2181 
2182  case SwPasteSdr::Replace:
2183  if( rSh.IsObjSelected() )
2184  {
2185  rSh.ReplaceSdrObj( sURL, &aGraphic );
2186  Point aPt( pPt ? *pPt : rSh.GetCursorDocPos() );
2187  SwTransferable::SetSelInShell( rSh, true, &aPt );
2188  }
2189  else
2190  rSh.ReRead(sURL, OUString(), &aGraphic);
2191  break;
2192 
2193  case SwPasteSdr::SetAttr:
2194  if( rSh.IsObjSelected() )
2195  rSh.Paste( aGraphic, OUString() );
2196  else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() )
2197  rSh.ReRead(sURL, OUString(), &aGraphic);
2198  else
2199  {
2200  SwTransferable::SetSelInShell( rSh, false, pPt );
2201  rSh.Insert(sURL, OUString(), aGraphic);
2202  }
2203  break;
2204  default:
2205  bRet = false;
2206  }
2207  }
2208  }
2209  else
2210  bRet = true;
2211  }
2212 
2213  if( bRet )
2214  {
2216  rSh.GetFlyFrameAttr( aSet );
2217  SwFormatURL aURL( aSet.Get( RES_URL ) );
2218 
2219  if( aURL.GetURL() != aINetImg.GetTargetURL() ||
2220  aURL.GetTargetFrameName() != aINetImg.GetTargetFrame() )
2221  {
2222  aURL.SetURL( aINetImg.GetTargetURL(), false );
2223  aURL.SetTargetFrameName( aINetImg.GetTargetFrame() );
2224  aSet.Put( aURL );
2225  rSh.SetFlyFrameAttr( aSet );
2226  }
2227  }
2228  return bRet;
2229 }
2230 
2231 void SwTransferable::SetSelInShell( SwWrtShell& rSh, bool bSelectFrame,
2232  const Point* pPt )
2233 {
2234  if( bSelectFrame )
2235  {
2236  // select frames/objects
2237  if( pPt && !rSh.GetView().GetViewFrame()->GetDispatcher()->IsLocked() )
2238  {
2239  rSh.GetView().NoRotate();
2240  if( rSh.SelectObj( *pPt ))
2241  {
2242  rSh.HideCursor();
2243  rSh.EnterSelFrameMode( pPt );
2244  g_bFrameDrag = true;
2245  }
2246  }
2247  }
2248  else
2249  {
2250  if( rSh.IsFrameSelected() || rSh.IsObjSelected() )
2251  {
2252  rSh.UnSelectFrame();
2253  rSh.LeaveSelFrameMode();
2254  rSh.GetView().GetEditWin().StopInsFrame();
2255  g_bFrameDrag = false;
2256  }
2257  else if( rSh.GetView().GetDrawFuncPtr() )
2258  rSh.GetView().GetEditWin().StopInsFrame();
2259 
2260  rSh.EnterStdMode();
2261  if( pPt )
2262  rSh.SwCursorShell::SetCursor( *pPt, true );
2263  }
2264 }
2265 
2267  SwWrtShell& rWrtShell, bool bReReadGrf,
2268  bool bMsg )
2269 {
2270  // data from Clipboardformat
2271  OUString aApp, aTopic, aItem;
2272 
2273  {
2275  if( !rData.GetSotStorageStream( SotClipboardFormatId::LINK, xStrm ))
2276  {
2277  OSL_ENSURE( false, "DDE Data not found." );
2278  return false;
2279  } // report useful error!!
2280 
2281  rtl_TextEncoding eEncoding = DDE_TXT_ENCODING;
2282  aApp = read_zeroTerminated_uInt8s_ToOUString(*xStrm, eEncoding);
2283  aTopic = read_zeroTerminated_uInt8s_ToOUString(*xStrm, eEncoding);
2284  aItem = read_zeroTerminated_uInt8s_ToOUString(*xStrm, eEncoding);
2285  }
2286 
2287  OUString aCmd;
2288  sfx2::MakeLnkName( aCmd, &aApp, aTopic, aItem );
2289 
2290  // do we want to read in a graphic now?
2291  SotClipboardFormatId nFormat;
2292  if( !rData.HasFormat( SotClipboardFormatId::RTF ) &&
2293  !rData.HasFormat( SotClipboardFormatId::RICHTEXT ) &&
2294  !rData.HasFormat( SotClipboardFormatId::HTML ) &&
2295  !rData.HasFormat( SotClipboardFormatId::STRING ) &&
2296  (rData.HasFormat( nFormat = SotClipboardFormatId::GDIMETAFILE ) ||
2297  rData.HasFormat( nFormat = SotClipboardFormatId::BITMAP )) )
2298  {
2299  Graphic aGrf;
2300  bool bRet = rData.GetGraphic( nFormat, aGrf );
2301  if( bRet )
2302  {
2303  OUString sLnkTyp("DDE");
2304  if ( bReReadGrf )
2305  rWrtShell.ReRead( aCmd, sLnkTyp, &aGrf );
2306  else
2307  rWrtShell.Insert( aCmd, sLnkTyp, aGrf );
2308  }
2309  return bRet;
2310  }
2311 
2312  SwFieldType* pTyp = nullptr;
2313  size_t i = 1;
2314  size_t j;
2315  OUString aName;
2316  bool bDoublePaste = false;
2317  const size_t nSize = rWrtShell.GetFieldTypeCount();
2318  const ::utl::TransliterationWrapper& rColl = ::GetAppCmpStrIgnore();
2319 
2320  do {
2321  aName = aApp + OUString::number( i );
2322  for( j = INIT_FLDTYPES; j < nSize; j++ )
2323  {
2324  pTyp = rWrtShell.GetFieldType( j );
2325  if( SwFieldIds::Dde == pTyp->Which() )
2326  {
2327  if( rColl.isEqual( static_cast<SwDDEFieldType*>(pTyp)->GetCmd(), aCmd ) &&
2328  SfxLinkUpdateMode::ALWAYS == static_cast<SwDDEFieldType*>(pTyp)->GetType() )
2329  {
2330  aName = pTyp->GetName();
2331  bDoublePaste = true;
2332  break;
2333  }
2334  else if( rColl.isEqual( aName, pTyp->GetName() ) )
2335  break;
2336  }
2337  }
2338  if( j == nSize )
2339  break;
2340  ++i;
2341  }
2342  while( !bDoublePaste );
2343 
2344  if( !bDoublePaste )
2345  {
2346  SwDDEFieldType aType( aName, aCmd, SfxLinkUpdateMode::ALWAYS );
2347  pTyp = rWrtShell.InsertFieldType( aType );
2348  }
2349 
2350  SwDDEFieldType* pDDETyp = static_cast<SwDDEFieldType*>(pTyp);
2351 
2352  OUString aExpand;
2353  if( rData.GetString( SotClipboardFormatId::STRING, aExpand ))
2354  {
2355  do { // middle checked loop
2356 
2357  const sal_Int32 nNewlines{comphelper::string::getTokenCount(aExpand, '\n')};
2358  // When data comes from a spreadsheet, we add a DDE-table
2359  if( !aExpand.isEmpty() &&
2360  ( rData.HasFormat( SotClipboardFormatId::SYLK ) ||
2361  rData.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS ) ) )
2362  {
2363  const sal_Int32 nRows = nNewlines ? nNewlines-1 : 0;
2364  const sal_Int32 nCols = comphelper::string::getTokenCount(aExpand.getToken(0, '\n'), '\t');
2365 
2366  // don't try to insert tables that are too large for writer
2367  if (nRows > SAL_MAX_UINT16 || nCols > SAL_MAX_UINT16)
2368  {
2369  if( bMsg )
2370  {
2371  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2372  VclMessageType::Info, VclButtonsType::Ok,
2373  SwResId(STR_TABLE_TOO_LARGE)));
2374  xBox->run();
2375  }
2376  pDDETyp = nullptr;
2377  break;
2378  }
2379 
2380  // at least one column & row must be there
2381  if( !nRows || !nCols )
2382  {
2383  if( bMsg )
2384  {
2385  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2386  VclMessageType::Info, VclButtonsType::Ok,
2387  SwResId(STR_NO_TABLE)));
2388  xBox->run();
2389  }
2390  pDDETyp = nullptr;
2391  break;
2392  }
2393 
2394  rWrtShell.InsertDDETable(
2395  SwInsertTableOptions( SwInsertTableFlags::SplitLayout, 1 ), // TODO MULTIHEADER
2396  pDDETyp, nRows, nCols );
2397  }
2398  else if( nNewlines > 1 )
2399  {
2400  // multiple paragraphs -> insert a protected section
2401  if( rWrtShell.HasSelection() )
2402  rWrtShell.DelRight();
2403 
2404  SwSectionData aSect( DDE_LINK_SECTION, aName );
2405  aSect.SetLinkFileName( aCmd );
2406  aSect.SetProtectFlag(true);
2407  rWrtShell.InsertSection( aSect );
2408 
2409  pDDETyp = nullptr; // remove FieldTypes again
2410  }
2411  else
2412  {
2413  // insert
2414  SwDDEField aSwDDEField( pDDETyp );
2415  rWrtShell.Insert( aSwDDEField );
2416  }
2417 
2418  } while( false );
2419  }
2420  else
2421  pDDETyp = nullptr; // remove FieldTypes again
2422 
2423  if( !pDDETyp && !bDoublePaste )
2424  {
2425  // remove FieldType again - error occurred!
2426  for( j = nSize; j >= INIT_FLDTYPES; --j )
2427  if( pTyp == rWrtShell.GetFieldType( j ) )
2428  {
2429  rWrtShell.RemoveFieldType( j );
2430  break;
2431  }
2432  }
2433 
2434  return true;
2435 }
2436 
2438  SwWrtShell& rSh, SwPasteSdr nAction,
2439  const Point* pPt, SotExchangeActionFlags nActionFlags, bool bNeedToSelectBeforePaste)
2440 {
2441  bool bRet = false;
2443  if( rData.GetSotStorageStream( SotClipboardFormatId::DRAWING, xStrm ))
2444  {
2445  xStrm->SetVersion( SOFFICE_FILEFORMAT_50 );
2446 
2447  if(bNeedToSelectBeforePaste && pPt)
2448  {
2449  // if this is an internal drag, need to set the target right (select it), else
2450  // still the source will be selected
2451  SwTransferable::SetSelInShell( rSh, true, pPt );
2452  }
2453 
2454  rSh.Paste( *xStrm, nAction, pPt );
2455  bRet = true;
2456 
2457  if( bRet && ( nActionFlags & SotExchangeActionFlags::InsertTargetUrl ))
2458  SwTransferable::PasteTargetURL( rData, rSh, SwPasteSdr::NONE, nullptr, false );
2459  }
2460  return bRet;
2461 }
2462 
2464  SotClipboardFormatId nFormat, SwPasteSdr nAction, const Point* pPt,
2465  SotExchangeActionFlags nActionFlags, sal_Int8 nDropAction, bool bNeedToSelectBeforePaste, RndStdIds nAnchorType )
2466 {
2467  bool bRet = false;
2468 
2469  Graphic aGraphic;
2470  INetBookmark aBkmk;
2471  bool bCheckForGrf = false, bCheckForImageMap = false;
2472 
2473  switch( nFormat )
2474  {
2475  case SotClipboardFormatId::BITMAP:
2476  case SotClipboardFormatId::PNG:
2477  case SotClipboardFormatId::GDIMETAFILE:
2478  bRet = rData.GetGraphic( nFormat, aGraphic );
2479  break;
2480 
2481  case SotClipboardFormatId::SVXB:
2482  {
2484 
2485  if(rData.GetSotStorageStream(SotClipboardFormatId::SVXB, xStm))
2486  {
2487  ReadGraphic( *xStm, aGraphic );
2488  bRet = (GraphicType::NONE != aGraphic.GetType() && GraphicType::Default != aGraphic.GetType());
2489  }
2490 
2491  break;
2492  }
2493 
2494  case SotClipboardFormatId::NETSCAPE_BOOKMARK:
2495  case SotClipboardFormatId::FILEGRPDESCRIPTOR:
2496  case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
2497  bRet = rData.GetINetBookmark( nFormat, aBkmk );
2498  if( bRet )
2499  {
2500  if( SwPasteSdr::SetAttr == nAction )
2501  nFormat = SotClipboardFormatId::NETSCAPE_BOOKMARK;
2502  else
2503  bCheckForGrf = true;
2504  }
2505  break;
2506 
2507  case SotClipboardFormatId::SIMPLE_FILE:
2508  {
2509  OUString sText;
2510  bRet = rData.GetString( nFormat, sText );
2511  if( bRet )
2512  {
2513  OUString sDesc;
2514  SwTransferable::CheckForURLOrLNKFile( rData, sText, &sDesc );
2515 
2517  false);
2518 
2519 #ifdef _WIN32
2520  // Now that the path could be modified after SwTransferable::CheckForURLOrLNKFile,
2521  // where it could have been converted to URL, and made sure it's actually converted
2522  // to URL in URIHelper::SmartRel2Abs, we can finally convert file: URL back to
2523  // system path to make sure we don't use short path.
2524  // It looks not optimal, when we could apply GetLongPathNameW right to the original
2525  // pasted filename. But I don't know if (1) all arriving strings are system paths;
2526  // and (2) if SwTransferable::CheckForURLOrLNKFile could result in a different short
2527  // path, so taking a safe route.
2528  if (sText.startsWithIgnoreAsciiCase("file:"))
2529  {
2530  // tdf#124500: Convert short path to long path which should be used in links
2531  OUString sSysPath;
2532  osl::FileBase::getSystemPathFromFileURL(sText, sSysPath);
2533  std::unique_ptr<sal_Unicode[]> aBuf(new sal_Unicode[32767]);
2534  DWORD nCopied = GetLongPathNameW(o3tl::toW(sSysPath.getStr()),
2535  o3tl::toW(aBuf.get()), 32767);
2536  if (nCopied && nCopied < 32767)
2537  sText = URIHelper::SmartRel2Abs(INetURLObject(), aBuf.get(),
2538  Link<OUString*, bool>(), false);
2539  }
2540 #endif
2541 
2542  aBkmk = INetBookmark(sText, sDesc);
2543  bCheckForGrf = true;
2544  bCheckForImageMap = SwPasteSdr::Replace == nAction;
2545  }
2546  }
2547  break;
2548 
2549  default:
2550  bRet = rData.GetGraphic( nFormat, aGraphic );
2551  break;
2552  }
2553 
2554  if( bCheckForGrf )
2555  {
2558  bRet = ERRCODE_NONE == GraphicFilter::LoadGraphic(aBkmk.GetURL(), OUString(),
2559  aGraphic, &rFlt );
2560 
2561  if( !bRet && SwPasteSdr::SetAttr == nAction &&
2562  SotClipboardFormatId::SIMPLE_FILE == nFormat &&
2563  // only at frame selection
2564  rSh.IsFrameSelected() )
2565  {
2566  // then set as hyperlink after the graphic
2567  nFormat = SotClipboardFormatId::NETSCAPE_BOOKMARK;
2568  bRet = true;
2569  }
2570  }
2571 
2572  if(pPt && bNeedToSelectBeforePaste)
2573  {
2574  // when using internal D&Ds, still the source object is selected and
2575  // this is necessary to get the correct source data which is also
2576  // dependent from selection. After receiving the drag data it is
2577  // now time to select the correct target object
2578  SwTransferable::SetSelInShell( rSh, true, pPt );
2579  }
2580 
2581  if( bRet )
2582  {
2583  //Check and Perform rotation if needed
2584  lclCheckAndPerformRotation(aGraphic);
2585 
2586  OUString sURL;
2587  if( dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr
2588  // #i123922# if link action is noted, also take URL
2589  || DND_ACTION_LINK == nDropAction)
2590  {
2591  sURL = aBkmk.GetURL();
2592  }
2593 
2594  switch( nAction )
2595  {
2596  case SwPasteSdr::Insert:
2597  {
2598  SwTransferable::SetSelInShell( rSh, false, pPt );
2599  rSh.Insert(sURL, OUString(), aGraphic, nullptr, nAnchorType);
2600  break;
2601  }
2602 
2603  case SwPasteSdr::Replace:
2604  {
2605  if( rSh.IsObjSelected() )
2606  {
2607  // #i123922# for D&D on draw objects, do for now the same for
2608  // SwPasteSdr::Replace (D&D) as for SwPasteSdr::SetAttr (D&D and
2609  // CTRL+SHIFT). The code below replaces the draw object with
2610  // a writer graphic; maybe this is an option later again if wanted
2611  rSh.Paste( aGraphic, sURL );
2612 
2613  // rSh.ReplaceSdrObj(sURL, OUString(), &aGraphic);
2614  // Point aPt( pPt ? *pPt : rSh.GetCursorDocPos() );
2615  // SwTransferable::SetSelInShell( rSh, true, &aPt );
2616  }
2617  else
2618  {
2619  // set graphic at writer graphic without link
2620  rSh.ReRead(sURL, OUString(), &aGraphic);
2621  }
2622 
2623  break;
2624  }
2625 
2626  case SwPasteSdr::SetAttr:
2627  {
2628  if( SotClipboardFormatId::NETSCAPE_BOOKMARK == nFormat )
2629  {
2630  if( rSh.IsFrameSelected() )
2631  {
2633  rSh.GetFlyFrameAttr( aSet );
2634  SwFormatURL aURL( aSet.Get( RES_URL ) );
2635  aURL.SetURL( aBkmk.GetURL(), false );
2636  aSet.Put( aURL );
2637  rSh.SetFlyFrameAttr( aSet );
2638  }
2639  }
2640  else if( rSh.IsObjSelected() )
2641  {
2642  // set as attribute at DrawObject
2643  rSh.Paste( aGraphic, sURL );
2644  }
2645  else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() )
2646  {
2647  // set as linked graphic at writer graphic frame
2648  rSh.ReRead(sURL, OUString(), &aGraphic);
2649  }
2650  else
2651  {
2652  SwTransferable::SetSelInShell( rSh, false, pPt );
2653  rSh.Insert(aBkmk.GetURL(), OUString(), aGraphic);
2654  }
2655  break;
2656  }
2657  default:
2658  {
2659  bRet = false;
2660  break;
2661  }
2662  }
2663  }
2664 
2665  if( bRet )
2666  {
2667 
2668  if( nActionFlags &
2669  ( SotExchangeActionFlags::InsertImageMap | SotExchangeActionFlags::ReplaceImageMap ) )
2670  SwTransferable::PasteImageMap( rData, rSh );
2671 
2672  if( nActionFlags & SotExchangeActionFlags::InsertTargetUrl )
2673  SwTransferable::PasteTargetURL( rData, rSh, SwPasteSdr::NONE, nullptr, false );
2674  }
2675  else if( bCheckForImageMap )
2676  {
2677  // or should the file be an ImageMap-File?
2678  ImageMap aMap;
2679  SfxMedium aMed( INetURLObject(aBkmk.GetURL()).GetFull(),
2680  StreamMode::STD_READ );
2681  SvStream* pStream = aMed.GetInStream();
2682  if( pStream != nullptr &&
2683  !pStream->GetError() &&
2684  // mba: no BaseURL for clipboard functionality
2685  aMap.Read( *pStream, IMAP_FORMAT_DETECT ) == IMAP_ERR_OK &&
2686  aMap.GetIMapObjectCount() )
2687  {
2689  rSh.GetFlyFrameAttr( aSet );
2690  SwFormatURL aURL( aSet.Get( RES_URL ) );
2691  aURL.SetMap( &aMap );
2692  aSet.Put( aURL );
2693  rSh.SetFlyFrameAttr( aSet );
2694  bRet = true;
2695  }
2696  }
2697 
2698  return bRet;
2699 }
2700 
2702  SwWrtShell& rSh )
2703 {
2704  bool bRet = false;
2705  if( rData.HasFormat( SotClipboardFormatId::SVIM ))
2706  {
2708  rSh.GetFlyFrameAttr( aSet );
2709  SwFormatURL aURL( aSet.Get( RES_URL ) );
2710  const ImageMap* pOld = aURL.GetMap();
2711 
2712  // set or replace, that is the question
2713  ImageMap aImageMap;
2714  if( rData.GetImageMap( SotClipboardFormatId::SVIM, aImageMap ) &&
2715  ( !pOld || aImageMap != *pOld ))
2716  {
2717  aURL.SetMap( &aImageMap );
2718  aSet.Put( aURL );
2719  rSh.SetFlyFrameAttr( aSet );
2720  }
2721  bRet = true;
2722  }
2723  return bRet;
2724 }
2725 
2727  SwWrtShell& rSh, SotClipboardFormatId nFormat )
2728 {
2729  bool bRet = false;
2730  OUString sFile;
2731  if( rData.GetString( nFormat, sFile ) && !sFile.isEmpty() )
2732  {
2733  OUString sDesc;
2734  SwTransferable::CheckForURLOrLNKFile( rData, sFile, &sDesc );
2735 
2736  // first, make the URL absolute
2737  INetURLObject aURL;
2738  aURL.SetSmartProtocol( INetProtocol::File );
2739  aURL.SetSmartURL( sFile );
2741 
2742  switch( rSh.GetObjCntTypeOfSelection() )
2743  {
2744  case OBJCNT_FLY:
2745  case OBJCNT_GRF:
2746  case OBJCNT_OLE:
2747  {
2749  rSh.GetFlyFrameAttr( aSet );
2750  SwFormatURL aURL2( aSet.Get( RES_URL ) );
2751  aURL2.SetURL( sFile, false );
2752  if( aURL2.GetName().isEmpty() )
2753  aURL2.SetName( sFile );
2754  aSet.Put( aURL2 );
2755  rSh.SetFlyFrameAttr( aSet );
2756  }
2757  break;
2758 
2759  default:
2760  {
2761  rSh.InsertURL( SwFormatINetFormat( sFile, OUString() ),
2762  sDesc.isEmpty() ? sFile : sDesc);
2763  }
2764  }
2765  bRet = true;
2766  }
2767  return bRet;
2768 }
2769 
2771  SwWrtShell& rSh, SotClipboardFormatId nFormat,
2772  SwPasteSdr nAction, const Point* pPt,
2773  SotExchangeActionFlags nActionFlags,
2774  bool * graphicInserted)
2775 {
2776  bool bRet = SwTransferable::PasteGrf( rData, rSh, nFormat, nAction,
2777  pPt, nActionFlags, 0, false);
2778  if (graphicInserted != nullptr) {
2779  *graphicInserted = bRet;
2780  }
2781  if( !bRet )
2782  {
2783  OUString sFile, sDesc;
2784  if( rData.GetString( nFormat, sFile ) && !sFile.isEmpty() )
2785  {
2786 #if HAVE_FEATURE_AVMEDIA
2787  INetURLObject aMediaURL;
2788 
2789  aMediaURL.SetSmartURL( sFile );
2790  const OUString aMediaURLStr( aMediaURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
2791 
2792  if( ::avmedia::MediaWindow::isMediaURL( aMediaURLStr, ""/*TODO?*/ ) )
2793  {
2794  const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aMediaURLStr );
2796  SID_INSERT_AVMEDIA, SfxCallMode::SYNCHRON,
2797  { &aMediaURLItem });
2798  }
2799 #else
2800  if (false)
2801  {
2802  }
2803 #endif
2804  else
2805  {
2806  bool bIsURLFile = SwTransferable::CheckForURLOrLNKFile( rData, sFile, &sDesc );
2807 
2808  //Own FileFormat? --> insert, not for StarWriter/Web
2809  OUString sFileURL = URIHelper::SmartRel2Abs(INetURLObject(), sFile, Link<OUString *, bool>(), false );
2810  std::shared_ptr<const SfxFilter> pFlt = SwPasteSdr::SetAttr == nAction
2811  ? nullptr : SwIoSystem::GetFileFilter(sFileURL);
2812  if( pFlt && dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) == nullptr )
2813  {
2814  // and then pull up the insert-region-dialog
2815  SwSectionData aSect(
2817  rSh.GetDoc()->GetUniqueSectionName() );
2818  aSect.SetLinkFileName( sFileURL );
2819  aSect.SetProtectFlag( true );
2820 
2821  rSh.StartInsertRegionDialog( aSect ); // starts dialog asynchronously
2822  bRet = true;
2823  }
2824  else if( SwPasteSdr::SetAttr == nAction ||
2825  ( bIsURLFile && SwPasteSdr::Insert == nAction ))
2826  {
2827  //we can insert foreign files as links after all
2828 
2829  // first, make the URL absolute
2830  INetURLObject aURL;
2831  aURL.SetSmartProtocol( INetProtocol::File );
2832  aURL.SetSmartURL( sFile );
2834 
2835  switch( rSh.GetObjCntTypeOfSelection() )
2836  {
2837  case OBJCNT_FLY:
2838  case OBJCNT_GRF:
2839  case OBJCNT_OLE:
2840  {
2842  rSh.GetFlyFrameAttr( aSet );
2843  SwFormatURL aURL2( aSet.Get( RES_URL ) );
2844  aURL2.SetURL( sFile, false );
2845  if( aURL2.GetName().isEmpty() )
2846  aURL2.SetName( sFile );
2847  aSet.Put( aURL2 );
2848  rSh.SetFlyFrameAttr( aSet );
2849  }
2850  break;
2851 
2852  default:
2853  {
2854  rSh.InsertURL( SwFormatINetFormat( sFile, OUString() ),
2855  sDesc.isEmpty() ? sFile : sDesc );
2856  }
2857  }
2858  bRet = true;
2859  }
2860  }
2861  }
2862  }
2863  return bRet;
2864 }
2865 
2867  SwWrtShell& rSh, SotClipboardFormatId nFormat, bool bLink,
2868  const Point* pDragPt, bool bMsg )
2869 {
2870  bool bRet = false;
2871  OUString sText;
2872  if( rData.GetString( nFormat, sText ) && !sText.isEmpty() )
2873  {
2874  sal_uInt16 nWh = SotClipboardFormatId::SBA_CTRLDATAEXCHANGE == nFormat
2875  ? 0
2876  : SotClipboardFormatId::SBA_DATAEXCHANGE == nFormat
2877  ? (bLink
2879  : FN_QRY_INSERT)
2880  : (bLink
2881  ? 0
2882  : FN_QRY_INSERT_FIELD );
2883  const DataFlavorExVector& rVector = rData.GetDataFlavorExVector();
2884  bool bHaveColumnDescriptor = OColumnTransferable::canExtractColumnDescriptor(rVector, ColumnTransferFormatFlags::COLUMN_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE);
2885  if ( SotClipboardFormatId::XFORMS == nFormat )
2886  {
2887  rSh.MakeDrawView();
2888  FmFormView* pFmView = dynamic_cast<FmFormView*>( rSh.GetDrawView() );
2889  if (pFmView && pDragPt)
2890  {
2891  const OXFormsDescriptor &rDesc = OXFormsTransferable::extractDescriptor(rData);
2892  SdrObjectUniquePtr pObj = pFmView->CreateXFormsControl(rDesc);
2893  if(pObj)
2894  {
2895  rSh.SwFEShell::InsertDrawObj( *(pObj.release()), *pDragPt );
2896  }
2897  }
2898  }
2899  else if( nWh )
2900  {
2901  std::unique_ptr<SfxUnoAnyItem> pConnectionItem;
2902  std::unique_ptr<SfxUnoAnyItem> pCursorItem;
2903  std::unique_ptr<SfxUnoAnyItem> pColumnItem;
2904  std::unique_ptr<SfxUnoAnyItem> pSourceItem;
2905  std::unique_ptr<SfxUnoAnyItem> pCommandItem;
2906  std::unique_ptr<SfxUnoAnyItem> pCommandTypeItem;
2907  std::unique_ptr<SfxUnoAnyItem> pColumnNameItem;
2908  std::unique_ptr<SfxUnoAnyItem> pSelectionItem;
2909 
2910  bool bDataAvailable = true;
2911  ODataAccessDescriptor aDesc;
2912  if(bHaveColumnDescriptor)
2913  aDesc = OColumnTransferable::extractColumnDescriptor(rData);
2914  else if(ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
2915  aDesc = ODataAccessObjectTransferable::extractObjectDescriptor(rData);
2916  else
2917  bDataAvailable = false;
2918 
2919  if ( bDataAvailable )
2920  {
2921  pConnectionItem.reset(new SfxUnoAnyItem(FN_DB_CONNECTION_ANY, aDesc[DataAccessDescriptorProperty::Connection]));
2922  pColumnItem.reset(new SfxUnoAnyItem(FN_DB_COLUMN_ANY, aDesc[DataAccessDescriptorProperty::ColumnObject]));
2923  pSourceItem.reset(new SfxUnoAnyItem(FN_DB_DATA_SOURCE_ANY, makeAny(aDesc.getDataSource())));
2924  pCommandItem.reset(new SfxUnoAnyItem(FN_DB_DATA_COMMAND_ANY, aDesc[DataAccessDescriptorProperty::Command]));
2925  pCommandTypeItem.reset(new SfxUnoAnyItem(FN_DB_DATA_COMMAND_TYPE_ANY, aDesc[DataAccessDescriptorProperty::CommandType]));
2926  pColumnNameItem.reset(new SfxUnoAnyItem(FN_DB_DATA_COLUMN_NAME_ANY, aDesc[DataAccessDescriptorProperty::ColumnName]));
2927  pSelectionItem.reset(new SfxUnoAnyItem(FN_DB_DATA_SELECTION_ANY, aDesc[DataAccessDescriptorProperty::Selection]));
2928  pCursorItem.reset(new SfxUnoAnyItem(FN_DB_DATA_CURSOR_ANY, aDesc[DataAccessDescriptorProperty::Cursor]));
2929  }
2930 
2931  SwView& rView = rSh.GetView();
2932  //force ::SelectShell
2933  rView.StopShellTimer();
2934 
2935  SfxStringItem aDataDesc( nWh, sText );
2937  nWh, SfxCallMode::ASYNCHRON,
2938  { &aDataDesc, pConnectionItem.get(), pColumnItem.get(),
2939  pSourceItem.get(), pCommandItem.get(), pCommandTypeItem.get(),
2940  pColumnNameItem.get(), pSelectionItem.get(),
2941  pCursorItem.get() });
2942  }
2943  else
2944  {
2945  rSh.MakeDrawView();
2946  FmFormView* pFmView = dynamic_cast<FmFormView*>( rSh.GetDrawView() );
2947  if (pFmView && bHaveColumnDescriptor && pDragPt)
2948  {
2949  SdrObjectUniquePtr pObj = pFmView->CreateFieldControl( OColumnTransferable::extractColumnDescriptor(rData) );
2950  if (pObj)
2951  rSh.SwFEShell::InsertDrawObj( *(pObj.release()), *pDragPt );
2952  }
2953  }
2954  bRet = true;
2955  }
2956  else if( bMsg )
2957  {
2958  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2959  VclMessageType::Info, VclButtonsType::Ok,
2960  SwResId(STR_CLPBRD_FORMAT_ERROR)));
2961  xBox->run();
2962  }
2963  return bRet;
2964 }
2965 
2967  SwWrtShell& rSh, bool bLink,
2968  const Point* pPt, bool bMsg )
2969 {
2970  bool bRet = false;
2971  FileList aFileList;
2972  if( rData.GetFileList( SotClipboardFormatId::FILE_LIST, aFileList ) &&
2973  aFileList.Count() )
2974  {
2976  OUString sFlyNm;
2977  // iterate over the filelist
2978  for( sal_uLong n = 0, nEnd = aFileList.Count(); n < nEnd; ++n )
2979  {
2981  pHlp->CopyString( SotClipboardFormatId::SIMPLE_FILE, aFileList.GetFile( n ));
2982  TransferableDataHelper aData( pHlp );
2983 
2984  if( SwTransferable::PasteFileName( aData, rSh, SotClipboardFormatId::SIMPLE_FILE, nAct,
2985  pPt, SotExchangeActionFlags::NONE, nullptr ))
2986  {
2987  if( bLink )
2988  {
2989  sFlyNm = rSh.GetFlyName();
2990  SwTransferable::SetSelInShell( rSh, false, pPt );
2991  }
2992  bRet = true;
2993  }
2994  }
2995  if( !sFlyNm.isEmpty() )
2996  rSh.GotoFly( sFlyNm );
2997  }
2998  else if( bMsg )
2999  {
3000  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
3001  VclMessageType::Info, VclButtonsType::Ok,
3002  SwResId(STR_CLPBRD_FORMAT_ERROR)));
3003  xBox->run();
3004  }
3005  return bRet;
3006 }
3007 
3009  OUString& rFileName, OUString* pTitle )
3010 {
3011  bool bIsURLFile = false;
3012  INetBookmark aBkmk;
3013  if( rData.GetINetBookmark( SotClipboardFormatId::SOLK, aBkmk ) )
3014  {
3015  rFileName = aBkmk.GetURL();
3016  if( pTitle )
3017  *pTitle = aBkmk.GetDescription();
3018  bIsURLFile = true;
3019  }
3020  else
3021  {
3022  if( rFileName.getLength()>4 && rFileName.endsWithIgnoreAsciiCase(".url") )
3023  {
3024  OSL_ENSURE( false, "how do we read today .URL - Files?" );
3025  }
3026  }
3027  return bIsURLFile;
3028 }
3029 
3031  const TransferableDataHelper& rData )
3032 {
3033  // we can paste-special if there's an entry in the paste-special-format list
3034  SvxClipboardFormatItem aClipboardFormatItem(0);
3035  FillClipFormatItem( rWrtShell, rData, aClipboardFormatItem);
3036  return aClipboardFormatItem.Count() > 0;
3037 }
3038 
3040  TransferableDataHelper& rData,
3041  SotClipboardFormatId nFormat )
3042 {
3043  SwWait aWait( *rSh.GetView().GetDocShell(), false );
3044  bool bRet = false;
3045 
3046  SotClipboardFormatId nPrivateFormat = SotClipboardFormatId::PRIVATE;
3047  SwTransferable *pClipboard = GetSwTransferable( rData );
3048  if( pClipboard &&
3050  nPrivateFormat = SotClipboardFormatId::EMBED_SOURCE;
3051 
3052  if( pClipboard && nPrivateFormat == nFormat )
3053  bRet = pClipboard->PrivatePaste( rSh );
3054  else if( rData.HasFormat( nFormat ) )
3055  {
3056  uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
3057  sal_uInt8 nEventAction;
3058  SotExchangeDest nDestination = SwTransferable::GetSotDestination( rSh );
3059  sal_uInt16 nSourceOptions =
3060  (( SotExchangeDest::DOC_TEXTFRAME == nDestination ||
3061  SotExchangeDest::SWDOC_FREE_AREA == nDestination ||
3062  SotExchangeDest::DOC_TEXTFRAME_WEB == nDestination ||
3063  SotExchangeDest::SWDOC_FREE_AREA_WEB == nDestination )
3066  SotExchangeActionFlags nActionFlags;
3068  rData.GetDataFlavorExVector(),
3069  nDestination,
3070  nSourceOptions, /* ?? */
3071  EXCHG_IN_ACTION_DEFAULT, /* ?? */
3072  nFormat, nEventAction, nFormat,
3073  lcl_getTransferPointer ( xTransferable ),
3074  &nActionFlags );
3075 
3076  if( EXCHG_INOUT_ACTION_NONE != nAction )
3077  bRet = SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat,
3078  nDestination, true, false );
3079  }
3080  return bRet;
3081 }
3082 
3084  SotClipboardFormatId nFormat, SotExchangeDest nDestination )
3085 {
3086  sal_uInt8 nAction = EXCHG_INOUT_ACTION_NONE, nEventAction;
3087  if( rData.HasFormat( nFormat )) {
3088  uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
3090  rData.GetDataFlavorExVector(),
3091  nDestination, EXCHG_IN_ACTION_COPY,
3092  EXCHG_IN_ACTION_COPY, nFormat,
3093  nEventAction, nFormat,
3094  lcl_getTransferPointer ( xTransferable ) );
3095  }
3096  return EXCHG_INOUT_ACTION_NONE != nAction;
3097 }
3098 
3104 {
3105  SotClipboardFormatId::HTML,
3106  SotClipboardFormatId::HTML_SIMPLE,
3107  SotClipboardFormatId::HTML_NO_COMMENT,
3108  SotClipboardFormatId::RTF,
3109  SotClipboardFormatId::RICHTEXT,
3110  SotClipboardFormatId::STRING,
3111  SotClipboardFormatId::SONLK,
3112  SotClipboardFormatId::NETSCAPE_BOOKMARK,
3113  SotClipboardFormatId::DRAWING,
3114  SotClipboardFormatId::SVXB,
3115  SotClipboardFormatId::GDIMETAFILE,
3116  SotClipboardFormatId::BITMAP,
3117  SotClipboardFormatId::SVIM,
3118  SotClipboardFormatId::FILEGRPDESCRIPTOR,
3119  SotClipboardFormatId::NONE
3120 };
3121 
3123 {
3124  // Plain text == unformatted
3125  return SwTransferable::PasteFormat( rSh, rData, SotClipboardFormatId::STRING );
3126 }
3127 
3129 {
3130  DataFlavorExVector aFormats( rData.GetDataFlavorExVector() );
3132 
3134 
3135  SwTransferable *pClipboard = GetSwTransferable( rData );
3136  if( pClipboard )
3137  {
3138  aDesc = pClipboard->m_aObjDesc;
3139  const char* pResId;
3140  if( pClipboard->m_eBufferType & TransferBufferType::Document )
3141  pResId = STR_PRIVATETEXT;
3142  else if( pClipboard->m_eBufferType & TransferBufferType::Graphic )
3143  pResId = STR_PRIVATEGRAPHIC;
3144  else if( pClipboard->m_eBufferType == TransferBufferType::Ole )
3145  pResId = STR_PRIVATEOLE;
3146  else
3147  pResId = nullptr;
3148 
3149  if (pResId)
3150  {
3151  if (strcmp(STR_PRIVATEOLE, pResId) == 0 || strcmp(STR_PRIVATEGRAPHIC, pResId) == 0)
3152  {
3153  // add SotClipboardFormatId::EMBED_SOURCE to the formats. This
3154  // format display then the private format name.
3155  DataFlavorEx aFlavorEx;
3156  aFlavorEx.mnSotId = SotClipboardFormatId::EMBED_SOURCE;
3157  aFormats.insert( aFormats.begin(), aFlavorEx );
3158  }
3159  pDlg->SetObjName( pClipboard->m_aObjDesc.maClassName,
3160  SwResId(pResId) );
3161  pDlg->Insert( SotClipboardFormatId::EMBED_SOURCE, OUString() );
3162  }
3163  }
3164  else
3165  {
3166  if( rData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ) )
3167  {
3169  SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc );
3170  }
3171 
3172  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::EMBED_SOURCE, nDest ))
3173  pDlg->Insert( SotClipboardFormatId::EMBED_SOURCE, OUString() );
3174  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK_SOURCE, nDest ))
3175  pDlg->Insert( SotClipboardFormatId::LINK_SOURCE, OUString() );
3176  }
3177 
3178  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK, nDest ))
3179  pDlg->Insert( SotClipboardFormatId::LINK, SwResId(STR_DDEFORMAT) );
3180 
3181  for( SotClipboardFormatId* pIds = aPasteSpecialIds; *pIds != SotClipboardFormatId::NONE; ++pIds )
3182  if( SwTransferable::TestAllowedFormat( rData, *pIds, nDest ))
3183  pDlg->Insert( *pIds, OUString() );
3184 }
3185 
3187  const TransferableDataHelper& rData,
3188  SvxClipboardFormatItem & rToFill )
3189 {
3191 
3192  SwTransferable *pClipboard = GetSwTransferable( rData );
3193  if( pClipboard )
3194  {
3195  const char* pResId;
3196  if( pClipboard->m_eBufferType & TransferBufferType::Document )
3197  pResId = STR_PRIVATETEXT;
3198  else if( pClipboard->m_eBufferType & TransferBufferType::Graphic )
3199  pResId = STR_PRIVATEGRAPHIC;
3200  else if( pClipboard->m_eBufferType == TransferBufferType::Ole )
3201  pResId = STR_PRIVATEOLE;
3202  else
3203  pResId = nullptr;
3204 
3205  if (pResId)
3206  rToFill.AddClipbrdFormat(SotClipboardFormatId::EMBED_SOURCE,
3207  SwResId(pResId));
3208  }
3209  else
3210  {
3212  if (rData.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
3213  {
3214  (void)const_cast<TransferableDataHelper&>(rData).GetTransferableObjectDescriptor(
3215  SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc);
3216  }
3217 
3218  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::EMBED_SOURCE, nDest ))
3219  rToFill.AddClipbrdFormat( SotClipboardFormatId::EMBED_SOURCE,
3220  aDesc.maTypeName );
3221  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK_SOURCE, nDest ))
3222  rToFill.AddClipbrdFormat( SotClipboardFormatId::LINK_SOURCE );
3223 
3224  SotClipboardFormatId nFormat;
3225  if ( rData.HasFormat(nFormat = SotClipboardFormatId::EMBED_SOURCE_OLE) || rData.HasFormat(nFormat = SotClipboardFormatId::EMBEDDED_OBJ_OLE) )
3226  {
3227  OUString sName,sSource;
3228  if ( SvPasteObjectHelper::GetEmbeddedName(rData,sName,sSource,nFormat) )
3229  rToFill.AddClipbrdFormat( nFormat, sName );
3230  }
3231  }
3232 
3233  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK, nDest ))
3234  rToFill.AddClipbrdFormat( SotClipboardFormatId::LINK, SwResId(STR_DDEFORMAT) );
3235 
3236  for( SotClipboardFormatId* pIds = aPasteSpecialIds; *pIds != SotClipboardFormatId::NONE; ++pIds )
3237  if( SwTransferable::TestAllowedFormat( rData, *pIds, nDest ))
3238  rToFill.AddClipbrdFormat(*pIds, OUString());
3239 }
3240 
3242 {
3243  if(!m_pWrtShell)
3244  return;
3245  OUString sGrfNm;
3246  const SelectionType nSelection = m_pWrtShell->GetSelectionType();
3247  if( SelectionType::Graphic == nSelection)
3248  {
3249  AddFormat( SotClipboardFormatId::SVXB );
3250  const Graphic* pGrf = m_pWrtShell->GetGraphic();
3251  if ( pGrf && pGrf->IsSupportedGraphic() )
3252  {
3253  AddFormat( SotClipboardFormatId::GDIMETAFILE );
3254  AddFormat( SotClipboardFormatId::PNG );
3255  AddFormat( SotClipboardFormatId::BITMAP );
3256  }
3258  m_pWrtShell->GetGrfNms( &sGrfNm, nullptr );
3259  }
3260  else if( SelectionType::Ole == nSelection )
3261  {
3262  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
3264  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
3265  AddFormat( SotClipboardFormatId::GDIMETAFILE );
3267  }
3268  //Is there anything to provide anyway?
3269  else if ( m_pWrtShell->IsSelection() || m_pWrtShell->IsFrameSelected() ||
3271  {
3272  if( m_pWrtShell->IsObjSelected() )
3274  else
3275  {
3277  if( SwWrtShell::NO_WORD !=
3278  m_pWrtShell->IntelligentCut( nSelection, false ))
3280  }
3281 
3282  if( nSelection & SelectionType::TableCell )
3284 
3285  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
3286 
3287  //put RTF ahead of the OLE's Metafile for less loss
3288  if( !m_pWrtShell->IsObjSelected() )
3289  {
3290  AddFormat( SotClipboardFormatId::RTF );
3291  AddFormat( SotClipboardFormatId::RICHTEXT );
3292  AddFormat( SotClipboardFormatId::HTML );
3293  }
3294  if( m_pWrtShell->IsSelection() )
3295  AddFormat( SotClipboardFormatId::STRING );
3296 
3297  if( nSelection & ( SelectionType::DrawObject | SelectionType::DbForm ))
3298  {
3299  AddFormat( SotClipboardFormatId::DRAWING );
3300  if ( nSelection & SelectionType::DrawObject )
3301  {
3302  AddFormat( SotClipboardFormatId::GDIMETAFILE );
3303  AddFormat( SotClipboardFormatId::PNG );
3304  AddFormat( SotClipboardFormatId::BITMAP );
3305  }
3307 
3308  m_pClpGraphic.reset(new Graphic);
3309  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_pClpGraphic ))
3310  m_pOrigGraphic = m_pClpGraphic.get();
3311  m_pClpBitmap.reset(new Graphic);
3312  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_pClpBitmap ))
3313  m_pOrigGraphic = m_pClpBitmap.get();
3314 
3315  // is it a URL-Button ?
3316  OUString sURL;
3317  OUString sDesc;
3318  if( m_pWrtShell->GetURLFromButton( sURL, sDesc ) )
3319  {
3320  AddFormat( SotClipboardFormatId::STRING );
3321  AddFormat( SotClipboardFormatId::SOLK );
3322  AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
3323  AddFormat( SotClipboardFormatId::FILECONTENT );
3324  AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
3325  AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
3327  }
3328  }
3329 
3330  //ObjectDescriptor was already filled from the old DocShell.
3331  //Now adjust it. Thus in GetData the first query can still
3332  //be answered with delayed rendering.
3333  m_aObjDesc.maDragStartPos = rSttPos;
3335  MapMode(MapUnit::MapTwip), MapMode(MapUnit::Map100thMM));
3337  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
3338  }
3339  else if( nSelection & SelectionType::Text && !m_pWrtShell->HasMark() )
3340  {
3341  // is only one field - selected?
3342  SwContentAtPos aContentAtPos( IsAttrAtPos::InetAttr );
3344 
3345  if( m_pWrtShell->GetContentAtPos( aPos, aContentAtPos ) )
3346  {
3347  AddFormat( SotClipboardFormatId::STRING );
3348  AddFormat( SotClipboardFormatId::SOLK );
3349  AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
3350  AddFormat( SotClipboardFormatId::FILECONTENT );
3351  AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
3352  AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
3354  }
3355  }
3356 
3357  if( m_pWrtShell->IsFrameSelected() )
3358  {
3360  m_pWrtShell->GetFlyFrameAttr( aSet );
3361  const SwFormatURL& rURL = aSet.Get( RES_URL );
3362  if( rURL.GetMap() )
3363  {
3364  m_pImageMap.reset( new ImageMap( *rURL.GetMap() ) );
3365  AddFormat( SotClipboardFormatId::SVIM );
3366  }
3367  else if( !rURL.GetURL().isEmpty() )
3368  {
3369  m_pTargetURL.reset(new INetImage( sGrfNm, rURL.GetURL(),
3370  rURL.GetTargetFrameName() ));
3371  AddFormat( SotClipboardFormatId::INET_IMAGE );
3372  }
3373  }
3374 }
3375 
3376 void SwTransferable::StartDrag( vcl::Window* pWin, const Point& rPos )
3377 {
3378  if(!m_pWrtShell)
3379  return;
3381  m_bCleanUp = true;
3382 
3383  m_pWrtShell->GetViewOptions()->SetIdle( false );
3384 
3385  if( m_pWrtShell->IsSelFrameMode() )
3387 
3388  SW_MOD()->m_pDragDrop = this;
3389 
3390  SetDataForDragAndDrop( rPos );
3391 
3392  sal_Int8 nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK;
3393  SwDocShell* pDShell = m_pWrtShell->GetView().GetDocShell();
3394  if( ( pDShell && pDShell->IsReadOnly() ) || m_pWrtShell->HasReadonlySel() )
3395  nDragOptions &= ~DND_ACTION_MOVE;
3396 
3397  TransferableHelper::StartDrag( pWin, nDragOptions );
3398 }
3399 
3401 {
3402  //And the last finishing work so that all statuses are right
3403  if( DND_ACTION_MOVE == nAction )
3404  {
3405  if( m_bCleanUp )
3406  {
3407  //It was dropped outside of Writer. We still have to
3408  //delete.
3409 
3412  if ( m_pWrtShell->IsTableMode() )
3414  else
3415  {
3417  //SmartCut, take one of the blanks along
3419  m_pWrtShell->DelRight();
3420  }
3423  }
3424  else
3425  {
3426  const SelectionType nSelection = m_pWrtShell->GetSelectionType();
3429  {
3431  }
3432  }
3433  }
3435 
3436  if( m_pWrtShell->IsSelFrameMode() )
3438  else
3440 
3442 }
3443 
3444 namespace
3445 {
3446 
3447 bool lcl_checkClassification(SwDoc* pSourceDoc, SwDoc* pDestinationDoc)
3448 {
3449  if (!pSourceDoc || !pDestinationDoc)
3450  return true;
3451 
3452  SwDocShell* pSourceShell = pSourceDoc->GetDocShell();
3453  SwDocShell* pDestinationShell = pDestinationDoc->GetDocShell();
3454  if (!pSourceShell || !pDestinationShell)
3455  return true;
3456 
3459 }
3460 
3461 }
3462 
3464 {
3465  // first, ask for the SelectionType, then action-bracketing !!!!
3466  // (otherwise it's not pasted into a TableSelection!!!)
3467  OSL_ENSURE( !rShell.ActionPend(), "Paste must never have an ActionPend" );
3468  if ( !m_pClpDocFac )
3469  return false; // the return value of the SwFEShell::Paste also is bool!
3470 
3471  const SelectionType nSelection = rShell.GetSelectionType();
3472 
3473  SwTrnsfrActionAndUndo aAction( &rShell );
3474 
3475  bool bKillPaMs = false;
3476 
3477  //Delete selected content, not at table-selection and table in Clipboard, and don't delete hovering graphics.
3478  if( rShell.HasSelection() && !( nSelection & SelectionType::TableCell) && !( nSelection & SelectionType::DrawObject))
3479  {
3480  bKillPaMs = true;
3481  rShell.SetRetainSelection( true );
3482  if (pContext)
3483  pContext->forget();
3484  rShell.DelRight();
3485  if (pContext)
3486  pContext->remember();
3487  // when a Fly was selected, a valid cursor position has to be found now
3488  // (parked Cursor!)
3490  SelectionType::Ole | SelectionType::DrawObject |
3491  SelectionType::DbForm ) & nSelection )
3492  {
3493  // position the cursor again
3494  Point aPt( rShell.GetCharRect().Pos() );
3495  rShell.SwCursorShell::SetCursor( aPt, true );
3496  }
3497  rShell.SetRetainSelection( false );
3498  }
3499  if ( nSelection & SelectionType::DrawObject) //unselect hovering graphics
3500  {
3501  rShell.ResetSelect(nullptr,false);
3502  }
3503 
3504  bool bInWrd = false, bEndWrd = false, bSttWrd = false,
3506  if( bSmart )
3507  {
3508  // Why not for other Scripts? If TransferBufferType::DocumentWord is set, we have a word
3509  // in the buffer, word in this context means 'something with spaces at beginning
3510  // and end'. In this case we definitely want these spaces to be inserted here.
3511  bInWrd = rShell.IsInWord();
3512  bEndWrd = rShell.IsEndWrd();
3513  bSmart = bInWrd || bEndWrd;
3514  if( bSmart )
3515  {
3516  bSttWrd = rShell.IsStartWord();
3517  if (!bSttWrd && (bInWrd || bEndWrd))
3518  rShell.SwEditShell::Insert(' ');
3519  }
3520  }
3521 
3522  bool bRet = true;
3523  // m_pWrtShell is nullptr when the source document is closed already.
3524  if (!m_pWrtShell || lcl_checkClassification(m_pWrtShell->GetDoc(), rShell.GetDoc()))
3525  bRet = rShell.Paste(m_pClpDocFac->GetDoc());
3526 
3527  if( bKillPaMs )
3528  rShell.KillPams();
3529 
3530  // If Smart Paste then insert blank
3531  if( bRet && bSmart && ((bInWrd && !bEndWrd )|| bSttWrd) )
3532  rShell.SwEditShell::Insert(' ');
3533 
3534  return bRet;
3535 }
3536 
3537 bool SwTransferable::PrivateDrop( SwWrtShell& rSh, const Point& rDragPt,
3538  bool bMove, bool bIsXSelection )
3539 {
3540  int cWord = 0;
3541  bool bInWrd = false;
3542  bool bEndWrd = false;
3543  bool bSttWrd = false;
3544  bool bSttPara = false;
3545  bool bTableSel = false;
3546  bool bFrameSel = false;
3547 
3548  SwWrtShell& rSrcSh = *GetShell();
3549 
3550  rSh.UnSetVisibleCursor();
3551 
3553  {
3554  if( rSh.GetFormatFromObj( rDragPt ) )
3555  {
3556  INetBookmark aTmp;
3558  aTmp = *m_pBookmark;
3559 
3560  // select target graphic
3561  if( rSh.SelectObj( rDragPt ) )
3562  {
3563  rSh.HideCursor();
3564  rSh.EnterSelFrameMode( &rDragPt );
3565  g_bFrameDrag = true;
3566  }
3567 
3568  const SelectionType nSelection = rSh.GetSelectionType();
3569 
3570  // not yet consider Draw objects
3571  if( SelectionType::Graphic & nSelection )
3572  {
3574  rSh.GetFlyFrameAttr( aSet );
3575  SwFormatURL aURL( aSet.Get( RES_URL ) );
3576  aURL.SetURL( aTmp.GetURL(), false );
3577  aSet.Put( aURL );
3578  rSh.SetFlyFrameAttr( aSet );
3579  return true;
3580  }
3581 
3582  if( SelectionType::DrawObject & nSelection )
3583  {
3584  rSh.LeaveSelFrameMode();
3585  rSh.UnSelectFrame();
3586  rSh.ShowCursor();
3587  g_bFrameDrag = false;
3588  }
3589  }
3590  }
3591 
3592  if( &rSh != &rSrcSh && (SelectionType::Graphic & rSh.GetSelectionType()) &&
3594  {
3595  // ReRead the graphic
3596  OUString sGrfNm;
3597  OUString sFltNm;
3598  rSrcSh.GetGrfNms( &sGrfNm, &sFltNm );
3599  rSh.ReRead( sGrfNm, sFltNm, rSrcSh.GetGraphic() );
3600  return true;
3601  }
3602 
3603  //not in selections or selected frames
3604  if( rSh.TestCurrPam( rDragPt ) ||
3605  ( rSh.IsSelFrameMode() && rSh.IsInsideSelectedObj( rDragPt )) )
3606  return false;
3607 
3608  if( rSrcSh.IsTableMode() )
3609  bTableSel = true;
3610  else if( rSrcSh.IsSelFrameMode() || rSrcSh.IsObjSelected() )
3611  {
3612  // don't move position-protected objects!
3614  return false;
3615 
3616  bFrameSel = true;
3617  }
3618 
3619  const SelectionType nSel = rSrcSh.GetSelectionType();
3620 
3622 
3623  SwRewriter aRewriter;
3624 
3625  aRewriter.AddRule(UndoArg1, rSrcSh.GetSelDescr());
3626 
3627  if(rSrcSh.GetDoc() != rSh.GetDoc())
3628  rSrcSh.StartUndo( eUndoId, &aRewriter );
3629  rSh.StartUndo( eUndoId, &aRewriter );
3630 
3631  rSh.StartAction();
3632  rSrcSh.StartAction();
3633 
3634  if( &rSrcSh != &rSh )
3635  {
3636  rSh.EnterStdMode();
3637  rSh.SwCursorShell::SetCursor( rDragPt, true );
3638  cWord = rSrcSh.IntelligentCut( nSel, false );
3639  }
3640  else if( !bTableSel && !bFrameSel )
3641  {
3642  if( !rSh.IsAddMode() )
3643  {
3644  // #i87233#
3645  if ( rSh.IsBlockMode() )
3646  {
3647  // preserve order of cursors for block mode
3648  rSh.GoPrevCursor();
3649  }
3650 
3651  rSh.SwCursorShell::CreateCursor();
3652  }
3653  rSh.SwCursorShell::SetCursor( rDragPt, true, false );
3654  rSh.GoPrevCursor();
3655  cWord = rSh.IntelligentCut( rSh.GetSelectionType(), false );
3656  rSh.GoNextCursor();
3657  }
3658 
3659  bInWrd = rSh.IsInWord();
3660  bEndWrd = rSh.IsEndWrd();
3661  bSttWrd = !bEndWrd && rSh.IsStartWord();
3662  bSttPara= rSh.IsSttPara();
3663 
3665 
3666  // at first, select InetFields!
3668  {
3669  if( &rSrcSh == &rSh )
3670  {
3671  rSh.GoPrevCursor();
3672  rSh.SwCursorShell::SetCursor( aSttPt, true );
3674  if( rSh.TestCurrPam( rDragPt ) )
3675  {
3676  // don't copy/move inside of yourself
3677  rSh.DestroyCursor();
3678  rSh.EndUndo();
3679  rSh.EndAction();
3680  rSh.EndAction();
3681  return false;
3682  }
3683  rSh.GoNextCursor();
3684  }
3685  else
3686  {
3687  rSrcSh.SwCursorShell::SetCursor( aSttPt, true );
3689  }
3690 
3691  // is there a URL attribute at the insert point? Then replace that,
3692  // so simply put up a selection?
3693  rSh.DelINetAttrWithText();
3694  g_bDDINetAttr = true;
3695  }
3696 
3697  if ( rSrcSh.IsSelFrameMode() )
3698  {
3699  //Hack: fool the special treatment
3700  aSttPt = rSrcSh.GetObjRect().Pos();
3701  }
3702 
3703  bool bRet = rSrcSh.SwFEShell::Copy( &rSh, aSttPt, rDragPt, bMove,
3704  !bIsXSelection );
3705 
3706  if( !bIsXSelection )
3707  {
3708  rSrcSh.Push();
3709  if ( bRet && bMove && !bFrameSel )
3710  {
3711  if ( bTableSel )
3712  {
3713  /* delete table contents not cells */
3714  rSrcSh.Delete();
3715  }
3716  else
3717  {
3718  //SmartCut, take one of the blanks along.
3719  rSh.SwCursorShell::DestroyCursor();
3720  if ( cWord == SwWrtShell::WORD_SPACE_BEFORE )
3721  rSh.ExtendSelection( false );
3722  else if ( cWord == SwWrtShell::WORD_SPACE_AFTER )
3723  rSh.ExtendSelection();
3724  rSrcSh.DelRight();
3725  }
3726  }
3727  rSrcSh.KillPams();
3729 
3730  /* after dragging a table selection inside one shell
3731  set cursor to the drop position. */
3732  if( &rSh == &rSrcSh && ( bTableSel || rSh.IsBlockMode() ) )
3733  {
3734  rSrcSh.CalcLayout();
3735  rSrcSh.SwCursorShell::SetCursor(rDragPt);
3736  rSrcSh.GetSwCursor()->SetMark();
3737  }
3738  }
3739 
3740  if( bRet && !bTableSel && !bFrameSel )
3741  {
3742  if( (bInWrd || bEndWrd) &&
3743  (cWord == SwWrtShell::WORD_SPACE_AFTER ||
3744  cWord == SwWrtShell::WORD_SPACE_BEFORE) )
3745  {
3746  if ( bSttWrd || (bInWrd && !bEndWrd))
3747  rSh.SwEditShell::Insert(' ', bIsXSelection);
3748  if ( !bSttWrd || (bInWrd && !bSttPara) )
3749  {
3750  rSh.SwapPam();
3751  if ( !bSttWrd )
3752  rSh.SwEditShell::Insert(' ', bIsXSelection);
3753  rSh.SwapPam();
3754  }
3755  }
3756 
3757  if( bIsXSelection )
3758  {
3759  if( &rSrcSh == &rSh && !rSh.IsAddMode() )
3760  {
3761  rSh.SwCursorShell::DestroyCursor();
3762  rSh.GoPrevCursor();
3763  }
3764  else
3765  {
3766  rSh.SwapPam();
3767  rSh.SwCursorShell::ClearMark();
3768  }
3769  }
3770  else
3771  {
3772  if( rSh.IsAddMode() )
3773  rSh.SwCursorShell::CreateCursor();
3774  else
3775  {
3776  // turn on selection mode
3777  rSh.SttSelect();
3778  rSh.EndSelect();
3779  }
3780  }
3781  }
3782 
3783  if( bRet && bMove && bFrameSel )
3784  rSrcSh.LeaveSelFrameMode();
3785 
3786  if( rSrcSh.GetDoc() != rSh.GetDoc() )
3787  rSrcSh.EndUndo();
3788  rSh.EndUndo();
3789 
3790  // put the shell in the right state
3791  if( &rSrcSh != &rSh && ( rSh.IsFrameSelected() || rSh.IsObjSelected() ))
3792  rSh.EnterSelFrameMode();
3793 
3794  rSrcSh.EndAction();
3795  rSh.EndAction();
3796  return true;
3797 }
3798 
3799 // Interfaces for Selection
3801  const SwFrameShell * _pCreatorView )
3802 {
3803  SwModule *pMod = SW_MOD();
3805 
3806  pNew->m_pCreatorView = _pCreatorView;
3807 
3808  pMod->m_pXSelection = pNew.get();
3809  pNew->CopyToSelection( rSh.GetWin() );
3810 }
3811 
3813  const SwFrameShell * _pCreatorView)
3814 {
3815  SwModule *pMod = SW_MOD();
3816  if( pMod->m_pXSelection &&
3817  ((!pMod->m_pXSelection->m_pWrtShell) || (pMod->m_pXSelection->m_pWrtShell == &rSh)) &&
3818  (!_pCreatorView || (pMod->m_pXSelection->m_pCreatorView == _pCreatorView)) )
3819  {
3821  }
3822 }
3823 
3824 namespace
3825 {
3826  class theSwTransferableUnoTunnelId : public rtl::Static< UnoTunnelIdInit, SwTransferable > {};
3827 }
3828 
3830 {
3831  return theSwTransferableUnoTunnelId::get().getSeq();
3832 }
3833 
3835 {
3836  sal_Int64 nRet;
3837  if( ( rId.getLength() == 16 ) &&
3838  ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
3839  {
3840  nRet = sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ) );
3841  }
3842  else
3844  return nRet;
3845 }
3846 
3848 {
3849  SwTransferable* pSwTransferable = nullptr;
3850 
3851  uno::Reference<XUnoTunnel> xTunnel( rData.GetTransferable(), UNO_QUERY );
3852  if ( xTunnel.is() )
3853  {
3854  sal_Int64 nHandle = xTunnel->getSomething( getUnoTunnelId() );
3855  if ( nHandle )
3856  pSwTransferable = reinterpret_cast<SwTransferable*>( static_cast<sal_IntPtr>(nHandle) );
3857  }
3858 
3859  return pSwTransferable;
3860 
3861 }
3862 
3864  : rTrnsfr(rTrans)
3865  , pDocShell(nullptr)
3866  , nOldTimeOut(0)
3867  , bDelBookmrk(false)
3868  , bInDisconnect(false)
3869 {
3870  // we only end up here with table- or text selection
3872  {
3873  SwFrameFormat* pFormat = rSh.GetTableFormat();
3874  if( pFormat )
3875  sName = pFormat->GetName();
3876  }
3877  else
3878  {
3879  // creating a temp. bookmark without undo
3880  bool bUndo = rSh.DoesUndo();
3881  rSh.DoUndo( false );
3882  bool bIsModified = rSh.IsModified();
3883 
3884  ::sw::mark::IMark* pMark = rSh.SetBookmark(
3885  vcl::KeyCode(),
3886  OUString(),
3888  if(pMark)
3889  {
3890  sName = pMark->GetName();
3891  bDelBookmrk = true;
3892  if( !bIsModified )
3893  rSh.ResetModified();
3894  }
3895  else
3896  sName.clear();
3897  rSh.DoUndo( bUndo );
3898  }
3899 
3900  if( !sName.isEmpty() &&
3901  nullptr != ( pDocShell = rSh.GetDoc()->GetDocShell() ) )
3902  {
3903  // then we create our "server" and connect to it
3905  if( refObj.is() )
3906  {
3907  refObj->AddConnectAdvise( this );
3908  refObj->AddDataAdvise( this,
3909  OUString(),
3911  nOldTimeOut = refObj->GetUpdateTimeout();
3912  refObj->SetUpdateTimeout( 0 );
3913  }
3914  }
3915 }
3916 
3918 {
3919  if( refObj.is() )
3920  Disconnect( true );
3921 }
3922 
3924  const uno::Any& )
3925 {
3926  // well, that's it with the link
3927  if( !bInDisconnect )
3928  {
3929  if( FindDocShell() && pDocShell->GetView() )
3931  Disconnect( false );
3932  }
3933  return SUCCESS;
3934 }
3935 
3937 {
3938  if( !refObj.is() || !FindDocShell() )
3939  return false;
3940 
3941  rtl_TextEncoding eEncoding = DDE_TXT_ENCODING;
3942  const OString aAppNm(OUStringToOString(
3943  Application::GetAppName(), eEncoding));
3944  const OString aTopic(OUStringToOString(
3945  pDocShell->GetTitle(SFX_TITLE_FULLNAME), eEncoding));
3946  const OString aName(OUStringToOString(sName, eEncoding));
3947 
3948  std::unique_ptr<sal_Char[]> pMem(new sal_Char[ aAppNm.getLength() + aTopic.getLength() + aName.getLength() + 4 ]);
3949 
3950  sal_Int32 nLen = aAppNm.getLength();
3951  memcpy( pMem.get(), aAppNm.getStr(), nLen );
3952  pMem[ nLen++ ] = 0;
3953  memcpy( pMem.get() + nLen, aTopic.getStr(), aTopic.getLength() );
3954  nLen = nLen + aTopic.getLength();
3955  pMem[ nLen++ ] = 0;
3956  memcpy( pMem.get() + nLen, aName.getStr(), aName.getLength() );
3957  nLen = nLen + aName.getLength();
3958  pMem[ nLen++ ] = 0;
3959  pMem[ nLen++ ] = 0;
3960 
3961  rStrm.WriteBytes( pMem.get(), nLen );
3962  pMem.reset();
3963 
3964  IDocumentMarkAccess* const pMarkAccess = pDocShell->GetDoc()->getIDocumentMarkAccess();
3965  IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(sName);
3966  if(ppMark != pMarkAccess->getAllMarksEnd()
3968  {
3969  // the mark is still a DdeBookmark
3970  // we replace it with a Bookmark, so it will get saved etc.
3971  ::sw::mark::IMark* const pMark = *ppMark;
3973  SwServerObject& rServerObject = dynamic_cast<SwServerObject&>(*p);
3974 
3975  // collecting state of old mark
3976  SwPaM aPaM(pMark->GetMarkStart());
3977  *aPaM.GetPoint() = pMark->GetMarkStart();
3978  if(pMark->IsExpanded())
3979  {
3980  aPaM.SetMark();
3981  *aPaM.GetMark() = pMark->GetMarkEnd();
3982  }
3983  OUString sMarkName = pMark->GetName();
3984 
3985  // remove mark
3986  rServerObject.SetNoServer(); // this removes the connection between SwServerObject and mark
3987  // N.B. ppMark was not loaded from file and cannot have xml:id
3988  pMarkAccess->deleteMark(ppMark);
3989 
3990  // recreate as Bookmark
3991  ::sw::mark::IMark* const pNewMark = pMarkAccess->makeMark(
3992  aPaM,
3993  sMarkName,
3996  rServerObject.SetDdeBookmark(*pNewMark);
3997  }
3998 
3999  bDelBookmrk = false;
4000  return true;
4001 }
4002 
4003 void SwTrnsfrDdeLink::Disconnect( bool bRemoveDataAdvise )
4004 {
4005  // don't accept DataChanged anymore, when already in Disconnect!
4006  // (DTOR from Bookmark sends a DataChanged!)
4007  bool bOldDisconnect = bInDisconnect;
4008  bInDisconnect = true;
4009 
4010  // destroy the unused bookmark again (without Undo!)?
4011  if( bDelBookmrk && refObj.is() && FindDocShell() )
4012  {
4013  SwDoc* pDoc = pDocShell->GetDoc();
4014  ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
4015 
4016  // #i58448#
4017  Link<bool,void> aSavedOle2Link( pDoc->GetOle2Link() );
4018  pDoc->SetOle2Link( Link<bool,void>() );
4019 
4020  bool bIsModified = pDoc->getIDocumentState().IsModified();
4021 
4022  IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
4023  pMarkAccess->deleteMark(pMarkAccess->findMark(sName));
4024 
4025  if( !bIsModified )
4026  pDoc->getIDocumentState().ResetModified();
4027  // #i58448#
4028  pDoc->SetOle2Link( aSavedOle2Link );
4029 
4030  bDelBookmrk = false;
4031  }
4032 
4033  if( refObj.is() )
4034  {
4035  refObj->SetUpdateTimeout( nOldTimeOut );
4036  refObj->RemoveConnectAdvise( this );
4037  if( bRemoveDataAdvise )
4038  // in a DataChanged the SelectionObject must NEVER be deleted
4039  // is already handled by the base class
4040  // (ADVISEMODE_ONLYONCE!!!!)
4041  // but always in normal Disconnect!
4042  refObj->RemoveAllDataAdvise( this );
4043  refObj.clear();
4044  }
4045  bInDisconnect = bOldDisconnect;
4046 }
4047 
4049 {
4050  SfxObjectShell* pTmpSh = SfxObjectShell::GetFirst( checkSfxObjectShell<SwDocShell> );
4051  while( pTmpSh )
4052  {
4053  if( pTmpSh == pDocShell ) // that's what we want to have
4054  {
4055  if( pDocShell->GetDoc() )
4056  return true;
4057  break; // the Doc is not there anymore, so leave!
4058  }
4059  pTmpSh = SfxObjectShell::GetNext( *pTmpSh, checkSfxObjectShell<SwDocShell> );
4060  }
4061 
4062  pDocShell = nullptr;
4063  return false;
4064 }
4065 
4067 {
4068  if( !bInDisconnect && refObj.is() )
4069  {
4070  refObj->RemoveAllDataAdvise( this );
4071  refObj->RemoveConnectAdvise( this );
4072  refObj.clear();
4073  }
4074 }
4075 
4076 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwFieldType * GetFieldType(size_t nField, SwFieldIds nResId=SwFieldIds::Unknown) const
get field types with a ResId, if 0 get all
Definition: edfld.cxx:68
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
SfxViewFrame * GetViewFrame() const
bool UnloadObject()
Definition: ndole.cxx:958
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:233
long Width() const
bool is() const
void StopShellTimer()
Definition: view.cxx:1757
SwWrtShell * GetShell()
Definition: swdtflvr.hxx:209
#define EXCHG_IN_ACTION_COPY
#define FN_DB_CONNECTION_ANY
Definition: cmdid.h:711
#define FN_DB_DATA_SOURCE_ANY
Definition: cmdid.h:713
bool GetGraphic(SotClipboardFormatId nFormat, Graphic &rGraphic)
virtual void SetVisArea(const tools::Rectangle &rVisArea)
const ::utl::TransliterationWrapper & GetAppCmpStrIgnore()
Definition: init.cxx:834
bool SetINetImage(const INetImage &rINtImg, const css::datatransfer::DataFlavor &rFlavor)
static OUString GetAppName()
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 * >())
#define EXCHG_IN_ACTION_MOVE
void KillPams()
Definition: crsrsh.cxx:1010
void SetDataForDragAndDrop(const Point &rSttPos)
Definition: swdtflvr.cxx:3241
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
static SwTransferable * GetSwTransferable(const TransferableDataHelper &rData)
Definition: swdtflvr.cxx:3847
bool hasValue()
SwTransferable(const SwTransferable &)=delete
static bool PasteAsHyperlink(TransferableDataHelper &rData, SwWrtShell &rSh, SotClipboardFormatId nFormat)
Definition: swdtflvr.cxx:2726
#define RES_URL
Definition: hintids.hxx:216
#define EXCHG_OUT_ACTION_INSERT_STRING
virtual const OUString & GetName() const =0
Marks a position in the document model.
Definition: pam.hxx:35
SwTransferable * m_pXSelection
Definition: swmodule.hxx:128
TransferableObjectDescriptor m_aObjDesc
Definition: swdtflvr.hxx:67
css::uno::Any GetAny(SotClipboardFormatId nFormat, const OUString &rDestDoc) const
bool SetBitmapEx(const BitmapEx &rBitmap, const css::datatransfer::DataFlavor &rFlavor)
SdrView * GetDrawView()
Definition: vnew.cxx:376
void AutoCaption(const sal_uInt16 nType, const SvGlobalName *pOleId=nullptr)
Definition: viewdlg2.cxx:135
virtual bool DoSaveCompleted(SfxMedium *pNewStor=nullptr, bool bRegisterRecent=true)
#define ADVISEMODE_NODATA
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:185
const OUString & GetImageURL() const
virtual ::sfx2::SvLinkSource * DdeCreateLinkSource(const OUString &rItem) override
Definition: docsh2.cxx:1358
void SaveTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:873
void InsertDDETable(const SwInsertTableOptions &rInsTableOpts, SwDDEFieldType *pDDEType, sal_uInt16 nRows, sal_uInt16 nCols)
Definition: edtab.cxx:212
tools::SvRef< sfx2::SvBaseLink > m_xDdeLink
Definition: swdtflvr.hxx:68
SAL_DLLPRIVATE void SetProtectFlag(bool const bFlag)
Definition: section.hxx:106
void SetLinkFileName(OUString const &rNew)
Definition: section.hxx:118
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 ReRead(const OUString &rGrfName, const OUString &rFltName, const Graphic *pGraphic=nullptr)
Re-read if graphic is not ok. Current graphic is replaced by the new one.
Definition: editsh.cxx:300
std::unique_ptr< SwPaM > m_pPaM
Definition: swdtflvr.cxx:208
bool GoNextCursor()
go to the next SSelection
Definition: crsrsh.cxx:1345
SwUndoId
Definition: swundo.hxx:29
SwDocShell * GetDocShell()
Definition: doc.hxx:1340
bool g_bExecuteDrag
Definition: edtdd.cxx:48
bool GetURLFromButton(OUString &rURL, OUString &rDescr) const
Definition: wrtsh3.cxx:202
void ReadGraphic(SvStream &rIStream, Graphic &rGraphic)
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
const OUString & GetTargetURL() const
void AddTransferable(SwTransferable &rTransferable)
Definition: view.cxx:1851
constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_DRAWMODEL
Definition: swdtflvr.cxx:152
const SfxObjectShellLock & GetTmpDocShell()
Definition: doc.hxx:1347
long Height() const
signed char sal_Int8
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsTableMode() const
Definition: crsrsh.hxx:645
bool IsSttPara() const
Definition: crsrsh.cxx:1083
void Copy(SwDoc *pClpDoc, const OUString *pNewClpText=nullptr)
Copy and Paste methods for internal clipboard.
Definition: fecopy.cxx:84
bool Is() const
#define FN_TABLE_DELETE_TABLE
Definition: cmdid.h:353
static sal_uInt8 GetExchangeAction(const DataFlavorExVector &rDataFlavorExVector, SotExchangeDest nDestination, sal_uInt16 nSourceOptions, sal_uInt8 nUserAction, SotClipboardFormatId &rFormat, sal_uInt8 &rDefaultAction, SotClipboardFormatId nOnlyTestFormat=SotClipboardFormatId::NONE, const css::uno::Reference< css::datatransfer::XTransferable > *pxTransferable=nullptr, SotExchangeActionFlags *pActionFlags=nullptr)
SfxDispatcher * GetDispatcher()
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
int PrepareForCopy(bool bIsCut=false)
Definition: swdtflvr.cxx:809
static bool IsPaste(const SwWrtShell &, const TransferableDataHelper &)
Definition: swdtflvr.cxx:1230
::std::vector< DataFlavorEx > DataFlavorExVector
sal_uIntPtr sal_uLong
constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_RICHTEXT
Definition: swdtflvr.cxx:158
void SetPrefMapMode(const MapMode &rPrefMapMode)
Size GetObjSize() const
Definition: feshview.cxx:2310
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:483
bool PrivateDrop(SwWrtShell &rSh, const Point &rDragPt, bool bMove, bool bIsXSelection)
Definition: swdtflvr.cxx:3537
const SfxPoolItem * pAttr
Definition: crsrsh.hxx:100
#define DDE_TXT_ENCODING
Definition: swdtflvr.cxx:165
bool Pop(SwCursorShell::PopMode=SwCursorShell::PopMode::DeleteStack)
Definition: wrtsh1.cxx:1697
bool SetTransferableObjectDescriptor(const TransferableObjectDescriptor &rDesc)
#define EXCHG_OUT_ACTION_INSERT_DDE
#define CNT_HasGrf(USH)
Definition: editsh.hxx:137
bool IsModified() const
Changes in document?
Definition: edws.cxx:64
#define SOFFICE_FILEFORMAT_CURRENT
static void PrePasteSpecial(SwWrtShell &rSh, TransferableDataHelper &, VclPtr< SfxAbstractPasteDialog > &pDlg)
PrePasteSpecial Prepares the given dialog without actually running it.
Definition: swdtflvr.cxx:3128
css::uno::Reference< css::document::XDocumentProperties > getDocProperties()
Provides access to the marks of a document.
void SetChgLnk(const Link< SwCursorShell *, void > &rLnk)
Definition: crsrsh.hxx:485
static bool PasteFileList(TransferableDataHelper &rData, SwWrtShell &rSh, bool bLink, const Point *pPt, bool bMsg)
Definition: swdtflvr.cxx:2966
static bool PasteFormat(SwWrtShell &rSh, TransferableDataHelper &rData, SotClipboardFormatId nFormat)
Definition: swdtflvr.cxx:3039
SwSection const * InsertSection(SwSectionData &rNewData, SfxItemSet const *const =nullptr)
Definition: edsect.cxx:35
bool IsSupportedGraphic() const
SwCursor * GetSwCursor() const
Definition: crsrsh.hxx:866
Definition: doc.hxx:185
bool HasFormat(SotClipboardFormatId nFormat)
void SetOle2Link(const Link< bool, void > &rLink)
Definition: doc.hxx:1316
SVL_DLLPUBLIC OUString removePassword(OUString const &rURI, INetURLObject::EncodeMechanism eEncodeMechanism, INetURLObject::DecodeMechanism eDecodeMechanism=INetURLObject::DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
OUString GetUniqueSectionName(const OUString *pChkStr=nullptr) const
Definition: ndsect.cxx:1356
static bool CheckForURLOrLNKFile(TransferableDataHelper &rData, OUString &rFileName, OUString *pTitle=nullptr)
Definition: swdtflvr.cxx:3008
aBuf
#define EXCHG_OUT_ACTION_REPLACE_SVXB
comphelper::OInterfaceContainerHelper2 & GetPasteListeners()
Definition: fecopy.cxx:1180
sal_Int16 nId