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>
37 #include <comphelper/string.hxx>
38 #include <o3tl/deleter.hxx>
40 #include <sot/filelist.hxx>
41 #include <svx/svxdlg.hxx>
43 #include <osl/endian.h>
44 #include <sfx2/linkmgr.hxx>
45 #include <tools/urlobj.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 <sfx2/mieclip.hxx>
59 #include <svl/urlbmk.hxx>
60 #include <vcl/inetimg.hxx>
61 #include <svx/fmview.hxx>
62 #include <sfx2/docfilt.hxx>
63 #include <vcl/imapobj.hxx>
64 #include <sfx2/docfile.hxx>
66 #include <unotools/streamwrap.hxx>
67 #include <vcl/graphicfilter.hxx>
68 
69 #ifdef _WIN32
70 #include <prewin.h>
71 #include <postwin.h>
73 #include <osl/file.hxx>
74 #endif
75 
76 #include <svx/unomodel.hxx>
77 #include <fmturl.hxx>
78 #include <fmtinfmt.hxx>
79 #include <swdtflvr.hxx>
80 #include <shellio.hxx>
81 #include <ddefld.hxx>
82 #include <doc.hxx>
83 #include <IDocumentUndoRedo.hxx>
87 #include <IDocumentState.hxx>
88 #include <IMark.hxx>
89 #include <section.hxx>
90 #include <ndtxt.hxx>
91 #include <edtdd.hxx>
92 #include <edtwin.hxx>
93 #include <navicont.hxx>
94 #include <swcont.hxx>
95 #include <wrtsh.hxx>
96 #include <swmodule.hxx>
97 #include <view.hxx>
98 #include <docsh.hxx>
99 #include <wdocsh.hxx>
100 #include <fldbas.hxx>
101 #include <swundo.hxx>
102 #include <pam.hxx>
103 #include <ndole.hxx>
104 #include <swwait.hxx>
105 #include <viewopt.hxx>
106 #include <SwCapObjType.hxx>
107 #include <cmdid.h>
108 #include <strings.hrc>
109 #include <svx/svditer.hxx>
110 #include <editeng/eeitem.hxx>
111 #include <editeng/fhgtitem.hxx>
112 #include <editeng/prntitem.hxx>
113 #include <svx/svdpage.hxx>
114 #include <avmedia/mediawindow.hxx>
115 #include <swcrsr.hxx>
116 #include <SwRewriter.hxx>
117 #include <vcl/svapp.hxx>
118 #include <swserv.hxx>
119 #include <fmtmeta.hxx>
120 #include <itabenum.hxx>
121 #include <iodetect.hxx>
122 #include <unotextrange.hxx>
123 #include <unoframe.hxx>
124 #include <txatbase.hxx>
125 #include <vcl/uitest/logger.hxx>
127 
130 #include <vcl/TypeSerializer.hxx>
131 #include <comphelper/lok.hxx>
133 #include <sfx2/sfxdlg.hxx>
134 #include <comphelper/classids.hxx>
135 #include <osl/diagnose.h>
136 
137 #include <memory>
138 
139 /* default (A4 format) width of 210mm - 2 * border size (border on both sides) */
141 
142 constexpr Size constOleSize100mm(
143  constOleWidthInMm * 100, // convert from mm to 100mm
144  3000 // 3 cm
145 );
146 
148 
149 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_DRAWMODEL = 0x00000001;
150 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_HTML = 0x00000002;
151 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_RTF = 0x00000004;
152 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_STRING = 0x00000008;
153 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_SWOLE = 0x00000010;
154 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_DDE = 0x00000020;
155 constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_RICHTEXT = 0x00000040;
156 
157 using namespace ::svx;
158 using namespace ::com::sun::star;
159 using namespace ::com::sun::star::uno;
160 using namespace ::com::sun::star::datatransfer;
161 namespace {
162 
163 void collectUIInformation(const OUString& rAction, const OUString& aParameters)
164 {
165  EventDescription aDescription;
166  aDescription.aAction = rAction;
167  aDescription.aParameters = {{"parameters", aParameters}};
168  aDescription.aID = "writer_edit";
169  aDescription.aKeyWord = "SwEditWinUIObject";
170  aDescription.aParent = "MainWindow";
171  UITestLogger::getInstance().logEvent(aDescription);
172 }
173 
174 }
175 
176 namespace {
177 
178 class SwTransferDdeLink : public ::sfx2::SvBaseLink
179 {
180  OUString m_sName;
181  ::sfx2::SvLinkSourceRef m_xRefObj;
182  SwTransferable& m_rTransfer;
183  SwDocShell* m_pDocShell;
184  sal_uLong m_nOldTimeOut;
185  bool m_bDelBookmark : 1;
186  bool m_bInDisconnect : 1;
187 
188  bool FindDocShell();
189 
191 
192 protected:
193  virtual ~SwTransferDdeLink() override;
194 
195 public:
196  SwTransferDdeLink( SwTransferable& rTrans, SwWrtShell& rSh );
197 
198  virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
199  const OUString& rMimeType, const css::uno::Any & rValue ) override;
200  virtual void Closed() override;
201 
202  bool WriteData( SvStream& rStrm );
203 
204  void Disconnect( bool bRemoveDataAdvise );
205 };
206 
207 }
208 
211 {
212 public:
213  SwPasteContext(SwWrtShell& rWrtShell);
214  ~SwPasteContext();
215 
216  void remember();
217  void forget();
218 
219 private:
221  std::unique_ptr<SwPaM> m_pPaM;
222  sal_Int32 m_nStartContent = 0;
223 };
224 
225 namespace {
226 
227 // helper class for Action and Undo enclosing
228 class SwTrnsfrActionAndUndo
229 {
230  SwWrtShell *pSh;
231 public:
232  SwTrnsfrActionAndUndo( SwWrtShell *pS, bool bDelSel = false, SwPasteContext* pContext = nullptr)
233  : pSh( pS )
234  {
236  if( bDelSel )
237  {
238  if (pContext)
239  pContext->forget();
240  pSh->DelRight();
241  if (pContext)
242  pContext->remember();
243  }
244  pSh->StartAllAction();
245  }
246  ~SwTrnsfrActionAndUndo() COVERITY_NOEXCEPT_FALSE
247  {
248  pSh->EndUndo();
249  pSh->EndAllAction();
250  }
251 };
252 
253 }
254 
256  : m_pWrtShell( &rSh ),
257  m_pCreatorView( nullptr ),
258  m_pOrigGraphic( nullptr ),
259  m_eBufferType( TransferBufferType::NONE ),
260  m_bOldIdle(false),
261  m_bCleanUp(false)
262 {
263  rSh.GetView().AddTransferable(*this);
264  SwDocShell* pDShell = rSh.GetDoc()->GetDocShell();
265  if( !pDShell )
266  return;
267 
269  if( pDShell->GetMedium() )
270  {
271  const INetURLObject& rURLObj = pDShell->GetMedium()->GetURLObject();
276  }
277 
279 }
280 
282 {
283  SolarMutexGuard aSolarGuard;
284 
285  // the DDELink still needs the WrtShell!
286  if( m_xDdeLink.is() )
287  {
288  static_cast<SwTransferDdeLink*>( m_xDdeLink.get() )->Disconnect( true );
289  m_xDdeLink.clear();
290  }
291 
292  m_pWrtShell = nullptr;
293 
294  // release reference to the document so that aDocShellRef will delete
295  // it (if aDocShellRef is set). Otherwise, the OLE nodes keep references
296  // to their sub-storage when the storage is already dead.
297  m_pClpDocFac.reset();
298 
299  // first close, then the Ref. can be cleared as well, so that
300  // the DocShell really gets deleted!
301  if( m_aDocShellRef.Is() )
302  {
304  SwDocShell* pDocSh = static_cast<SwDocShell*>(pObj);
305  pDocSh->DoClose();
306  }
308 
309  SwModule* pMod = SW_MOD();
310  if(pMod)
311  {
312  if ( pMod->m_pDragDrop == this )
313  pMod->m_pDragDrop = nullptr;
314  else if ( pMod->m_pXSelection == this )
315  pMod->m_pXSelection = nullptr;
316  }
317 
319 }
320 
321 static SwDoc& lcl_GetDoc(SwDocFac & rDocFac)
322 {
323  SwDoc& rDoc = rDocFac.GetDoc();
324  rDoc.SetClipBoard( true );
325  return rDoc;
326 }
327 
329 {
330  SwModule *pMod = SW_MOD();
331  if (!pMod)
332  return;
333  if( this == pMod->m_pDragDrop )
334  pMod->m_pDragDrop = nullptr;
335  else if( this == pMod->m_pXSelection )
336  pMod->m_pXSelection = nullptr;
337 }
338 
340 {
341  // only need if we are the current XSelection Object
342  SwModule *pMod = SW_MOD();
344  {
345  SetDataForDragAndDrop( Point( 0,0) );
346  }
347 }
348 
350 {
351  //set OleVisArea. Upper left corner of the page and size of
352  //RealSize in Twips.
353  const Size aSz(constOleSizeTwip);
354  SwRect aVis( Point( DOCUMENTBORDER, DOCUMENTBORDER ), aSz );
355  pDoc->SetVisArea( aVis.SVRect() );
356 }
357 
358 uno::Reference < embed::XEmbeddedObject > SwTransferable::FindOLEObj( sal_Int64& nAspect ) const
359 {
360  uno::Reference < embed::XEmbeddedObject > xObj;
361  if( m_pClpDocFac )
362  {
363  SwIterator<SwContentNode,SwFormatColl> aIter( *m_pClpDocFac->GetDoc().GetDfltGrfFormatColl() );
364  for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
365  if( SwNodeType::Ole == pNd->GetNodeType() )
366  {
367  xObj = static_cast<SwOLENode*>(pNd)->GetOLEObj().GetOleRef();
368  nAspect = static_cast<SwOLENode*>(pNd)->GetAspect();
369  break;
370  }
371  }
372  return xObj;
373 }
374 
376 {
377  if( m_pClpDocFac )
378  {
379  SwIterator<SwContentNode,SwFormatColl> aIter( *m_pClpDocFac->GetDoc().GetDfltGrfFormatColl() );
380  for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
381  if( SwNodeType::Ole == pNd->GetNodeType() )
382  {
383  return static_cast<SwOLENode*>(pNd)->GetGraphic();
384  }
385  }
386 
387  return nullptr;
388 }
389 
391 {
392  RemoveFormat( SotClipboardFormatId::LINK );
393  CopyToClipboard(&rWin);
394 }
395 
396 namespace
397 {
398  //Resolves: fdo#40717 surely when we create a clipboard document we should
399  //overwrite the clipboard documents styles and settings with that of the
400  //source, so that we can WYSIWYG paste. If we want that the destinations
401  //styles are used over the source styles, that's a matter of the
402  //destination paste code to handle, not the source paste code.
403  void lclOverWriteDoc(SwWrtShell &rSrcWrtShell, SwDoc &rDest)
404  {
405  const SwDoc &rSrc = *rSrcWrtShell.GetDoc();
406 
407  rDest.ReplaceCompatibilityOptions(rSrc);
408  rDest.ReplaceDefaults(rSrc);
409 
410  //It would probably make most sense here to only insert the styles used
411  //by the selection, e.g. apply SwDoc::IsUsed on styles ?
412  rDest.ReplaceStyles(rSrc, false);
413 
414  rSrcWrtShell.Copy(rDest);
415 
417  }
418 
419  void lclCheckAndPerformRotation(Graphic& aGraphic)
420  {
421  GraphicNativeMetadata aMetadata;
422  if ( !aMetadata.read(aGraphic) )
423  return;
424 
425  Degree10 aRotation = aMetadata.getRotation();
426  if (aRotation)
427  {
428  GraphicNativeTransform aTransform( aGraphic );
429  aTransform.rotate( aRotation );
430  }
431  }
432 }
433 
435 {
436  sal_Int32 nTextLength = 0;
437  SwNodes& aNodes = m_pWrtShell->GetDoc()->GetNodes();
438  for (SwPaM& rPaM : m_pWrtShell->GetCursor()->GetRingContainer())
439  {
440  for (SwNodeOffset nIndex = rPaM.GetMark()->nNode.GetIndex();
441  nIndex <= rPaM.GetPoint()->nNode.GetIndex(); ++nIndex)
442  {
443  SwNode& rNd = *aNodes[nIndex];
444 
445  SwTextNode* pTextNode = rNd.GetTextNode();
446  if (pTextNode)
447  {
448  if (pTextNode->HasHints())
449  {
450  for (size_t nHint = 0; nHint < pTextNode->GetSwpHints().Count(); ++nHint)
451  {
452  SwTextAttr* pHint = pTextNode->GetSwpHints().Get(nHint);
453  if (pHint->Which() == RES_TXTATR_FLYCNT)
454  {
455  return true; // Complex
456  }
457  }
458  }
459 
460  nTextLength += pTextNode->GetText().getLength();
461  if (nTextLength >= 1024 * 512)
462  return true; // Complex
463  }
464  }
465  }
466 
468  return true; // Complex
469 
470  // Simple
471  return false;
472 }
473 
474 bool SwTransferable::GetData( const DataFlavor& rFlavor, const OUString& rDestDoc )
475 {
476  SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
477 
478  // we can only fulfil the request if
479  // 1) we have data for this format
480  // 2) we have either a clipboard document (pClpDocFac), or
481  // we have a SwWrtShell (so we can generate a new clipboard document)
482  if( !HasFormat( nFormat ) || ( m_pClpDocFac == nullptr && m_pWrtShell == nullptr ) )
483  return false;
484 
485  if( !m_pClpDocFac )
486  {
487  SelectionType nSelectionType = m_pWrtShell->GetSelectionType();
488 
489  // when pending we will not get the correct type, but SelectionType::Text
490  // as fallback. This *happens* during D&D, so we need to check if we are in
491  // the fallback and just try to get a graphic
492  const bool bPending(m_pWrtShell->ActionPend());
493 
494  // SEL_GRF is from ContentType of editsh
495  if(bPending || ((SelectionType::Graphic | SelectionType::DrawObject | SelectionType::DbForm) & nSelectionType))
496  {
497  m_pClpGraphic.reset(new Graphic);
498  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_pClpGraphic ))
500  m_pClpBitmap.reset(new Graphic);
501  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_pClpBitmap ))
503 
504  // is it a URL-Button ?
505  OUString sURL;
506  OUString sDesc;
507  if( m_pWrtShell->GetURLFromButton( sURL, sDesc ) )
508  {
509  m_pBookmark.reset(new INetBookmark( sURL, sDesc ));
511  }
512  }
513 
514  m_pClpDocFac.reset(new SwDocFac);
515  SwDoc& rTmpDoc = lcl_GetDoc(*m_pClpDocFac);
516 
517  rTmpDoc.getIDocumentFieldsAccess().LockExpFields(); // never update fields - leave text as it is
518  lclOverWriteDoc(*m_pWrtShell, rTmpDoc);
519 
520  // in CORE a new one was created (OLE-objects copied!)
521  m_aDocShellRef = rTmpDoc.GetTmpDocShell();
522  if( m_aDocShellRef.Is() )
524  rTmpDoc.SetTmpDocShell( nullptr );
525 
526  if( nSelectionType & SelectionType::Text && !m_pWrtShell->HasMark() )
527  {
528  SwContentAtPos aContentAtPos( IsAttrAtPos::InetAttr );
529 
531 
532  bool bSelect = g_bExecuteDrag &&
535  if( m_pWrtShell->GetContentAtPos( aPos, aContentAtPos, bSelect ) )
536  {
537  m_pBookmark.reset(new INetBookmark(
538  static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr)->GetValue(),
539  aContentAtPos.sStr ));
541  if( bSelect )
543  }
544  }
546  {
548  m_pWrtShell->GetFlyFrameAttr( aSet );
549  const SwFormatURL& rURL = aSet.Get( RES_URL );
550  if( rURL.GetMap() )
551  m_pImageMap.reset(new ImageMap( *rURL.GetMap() ));
552  else if( !rURL.GetURL().isEmpty() )
553  m_pTargetURL.reset(new INetImage(OUString(), rURL.GetURL(),
554  rURL.GetTargetFrameName() ));
555  }
556  }
557 
558  bool bOK = false;
560  {
561  //TODO/MBA: testing - is this the "single OLE object" case?!
562  // get OLE-Object from ClipDoc and get the data from that.
563  sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT; // will be set in the next statement
564  uno::Reference < embed::XEmbeddedObject > xObj = FindOLEObj( nAspect );
565  const Graphic* pOLEGraph = FindOLEReplacementGraphic();
566  if( xObj.is() )
567  {
568  TransferableDataHelper aD( new SvEmbedTransferHelper( xObj, pOLEGraph, nAspect ) );
569  uno::Any aAny = aD.GetAny(rFlavor, rDestDoc);
570  if( aAny.hasValue() )
571  bOK = SetAny( aAny );
572  }
573 
574  // the following solution will be used in the case when the object can not generate the image
575  // TODO/LATER: in future the transferhelper must probably be created based on object and the replacement stream
576  // TODO: Block not required now, SvEmbedTransferHelper should be able to handle GDIMetaFile format
577  if ( nFormat == SotClipboardFormatId::GDIMETAFILE )
578  {
579  pOLEGraph = FindOLEReplacementGraphic();
580  if ( pOLEGraph )
581  bOK = SetGDIMetaFile( pOLEGraph->GetGDIMetaFile() );
582  }
583  }
584  else
585  {
586  switch( nFormat )
587  {
588  case SotClipboardFormatId::LINK:
589  if( m_xDdeLink.is() )
590  bOK = SetObject( m_xDdeLink.get(), SWTRANSFER_OBJECTTYPE_DDE, rFlavor );
591  break;
592 
593  case SotClipboardFormatId::OBJECTDESCRIPTOR:
594  case SotClipboardFormatId::LINKSRCDESCRIPTOR:
596  break;
597 
598  case SotClipboardFormatId::DRAWING:
599  {
600  SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
603  }
604  break;
605 
606  case SotClipboardFormatId::STRING:
607  {
608  SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
609  bOK = SetObject( &rDoc, SWTRANSFER_OBJECTTYPE_STRING, rFlavor );
610  }
611  break;
612  case SotClipboardFormatId::RTF:
613  {
614  SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
615  bOK = SetObject( &rDoc, SWTRANSFER_OBJECTTYPE_RTF, rFlavor );
616  }
617  break;
618  case SotClipboardFormatId::RICHTEXT:
619  {
620  SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
621  bOK = SetObject( &rDoc, SWTRANSFER_OBJECTTYPE_RICHTEXT, rFlavor );
622  }
623  break;
624 
625  case SotClipboardFormatId::HTML:
626  {
627  SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
628  bOK = SetObject( &rDoc, SWTRANSFER_OBJECTTYPE_HTML, rFlavor );
629  }
630  break;
631 
632  case SotClipboardFormatId::SVXB:
634  bOK = SetGraphic( *m_pOrigGraphic );
635  break;
636 
637  case SotClipboardFormatId::GDIMETAFILE:
639  bOK = SetGDIMetaFile( m_pClpGraphic->GetGDIMetaFile() );
640  break;
641  case SotClipboardFormatId::BITMAP:
642  case SotClipboardFormatId::PNG:
643  // Neither pClpBitmap nor pClpGraphic are necessarily set
644  if( (m_eBufferType & TransferBufferType::Graphic) && (m_pClpBitmap != nullptr || m_pClpGraphic != nullptr))
646  break;
647 
648  case SotClipboardFormatId::SVIM:
649  if( m_pImageMap )
650  bOK = SetImageMap( *m_pImageMap );
651  break;
652 
653  case SotClipboardFormatId::INET_IMAGE:
654  if( m_pTargetURL )
655  bOK = SetINetImage( *m_pTargetURL, rFlavor );
656  break;
657 
658  case SotClipboardFormatId::SOLK:
659  case SotClipboardFormatId::NETSCAPE_BOOKMARK:
660  case SotClipboardFormatId::FILEGRPDESCRIPTOR:
661  case SotClipboardFormatId::FILECONTENT:
662  case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
663  case SotClipboardFormatId::SIMPLE_FILE:
665  bOK = SetINetBookmark( *m_pBookmark, rFlavor );
666  break;
667 
668  case SotClipboardFormatId::EMBED_SOURCE:
669  if( !m_aDocShellRef.Is() )
670  {
671  SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
672  SwDocShell* pNewDocSh = new SwDocShell( rDoc,
673  SfxObjectCreateMode::EMBEDDED );
674  m_aDocShellRef = pNewDocSh;
677  }
679  rFlavor );
680  break;
681  default: break;
682  }
683  }
684  return bOK;
685 }
686 
688  void* pObject, sal_uInt32 nObjectType,
689  const DataFlavor& /*rFlavor*/ )
690 {
691  bool bRet = false;
692  WriterRef xWrt;
693 
694  switch( nObjectType )
695  {
697  {
698  // don't change the sequence of commands
699  SdrModel *pModel = static_cast<SdrModel*>(pObject);
700  xStream->SetBufferSize( 16348 );
701 
702  // for the changed pool defaults from drawing layer pool set those
703  // attributes as hard attributes to preserve them for saving
704  const SfxItemPool& rItemPool = pModel->GetItemPool();
705  const SvxFontHeightItem& rDefaultFontHeight = rItemPool.GetDefaultItem(EE_CHAR_FONTHEIGHT);
706 
707  // SW should have no MasterPages
708  OSL_ENSURE(0 == pModel->GetMasterPageCount(), "SW with MasterPages (!)");
709 
710  for(sal_uInt16 a(0); a < pModel->GetPageCount(); a++)
711  {
712  const SdrPage* pPage = pModel->GetPage(a);
713  SdrObjListIter aIter(pPage, SdrIterMode::DeepNoGroups);
714 
715  while(aIter.IsMore())
716  {
717  SdrObject* pObj = aIter.Next();
718  const SvxFontHeightItem& rItem = pObj->GetMergedItem(EE_CHAR_FONTHEIGHT);
719 
720  if(rItem.GetHeight() == rDefaultFontHeight.GetHeight())
721  {
722  pObj->SetMergedItem(rDefaultFontHeight);
723  }
724  }
725  }
726 
727  {
728  uno::Reference<io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *xStream ) );
729  SvxDrawingLayerExport( pModel, xDocOut );
730  }
731 
732  bRet = ERRCODE_NONE == xStream->GetError();
733  }
734  break;
735 
737  {
738  SfxObjectShell* pEmbObj = static_cast<SfxObjectShell*>(pObject);
739  try
740  {
741  ::utl::TempFile aTempFile;
742  aTempFile.EnableKillingFile();
743  uno::Reference< embed::XStorage > xWorkStore =
744  ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
745 
746  // write document storage
747  pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
748  // mba: no BaseURL for clipboard
749  SfxMedium aMedium( xWorkStore, OUString() );
750  pEmbObj->DoSaveObjectAs( aMedium, false );
751  pEmbObj->DoSaveCompleted();
752 
753  uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
754  if ( xTransact.is() )
755  xTransact->commit();
756 
757  std::unique_ptr<SvStream> pSrcStm(::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), StreamMode::READ ));
758  if( pSrcStm )
759  {
760  xStream->SetBufferSize( 0xff00 );
761  xStream->WriteStream( *pSrcStm );
762  pSrcStm.reset();
763  }
764 
765  xWorkStore->dispose();
766  xWorkStore.clear();
767  }
768  catch (const uno::Exception&)
769  {
770  }
771 
772  bRet = ( xStream->GetError() == ERRCODE_NONE );
773  }
774  break;
775 
777  {
778  xStream->SetBufferSize( 1024 );
779  SwTransferDdeLink* pDdeLnk = static_cast<SwTransferDdeLink*>(pObject);
780  if( pDdeLnk->WriteData( *xStream ) )
781  {
782  bRet = ERRCODE_NONE == xStream->GetError();
783  }
784  }
785  break;
786 
788  {
789  // LOK is interested in getting images embedded for copy/paste support.
790  GetHTMLWriter( comphelper::LibreOfficeKit::isActive() ? OUString("EmbedImages;NoLineLimit") : OUString(), OUString(), xWrt );
791  break;
792  }
793 
796  GetRTFWriter(std::u16string_view(), OUString(), xWrt);
797  break;
798 
800  GetASCWriter(std::u16string_view(), OUString(), xWrt);
801  if( xWrt.is() )
802  {
803  SwAsciiOptions aAOpt;
804  aAOpt.SetCharSet( RTL_TEXTENCODING_UTF8 );
805  xWrt->SetAsciiOptions( aAOpt );
806 
807  // no start char for clipboard
808  xWrt->m_bUCS2_WithStartChar = false;
809  }
810  break;
811  default: break;
812  }
813 
814  if( xWrt.is() )
815  {
816  SwDoc* pDoc = static_cast<SwDoc*>(pObject);
817  xWrt->m_bWriteClipboardDoc = true;
818  xWrt->m_bWriteOnlyFirstTable = bool(TransferBufferType::Table & m_eBufferType);
819  xWrt->SetShowProgress(false);
820 
821 #if defined(DEBUGPASTE)
822  SvFileStream aPasteDebug(OUString(
823  "PASTEBUFFER.debug"), StreamMode::WRITE|StreamMode::TRUNC);
824  SwWriter aDbgWrt( aPasteDebug, *pDoc );
825  aDbgWrt.Write( xWrt );
826 #endif
827 
828  SwWriter aWrt( *xStream, *pDoc );
829  if( ! aWrt.Write( xWrt ).IsError() )
830  {
831  xStream->WriteChar( '\0' ); // terminate with a zero
832  bRet = true;
833  }
834  }
835 
836  return bRet;
837 }
838 
840 {
841  int nRet = Copy( true );
842  if( nRet )
843  DeleteSelection();
844  collectUIInformation("CUT", "parameter");
845  return nRet;
846 }
847 
849 {
850  if(!m_pWrtShell)
851  return;
852  // ask for type of selection before action-bracketing
853  const SelectionType nSelection = m_pWrtShell->GetSelectionType();
854  // cut rows or columns selected by enhanced table selection and wholly selected tables
855  bool bCutMode = ( SelectionType::TableCell & nSelection ) && ( (SelectionType::TableRow | SelectionType::TableCol) & nSelection ||
857 
859  if( bCutMode )
860  {
861  if( !(SelectionType::TableCol & nSelection) )
863  else
864  {
866  pDispatch->Execute(FN_TABLE_DELETE_COL, SfxCallMode::SYNCHRON);
867  }
868  }
869  else
870  {
871  if( ( SelectionType::Text | SelectionType::Table ) & nSelection )
872  m_pWrtShell->IntelligentCut( nSelection );
874  }
876 }
877 
878 static void DeleteDDEMarks(SwDoc & rDest)
879 {
880  IDocumentMarkAccess *const pMarkAccess = rDest.getIDocumentMarkAccess();
881  std::vector< ::sw::mark::IMark* > vDdeMarks;
882  // find all DDE-Bookmarks
883  for (IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
884  ppMark != pMarkAccess->getAllMarksEnd();
885  ++ppMark)
886  {
888  {
889  vDdeMarks.push_back(*ppMark);
890  }
891  }
892  // remove all DDE-Bookmarks, they are invalid inside the clipdoc!
893  for (const auto& rpMark : vDdeMarks)
894  {
895  pMarkAccess->deleteMark(rpMark);
896  }
897 }
898 
900 {
901  std::unique_ptr<SwWait> pWait;
902  if (m_pWrtShell->ShouldWait())
903  {
904  pWait.reset(new SwWait( *m_pWrtShell->GetView().GetDocShell(), true ));
905  }
906 
907  m_pClpDocFac.reset(new SwDocFac);
908 
909  SwDoc& rDest(lcl_GetDoc(*m_pClpDocFac));
910  rDest.getIDocumentFieldsAccess().LockExpFields(); // Never update fields - leave text as is
911  {
912  SwDoc const& rSrc(*m_pWrtShell->GetDoc());
913  assert(&rSrc == &rPaM.GetDoc());
914 
915  rDest.ReplaceCompatibilityOptions(rSrc);
916  rDest.ReplaceDefaults(rSrc);
917 
918  //It would probably make most sense here to only insert the styles used
919  //by the selection, e.g. apply SwDoc::IsUsed on styles ?
920  rDest.ReplaceStyles(rSrc, false);
921 
922  // relevant bits of rSrcWrtShell.Copy(rDest);
923  rDest.GetIDocumentUndoRedo().DoUndo(false); // always false!
925 
926  SwNodeIndex const aIdx(rDest.GetNodes().GetEndOfContent(), -1);
927  SwContentNode *const pContentNode(aIdx.GetNode().GetContentNode());
928  SwPosition aPos(aIdx,
929  SwIndex(pContentNode, pContentNode ? pContentNode->Len() : 0));
930 
932 
934 
936  }
937 
938  DeleteDDEMarks(rDest);
939 
940  // a new one was created in core (OLE objects copied!)
941  m_aDocShellRef = rDest.GetTmpDocShell();
942  if (m_aDocShellRef.Is())
944  rDest.SetTmpDocShell( nullptr );
945 
946  // let's add some formats
947  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
948  AddFormat( SotClipboardFormatId::RTF );
949 #if HAVE_FEATURE_DESKTOP
950  AddFormat( SotClipboardFormatId::RICHTEXT );
951  AddFormat( SotClipboardFormatId::HTML );
952 #endif
953  AddFormat( SotClipboardFormatId::STRING );
954 }
955 
957 {
958  int nRet = 1;
959  if(!m_pWrtShell)
960  return 0;
961 
964 
965  if ( m_pWrtShell->GetTableCopied() )
966  m_pWrtShell->SetTableCopied( false );
967 
968  OUString sGrfNm;
969  const SelectionType nSelection = m_pWrtShell->GetSelectionType();
970  if( nSelection == SelectionType::Graphic )
971  {
972  m_pClpGraphic.reset(new Graphic);
973  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_pClpGraphic ))
975  m_pClpBitmap.reset(new Graphic);
976  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_pClpBitmap ))
978 
979  m_pClpDocFac.reset(new SwDocFac);
980  SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
981  m_pWrtShell->Copy(rDoc);
982 
983 #if HAVE_FEATURE_DESKTOP
985  AddFormat( SotClipboardFormatId::SVXB );
986 #endif
987 
989  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
990 
991  const Graphic* pGrf = m_pWrtShell->GetGraphic();
992  if( pGrf && pGrf->IsSupportedGraphic() )
993  {
994  AddFormat( SotClipboardFormatId::PNG );
995 #if HAVE_FEATURE_DESKTOP
996  AddFormat( SotClipboardFormatId::GDIMETAFILE );
997  AddFormat( SotClipboardFormatId::BITMAP );
998 #endif
999  }
1001  m_pWrtShell->GetGrfNms( &sGrfNm, nullptr );
1002  }
1003  else if ( nSelection == SelectionType::Ole )
1004  {
1005  m_pClpDocFac.reset(new SwDocFac);
1006  SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
1007  m_aDocShellRef = new SwDocShell(rDoc, SfxObjectCreateMode::EMBEDDED);
1009  m_pWrtShell->Copy(rDoc);
1010 
1011  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
1012 
1013  // --> OD #i98753#
1014  // set size of embedded object at the object description structure
1016 
1017  // <--
1019 
1020 #if HAVE_FEATURE_DESKTOP
1021  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
1022  AddFormat( SotClipboardFormatId::GDIMETAFILE );
1023 
1024  // Fetch the formats supported via embedtransferhelper as well
1025  sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
1026  uno::Reference < embed::XEmbeddedObject > xObj = FindOLEObj( nAspect );
1027  const Graphic* pOLEGraph = FindOLEReplacementGraphic();
1028  if( xObj.is() )
1029  {
1030  TransferableDataHelper aD( new SvEmbedTransferHelper( xObj, pOLEGraph, nAspect ) );
1031  if ( aD.GetTransferable().is() )
1032  {
1033  DataFlavorExVector aVector( aD.GetDataFlavorExVector() );
1034 
1035  for( const auto& rItem : aVector )
1036  AddFormat( rItem );
1037  }
1038  }
1039 #endif
1041  }
1042  // Is there anything to provide anyway?
1043  else if ( m_pWrtShell->IsSelection() || m_pWrtShell->IsFrameSelected() ||
1045  {
1046  std::unique_ptr<SwWait> pWait;
1047  if( m_pWrtShell->ShouldWait() )
1048  pWait.reset(new SwWait( *m_pWrtShell->GetView().GetDocShell(), true ));
1049 
1050  m_pClpDocFac.reset(new SwDocFac);
1051 
1052  // create additional cursor so that equal treatment of keyboard
1053  // and mouse selection is possible.
1054  // In AddMode with keyboard selection, the new cursor is not created
1055  // before the cursor is moved after end of selection.
1056  if( m_pWrtShell->IsAddMode() && m_pWrtShell->SwCursorShell::HasSelection() )
1058 
1059  SwDoc& rTmpDoc = lcl_GetDoc(*m_pClpDocFac);
1060 
1061  rTmpDoc.getIDocumentFieldsAccess().LockExpFields(); // Never update fields - leave text as is
1062  lclOverWriteDoc(*m_pWrtShell, rTmpDoc);
1063 
1064  DeleteDDEMarks(rTmpDoc);
1065 
1066  // a new one was created in CORE (OLE objects copied!)
1067  m_aDocShellRef = rTmpDoc.GetTmpDocShell();
1068  if( m_aDocShellRef.Is() )
1070  rTmpDoc.SetTmpDocShell( nullptr );
1071 
1072  if( m_pWrtShell->IsObjSelected() )
1074  else
1075  {
1077  if (m_pWrtShell->IntelligentCut(nSelection, false) != SwWrtShell::NO_WORD)
1079  }
1080 
1081  bool bDDELink = m_pWrtShell->IsSelection();
1082  if( nSelection & SelectionType::TableCell )
1083  {
1085  bDDELink = m_pWrtShell->HasWholeTabSelection();
1086 
1087  m_pWrtShell->SetTableCopied(true);
1088 
1089  if ( bIsCut && (SelectionType::TableRow | SelectionType::TableCol) & nSelection )
1091  }
1092 
1093 #if HAVE_FEATURE_DESKTOP
1094  //When someone needs it, we 'OLE' him something
1095  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
1096 #endif
1097 
1098  //put RTF ahead of the OLE's Metafile to have less loss
1099  if( !m_pWrtShell->IsObjSelected() )
1100  {
1101  AddFormat( SotClipboardFormatId::RTF );
1102 #if HAVE_FEATURE_DESKTOP
1103  AddFormat( SotClipboardFormatId::RICHTEXT );
1104  AddFormat( SotClipboardFormatId::HTML );
1105 #endif
1106  }
1107  if( m_pWrtShell->IsSelection() )
1108  AddFormat( SotClipboardFormatId::STRING );
1109 
1110  if( nSelection & ( SelectionType::DrawObject | SelectionType::DbForm ))
1111  {
1112  AddFormat( SotClipboardFormatId::DRAWING );
1113  if ( nSelection & SelectionType::DrawObject )
1114  {
1115 #if HAVE_FEATURE_DESKTOP
1116  AddFormat( SotClipboardFormatId::GDIMETAFILE );
1117  AddFormat( SotClipboardFormatId::BITMAP );
1118 #endif
1119  AddFormat( SotClipboardFormatId::PNG );
1120  }
1122 
1123  m_pClpGraphic.reset(new Graphic);
1124  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_pClpGraphic ))
1125  m_pOrigGraphic = m_pClpGraphic.get();
1126  m_pClpBitmap.reset(new Graphic);
1127  if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_pClpBitmap ))
1128  m_pOrigGraphic = m_pClpBitmap.get();
1129 
1130  // is it a URL-Button ?
1131  OUString sURL;
1132  OUString sDesc;
1133  if( m_pWrtShell->GetURLFromButton( sURL, sDesc ) )
1134  {
1135  AddFormat( SotClipboardFormatId::STRING );
1136 #if HAVE_FEATURE_DESKTOP
1137  AddFormat( SotClipboardFormatId::SOLK );
1138  AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
1139  AddFormat( SotClipboardFormatId::FILECONTENT );
1140  AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
1141 #endif
1142  AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
1144  nRet = 1;
1145  }
1146  }
1147 
1148  // at Cut, DDE-Link doesn't make sense!!
1149  SwDocShell* pDShell;
1150  if( !bIsCut && bDDELink &&
1151  nullptr != ( pDShell = m_pWrtShell->GetDoc()->GetDocShell()) &&
1152  SfxObjectCreateMode::STANDARD == pDShell->GetCreateMode() )
1153  {
1154 #if HAVE_FEATURE_DESKTOP
1155  AddFormat( SotClipboardFormatId::LINK );
1156 #endif
1157  m_xDdeLink = new SwTransferDdeLink( *this, *m_pWrtShell );
1158  }
1159 
1160  //ObjectDescriptor was already filly from the old DocShell.
1161  //Now adjust it. Thus in GetData the first query can still
1162  //be answered with delayed rendering.
1164 
1166 #if HAVE_FEATURE_DESKTOP
1167  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
1168 #endif
1169  }
1170  else
1171  nRet = 0;
1172 
1173  if( m_pWrtShell->IsFrameSelected() )
1174  {
1176  m_pWrtShell->GetFlyFrameAttr( aSet );
1177  const SwFormatURL& rURL = aSet.Get( RES_URL );
1178  if( rURL.GetMap() )
1179  {
1180  m_pImageMap.reset( new ImageMap( *rURL.GetMap() ) );
1181  AddFormat( SotClipboardFormatId::SVIM );
1182  }
1183  else if( !rURL.GetURL().isEmpty() )
1184  {
1185  m_pTargetURL.reset(new INetImage( sGrfNm, rURL.GetURL(),
1186  rURL.GetTargetFrameName() ));
1187  AddFormat( SotClipboardFormatId::INET_IMAGE );
1188  }
1189  }
1190 
1191  return nRet;
1192 }
1193 
1194 int SwTransferable::Copy( bool bIsCut )
1195 {
1197  return 0;
1198 
1199  int nRet = PrepareForCopy( bIsCut );
1200  if ( nRet )
1201  {
1203  }
1204 
1205  if( !bIsCut ){
1206  collectUIInformation("COPY", "parameter");
1207  }
1208 
1209  return nRet;
1210 }
1211 
1213 {
1214  if(!m_pWrtShell)
1215  return;
1216  SwWait aWait( *m_pWrtShell->GetView().GetDocShell(), true );
1217 
1218  OUString aStr( m_pWrtShell->Calculate() );
1219 
1220  m_pClpDocFac.reset(new SwDocFac);
1221  SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
1222  m_pWrtShell->Copy(rDoc, &aStr);
1224  AddFormat( SotClipboardFormatId::STRING );
1225 
1227 }
1228 
1229 bool SwTransferable::CopyGlossary( SwTextBlocks& rGlossary, const OUString& rStr )
1230 {
1231  if(!m_pWrtShell)
1232  return false;
1233  SwWait aWait( *m_pWrtShell->GetView().GetDocShell(), true );
1234 
1235  m_pClpDocFac.reset(new SwDocFac);
1236  SwDoc& rCDoc = lcl_GetDoc(*m_pClpDocFac);
1237 
1238  SwNodes& rNds = rCDoc.GetNodes();
1239  SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() );
1240  SwContentNode* pCNd = rNds.GoNext( &aNodeIdx ); // go to 1st ContentNode
1241  SwPaM aPam( *pCNd );
1242 
1243  rCDoc.getIDocumentFieldsAccess().LockExpFields(); // never update fields - leave text as it is
1244 
1245  rCDoc.InsertGlossary( rGlossary, rStr, aPam );
1246 
1247  // a new one was created in CORE (OLE-Objects copied!)
1248  m_aDocShellRef = rCDoc.GetTmpDocShell();
1249  if( m_aDocShellRef.Is() )
1251  rCDoc.SetTmpDocShell( nullptr );
1252 
1254 
1255  //When someone needs it, we 'OLE' her something.
1256  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
1257  AddFormat( SotClipboardFormatId::RTF );
1258  AddFormat( SotClipboardFormatId::RICHTEXT );
1259  AddFormat( SotClipboardFormatId::HTML );
1260  AddFormat( SotClipboardFormatId::STRING );
1261 
1262  //ObjectDescriptor was already filled from the old DocShell.
1263  //Now adjust it. Thus in GetData the first query can still
1264  //be answered with delayed rendering.
1266 
1268  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
1269 
1271 
1272  return true;
1273 }
1274 
1275 static uno::Reference < XTransferable > * lcl_getTransferPointer ( uno::Reference < XTransferable > &xRef )
1276 {
1277  return &xRef;
1278 }
1279 
1281  : m_rWrtShell(rWrtShell)
1282 {
1283  remember();
1284 }
1285 
1287 {
1289  return;
1290 
1291  SwPaM* pCursor = m_rWrtShell.GetCursor();
1292  if (!pCursor)
1293  return;
1294 
1295  // Set point to the previous node, so it is not moved.
1296  const SwNodeIndex& rNodeIndex = pCursor->GetPoint()->nNode;
1297  m_pPaM.reset(new SwPaM(rNodeIndex, rNodeIndex, SwNodeOffset(0), SwNodeOffset(-1)));
1298  m_nStartContent = pCursor->GetPoint()->nContent.GetIndex();
1299 }
1300 
1301 void SwPasteContext::forget() { m_pPaM.reset(); }
1302 
1304 {
1305  try
1306  {
1308  return;
1309 
1310  beans::PropertyValue aPropertyValue;
1311 
1312  switch (m_rWrtShell.GetView().GetShellMode())
1313  {
1314  case ShellMode::Graphic:
1315  {
1317  if (!pFormat)
1318  return;
1319 
1320  aPropertyValue.Name = "TextGraphicObject";
1321  aPropertyValue.Value
1322  <<= SwXTextGraphicObject::CreateXTextGraphicObject(*pFormat->GetDoc(), pFormat);
1323  break;
1324  }
1325 
1326  default:
1327  {
1328  if (!m_pPaM)
1329  return;
1330 
1331  SwPaM* pCursor = m_rWrtShell.GetCursor();
1332  if (!pCursor)
1333  return;
1334 
1335  if (!pCursor->GetPoint()->nNode.GetNode().IsTextNode())
1336  // Non-text was pasted.
1337  return;
1338 
1339  // Update mark after paste.
1340  *m_pPaM->GetMark() = *pCursor->GetPoint();
1341 
1342  // Restore point.
1343  ++m_pPaM->GetPoint()->nNode;
1344  SwNode& rNode = m_pPaM->GetNode();
1345  if (!rNode.IsTextNode())
1346  // Starting point is no longer text.
1347  return;
1348 
1349  m_pPaM->GetPoint()->nContent.Assign(static_cast<SwContentNode*>(&rNode),
1350  m_nStartContent);
1351 
1352  aPropertyValue.Name = "TextRange";
1353  const uno::Reference<text::XTextRange> xTextRange = SwXTextRange::CreateXTextRange(
1354  m_pPaM->GetDoc(), *m_pPaM->GetPoint(), m_pPaM->GetMark());
1355  aPropertyValue.Value <<= xTextRange;
1356  break;
1357  }
1358  }
1359 
1360  if (aPropertyValue.Name.isEmpty())
1361  return;
1362 
1363  // Invoke the listeners.
1364  uno::Sequence<beans::PropertyValue> aEvent{ aPropertyValue };
1365  m_rWrtShell.GetPasteListeners().notifyEach( &css::text::XPasteListener::notifyPasteEvent, aEvent );
1366  }
1367  catch (const uno::Exception& rException)
1368  {
1369  SAL_WARN("sw",
1370  "SwPasteContext::~SwPasteContext: uncaught exception: " << rException.Message);
1371  }
1372 }
1373 
1375  const TransferableDataHelper& rData )
1376 {
1377  // Check the common case first: We can always paste our own data!
1378  // If _only_ the internal format can be pasted, this check will
1379  // yield 'true', while the one below would give a (wrong) result 'false'.
1380 
1381  bool bIsPaste = ( GetSwTransferable( rData ) != nullptr );
1382 
1383  // if it's not our own data, we need to have a closer look:
1384  if( ! bIsPaste )
1385  {
1386  // determine the proper paste action, and return true if we find one
1387  uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
1388 
1389  SotExchangeDest nDestination = SwTransferable::GetSotDestination( rSh );
1390  sal_uInt16 nSourceOptions =
1391  (( SotExchangeDest::DOC_TEXTFRAME == nDestination ||
1392  SotExchangeDest::SWDOC_FREE_AREA == nDestination ||
1393  SotExchangeDest::DOC_TEXTFRAME_WEB == nDestination ||
1394  SotExchangeDest::SWDOC_FREE_AREA_WEB == nDestination )
1397 
1398  SotClipboardFormatId nFormat; // output param for GetExchangeAction
1399  sal_uInt8 nEventAction; // output param for GetExchangeAction
1401  rData.GetDataFlavorExVector(),
1402  nDestination,
1403  nSourceOptions, /* ?? */
1404  EXCHG_IN_ACTION_DEFAULT, /* ?? */
1405  nFormat, nEventAction, SotClipboardFormatId::NONE,
1406  lcl_getTransferPointer ( xTransferable ) );
1407 
1408  // if we find a suitable action, we can paste!
1409  bIsPaste = (EXCHG_INOUT_ACTION_NONE != nAction);
1410  }
1411 
1412  return bIsPaste;
1413 }
1414 
1416  SotClipboardFormatId& nFormat)
1417 {
1418  if (nFormat != SotClipboardFormatId::RICHTEXT)
1419  {
1420  return;
1421  }
1422 
1423  if (!rData.HasFormat(SotClipboardFormatId::EMBED_SOURCE))
1424  {
1425  return;
1426  }
1427 
1428  if (!rData.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
1429  {
1430  return;
1431  }
1432 
1434  if (!rData.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc))
1435  {
1436  return;
1437  }
1438 
1439  if (aObjDesc.maClassName != SvGlobalName(SO3_SW_CLASSID))
1440  {
1441  return;
1442  }
1443 
1444  // At this point we know that we paste from Writer to Writer and the clipboard has the content
1445  // in both RTF and ODF formats. Prefer ODF in this case.
1446  nAction = EXCHG_OUT_ACTION_INSERT_OLE;
1447  nFormat = SotClipboardFormatId::EMBED_SOURCE;
1448 }
1449 
1450 // get HTML indentation level by counting tabulator characters before the index
1451 // (also index value -1 returns with 0)
1452 static sal_Int32 lcl_getLevel(OUString& sText, sal_Int32 nIdx)
1453 {
1454  sal_Int32 nRet = 0;
1455  while ( nIdx-- > 0 && sText[nIdx] == '\t' )
1456  {
1457  nRet++;
1458  }
1459  return nRet;
1460 }
1461 
1462 bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndStdIds nAnchorType, bool bIgnoreComments, PasteTableType ePasteTable)
1463 {
1464  SwPasteContext aPasteContext(rSh);
1465 
1466  sal_uInt8 nAction=0;
1467  SotExchangeDest nDestination = SwTransferable::GetSotDestination( rSh );
1468  SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
1469  SotExchangeActionFlags nActionFlags = SotExchangeActionFlags::NONE;
1470  bool bSingleCellTable = false;
1471 
1472  if( GetSwTransferable( rData ) )
1473  {
1475  }
1476  else
1477  {
1478  sal_uInt16 nSourceOptions =
1479  (( SotExchangeDest::DOC_TEXTFRAME == nDestination ||
1480  SotExchangeDest::SWDOC_FREE_AREA == nDestination ||
1481  SotExchangeDest::DOC_TEXTFRAME_WEB == nDestination ||
1482  SotExchangeDest::SWDOC_FREE_AREA_WEB == nDestination )
1485  uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
1486  sal_uInt8 nEventAction;
1488  rData.GetDataFlavorExVector(),
1489  nDestination,
1490  nSourceOptions, /* ?? */
1491  EXCHG_IN_ACTION_DEFAULT, /* ?? */
1492  nFormat, nEventAction, SotClipboardFormatId::NONE,
1493  lcl_getTransferPointer ( xTransferable ),
1494  &nActionFlags );
1495  }
1496 
1497  // tdf#37223 avoid non-native insertion of Calc worksheets in the following cases:
1498  // content of 1-cell worksheets are inserted as simple text using RTF format,
1499  // bigger worksheets within native (Writer) table cells are inserted as native tables,
1500  // ie. cell by cell instead of embedding the worksheet in a single cell of the Writer table
1501  if ( EXCHG_IN_ACTION_COPY == nAction && ( rData.HasFormat( SotClipboardFormatId::SYLK ) ||
1502  rData.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS ) ) )
1503  {
1504  // is it a 1-cell worksheet?
1505  OUString aExpand;
1506  if( rData.GetString( SotClipboardFormatId::STRING, aExpand ))
1507  {
1508  const sal_Int32 nNewlines{comphelper::string::getTokenCount(aExpand, '\n')};
1509  const sal_Int32 nRows = nNewlines ? nNewlines-1 : 0;
1510  if ( nRows == 1 )
1511  {
1512  const sal_Int32 nCols = comphelper::string::getTokenCount(o3tl::getToken(aExpand, 0, '\n'), '\t');
1513  if (nCols == 1)
1514  bSingleCellTable = true;
1515  }
1516  }
1517 
1518  // convert the worksheet to a temporary native table using HTML format, and copy that into the original native table
1519  if (!bSingleCellTable && rData.HasFormat( SotClipboardFormatId::HTML ) &&
1520  rSh.GetDoc()->IsIdxInTable(rSh.GetCursor()->GetNode()) != nullptr && rSh.DoesUndo())
1521  {
1522  SfxDispatcher* pDispatch = rSh.GetView().GetViewFrame()->GetDispatcher();
1523  sal_uInt32 nLevel = 0;
1524  // within Writer table cells, inserting worksheets using HTML format results only plain text, not a native table,
1525  // so remove all outer nested tables temporary to get a working insertion point
1526  // (RTF format has no such problem, but that inserts the hidden rows of the original Calc worksheet, too)
1527  do
1528  {
1529  // insert a random character to redo the place of the insertion at the end
1530  pDispatch->Execute(FN_INSERT_NNBSP, SfxCallMode::SYNCHRON);
1531  pDispatch->Execute(FN_TABLE_DELETE_TABLE, SfxCallMode::SYNCHRON);
1532  nLevel++;
1533  } while (rSh.GetDoc()->IsIdxInTable(rSh.GetCursor()->GetNode()) != nullptr);
1534  if ( SwTransferable::PasteData( rData, rSh, EXCHG_OUT_ACTION_INSERT_STRING, nActionFlags, SotClipboardFormatId::HTML,
1535  nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext, ePasteTable) )
1536  {
1537  bool bFoundTemporaryTable = false;
1538  pDispatch->Execute(FN_LINE_UP, SfxCallMode::SYNCHRON);
1539  if (rSh.GetDoc()->IsIdxInTable(rSh.GetCursor()->GetNode()) != nullptr)
1540  {
1541  bFoundTemporaryTable = true;
1542  pDispatch->Execute(FN_TABLE_SELECT_ALL, SfxCallMode::SYNCHRON);
1543  pDispatch->Execute(SID_COPY, SfxCallMode::SYNCHRON);
1544  }
1545  for(sal_uInt32 a = 0; a < 1 + (nLevel * 2); a++)
1546  pDispatch->Execute(SID_UNDO, SfxCallMode::SYNCHRON);
1547  // clipboard content hasn't changed (limit potential infinite
1548  // recursion with the same non-native table, as was in tdf#138688)
1549  if (!bFoundTemporaryTable)
1550  return false;
1551  if (ePasteTable == PasteTableType::PASTE_TABLE)
1552  pDispatch->Execute(FN_PASTE_NESTED_TABLE, SfxCallMode::SYNCHRON);
1553  else if (ePasteTable == PasteTableType::PASTE_ROW)
1554  pDispatch->Execute(FN_TABLE_PASTE_ROW_BEFORE, SfxCallMode::SYNCHRON);
1555  else if (ePasteTable == PasteTableType::PASTE_COLUMN)
1556  pDispatch->Execute(FN_TABLE_PASTE_COL_BEFORE, SfxCallMode::SYNCHRON);
1557  else
1558  pDispatch->Execute(SID_PASTE, SfxCallMode::SYNCHRON);
1559  return true;
1560  } else {
1561  for(sal_uInt32 a = 0; a < (nLevel * 2); a++)
1562  pDispatch->Execute(SID_UNDO, SfxCallMode::SYNCHRON);
1563  }
1564  }
1565  }
1566  // insert clipboard content as new table rows/columns before the actual row/column instead of overwriting it
1567  else if ( (rSh.GetTableInsertMode() != SwTable::SEARCH_NONE || ePasteTable == PasteTableType::PASTE_ROW || ePasteTable == PasteTableType::PASTE_COLUMN) &&
1568  rData.HasFormat( SotClipboardFormatId::HTML ) &&
1569  rSh.GetDoc()->IsIdxInTable(rSh.GetCursor()->GetNode()) != nullptr )
1570  {
1571  OUString aExpand;
1572  sal_Int32 nIdx;
1573  bool bRowMode = rSh.GetTableInsertMode() == SwTable::SEARCH_ROW || ePasteTable == PasteTableType::PASTE_ROW;
1574  if( rData.GetString( SotClipboardFormatId::HTML, aExpand ) && (nIdx = aExpand.indexOf("<table")) > -1 )
1575  {
1576  // calculate table row/column count by analysing indentation of the HTML table extract
1577 
1578  // calculate indentation level of <table>, which is the base of the next calculations
1579  // (tdf#148791 table alignment can enlarge it using first level <center>, <div> or <dl>)
1580  sal_Int32 nTableLevel = lcl_getLevel(aExpand, nIdx);
1581  // table rows repeated heading use extra indentation, too:
1582  // <thead> is always used here, and the first table with <thead> is not nested,
1583  // if its indentation level is greater only by 1, than indentation level of the table
1584  bool bShifted = lcl_getLevel(aExpand, aExpand.indexOf("<thead")) == nTableLevel + 1;
1585  // calculate count of selected rows or columns
1586  sal_Int32 nSelectedRowsOrCols = 0;
1587  const OUString sSearchRowOrCol = bRowMode ? OUString("</tr>") : OUString("<col ");
1588  while((nIdx = aExpand.indexOf(sSearchRowOrCol, nIdx)) > -1)
1589  {
1590  // skip rows/columns of nested tables, based on HTML indentation
1591  if ( lcl_getLevel(aExpand, nIdx) == nTableLevel + (bShifted ? 2 : 1) &&
1592  // skip also strange hidden empty rows <tr></tr>
1593  !aExpand.match("<tr></tr>", nIdx - 4) )
1594  {
1595  ++nSelectedRowsOrCols;
1596  }
1597  ++nIdx;
1598  }
1599  // are we at the beginning of the cell?
1600  bool bStartTableBoxNode =
1601  // first paragraph of the cell?
1602  rSh.GetCursor()->GetNode().GetIndex() == rSh.GetCursor()->GetNode().FindTableBoxStartNode()->GetIndex()+1 &&
1603  // beginning of the paragraph?
1604  !rSh.GetCursor()->GetPoint()->nContent.GetIndex();
1605  SfxDispatcher* pDispatch = rSh.GetView().GetViewFrame()->GetDispatcher();
1606 
1607  // go start of the cell
1608  if (!bStartTableBoxNode)
1609  pDispatch->Execute(FN_START_OF_DOCUMENT, SfxCallMode::SYNCHRON);
1610 
1611  // store cursor position in row mode
1612  ::sw::mark::IMark* pMark = (!bRowMode || nSelectedRowsOrCols == 0) ? nullptr : rSh.SetBookmark(
1613  vcl::KeyCode(),
1614  OUString(),
1616 
1617  // add a new empty row/column before the actual table row/column and go there
1618  // (without setting the rows to tracked table row insertion here, do that at the end
1619  // to avoid layout problems and unnecessary insertion of dummy characters for empty rows)
1621  if ( eOld & RedlineFlags::On )
1623 
1624  const sal_uInt16 nDispatchSlot = bRowMode ? FN_TABLE_INSERT_ROW_BEFORE : FN_TABLE_INSERT_COL_BEFORE;
1625  pDispatch->Execute(nDispatchSlot, SfxCallMode::SYNCHRON);
1626  pDispatch->Execute(bRowMode ? FN_LINE_UP : FN_CHAR_LEFT, SfxCallMode::SYNCHRON);
1627 
1628  // add the other new empty rows/columns after the actual table row/column
1629  if ( nSelectedRowsOrCols > 1 )
1630  {
1631  SfxInt16Item aCountItem( nDispatchSlot, nSelectedRowsOrCols-1 );
1632  SfxBoolItem aAfter( FN_PARAM_INSERT_AFTER, true );
1633  pDispatch->ExecuteList(nDispatchSlot,
1634  SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
1635  { &aCountItem, &aAfter });
1636  }
1637 
1638  if ( eOld & RedlineFlags::On )
1640 
1641  // paste rows
1642  bool bResult = SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat,
1643  nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext );
1644 
1645  // set tracked insertion, if it's not in a drag & drop action
1646  if ( !rSh.ActionPend() && ( eOld & RedlineFlags::On) )
1647  {
1648  SvxPrintItem aTracked(RES_PRINT, false);
1649  rSh.GetDoc()->SetRowNotTracked( *rSh.GetCursor(), aTracked );
1650  }
1651 
1652  // restore cursor position
1653  if (pMark != nullptr)
1654  {
1655  rSh.GotoMark( pMark );
1656  rSh.getIDocumentMarkAccess()->deleteMark( pMark );
1657  }
1658 
1659  return bResult;
1660  }
1661  }
1662 
1663  // special case for tables from draw application or 1-cell tables
1664  if( EXCHG_OUT_ACTION_INSERT_DRAWOBJ == nAction || bSingleCellTable )
1665  {
1666  if( rData.HasFormat( SotClipboardFormatId::RTF ) )
1667  {
1669  nFormat = SotClipboardFormatId::RTF;
1670  }
1671  else if( rData.HasFormat( SotClipboardFormatId::RICHTEXT ) )
1672  {
1674  nFormat = SotClipboardFormatId::RICHTEXT;
1675  }
1676  }
1677 
1678  // Tweak the format if necessary: the source application can be considered in this context,
1679  // while not in sot/ code.
1680  SwTransferable::SelectPasteFormat(rData, nAction, nFormat);
1681 
1682  collectUIInformation("PASTE", "parameter");
1683 
1684  return EXCHG_INOUT_ACTION_NONE != nAction &&
1685  SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat,
1686  nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext, ePasteTable);
1687 }
1688 
1690  SwWrtShell& rSh, sal_uInt8 nAction, SotExchangeActionFlags nActionFlags,
1691  SotClipboardFormatId nFormat,
1692  SotExchangeDest nDestination, bool bIsPasteFormat,
1693  bool bIsDefault,
1694  const Point* pPt, sal_Int8 nDropAction,
1695  bool bPasteSelection, RndStdIds nAnchorType,
1696  bool bIgnoreComments,
1697  SwPasteContext* pContext,
1698  PasteTableType ePasteTable )
1699 {
1700  SwWait aWait( *rSh.GetView().GetDocShell(), false );
1701  std::unique_ptr<SwTrnsfrActionAndUndo, o3tl::default_delete<SwTrnsfrActionAndUndo>> pAction;
1702  SwModule* pMod = SW_MOD();
1703 
1704  bool bRet = false;
1705  bool bCallAutoCaption = false;
1706 
1707  if( pPt )
1708  {
1709  // external Drop
1710  if( bPasteSelection ? !pMod->m_pXSelection : !pMod->m_pDragDrop )
1711  {
1712  switch( nDestination )
1713  {
1714  case SotExchangeDest::DOC_LNKD_GRAPH_W_IMAP:
1715  case SotExchangeDest::DOC_LNKD_GRAPHOBJ:
1716  case SotExchangeDest::DOC_GRAPH_W_IMAP:
1717  case SotExchangeDest::DOC_GRAPHOBJ:
1718  case SotExchangeDest::DOC_OLEOBJ:
1719  case SotExchangeDest::DOC_DRAWOBJ:
1720  case SotExchangeDest::DOC_URLBUTTON:
1721  case SotExchangeDest::DOC_GROUPOBJ:
1722  // select frames/objects
1723  SwTransferable::SetSelInShell( rSh, true, pPt );
1724  break;
1725 
1726  default:
1727  SwTransferable::SetSelInShell( rSh, false, pPt );
1728  break;
1729  }
1730  }
1731  }
1732  else if( ( !GetSwTransferable( rData ) || bIsPasteFormat ) &&
1733  !rSh.IsTableMode() && rSh.HasSelection() )
1734  {
1735  // then delete the selections
1736 
1737  //don't delete selected content
1738  // - at table-selection
1739  // - at ReRead of a graphic/DDEData
1740  // - at D&D, for the right selection was taken care of
1741  // in Drop-Handler
1742  bool bDelSel = false;
1743  switch( nDestination )
1744  {
1745  case SotExchangeDest::DOC_TEXTFRAME:
1746  case SotExchangeDest::SWDOC_FREE_AREA:
1747  case SotExchangeDest::DOC_TEXTFRAME_WEB:
1748  case SotExchangeDest::SWDOC_FREE_AREA_WEB:
1749  bDelSel = true;
1750  break;
1751  default:
1752  break;
1753  }
1754 
1755  if( bDelSel )
1756  // #i34830#
1757  pAction.reset(new SwTrnsfrActionAndUndo(&rSh, true, pContext));
1758  }
1759 
1760  SwTransferable *pTrans=nullptr, *pTunneledTrans=GetSwTransferable( rData );
1761 
1762  // check for private drop
1763  bool bPrivateDrop(pPt);
1764  if (bPrivateDrop)
1765  {
1766  if (bPasteSelection)
1767  pTrans = pMod->m_pXSelection;
1768  else
1769  pTrans = pMod->m_pDragDrop;
1770  bPrivateDrop = nullptr != pTrans;
1771  }
1772  bool bNeedToSelectBeforePaste(false);
1773 
1774  if(bPrivateDrop && DND_ACTION_LINK == nDropAction)
1775  {
1776  // internal drop on object, suppress bPrivateDrop to change internal fill
1777  bPrivateDrop = false;
1778  bNeedToSelectBeforePaste = true;
1779  }
1780 
1781  if(bPrivateDrop && pPt && DND_ACTION_MOVE == nDropAction)
1782  {
1783  // check if dragged over a useful target. If yes, use as content exchange
1784  // drop as if from external
1785  const SwFrameFormat* pSwFrameFormat = rSh.GetFormatFromObj(*pPt);
1786 
1787  if(dynamic_cast< const SwDrawFrameFormat* >(pSwFrameFormat))
1788  {
1789  bPrivateDrop = false;
1790  bNeedToSelectBeforePaste = true;
1791  }
1792  }
1793 
1794  if(bPrivateDrop)
1795  {
1796  // then internal Drag & Drop or XSelection
1797  bRet = pTrans->PrivateDrop( rSh, *pPt, DND_ACTION_MOVE == nDropAction,
1798  bPasteSelection );
1799  }
1800  else if( !pPt && pTunneledTrans &&
1801  EXCHG_OUT_ACTION_INSERT_PRIVATE == nAction )
1802  {
1803  // then internal paste
1804  bRet = pTunneledTrans->PrivatePaste(rSh, pContext, ePasteTable);
1805  }
1806  else if( EXCHG_INOUT_ACTION_NONE != nAction )
1807  {
1808  if( !pAction )
1809  {
1810  pAction.reset(new SwTrnsfrActionAndUndo( &rSh ));
1811  }
1812 
1813  // in Drag&Drop MessageBoxes must not be showed
1814  bool bMsg = nullptr == pPt;
1815 
1816  // delete selections
1817 
1818  switch( nAction )
1819  {
1821  OSL_ENSURE( pPt, "EXCHG_OUT_ACTION_INSERT_PRIVATE: what should happen here?" );
1822  break;
1823 
1825  OSL_ENSURE( pPt, "EXCHG_OUT_ACTION_MOVE_PRIVATE: what should happen here?" );
1826  break;
1827 
1828  case EXCHG_IN_ACTION_MOVE:
1829  case EXCHG_IN_ACTION_COPY:
1830  case EXCHG_IN_ACTION_LINK:
1835 
1836  // then we have to use the format
1837  switch( nFormat )
1838  {
1839  case SotClipboardFormatId::DRAWING:
1840  bRet = SwTransferable::PasteSdrFormat( rData, rSh,
1841  SwPasteSdr::Insert, pPt,
1842  nActionFlags, bNeedToSelectBeforePaste);
1843  break;
1844 
1845  case SotClipboardFormatId::HTML:
1846  case SotClipboardFormatId::HTML_SIMPLE:
1847  case SotClipboardFormatId::HTML_NO_COMMENT:
1848  case SotClipboardFormatId::RTF:
1849  case SotClipboardFormatId::RICHTEXT:
1850  case SotClipboardFormatId::STRING:
1851  bRet = SwTransferable::PasteFileContent( rData, rSh,
1852  nFormat, bMsg, bIgnoreComments );
1853  break;
1854 
1855  case SotClipboardFormatId::NETSCAPE_BOOKMARK:
1856  {
1857  INetBookmark aBkmk;
1858  if( rData.GetINetBookmark( nFormat, aBkmk ) )
1859  {
1860  SwFormatINetFormat aFormat( aBkmk.GetURL(), OUString() );
1861  rSh.InsertURL( aFormat, aBkmk.GetDescription() );
1862  bRet = true;
1863  }
1864  }
1865  break;
1866 
1867  case SotClipboardFormatId::SD_OLE:
1868  bRet = SwTransferable::PasteOLE( rData, rSh, nFormat,
1869  nActionFlags, bMsg );
1870  break;
1871 
1872  case SotClipboardFormatId::SVIM:
1873  bRet = SwTransferable::PasteImageMap( rData, rSh );
1874  break;
1875 
1876  case SotClipboardFormatId::SVXB:
1877  case SotClipboardFormatId::BITMAP:
1878  case SotClipboardFormatId::PNG:
1879  case SotClipboardFormatId::GDIMETAFILE:
1880  bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
1881  SwPasteSdr::Insert,pPt,
1882  nActionFlags, nDropAction, bNeedToSelectBeforePaste);
1883  break;
1884 
1885  case SotClipboardFormatId::XFORMS:
1886  case SotClipboardFormatId::SBA_FIELDDATAEXCHANGE:
1887  case SotClipboardFormatId::SBA_DATAEXCHANGE:
1888  case SotClipboardFormatId::SBA_CTRLDATAEXCHANGE:
1889  bRet = SwTransferable::PasteDBData( rData, rSh, nFormat,
1890  EXCHG_IN_ACTION_LINK == nAction,
1891  pPt, bMsg );
1892  break;
1893 
1894  case SotClipboardFormatId::SIMPLE_FILE:
1895  bRet = SwTransferable::PasteFileName( rData, rSh, nFormat,
1896  ( EXCHG_IN_ACTION_MOVE == nAction
1898  : EXCHG_IN_ACTION_LINK == nAction
1900  : SwPasteSdr::Insert),
1901  pPt, nActionFlags, nullptr );
1902  break;
1903 
1904  case SotClipboardFormatId::FILE_LIST:
1905  // then insert as graphics only
1906  bRet = SwTransferable::PasteFileList( rData, rSh,
1907  EXCHG_IN_ACTION_LINK == nAction,
1908  pPt, bMsg );
1909  break;
1910 
1911  case SotClipboardFormatId::SONLK:
1912  if( pPt )
1913  {
1914  NaviContentBookmark aBkmk;
1915  if( aBkmk.Paste( rData ) )
1916  {
1917  if(bIsDefault)
1918  {
1919  switch(aBkmk.GetDefaultDragType())
1920  {
1921  case RegionMode::NONE: nAction = EXCHG_IN_ACTION_COPY; break;
1922  case RegionMode::EMBEDDED: nAction = EXCHG_IN_ACTION_MOVE; break;
1923  case RegionMode::LINK: nAction = EXCHG_IN_ACTION_LINK; break;
1924  }
1925  }
1926  rSh.NavigatorPaste( aBkmk, nAction );
1927  bRet = true;
1928  }
1929  }
1930  break;
1931 
1932  case SotClipboardFormatId::INET_IMAGE:
1933  case SotClipboardFormatId::NETSCAPE_IMAGE:
1934  bRet = SwTransferable::PasteTargetURL( rData, rSh,
1935  SwPasteSdr::Insert,
1936  pPt, true );
1937  break;
1938 
1939  default:
1940  OSL_ENSURE( pPt, "unknown format" );
1941  }
1942  break;
1943 
1945  {
1946  bool graphicInserted;
1947  bRet = SwTransferable::PasteFileName( rData, rSh, nFormat,
1948  SwPasteSdr::Insert, pPt,
1949  nActionFlags,
1950  &graphicInserted );
1951  if( graphicInserted )
1952  bCallAutoCaption = true;
1953  }
1954  break;
1955 
1957  bRet = SwTransferable::PasteOLE( rData, rSh, nFormat,
1958  nActionFlags,bMsg );
1959  break;
1960 
1962  {
1963  bool bReRead = 0 != CNT_HasGrf( rSh.GetCntType() );
1964  bRet = SwTransferable::PasteDDE( rData, rSh, bReRead, bMsg );
1965  }
1966  break;
1967 
1969  {
1970  OUString sURL, sDesc;
1971  if( SotClipboardFormatId::SIMPLE_FILE == nFormat )
1972  {
1973  if( rData.GetString( nFormat, sURL ) && !sURL.isEmpty() )
1974  {
1975  SwTransferable::CheckForURLOrLNKFile( rData, sURL, &sDesc );
1976  if( sDesc.isEmpty() )
1977  sDesc = sURL;
1978  bRet = true;
1979  }
1980  }
1981  else
1982  {
1983  INetBookmark aBkmk;
1984  if( rData.GetINetBookmark( nFormat, aBkmk ) )
1985  {
1986  sURL = aBkmk.GetURL();
1987  sDesc = aBkmk.GetDescription();
1988  bRet = true;
1989  }
1990  }
1991 
1992  if( bRet )
1993  {
1994  SwFormatINetFormat aFormat( sURL, OUString() );
1995  rSh.InsertURL( aFormat, sDesc );
1996  }
1997  }
1998  break;
1999 
2001  switch( nFormat )
2002  {
2003  case SotClipboardFormatId::DRAWING:
2004  bRet = SwTransferable::PasteSdrFormat( rData, rSh,
2005  SwPasteSdr::SetAttr, pPt,
2006  nActionFlags, bNeedToSelectBeforePaste);
2007  break;
2008  case SotClipboardFormatId::SVXB:
2009  case SotClipboardFormatId::GDIMETAFILE:
2010  case SotClipboardFormatId::BITMAP:
2011  case SotClipboardFormatId::PNG:
2012  case SotClipboardFormatId::NETSCAPE_BOOKMARK:
2013  case SotClipboardFormatId::SIMPLE_FILE:
2014  case SotClipboardFormatId::FILEGRPDESCRIPTOR:
2015  case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
2016  bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
2017  SwPasteSdr::SetAttr, pPt,
2018  nActionFlags, nDropAction, bNeedToSelectBeforePaste);
2019  break;
2020  default:
2021  OSL_FAIL( "unknown format" );
2022  }
2023 
2024  break;
2025 
2027  bRet = SwTransferable::PasteSdrFormat( rData, rSh,
2028  SwPasteSdr::Insert, pPt,
2029  nActionFlags, bNeedToSelectBeforePaste);
2030  break;
2035  bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
2036  SwPasteSdr::Insert, pPt,
2037  nActionFlags, nDropAction, bNeedToSelectBeforePaste, nAnchorType );
2038  break;
2039 
2041  bRet = SwTransferable::PasteSdrFormat( rData, rSh,
2042  SwPasteSdr::Replace, pPt,
2043  nActionFlags, bNeedToSelectBeforePaste);
2044  break;
2045 
2050  bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
2051  SwPasteSdr::Replace,pPt,
2052  nActionFlags, nDropAction, bNeedToSelectBeforePaste);
2053  break;
2054 
2056  bRet = SwTransferable::PasteAsHyperlink( rData, rSh, nFormat );
2057  break;
2058 
2059  default:
2060  OSL_FAIL("unknown action" );
2061  }
2062  }
2063 
2064  if( !bPasteSelection && rSh.IsFrameSelected() )
2065  {
2066  rSh.EnterSelFrameMode();
2067  //force ::SelectShell
2068  rSh.GetView().StopShellTimer();
2069  }
2070 
2071  pAction.reset();
2072  if( bCallAutoCaption )
2073  rSh.GetView().AutoCaption( GRAPHIC_CAP );
2074 
2075  return bRet;
2076 }
2077 
2079 {
2080  SotExchangeDest nRet = SotExchangeDest::NONE;
2081 
2082  ObjCntType eOType = rSh.GetObjCntTypeOfSelection();
2083 
2084  switch( eOType )
2085  {
2086  case OBJCNT_GRF:
2087  {
2088  bool bIMap, bLink;
2089  bIMap = nullptr != rSh.GetFlyFrameFormat()->GetURL().GetMap();
2090  OUString aDummy;
2091  rSh.GetGrfNms( &aDummy, nullptr );
2092  bLink = !aDummy.isEmpty();
2093 
2094  if( bLink && bIMap )
2095  nRet = SotExchangeDest::DOC_LNKD_GRAPH_W_IMAP;
2096  else if( bLink )
2097  nRet = SotExchangeDest::DOC_LNKD_GRAPHOBJ;
2098  else if( bIMap )
2099  nRet = SotExchangeDest::DOC_GRAPH_W_IMAP;
2100  else
2101  nRet = SotExchangeDest::DOC_GRAPHOBJ;
2102  }
2103  break;
2104 
2105  case OBJCNT_FLY:
2106  if( dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr )
2107  nRet = SotExchangeDest::DOC_TEXTFRAME_WEB;
2108  else
2109  nRet = SotExchangeDest::DOC_TEXTFRAME;
2110  break;
2111  case OBJCNT_OLE: nRet = SotExchangeDest::DOC_OLEOBJ; break;
2112 
2113  case OBJCNT_CONTROL: /* no Action avail */
2114  case OBJCNT_SIMPLE: nRet = SotExchangeDest::DOC_DRAWOBJ; break;
2115  case OBJCNT_URLBUTTON: nRet = SotExchangeDest::DOC_URLBUTTON; break;
2116  case OBJCNT_GROUPOBJ: nRet = SotExchangeDest::DOC_GROUPOBJ; break;
2117 
2118  // what do we do at multiple selections???
2119  default:
2120  {
2121  if( dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr )
2122  nRet = SotExchangeDest::SWDOC_FREE_AREA_WEB;
2123  else
2124  nRet = SotExchangeDest::SWDOC_FREE_AREA;
2125  }
2126  }
2127 
2128  return nRet;
2129 }
2130 
2132  SwWrtShell& rSh, SotClipboardFormatId nFormat, bool bMsg, bool bIgnoreComments )
2133 {
2134  TranslateId pResId = STR_CLPBRD_FORMAT_ERROR;
2135  bool bRet = false;
2136 
2137  MSE40HTMLClipFormatObj aMSE40ClpObj;
2138 
2140  SvStream* pStream = nullptr;
2141  Reader* pRead = nullptr;
2142  OUString sData;
2143  switch( nFormat )
2144  {
2145  case SotClipboardFormatId::STRING:
2146  {
2147  pRead = ReadAscii;
2148  if( rData.GetString( nFormat, sData ) )
2149  {
2150  pStream = new SvMemoryStream( const_cast<sal_Unicode *>(sData.getStr()),
2151  sData.getLength() * sizeof( sal_Unicode ),
2152  StreamMode::READ );
2153 #ifdef OSL_BIGENDIAN
2154  pStream->SetEndian( SvStreamEndian::BIG );
2155 #else
2156  pStream->SetEndian( SvStreamEndian::LITTLE );
2157 #endif
2158 
2159  SwAsciiOptions aAOpt;
2160  aAOpt.SetCharSet( RTL_TEXTENCODING_UCS2 );
2161  pRead->GetReaderOpt().SetASCIIOpts( aAOpt );
2162  break;
2163  }
2164  }
2165  [[fallthrough]]; // because then test if we get a stream
2166 
2167  default:
2168  if( rData.GetSotStorageStream( nFormat, xStrm ) )
2169  {
2170  if( ( SotClipboardFormatId::HTML_SIMPLE == nFormat ) ||
2171  ( SotClipboardFormatId::HTML_NO_COMMENT == nFormat ) )
2172  {
2173  pStream = aMSE40ClpObj.IsValid( *xStrm );
2174  pRead = ReadHTML;
2175  pRead->SetReadUTF8( true );
2176 
2177  bool bNoComments =
2178  ( nFormat == SotClipboardFormatId::HTML_NO_COMMENT );
2179  pRead->SetIgnoreHTMLComments( bNoComments );
2180  }
2181  else
2182  {
2183  pStream = xStrm.get();
2184  if( SotClipboardFormatId::RTF == nFormat || SotClipboardFormatId::RICHTEXT == nFormat)
2185  pRead = SwReaderWriter::GetRtfReader();
2186  else if( !pRead )
2187  {
2188  pRead = ReadHTML;
2189  pRead->SetReadUTF8( true );
2190  }
2191  }
2192  }
2193  break;
2194  }
2195 
2196  if( pStream && pRead )
2197  {
2198  Link<LinkParamNone*,void> aOldLink( rSh.GetChgLnk() );
2200 
2201  const SwPosition& rInsPos = *rSh.GetCursor()->Start();
2202  SwReader aReader(*pStream, OUString(), OUString(), *rSh.GetCursor());
2203  rSh.SaveTableBoxContent( &rInsPos );
2204 
2205  if (bIgnoreComments)
2206  pRead->SetIgnoreHTMLComments(true);
2207 
2208  if( aReader.Read( *pRead ).IsError() )
2209  pResId = STR_ERROR_CLPBRD_READ;
2210  else
2211  {
2212  pResId = TranslateId();
2213  bRet = true;
2214  }
2215 
2216  rSh.SetChgLnk( aOldLink );
2217  if( bRet )
2218  rSh.CallChgLnk();
2219  }
2220  else
2221  pResId = STR_CLPBRD_FORMAT_ERROR;
2222 
2223  // Exist a SvMemoryStream? (data in the OUString and xStrm is empty)
2224  if( pStream && !xStrm.is() )
2225  delete pStream;
2226 
2227  if (bMsg && pResId)
2228  {
2229  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2230  VclMessageType::Info, VclButtonsType::Ok,
2231  SwResId(pResId)));
2232  xBox->run();
2233  }
2234  return bRet;
2235 }
2236 
2238  SotClipboardFormatId nFormat, SotExchangeActionFlags nActionFlags, bool bMsg )
2239 {
2240  bool bRet = false;
2242  uno::Reference < io::XInputStream > xStrm;
2243  uno::Reference < embed::XStorage > xStore;
2244  Reader* pRead = nullptr;
2245 
2246  // Get the preferred format
2248  if( rData.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ ) )
2249  nId = SotClipboardFormatId::EMBEDDED_OBJ;
2250  else if( rData.HasFormat( SotClipboardFormatId::EMBED_SOURCE ) &&
2251  rData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ))
2252  nId = SotClipboardFormatId::EMBED_SOURCE;
2253  else
2254  nId = SotClipboardFormatId::NONE;
2255 
2256  if (nId != SotClipboardFormatId::NONE)
2257  {
2258  SwDocShell* pDocSh = rSh.GetDoc()->GetDocShell();
2259  xStrm = rData.GetInputStream(nId, SfxObjectShell::CreateShellID(pDocSh));
2260  }
2261 
2262  if (xStrm.is())
2263  {
2264  // if there is an embedded object, first try if it's a writer object
2265  // this will be inserted into the document by using a Reader
2266  try
2267  {
2269  switch( SotStorage::GetFormatID( xStore ) )
2270  {
2271  case SotClipboardFormatId::STARWRITER_60:
2272  case SotClipboardFormatId::STARWRITERWEB_60:
2273  case SotClipboardFormatId::STARWRITERGLOB_60:
2274  case SotClipboardFormatId::STARWRITER_8:
2275  case SotClipboardFormatId::STARWRITERWEB_8:
2276  case SotClipboardFormatId::STARWRITERGLOB_8:
2277  pRead = ReadXML;
2278  break;
2279  default:
2280  try
2281  {
2282  xStore->dispose();
2283  xStore = nullptr;
2284  }
2285  catch (const uno::Exception&)
2286  {
2287  }
2288 
2289  break;
2290  }
2291  }
2292  catch (const uno::Exception&)
2293  {
2294  // it wasn't a storage, but maybe it's a useful stream
2295  }
2296  }
2297 
2298  if( pRead )
2299  {
2300  SwPaM &rPAM = *rSh.GetCursor();
2301  SwReader aReader(xStore, OUString(), rPAM);
2302  if( ! aReader.Read( *pRead ).IsError() )
2303  bRet = true;
2304  else if( bMsg )
2305  {
2306  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2307  VclMessageType::Info, VclButtonsType::Ok,
2308  SwResId(STR_ERROR_CLPBRD_READ)));
2309  xBox->run();
2310  }
2311  }
2312  else
2313  {
2314  // temporary storage until the object is inserted
2315  uno::Reference< embed::XStorage > xTmpStor;
2316  uno::Reference < embed::XEmbeddedObject > xObj;
2317  OUString aName;
2319 
2320  if ( xStrm.is() )
2321  {
2322  if ( !rData.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc ) )
2323  {
2324  OSL_ENSURE( !xStrm.is(), "An object without descriptor in clipboard!");
2325  }
2326  }
2327  else
2328  {
2329  if( rData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE ) && rData.GetTransferableObjectDescriptor( nFormat, aObjDesc ) )
2330  {
2331  xStrm = rData.GetInputStream(SotClipboardFormatId::EMBED_SOURCE_OLE, OUString());
2332  if (!xStrm.is())
2333  xStrm = rData.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE, OUString());
2334 
2335  if ( !xStrm.is() )
2336  {
2337  // This is MSOLE object that should be created by direct using of system clipboard
2338  try
2339  {
2341  uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator =
2342  embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
2343 
2344  embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
2345  xTmpStor,
2346  "DummyName",
2347  uno::Sequence< beans::PropertyValue >() );
2348 
2349  // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
2350  // for example whether the object should be an iconified one
2351  xObj = aInfo.Object;
2352  }
2353  catch (const uno::Exception&)
2354  {
2355  }
2356  }
2357  }
2358  else if (rData.HasFormat(SotClipboardFormatId::SIMPLE_FILE))
2359  {
2360  OUString sFile;
2361  if (rData.GetString(nFormat, sFile) && !sFile.isEmpty())
2362  {
2363  // Copied from sd::View::DropInsertFileHdl
2364  uno::Sequence< beans::PropertyValue > aMedium{ comphelper::makePropertyValue(
2365  "URL", sFile) };
2366  SwDocShell* pDocSh = rSh.GetDoc()->GetDocShell();
2367  xObj = pDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject(aMedium, aName);
2368  }
2369  }
2370  }
2371 
2372  if ( xStrm.is() && !xObj.is() )
2373  xObj = aCnt.InsertEmbeddedObject( xStrm, aName );
2374 
2375  if( xObj.is() )
2376  {
2377  svt::EmbeddedObjectRef xObjRef( xObj, aObjDesc.mnViewAspect );
2378 
2379  // try to get the replacement image from the clipboard
2380  Graphic aGraphic;
2381  SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
2382 
2383  // limit the size of the preview metafile to 100000 actions
2384  GDIMetaFile aMetafile;
2385  if (rData.GetGDIMetaFile(SotClipboardFormatId::GDIMETAFILE, aMetafile, 100000))
2386  {
2387  nGrFormat = SotClipboardFormatId::GDIMETAFILE;
2388  aGraphic = aMetafile;
2389  }
2390 
2391  // insert replacement image ( if there is one ) into the object helper
2392  if ( nGrFormat != SotClipboardFormatId::NONE )
2393  {
2394  DataFlavor aDataFlavor;
2395  SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
2396  xObjRef.SetGraphic( aGraphic, aDataFlavor.MimeType );
2397  }
2398  else if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
2399  {
2400  // it is important to have an icon, let an empty graphic be used
2401  // if no other graphic is provided
2402  // TODO/LATER: in future a default bitmap could be used
2403  MapMode aMapMode( MapUnit::Map100thMM );
2404  aGraphic.SetPrefSize( Size( 2500, 2500 ) );
2405  aGraphic.SetPrefMapMode( aMapMode );
2406  xObjRef.SetGraphic( aGraphic, OUString() );
2407  }
2408 
2409  //set size. This is a hack because of handing over, size should be
2410  //passed to the InsertOle!!!!!!!!!!
2411  Size aSize;
2412  if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
2413  {
2414  if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
2415  aSize = aObjDesc.maSize;
2416  else
2417  {
2418  MapMode aMapMode( MapUnit::Map100thMM );
2419  aSize = xObjRef.GetSize( &aMapMode );
2420  }
2421  }
2422  else if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
2423  {
2424  aSize = aObjDesc.maSize; //always 100TH_MM
2425  MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) );
2426  aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(aUnit));
2427  awt::Size aSz;
2428  try
2429  {
2430  aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
2431  }
2432  catch (const embed::NoVisualAreaSizeException&)
2433  {
2434  // in this case the provided size is used
2435  }
2436 
2437  if ( aSz.Width != aSize.Width() || aSz.Height != aSize.Height() )
2438  {
2439  aSz.Width = aSize.Width();
2440  aSz.Height = aSize.Height();
2441  xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
2442  }
2443  }
2444  else
2445  {
2446  // the descriptor contains the wrong object size
2447  // the following call will let the MSOLE objects cache the size if it is possible
2448  // it should be done while the object is running
2449  try
2450  {
2451  xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
2452  }
2453  catch (const uno::Exception&)
2454  {
2455  }
2456  }
2457  //End of Hack!
2458 
2459  rSh.InsertOleObject( xObjRef );
2460  bRet = true;
2461 
2462  if( bRet && ( nActionFlags & SotExchangeActionFlags::InsertTargetUrl) )
2463  SwTransferable::PasteTargetURL( rData, rSh, SwPasteSdr::NONE, nullptr, false );
2464 
2465  // let the object be unloaded if possible
2466  SwOLEObj::UnloadObject( xObj, rSh.GetDoc(), embed::Aspects::MSOLE_CONTENT );
2467  }
2468  }
2469  return bRet;
2470 }
2471 
2473  SwWrtShell& rSh, SwPasteSdr nAction,
2474  const Point* pPt, bool bInsertGRF )
2475 {
2476  bool bRet = false;
2477  INetImage aINetImg;
2478  if( ( rData.HasFormat( SotClipboardFormatId::INET_IMAGE ) &&
2479  rData.GetINetImage( SotClipboardFormatId::INET_IMAGE, aINetImg )) ||
2480  ( rData.HasFormat( SotClipboardFormatId::NETSCAPE_IMAGE ) &&
2481  rData.GetINetImage( SotClipboardFormatId::NETSCAPE_IMAGE, aINetImg )) )
2482  {
2483  if( !aINetImg.GetImageURL().isEmpty() && bInsertGRF )
2484  {
2485  OUString sURL( aINetImg.GetImageURL() );
2486  SwTransferable::CheckForURLOrLNKFile( rData, sURL );
2487 
2489  Graphic aGraphic;
2491  bRet = ERRCODE_NONE == GraphicFilter::LoadGraphic(sURL, OUString(), aGraphic, &rFlt);
2492 
2493  if( bRet )
2494  {
2495  //Check and Perform rotation if needed
2496  lclCheckAndPerformRotation(aGraphic);
2497 
2498  switch( nAction )
2499  {
2500  case SwPasteSdr::Insert:
2501  SwTransferable::SetSelInShell( rSh, false, pPt );
2502  rSh.InsertGraphic(sURL, OUString(), aGraphic);
2503  break;
2504 
2505  case SwPasteSdr::Replace:
2506  if( rSh.IsObjSelected() )
2507  {
2508  rSh.ReplaceSdrObj( sURL, &aGraphic );
2509  Point aPt( pPt ? *pPt : rSh.GetCursorDocPos() );
2510  SwTransferable::SetSelInShell( rSh, true, &aPt );
2511  }
2512  else
2513  rSh.ReRead(sURL, OUString(), &aGraphic);
2514  break;
2515 
2516  case SwPasteSdr::SetAttr:
2517  if( rSh.IsObjSelected() )
2518  rSh.Paste( aGraphic, OUString() );
2519  else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() )
2520  rSh.ReRead(sURL, OUString(), &aGraphic);
2521  else
2522  {
2523  SwTransferable::SetSelInShell( rSh, false, pPt );
2524  rSh.InsertGraphic(sURL, OUString(), aGraphic);
2525  }
2526  break;
2527  default:
2528  bRet = false;
2529  }
2530  }
2531  }
2532  else
2533  bRet = true;
2534  }
2535 
2536  if( bRet )
2537  {
2539  rSh.GetFlyFrameAttr( aSet );
2540  SwFormatURL aURL( aSet.Get( RES_URL ) );
2541 
2542  if( aURL.GetURL() != aINetImg.GetTargetURL() ||
2543  aURL.GetTargetFrameName() != aINetImg.GetTargetFrame() )
2544  {
2545  aURL.SetURL( aINetImg.GetTargetURL(), false );
2546  aURL.SetTargetFrameName( aINetImg.GetTargetFrame() );
2547  aSet.Put( aURL );
2548  rSh.SetFlyFrameAttr( aSet );
2549  }
2550  }
2551  return bRet;
2552 }
2553 
2554 void SwTransferable::SetSelInShell( SwWrtShell& rSh, bool bSelectFrame,
2555  const Point* pPt )
2556 {
2557  if( bSelectFrame )
2558  {
2559  // select frames/objects
2560  if( pPt && !rSh.GetView().GetViewFrame()->GetDispatcher()->IsLocked() )
2561  {
2562  rSh.GetView().NoRotate();
2563  if( rSh.SelectObj( *pPt ))
2564  {
2565  rSh.HideCursor();
2566  rSh.EnterSelFrameMode( pPt );
2567  g_bFrameDrag = true;
2568  }
2569  }
2570  }
2571  else
2572  {
2573  if( rSh.IsFrameSelected() || rSh.IsObjSelected() )
2574  {
2575  rSh.UnSelectFrame();
2576  rSh.LeaveSelFrameMode();
2577  rSh.GetView().GetEditWin().StopInsFrame();
2578  g_bFrameDrag = false;
2579  }
2580  else if( rSh.GetView().GetDrawFuncPtr() )
2581  rSh.GetView().GetEditWin().StopInsFrame();
2582 
2583  rSh.EnterStdMode();
2584  if( pPt )
2585  rSh.SwCursorShell::SetCursor( *pPt, true );
2586  }
2587 }
2588 
2590  SwWrtShell& rWrtShell, bool bReReadGrf,
2591  bool bMsg )
2592 {
2593  // data from Clipboardformat
2594  OUString aApp, aTopic, aItem;
2595 
2596  {
2598  if( !rData.GetSotStorageStream( SotClipboardFormatId::LINK, xStrm ))
2599  {
2600  OSL_ENSURE( false, "DDE Data not found." );
2601  return false;
2602  } // report useful error!!
2603 
2604  rtl_TextEncoding eEncoding = osl_getThreadTextEncoding();
2605  aApp = read_zeroTerminated_uInt8s_ToOUString(*xStrm, eEncoding);
2606  aTopic = read_zeroTerminated_uInt8s_ToOUString(*xStrm, eEncoding);
2607  aItem = read_zeroTerminated_uInt8s_ToOUString(*xStrm, eEncoding);
2608  }
2609 
2610  OUString aCmd;
2611  sfx2::MakeLnkName( aCmd, &aApp, aTopic, aItem );
2612 
2613  // do we want to read in a graphic now?
2614  SotClipboardFormatId nFormat;
2615  if( !rData.HasFormat( SotClipboardFormatId::RTF ) &&
2616  !rData.HasFormat( SotClipboardFormatId::RICHTEXT ) &&
2617  !rData.HasFormat( SotClipboardFormatId::HTML ) &&
2618  !rData.HasFormat( SotClipboardFormatId::STRING ) &&
2619  (rData.HasFormat( nFormat = SotClipboardFormatId::GDIMETAFILE ) ||
2620  rData.HasFormat( nFormat = SotClipboardFormatId::BITMAP )) )
2621  {
2622  Graphic aGrf;
2623  bool bRet = rData.GetGraphic( nFormat, aGrf );
2624  if( bRet )
2625  {
2626  OUString sLnkTyp("DDE");
2627  if ( bReReadGrf )
2628  rWrtShell.ReRead( aCmd, sLnkTyp, &aGrf );
2629  else
2630  rWrtShell.InsertGraphic( aCmd, sLnkTyp, aGrf );
2631  }
2632  return bRet;
2633  }
2634 
2635  SwFieldType* pTyp = nullptr;
2636  size_t i = 1;
2637  size_t j;
2638  OUString aName;
2639  bool bDoublePaste = false;
2640  const size_t nSize = rWrtShell.GetFieldTypeCount();
2641  const ::utl::TransliterationWrapper& rColl = ::GetAppCmpStrIgnore();
2642 
2643  do {
2644  aName = aApp + OUString::number( i );
2645  for( j = INIT_FLDTYPES; j < nSize; j++ )
2646  {
2647  pTyp = rWrtShell.GetFieldType( j );
2648  if( SwFieldIds::Dde == pTyp->Which() )
2649  {
2650  if( rColl.isEqual( static_cast<SwDDEFieldType*>(pTyp)->GetCmd(), aCmd ) &&
2651  SfxLinkUpdateMode::ALWAYS == static_cast<SwDDEFieldType*>(pTyp)->GetType() )
2652  {
2653  aName = pTyp->GetName();
2654  bDoublePaste = true;
2655  break;
2656  }
2657  else if( rColl.isEqual( aName, pTyp->GetName() ) )
2658  break;
2659  }
2660  }
2661  if( j == nSize )
2662  break;
2663  ++i;
2664  }
2665  while( !bDoublePaste );
2666 
2667  if( !bDoublePaste )
2668  {
2669  SwDDEFieldType aType( aName, aCmd, SfxLinkUpdateMode::ALWAYS );
2670  pTyp = rWrtShell.InsertFieldType( aType );
2671  }
2672 
2673  SwDDEFieldType* pDDETyp = static_cast<SwDDEFieldType*>(pTyp);
2674 
2675  OUString aExpand;
2676  if( rData.GetString( SotClipboardFormatId::STRING, aExpand ))
2677  {
2678  do { // middle checked loop
2679 
2680  const sal_Int32 nNewlines{comphelper::string::getTokenCount(aExpand, '\n')};
2681  // When data comes from a spreadsheet, we add a DDE-table
2682  if( !aExpand.isEmpty() &&
2683  ( rData.HasFormat( SotClipboardFormatId::SYLK ) ||
2684  rData.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS ) ) )
2685  {
2686  sal_Int32 nRows = nNewlines ? nNewlines-1 : 0;
2687  if (!aExpand.endsWith("\n"))
2688  ++nRows; // last row has no newline, e.g. one single cell
2689  const sal_Int32 nCols = comphelper::string::getTokenCount(o3tl::getToken(aExpand, 0, '\n'), '\t');
2690 
2691  // don't try to insert tables that are too large for writer
2692  if (nRows > SAL_MAX_UINT16 || nCols > SAL_MAX_UINT16)
2693  {
2694  if( bMsg )
2695  {
2696  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2697  VclMessageType::Info, VclButtonsType::Ok,
2698  SwResId(STR_TABLE_TOO_LARGE)));
2699  xBox->run();
2700  }
2701  pDDETyp = nullptr;
2702  break;
2703  }
2704 
2705  // at least one column & row must be there
2706  if( !nRows || !nCols )
2707  {
2708  if( bMsg )
2709  {
2710  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2711  VclMessageType::Info, VclButtonsType::Ok,
2712  SwResId(STR_NO_TABLE)));
2713  xBox->run();
2714  }
2715  pDDETyp = nullptr;
2716  break;
2717  }
2718 
2719  rWrtShell.InsertDDETable(
2720  SwInsertTableOptions( SwInsertTableFlags::SplitLayout, 1 ), // TODO MULTIHEADER
2721  pDDETyp, nRows, nCols );
2722  }
2723  else if( nNewlines > 1 )
2724  {
2725  // multiple paragraphs -> insert a protected section
2726  if( rWrtShell.HasSelection() )
2727  rWrtShell.DelRight();
2728 
2729  SwSectionData aSect( SectionType::DdeLink, aName );
2730  aSect.SetLinkFileName( aCmd );
2731  aSect.SetProtectFlag(true);
2732  rWrtShell.InsertSection( aSect );
2733 
2734  pDDETyp = nullptr; // remove FieldTypes again
2735  }
2736  else
2737  {
2738  // insert
2739  SwDDEField aSwDDEField( pDDETyp );
2740  rWrtShell.InsertField2( aSwDDEField );
2741  }
2742 
2743  } while( false );
2744  }
2745  else
2746  pDDETyp = nullptr; // remove FieldTypes again
2747 
2748  if( !pDDETyp && !bDoublePaste )
2749  {
2750  // remove FieldType again - error occurred!
2751  for( j = nSize; j >= INIT_FLDTYPES; --j )
2752  if( pTyp == rWrtShell.GetFieldType( j ) )
2753  {
2754  rWrtShell.RemoveFieldType( j );
2755  break;
2756  }
2757  }
2758 
2759  return true;
2760 }
2761 
2763  SwWrtShell& rSh, SwPasteSdr nAction,
2764  const Point* pPt, SotExchangeActionFlags nActionFlags, bool bNeedToSelectBeforePaste)
2765 {
2766  bool bRet = false;
2768  if( rData.GetSotStorageStream( SotClipboardFormatId::DRAWING, xStrm ))
2769  {
2770  xStrm->SetVersion( SOFFICE_FILEFORMAT_50 );
2771 
2772  if(bNeedToSelectBeforePaste && pPt)
2773  {
2774  // if this is an internal drag, need to set the target right (select it), else
2775  // still the source will be selected
2776  SwTransferable::SetSelInShell( rSh, true, pPt );
2777  }
2778 
2779  rSh.Paste( *xStrm, nAction, pPt );
2780  bRet = true;
2781 
2782  if( bRet && ( nActionFlags & SotExchangeActionFlags::InsertTargetUrl ))
2783  SwTransferable::PasteTargetURL( rData, rSh, SwPasteSdr::NONE, nullptr, false );
2784  }
2785  return bRet;
2786 }
2787 
2789  SotClipboardFormatId nFormat, SwPasteSdr nAction, const Point* pPt,
2790  SotExchangeActionFlags nActionFlags, sal_Int8 nDropAction, bool bNeedToSelectBeforePaste, RndStdIds nAnchorType )
2791 {
2792  bool bRet = false;
2793 
2794  Graphic aGraphic;
2795  INetBookmark aBkmk;
2796  bool bCheckForGrf = false, bCheckForImageMap = false;
2797 
2798  switch( nFormat )
2799  {
2800  case SotClipboardFormatId::BITMAP:
2801  case SotClipboardFormatId::PNG:
2802  case SotClipboardFormatId::GDIMETAFILE:
2803  bRet = rData.GetGraphic( nFormat, aGraphic );
2804  break;
2805 
2806  case SotClipboardFormatId::SVXB:
2807  {
2809 
2810  if(rData.GetSotStorageStream(SotClipboardFormatId::SVXB, xStm))
2811  {
2812  TypeSerializer aSerializer(*xStm);
2813  aSerializer.readGraphic(aGraphic);
2814  bRet = (GraphicType::NONE != aGraphic.GetType() && GraphicType::Default != aGraphic.GetType());
2815  }
2816 
2817  break;
2818  }
2819 
2820  case SotClipboardFormatId::NETSCAPE_BOOKMARK:
2821  case SotClipboardFormatId::FILEGRPDESCRIPTOR:
2822  case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
2823  bRet = rData.GetINetBookmark( nFormat, aBkmk );
2824  if( bRet )
2825  {
2826  if( SwPasteSdr::SetAttr == nAction )
2827  nFormat = SotClipboardFormatId::NETSCAPE_BOOKMARK;
2828  else
2829  bCheckForGrf = true;
2830  }
2831  break;
2832 
2833  case SotClipboardFormatId::SIMPLE_FILE:
2834  {
2835  OUString sText;
2836  bRet = rData.GetString( nFormat, sText );
2837  if( bRet )
2838  {
2839  OUString sDesc;
2840  SwTransferable::CheckForURLOrLNKFile( rData, sText, &sDesc );
2841 
2843  false);
2844 
2845 #ifdef _WIN32
2846  // Now that the path could be modified after SwTransferable::CheckForURLOrLNKFile,
2847  // where it could have been converted to URL, and made sure it's actually converted
2848  // to URL in URIHelper::SmartRel2Abs, we can finally convert file: URL back to
2849  // system path to make sure we don't use short path.
2850  // It looks not optimal, when we could apply GetLongPathNameW right to the original
2851  // pasted filename. But I don't know if (1) all arriving strings are system paths;
2852  // and (2) if SwTransferable::CheckForURLOrLNKFile could result in a different short
2853  // path, so taking a safe route.
2854  if (sText.startsWithIgnoreAsciiCase("file:"))
2855  {
2856  // tdf#124500: Convert short path to long path which should be used in links
2857  OUString sSysPath;
2858  osl::FileBase::getSystemPathFromFileURL(sText, sSysPath);
2859  std::unique_ptr<sal_Unicode[]> aBuf(new sal_Unicode[32767]);
2860  DWORD nCopied = GetLongPathNameW(o3tl::toW(sSysPath.getStr()),
2861  o3tl::toW(aBuf.get()), 32767);
2862  if (nCopied && nCopied < 32767)
2863  sText = URIHelper::SmartRel2Abs(INetURLObject(), OUString(aBuf.get()),
2864  Link<OUString*, bool>(), false);
2865  }
2866 #endif
2867 
2868  aBkmk = INetBookmark(sText, sDesc);
2869  bCheckForGrf = true;
2870  bCheckForImageMap = SwPasteSdr::Replace == nAction;
2871  }
2872  }
2873  break;
2874 
2875  default:
2876  bRet = rData.GetGraphic( nFormat, aGraphic );
2877  break;
2878  }
2879 
2880  if( bCheckForGrf )
2881  {
2884  bRet = ERRCODE_NONE == GraphicFilter::LoadGraphic(aBkmk.GetURL(), OUString(),
2885  aGraphic, &rFlt );
2886 
2887  if( !bRet && SwPasteSdr::SetAttr == nAction &&
2888  SotClipboardFormatId::SIMPLE_FILE == nFormat &&
2889  // only at frame selection
2890  rSh.IsFrameSelected() )
2891  {
2892  // then set as hyperlink after the graphic
2893  nFormat = SotClipboardFormatId::NETSCAPE_BOOKMARK;
2894  bRet = true;
2895  }
2896  }
2897 
2898  if(pPt && bNeedToSelectBeforePaste)
2899  {
2900  // when using internal D&Ds, still the source object is selected and
2901  // this is necessary to get the correct source data which is also
2902  // dependent from selection. After receiving the drag data it is
2903  // now time to select the correct target object
2904  SwTransferable::SetSelInShell( rSh, true, pPt );
2905  }
2906 
2907  if( bRet )
2908  {
2909  //Check and Perform rotation if needed
2910  lclCheckAndPerformRotation(aGraphic);
2911 
2912  OUString sURL;
2913  if( dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr
2914  // #i123922# if link action is noted, also take URL
2915  || DND_ACTION_LINK == nDropAction)
2916  {
2917  sURL = aBkmk.GetURL();
2918  }
2919 
2920  switch( nAction )
2921  {
2922  case SwPasteSdr::Insert:
2923  {
2924  SwTransferable::SetSelInShell( rSh, false, pPt );
2925  rSh.InsertGraphic(sURL, OUString(), aGraphic, nullptr, nAnchorType);
2926  break;
2927  }
2928 
2929  case SwPasteSdr::Replace:
2930  {
2931  if( rSh.IsObjSelected() )
2932  {
2933  // #i123922# for D&D on draw objects, do for now the same for
2934  // SwPasteSdr::Replace (D&D) as for SwPasteSdr::SetAttr (D&D and
2935  // CTRL+SHIFT). The code below replaces the draw object with
2936  // a writer graphic; maybe this is an option later again if wanted
2937  rSh.Paste( aGraphic, sURL );
2938 
2939  // rSh.ReplaceSdrObj(sURL, OUString(), &aGraphic);
2940  // Point aPt( pPt ? *pPt : rSh.GetCursorDocPos() );
2941  // SwTransferable::SetSelInShell( rSh, true, &aPt );
2942  }
2943  else
2944  {
2945  // set graphic at writer graphic without link
2946  rSh.ReRead(sURL, OUString(), &aGraphic);
2947  }
2948 
2949  break;
2950  }
2951 
2952  case SwPasteSdr::SetAttr:
2953  {
2954  if( SotClipboardFormatId::NETSCAPE_BOOKMARK == nFormat )
2955  {
2956  if( rSh.IsFrameSelected() )
2957  {
2959  rSh.GetFlyFrameAttr( aSet );
2960  SwFormatURL aURL( aSet.Get( RES_URL ) );
2961  aURL.SetURL( aBkmk.GetURL(), false );
2962  aSet.Put( aURL );
2963  rSh.SetFlyFrameAttr( aSet );
2964  }
2965  }
2966  else if( rSh.IsObjSelected() )
2967  {
2968  // set as attribute at DrawObject
2969  rSh.Paste( aGraphic, sURL );
2970  }
2971  else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() )
2972  {
2973  // set as linked graphic at writer graphic frame
2974  rSh.ReRead(sURL, OUString(), &aGraphic);
2975  }
2976  else
2977  {
2978  SwTransferable::SetSelInShell( rSh, false, pPt );
2979  rSh.InsertGraphic(aBkmk.GetURL(), OUString(), aGraphic);
2980  }
2981  break;
2982  }
2983  default:
2984  {
2985  bRet = false;
2986  break;
2987  }
2988  }
2989  }
2990 
2991  if( bRet )
2992  {
2993 
2994  if( nActionFlags &
2995  ( SotExchangeActionFlags::InsertImageMap | SotExchangeActionFlags::ReplaceImageMap ) )
2996  SwTransferable::PasteImageMap( rData, rSh );
2997 
2998  if( nActionFlags & SotExchangeActionFlags::InsertTargetUrl )
2999  SwTransferable::PasteTargetURL( rData, rSh, SwPasteSdr::NONE, nullptr, false );
3000  }
3001  else if( bCheckForImageMap )
3002  {
3003  // or should the file be an ImageMap-File?
3004  ImageMap aMap;
3005  SfxMedium aMed( INetURLObject(aBkmk.GetURL()).GetFull(),
3006  StreamMode::STD_READ );
3007  SvStream* pStream = aMed.GetInStream();
3008  if( pStream != nullptr &&
3009  !pStream->GetError() &&
3010  // mba: no BaseURL for clipboard functionality
3011  aMap.Read( *pStream, IMapFormat::Detect ) == IMAP_ERR_OK &&
3012  aMap.GetIMapObjectCount() )
3013  {
3015  rSh.GetFlyFrameAttr( aSet );
3016  SwFormatURL aURL( aSet.Get( RES_URL ) );
3017  aURL.SetMap( &aMap );
3018  aSet.Put( aURL );
3019  rSh.SetFlyFrameAttr( aSet );
3020  bRet = true;
3021  }
3022  }
3023 
3024  return bRet;
3025 }
3026 
3028  SwWrtShell& rSh )
3029 {
3030  bool bRet = false;
3031  if( rData.HasFormat( SotClipboardFormatId::SVIM ))
3032  {
3034  rSh.GetFlyFrameAttr( aSet );
3035  SwFormatURL aURL( aSet.Get( RES_URL ) );
3036  const ImageMap* pOld = aURL.GetMap();
3037 
3038  // set or replace, that is the question
3039  ImageMap aImageMap;
3040  if( rData.GetImageMap( SotClipboardFormatId::SVIM, aImageMap ) &&
3041  ( !pOld || aImageMap != *pOld ))
3042  {
3043  aURL.SetMap( &aImageMap );
3044  aSet.Put( aURL );
3045  rSh.SetFlyFrameAttr( aSet );
3046  }
3047  bRet = true;
3048  }
3049  return bRet;
3050 }
3051 
3053  SwWrtShell& rSh, SotClipboardFormatId nFormat )
3054 {
3055  bool bRet = false;
3056  OUString sFile;
3057  if( rData.GetString( nFormat, sFile ) && !sFile.isEmpty() )
3058  {
3059  OUString sDesc;
3060  SwTransferable::CheckForURLOrLNKFile( rData, sFile, &sDesc );
3061 
3062  // first, make the URL absolute
3064  aURL.SetSmartProtocol( INetProtocol::File );
3065  aURL.SetSmartURL( sFile );
3067 
3068  switch( rSh.GetObjCntTypeOfSelection() )
3069  {
3070  case OBJCNT_FLY:
3071  case OBJCNT_GRF:
3072  case OBJCNT_OLE:
3073  {
3075  rSh.GetFlyFrameAttr( aSet );
3076  SwFormatURL aURL2( aSet.Get( RES_URL ) );
3077  aURL2.SetURL( sFile, false );
3078  if( aURL2.GetName().isEmpty() )
3079  aURL2.SetName( sFile );
3080  aSet.Put( aURL2 );
3081  rSh.SetFlyFrameAttr( aSet );
3082  }
3083  break;
3084 
3085  default:
3086  {
3087  rSh.InsertURL( SwFormatINetFormat( sFile, OUString() ),
3088  sDesc.isEmpty() ? sFile : sDesc);
3089  }
3090  }
3091  bRet = true;
3092  }
3093  return bRet;
3094 }
3095 
3097  SwWrtShell& rSh, SotClipboardFormatId nFormat,
3098  SwPasteSdr nAction, const Point* pPt,
3099  SotExchangeActionFlags nActionFlags,
3100  bool * graphicInserted)
3101 {
3102  bool bRet = SwTransferable::PasteGrf( rData, rSh, nFormat, nAction,
3103  pPt, nActionFlags, 0, false);
3104  if (graphicInserted != nullptr) {
3105  *graphicInserted = bRet;
3106  }
3107  if( !bRet )
3108  {
3109  OUString sFile, sDesc;
3110  if( rData.GetString( nFormat, sFile ) && !sFile.isEmpty() )
3111  {
3112 #if HAVE_FEATURE_AVMEDIA
3113  INetURLObject aMediaURL;
3114 
3115  aMediaURL.SetSmartURL( sFile );
3116  const OUString aMediaURLStr( aMediaURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
3117 
3118  if( ::avmedia::MediaWindow::isMediaURL( aMediaURLStr, ""/*TODO?*/ ) )
3119  {
3120  const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aMediaURLStr );
3122  SID_INSERT_AVMEDIA, SfxCallMode::SYNCHRON,
3123  { &aMediaURLItem });
3124  }
3125 #else
3126  if (false)
3127  {
3128  }
3129 #endif
3130  else
3131  {
3132  bool bIsURLFile = SwTransferable::CheckForURLOrLNKFile( rData, sFile, &sDesc );
3133 
3134  //Own FileFormat? --> insert, not for StarWriter/Web
3135  OUString sFileURL = URIHelper::SmartRel2Abs(INetURLObject(), sFile, Link<OUString *, bool>(), false );
3136  std::shared_ptr<const SfxFilter> pFlt = SwPasteSdr::SetAttr == nAction
3137  ? nullptr : SwIoSystem::GetFileFilter(sFileURL);
3138  if( pFlt && dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) == nullptr )
3139  {
3140  // and then pull up the insert-region-dialog
3141  SwSectionData aSect(
3143  rSh.GetDoc()->GetUniqueSectionName() );
3144  aSect.SetLinkFileName( sFileURL );
3145  aSect.SetProtectFlag( true );
3146 
3147  rSh.StartInsertRegionDialog( aSect ); // starts dialog asynchronously
3148  bRet = true;
3149  }
3150  else if (SwPasteSdr::Insert == nAction && rData.HasFormat(SotClipboardFormatId::SIMPLE_FILE))
3151  {
3152  // insert file as OLE
3153  PasteOLE(rData, rSh, nFormat, nActionFlags, nullptr == pPt);
3154  }
3155  else if( SwPasteSdr::SetAttr == nAction ||
3156  ( bIsURLFile && SwPasteSdr::Insert == nAction ))
3157  {
3158  //we can insert foreign files as links after all
3159 
3160  // first, make the URL absolute
3162  aURL.SetSmartProtocol( INetProtocol::File );
3163  aURL.SetSmartURL( sFile );
3165 
3166  switch( rSh.GetObjCntTypeOfSelection() )
3167  {
3168  case OBJCNT_FLY:
3169  case OBJCNT_GRF:
3170  case OBJCNT_OLE:
3171  {
3173  rSh.GetFlyFrameAttr( aSet );
3174  SwFormatURL aURL2( aSet.Get( RES_URL ) );
3175  aURL2.SetURL( sFile, false );
3176  if( aURL2.GetName().isEmpty() )
3177  aURL2.SetName( sFile );
3178  aSet.Put( aURL2 );
3179  rSh.SetFlyFrameAttr( aSet );
3180  }
3181  break;
3182 
3183  default:
3184  {
3185  rSh.InsertURL( SwFormatINetFormat( sFile, OUString() ),
3186  sDesc.isEmpty() ? sFile : sDesc );
3187  }
3188  }
3189  bRet = true;
3190  }
3191  }
3192  }
3193  }
3194  return bRet;
3195 }
3196 
3198  SwWrtShell& rSh, SotClipboardFormatId nFormat, bool bLink,
3199  const Point* pDragPt, bool bMsg )
3200 {
3201  bool bRet = false;
3202  OUString sText;
3203  if( rData.GetString( nFormat, sText ) && !sText.isEmpty() )
3204  {
3205  sal_uInt16 nWh = SotClipboardFormatId::SBA_CTRLDATAEXCHANGE == nFormat
3206  ? 0
3207  : SotClipboardFormatId::SBA_DATAEXCHANGE == nFormat
3208  ? (bLink
3210  : FN_QRY_INSERT)
3211  : (bLink
3212  ? 0
3213  : FN_QRY_INSERT_FIELD );
3214  const DataFlavorExVector& rVector = rData.GetDataFlavorExVector();
3215  bool bHaveColumnDescriptor = OColumnTransferable::canExtractColumnDescriptor(rVector, ColumnTransferFormatFlags::COLUMN_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE);
3216  if ( SotClipboardFormatId::XFORMS == nFormat )
3217  {
3218  rSh.MakeDrawView();
3219  FmFormView* pFmView = dynamic_cast<FmFormView*>( rSh.GetDrawView() );
3220  if (pFmView && pDragPt)
3221  {
3222  const OXFormsDescriptor &rDesc = OXFormsTransferable::extractDescriptor(rData);
3223  SdrObjectUniquePtr pObj = pFmView->CreateXFormsControl(rDesc);
3224  if(pObj)
3225  {
3226  rSh.SwFEShell::InsertDrawObj( *(pObj.release()), *pDragPt );
3227  }
3228  }
3229  }
3230  else if( nWh )
3231  {
3232  std::unique_ptr<SfxUnoAnyItem> pConnectionItem;
3233  std::unique_ptr<SfxUnoAnyItem> pCursorItem;
3234  std::unique_ptr<SfxUnoAnyItem> pColumnItem;
3235  std::unique_ptr<SfxUnoAnyItem> pSourceItem;
3236  std::unique_ptr<SfxUnoAnyItem> pCommandItem;
3237  std::unique_ptr<SfxUnoAnyItem> pCommandTypeItem;
3238  std::unique_ptr<SfxUnoAnyItem> pColumnNameItem;
3239  std::unique_ptr<SfxUnoAnyItem> pSelectionItem;
3240 
3241  bool bDataAvailable = true;
3242  ODataAccessDescriptor aDesc;
3243  if(bHaveColumnDescriptor)
3244  aDesc = OColumnTransferable::extractColumnDescriptor(rData);
3245  else if(ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
3246  aDesc = ODataAccessObjectTransferable::extractObjectDescriptor(rData);
3247  else
3248  bDataAvailable = false;
3249 
3250  if ( bDataAvailable )
3251  {
3252  pConnectionItem.reset(new SfxUnoAnyItem(FN_DB_CONNECTION_ANY, aDesc[DataAccessDescriptorProperty::Connection]));
3253  pColumnItem.reset(new SfxUnoAnyItem(FN_DB_COLUMN_ANY, aDesc[DataAccessDescriptorProperty::ColumnObject]));
3254  pSourceItem.reset(new SfxUnoAnyItem(FN_DB_DATA_SOURCE_ANY, Any(aDesc.getDataSource())));
3255  pCommandItem.reset(new SfxUnoAnyItem(FN_DB_DATA_COMMAND_ANY, aDesc[DataAccessDescriptorProperty::Command]));
3256  pCommandTypeItem.reset(new SfxUnoAnyItem(FN_DB_DATA_COMMAND_TYPE_ANY, aDesc[DataAccessDescriptorProperty::CommandType]));
3257  pColumnNameItem.reset(new SfxUnoAnyItem(FN_DB_DATA_COLUMN_NAME_ANY, aDesc[DataAccessDescriptorProperty::ColumnName]));
3258  pSelectionItem.reset(new SfxUnoAnyItem(FN_DB_DATA_SELECTION_ANY, aDesc[DataAccessDescriptorProperty::Selection]));
3259  pCursorItem.reset(new SfxUnoAnyItem(FN_DB_DATA_CURSOR_ANY, aDesc[DataAccessDescriptorProperty::Cursor]));
3260  }
3261 
3262  SwView& rView = rSh.GetView();
3263  //force ::SelectShell
3264  rView.StopShellTimer();
3265 
3266  SfxStringItem aDataDesc( nWh, sText );
3268  nWh, SfxCallMode::ASYNCHRON,
3269  { &aDataDesc, pConnectionItem.get(), pColumnItem.get(),
3270  pSourceItem.get(), pCommandItem.get(), pCommandTypeItem.get(),
3271  pColumnNameItem.get(), pSelectionItem.get(),
3272  pCursorItem.get() });
3273  }
3274  else
3275  {
3276  rSh.MakeDrawView();
3277  FmFormView* pFmView = dynamic_cast<FmFormView*>( rSh.GetDrawView() );
3278  if (pFmView && bHaveColumnDescriptor && pDragPt)
3279  {
3280  SdrObjectUniquePtr pObj = pFmView->CreateFieldControl( OColumnTransferable::extractColumnDescriptor(rData) );
3281  if (pObj)
3282  rSh.SwFEShell::InsertDrawObj( *(pObj.release()), *pDragPt );
3283  }
3284  }
3285  bRet = true;
3286  }
3287  else if( bMsg )
3288  {
3289  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
3290  VclMessageType::Info, VclButtonsType::Ok,
3291  SwResId(STR_CLPBRD_FORMAT_ERROR)));
3292  xBox->run();
3293  }
3294  return bRet;
3295 }
3296 
3298  SwWrtShell& rSh, bool bLink,
3299  const Point* pPt, bool bMsg )
3300 {
3301  bool bRet = false;
3302  FileList aFileList;
3303  if( rData.GetFileList( SotClipboardFormatId::FILE_LIST, aFileList ) &&
3304  aFileList.Count() )
3305  {
3307  OUString sFlyNm;
3308  // iterate over the filelist
3309  for( sal_uLong n = 0, nEnd = aFileList.Count(); n < nEnd; ++n )
3310  {
3312  pHlp->CopyString( SotClipboardFormatId::SIMPLE_FILE, aFileList.GetFile( n ));
3313  TransferableDataHelper aData( pHlp );
3314 
3315  if( SwTransferable::PasteFileName( aData, rSh, SotClipboardFormatId::SIMPLE_FILE, nAct,
3316  pPt, SotExchangeActionFlags::NONE, nullptr ))
3317  {
3318  if( bLink )
3319  {
3320  sFlyNm = rSh.GetFlyName();
3321  SwTransferable::SetSelInShell( rSh, false, pPt );
3322  }
3323  bRet = true;
3324  }
3325  }
3326  if( !sFlyNm.isEmpty() )
3327  rSh.GotoFly( sFlyNm );
3328  }
3329  else if( bMsg )
3330  {
3331  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
3332  VclMessageType::Info, VclButtonsType::Ok,
3333  SwResId(STR_CLPBRD_FORMAT_ERROR)));
3334  xBox->run();
3335  }
3336  return bRet;
3337 }
3338 
3340  OUString& rFileName, OUString* pTitle )
3341 {
3342  bool bIsURLFile = false;
3343  INetBookmark aBkmk;
3344  if( rData.GetINetBookmark( SotClipboardFormatId::SOLK, aBkmk ) )
3345  {
3346  rFileName = aBkmk.GetURL();
3347  if( pTitle )
3348  *pTitle = aBkmk.GetDescription();
3349  bIsURLFile = true;
3350  }
3351  else
3352  {
3353  if( rFileName.getLength()>4 && rFileName.endsWithIgnoreAsciiCase(".url") )
3354  {
3355  OSL_ENSURE( false, "how do we read today .URL - Files?" );
3356  }
3357  }
3358  return bIsURLFile;
3359 }
3360 
3362  const TransferableDataHelper& rData )
3363 {
3364  // we can paste-special if there's an entry in the paste-special-format list
3366  FillClipFormatItem( rWrtShell, rData, aClipboardFormatItem);
3367  return aClipboardFormatItem.Count() > 0;
3368 }
3369 
3371 {
3372  return ( GetSwTransferable( rData ) != nullptr );
3373 }
3374 
3376  TransferableDataHelper& rData,
3377  SotClipboardFormatId nFormat )
3378 {
3379  SwWait aWait( *rSh.GetView().GetDocShell(), false );
3380  bool bRet = false;
3381 
3382  SotClipboardFormatId nPrivateFormat = SotClipboardFormatId::PRIVATE;
3383  SwTransferable *pClipboard = GetSwTransferable( rData );
3384  if( pClipboard &&
3386  nPrivateFormat = SotClipboardFormatId::EMBED_SOURCE;
3387 
3388  if( pClipboard && nPrivateFormat == nFormat )
3389  bRet = pClipboard->PrivatePaste( rSh );
3390  else if( rData.HasFormat( nFormat ) )
3391  {
3392  uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
3393  sal_uInt8 nEventAction;
3394  SotExchangeDest nDestination = SwTransferable::GetSotDestination( rSh );
3395  sal_uInt16 nSourceOptions =
3396  (( SotExchangeDest::DOC_TEXTFRAME == nDestination ||
3397  SotExchangeDest::SWDOC_FREE_AREA == nDestination ||
3398  SotExchangeDest::DOC_TEXTFRAME_WEB == nDestination ||
3399  SotExchangeDest::SWDOC_FREE_AREA_WEB == nDestination )
3402  SotExchangeActionFlags nActionFlags;
3404  rData.GetDataFlavorExVector(),
3405  nDestination,
3406  nSourceOptions, /* ?? */
3407  EXCHG_IN_ACTION_DEFAULT, /* ?? */
3408  nFormat, nEventAction, nFormat,
3409  lcl_getTransferPointer ( xTransferable ),
3410  &nActionFlags );
3411 
3412  if( EXCHG_INOUT_ACTION_NONE != nAction )
3413  bRet = SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat,
3414  nDestination, true, false );
3415  }
3416  return bRet;
3417 }
3418 
3420  SotClipboardFormatId nFormat, SotExchangeDest nDestination )
3421 {
3423  if( rData.HasFormat( nFormat )) {
3424  uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
3425  sal_uInt8 nEventAction;
3427  rData.GetDataFlavorExVector(),
3428  nDestination, EXCHG_IN_ACTION_COPY,
3429  EXCHG_IN_ACTION_COPY, nFormat,
3430  nEventAction, nFormat,
3431  lcl_getTransferPointer ( xTransferable ) );
3432  }
3433  return EXCHG_INOUT_ACTION_NONE != nAction;
3434 }
3435 
3441 {
3442  SotClipboardFormatId::HTML,
3443  SotClipboardFormatId::HTML_SIMPLE,
3444  SotClipboardFormatId::HTML_NO_COMMENT,
3445  SotClipboardFormatId::RTF,
3446  SotClipboardFormatId::RICHTEXT,
3447  SotClipboardFormatId::STRING,
3448  SotClipboardFormatId::SONLK,
3449  SotClipboardFormatId::NETSCAPE_BOOKMARK,
3450  SotClipboardFormatId::DRAWING,
3451  SotClipboardFormatId::SVXB,
3452  SotClipboardFormatId::GDIMETAFILE,
3453  SotClipboardFormatId::BITMAP,
3454  SotClipboardFormatId::SVIM,
3455  SotClipboardFormatId::FILEGRPDESCRIPTOR,
3456  SotClipboardFormatId::NONE
3457 };
3458 
3460 {
3461  // Plain text == unformatted
3462  return SwTransferable::PasteFormat( rSh, rData, SotClipboardFormatId::STRING );
3463 }
3464 
3466 {
3467  DataFlavorExVector aFormats( rData.GetDataFlavorExVector() );
3469 
3471 
3472  SwTransferable *pClipboard = GetSwTransferable( rData );
3473  if( pClipboard )
3474  {
3475  aDesc = pClipboard->m_aObjDesc;
3476  TranslateId pResId;
3477  if( pClipboard->m_eBufferType & TransferBufferType::Document )
3478  pResId = STR_PRIVATETEXT;
3479  else if( pClipboard->m_eBufferType & TransferBufferType::Graphic )
3480  pResId = STR_PRIVATEGRAPHIC;
3481  else if( pClipboard->m_eBufferType == TransferBufferType::Ole )
3482  pResId = STR_PRIVATEOLE;
3483 
3484  if (pResId)
3485  {
3486  if (STR_PRIVATEOLE == pResId || STR_PRIVATEGRAPHIC == pResId)
3487  {
3488  // add SotClipboardFormatId::EMBED_SOURCE to the formats. This
3489  // format display then the private format name.
3490  DataFlavorEx aFlavorEx;
3491  aFlavorEx.mnSotId = SotClipboardFormatId::EMBED_SOURCE;
3492  aFormats.insert( aFormats.begin(), aFlavorEx );
3493  }
3494  pDlg->SetObjName( pClipboard->m_aObjDesc.maClassName,
3495  SwResId(pResId) );
3496  pDlg->Insert( SotClipboardFormatId::EMBED_SOURCE, OUString() );
3497  }
3498  }
3499  else
3500  {
3501  if( rData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ) )
3502  {
3504  SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc );
3505  }
3506 
3507  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::EMBED_SOURCE, nDest ))
3508  pDlg->Insert( SotClipboardFormatId::EMBED_SOURCE, OUString() );
3509  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK_SOURCE, nDest ))
3510  pDlg->Insert( SotClipboardFormatId::LINK_SOURCE, OUString() );
3511  }
3512 
3513  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK, nDest ))
3514  pDlg->Insert( SotClipboardFormatId::LINK, SwResId(STR_DDEFORMAT) );
3515 
3516  for( SotClipboardFormatId* pIds = aPasteSpecialIds; *pIds != SotClipboardFormatId::NONE; ++pIds )
3517  if( SwTransferable::TestAllowedFormat( rData, *pIds, nDest ))
3518  pDlg->Insert( *pIds, OUString() );
3519 }
3520 
3522  const TransferableDataHelper& rData,
3523  SvxClipboardFormatItem & rToFill )
3524 {
3526 
3527  SwTransferable *pClipboard = GetSwTransferable( rData );
3528  if( pClipboard )
3529  {
3530  TranslateId pResId;
3531  if( pClipboard->m_eBufferType & TransferBufferType::Document )
3532  pResId = STR_PRIVATETEXT;
3533  else if( pClipboard->m_eBufferType & TransferBufferType::Graphic )
3534  pResId = STR_PRIVATEGRAPHIC;
3535  else if( pClipboard->m_eBufferType == TransferBufferType::Ole )
3536  pResId = STR_PRIVATEOLE;
3537 
3538  if (pResId)
3539  rToFill.AddClipbrdFormat(SotClipboardFormatId::EMBED_SOURCE,
3540  SwResId(pResId));
3541  }
3542  else
3543  {
3545  if (rData.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
3546  {
3547  (void)const_cast<TransferableDataHelper&>(rData).GetTransferableObjectDescriptor(
3548  SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc);
3549  }
3550 
3551  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::EMBED_SOURCE, nDest ))
3552  rToFill.AddClipbrdFormat( SotClipboardFormatId::EMBED_SOURCE,
3553  aDesc.maTypeName );
3554  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK_SOURCE, nDest ))
3555  rToFill.AddClipbrdFormat( SotClipboardFormatId::LINK_SOURCE );
3556 
3557  SotClipboardFormatId nFormat;
3558  if ( rData.HasFormat(nFormat = SotClipboardFormatId::EMBED_SOURCE_OLE) || rData.HasFormat(nFormat = SotClipboardFormatId::EMBEDDED_OBJ_OLE) )
3559  {
3560  OUString sName,sSource;
3561  if ( SvPasteObjectHelper::GetEmbeddedName(rData,sName,sSource,nFormat) )
3562  rToFill.AddClipbrdFormat( nFormat, sName );
3563  }
3564  }
3565 
3566  if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK, nDest ))
3567  rToFill.AddClipbrdFormat( SotClipboardFormatId::LINK, SwResId(STR_DDEFORMAT) );
3568 
3569  for( SotClipboardFormatId* pIds = aPasteSpecialIds; *pIds != SotClipboardFormatId::NONE; ++pIds )
3570  if( SwTransferable::TestAllowedFormat( rData, *pIds, nDest ))
3571  rToFill.AddClipbrdFormat(*pIds, OUString());
3572 }
3573 
3574 void SwTransferable::SetDataForDragAndDrop( const Point& rSttPos )
3575 {
3576  if(!m_pWrtShell)
3577  return;
3578  OUString sGrfNm;
3579  const SelectionType nSelection = m_pWrtShell->GetSelectionType();
3580  if( SelectionType::Graphic == nSelection)
3581  {
3582  AddFormat( SotClipboardFormatId::SVXB );
3583  const Graphic* pGrf = m_pWrtShell->GetGraphic();
3584  if ( pGrf && pGrf->IsSupportedGraphic() )
3585  {
3586  AddFormat( SotClipboardFormatId::GDIMETAFILE );
3587  AddFormat( SotClipboardFormatId::PNG );
3588  AddFormat( SotClipboardFormatId::BITMAP );
3589  }
3591  m_pWrtShell->GetGrfNms( &sGrfNm, nullptr );
3592  }
3593  else if( SelectionType::Ole == nSelection )
3594  {
3595  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
3597  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
3598  AddFormat( SotClipboardFormatId::GDIMETAFILE );
3600  }
3601  //Is there anything to provide anyway?
3602  else if ( m_pWrtShell->IsSelection() || m_pWrtShell->IsFrameSelected() ||
3604  {
3605  if( m_pWrtShell->IsObjSelected() )
3607  else
3608  {
3610  if( SwWrtShell::NO_WORD !=
3611  m_pWrtShell->IntelligentCut( nSelection, false ))
3613  }
3614 
3615  if( nSelection & SelectionType::TableCell )
3617 
3618  AddFormat( SotClipboardFormatId::EMBED_SOURCE );
3619 
3620  //put RTF ahead of the OLE's Metafile for less loss
3621  if( !m_pWrtShell->IsObjSelected() )
3622  {
3623  AddFormat( SotClipboardFormatId::RTF );
3624  AddFormat( SotClipboardFormatId::RICHTEXT );
3625  AddFormat( SotClipboardFormatId::HTML );
3626  }
3627  if( m_pWrtShell->IsSelection() )
3628  AddFormat( SotClipboardFormatId::STRING );
3629 
3630  if( nSelection & ( SelectionType::DrawObject | SelectionType::DbForm ))
3631  {
3632  AddFormat( SotClipboardFormatId::DRAWING );
3633  if ( nSelection & SelectionType::DrawObject )
3634  {
3635  AddFormat( SotClipboardFormatId::GDIMETAFILE );
3636  AddFormat( SotClipboardFormatId::PNG );
3637  AddFormat( SotClipboardFormatId::BITMAP );
3638  }
3640 
3641  // is it a URL-Button ?
3642  OUString sURL;
3643  OUString sDesc;
3644  if( m_pWrtShell->GetURLFromButton( sURL, sDesc ) )
3645  {
3646  AddFormat( SotClipboardFormatId::STRING );
3647  AddFormat( SotClipboardFormatId::SOLK );
3648  AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
3649  AddFormat( SotClipboardFormatId::FILECONTENT );
3650  AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
3651  AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
3653  }
3654  }
3655 
3656  //ObjectDescriptor was already filled from the old DocShell.
3657  //Now adjust it. Thus in GetData the first query can still
3658  //be answered with delayed rendering.
3659  m_aObjDesc.maDragStartPos = rSttPos;
3661 
3663  AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
3664  }
3665  else if( nSelection & SelectionType::Text && !m_pWrtShell->HasMark() )
3666  {
3667  // is only one field - selected?
3668  SwContentAtPos aContentAtPos( IsAttrAtPos::InetAttr );
3670 
3671  if( m_pWrtShell->GetContentAtPos( aPos, aContentAtPos ) )
3672  {
3673  AddFormat( SotClipboardFormatId::STRING );
3674  AddFormat( SotClipboardFormatId::SOLK );
3675  AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
3676  AddFormat( SotClipboardFormatId::FILECONTENT );
3677  AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
3678  AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
3680  }
3681  }
3682 
3683  if( !m_pWrtShell->IsFrameSelected() )
3684  return;
3685 
3687  m_pWrtShell->GetFlyFrameAttr( aSet );
3688  const SwFormatURL& rURL = aSet.Get( RES_URL );
3689  if( rURL.GetMap() )
3690  {
3691  m_pImageMap.reset( new ImageMap( *rURL.GetMap() ) );
3692  AddFormat( SotClipboardFormatId::SVIM );
3693  }
3694  else if( !rURL.GetURL().isEmpty() )
3695  {
3696  m_pTargetURL.reset(new INetImage( sGrfNm, rURL.GetURL(),
3697  rURL.GetTargetFrameName() ));
3698  AddFormat( SotClipboardFormatId::INET_IMAGE );
3699  }
3700 }
3701 
3702 void SwTransferable::StartDrag( vcl::Window* pWin, const Point& rPos )
3703 {
3704  if(!m_pWrtShell)
3705  return;
3707  m_bCleanUp = true;
3708 
3709  m_pWrtShell->GetViewOptions()->SetIdle( false );
3710 
3711  if( m_pWrtShell->IsSelFrameMode() )
3713 
3714  SW_MOD()->m_pDragDrop = this;
3715 
3716  SetDataForDragAndDrop( rPos );
3717 
3718  sal_Int8 nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK;
3719  SwDocShell* pDShell = m_pWrtShell->GetView().GetDocShell();
3720  if( ( pDShell && pDShell->IsReadOnly() ) || m_pWrtShell->HasReadonlySel() )
3721  nDragOptions &= ~DND_ACTION_MOVE;
3722 
3723  TransferableHelper::StartDrag( pWin, nDragOptions );
3724 }
3725 
3727 {
3728  //And the last finishing work so that all statuses are right
3729  if( DND_ACTION_MOVE == nAction )
3730  {
3731  if( m_bCleanUp )
3732  {
3733  //It was dropped outside of Writer. We still have to
3734  //delete.
3735 
3738  if ( m_pWrtShell->IsTableMode() )
3740  else
3741  {
3743  //SmartCut, take one of the blanks along
3745  m_pWrtShell->DelRight();
3746  }
3749  }
3750  else
3751  {
3752  const SelectionType nSelection = m_pWrtShell->GetSelectionType();
3755  {
3757  }
3758  }
3759  }
3761 
3762  if( m_pWrtShell->IsSelFrameMode() )
3764  else
3766 
3768 }
3769 
3770 namespace
3771 {
3772 
3773 bool lcl_checkClassification(SwDoc* pSourceDoc, SwDoc* pDestinationDoc)
3774 {
3775  if (!pSourceDoc || !pDestinationDoc)
3776  return true;
3777 
3778  SwDocShell* pSourceShell = pSourceDoc->GetDocShell();
3779  SwDocShell* pDestinationShell = pDestinationDoc->GetDocShell();
3780  if (!pSourceShell || !pDestinationShell)
3781  return true;
3782 
3785 }
3786 
3787 }
3788 
3790 {
3791  // first, ask for the SelectionType, then action-bracketing !!!!
3792  // (otherwise it's not pasted into a TableSelection!!!)
3793  OSL_ENSURE( !rShell.ActionPend(), "Paste must never have an ActionPend" );
3794  if ( !m_pClpDocFac )
3795  return false; // the return value of the SwFEShell::Paste also is bool!
3796 
3797  const SelectionType nSelection = rShell.GetSelectionType();
3798 
3799  SwTrnsfrActionAndUndo aAction( &rShell );
3800 
3801  bool bKillPaMs = false;
3802 
3803  //Delete selected content, not at table-selection and table in Clipboard, and don't delete hovering graphics.
3804  if( rShell.HasSelection() && !( nSelection & SelectionType::TableCell) && !( nSelection & SelectionType::DrawObject))
3805  {
3806  if (!(nSelection & SelectionType::NumberList))
3807  {
3808  bKillPaMs = true;
3809  rShell.SetRetainSelection( true );
3810  }
3811  if (pContext)
3812  pContext->forget();
3813  rShell.DelRight();
3814  if (pContext)
3815  pContext->remember();
3816  // when a Fly was selected, a valid cursor position has to be found now
3817  // (parked Cursor!)
3819  SelectionType::Ole | SelectionType::DrawObject |
3820  SelectionType::DbForm ) & nSelection )
3821  {
3822  // position the cursor again
3823  Point aPt( rShell.GetCharRect().Pos() );
3824  rShell.SwCursorShell::SetCursor( aPt, true );
3825  }
3826  if (!(nSelection & SelectionType::NumberList))
3827  {
3828  rShell.SetRetainSelection( false );
3829  }
3830  }
3831  if ( nSelection & SelectionType::DrawObject) //unselect hovering graphics
3832  {
3833  rShell.ResetSelect(nullptr,false);
3834  }
3835 
3836  bool bInWrd = false, bEndWrd = false, bSttWrd = false,
3838  if( bSmart )
3839  {
3840  // Why not for other Scripts? If TransferBufferType::DocumentWord is set, we have a word
3841  // in the buffer, word in this context means 'something with spaces at beginning
3842  // and end'. In this case we definitely want these spaces to be inserted here.
3843  bInWrd = rShell.IsInWord();
3844  bEndWrd = rShell.IsEndWrd();
3845  bSmart = bInWrd || bEndWrd;
3846  if( bSmart )
3847  {
3848  bSttWrd = rShell.IsStartWord();
3849  if (!bSttWrd && (bInWrd || bEndWrd))
3850  rShell.SwEditShell::Insert(' ');
3851  }
3852  }
3853 
3854  bool bRet = true;
3855  // m_pWrtShell is nullptr when the source document is closed already.
3856  if (!m_pWrtShell || lcl_checkClassification(m_pWrtShell->GetDoc(), rShell.GetDoc()))
3857  bRet = rShell.Paste(m_pClpDocFac->GetDoc(), ePasteTable == PasteTableType::PASTE_TABLE);
3858 
3859  if( bKillPaMs )
3860  rShell.KillPams();
3861 
3862  // If Smart Paste then insert blank
3863  if( bRet && bSmart && ((bInWrd && !bEndWrd )|| bSttWrd) )
3864  rShell.SwEditShell::Insert(' ');
3865 
3866  return bRet;
3867 }
3868 
3869 bool SwTransferable::PrivateDrop( SwWrtShell& rSh, const Point& rDragPt,
3870  bool bMove, bool bIsXSelection )
3871 {
3872  int cWord = 0;
3873  bool bInWrd = false;
3874  bool bEndWrd = false;
3875  bool bSttWrd = false;
3876  bool bSttPara = false;
3877  bool bTableSel = false;
3878  bool bTableMove = false;
3879  bool bFrameSel = false;
3880 
3881  SwWrtShell& rSrcSh = *GetShell();
3882 
3883  rSh.UnSetVisibleCursor();
3884 
3886  {
3887  if( rSh.GetFormatFromObj( rDragPt ) )
3888  {
3889  INetBookmark aTmp;
3891  aTmp = *m_pBookmark;
3892 
3893  // select target graphic
3894  if( rSh.SelectObj( rDragPt ) )
3895  {
3896  rSh.HideCursor();
3897  rSh.EnterSelFrameMode( &rDragPt );
3898  g_bFrameDrag = true;
3899  }
3900 
3901  const SelectionType nSelection = rSh.GetSelectionType();
3902 
3903  // not yet consider Draw objects
3904  if( SelectionType::Graphic & nSelection )
3905  {
3907  rSh.GetFlyFrameAttr( aSet );
3908  SwFormatURL aURL( aSet.Get( RES_URL ) );
3909  aURL.SetURL( aTmp.GetURL(), false );
3910  aSet.Put( aURL );
3911  rSh.SetFlyFrameAttr( aSet );
3912  return true;
3913  }
3914 
3915  if( SelectionType::DrawObject & nSelection )
3916  {
3917  rSh.LeaveSelFrameMode();
3918  rSh.UnSelectFrame();
3919  rSh.ShowCursor();
3920  g_bFrameDrag = false;
3921  }
3922  }
3923  }
3924 
3925  if( &rSh != &rSrcSh && (SelectionType::Graphic & rSh.GetSelectionType()) &&
3927  {
3928  // ReRead the graphic
3929  OUString sGrfNm;
3930  OUString sFltNm;
3931  rSrcSh.GetGrfNms( &sGrfNm, &sFltNm );
3932  rSh.ReRead( sGrfNm, sFltNm, rSrcSh.GetGraphic() );
3933  return true;
3934  }
3935 
3936  //not in selections or selected frames
3937  if( rSh.TestCurrPam( rDragPt ) ||
3938  ( rSh.IsSelFrameMode() && rSh.IsInsideSelectedObj( rDragPt )) )
3939  return false;
3940 
3941  if( rSrcSh.IsTableMode() )
3942  {
3943  bTableSel = true;
3944  const SelectionType nSelection = rSrcSh.GetSelectionType();
3945  // at enhanced table row/column selection or wholly selected tables,
3946  // paste rows above or columns before, and in the case of moving, remove the selection
3947  // (limit only to the single document case temporarily)
3948  if( rSrcSh.GetDoc() == rSh.GetDoc() &&
3949  ( (( SelectionType::TableRow | SelectionType::TableCol) & nSelection ) || rSrcSh.HasWholeTabSelection() ) )
3950  {
3951  bool bTableCol(SelectionType::TableCol & nSelection);
3952 
3953  ::sw::mark::IMark* pMarkMoveFrom = bMove
3954  ? rSh.SetBookmark(
3955  vcl::KeyCode(),
3956  OUString(),
3958  : nullptr;
3959 
3960  // row count and direction of the table selection:
3961  // up to down, if the cursor is there in its last table row
3962  const SwSelBoxes& rBoxes = rSrcSh.GetTableCursor()->GetSelectedBoxes();
3963  const SwTableNode* pTableNd = rSh.IsCursorInTable();
3964  sal_Int32 nSelRows = !rBoxes.back()
3965  ? 0
3966  : pTableNd->GetTable().GetTabLines().GetPos( rBoxes.back()->GetUpper() ) -
3967  pTableNd->GetTable().GetTabLines().GetPos( rBoxes.front()->GetUpper() ) + 1;
3968  bool bSelUpToDown = rBoxes.back() && rBoxes.back()->GetUpper() ==
3969  rSh.GetCursor()->GetNode().GetTableBox()->GetUpper();
3970 
3972 
3973  SwRewriter aRewriter;
3974 
3975  aRewriter.AddRule(UndoArg1, rSrcSh.GetSelDescr());
3976 
3977  if(rSrcSh.GetDoc() != rSh.GetDoc())
3978  rSrcSh.StartUndo( eUndoId, &aRewriter );
3979  rSh.StartUndo( eUndoId, &aRewriter );
3980 
3981  rSh.StartAction();
3982  rSrcSh.StartAction();
3983 
3984  SfxDispatcher* pDispatch = rSrcSh.GetView().GetViewFrame()->GetDispatcher();
3985  pDispatch->Execute(SID_COPY, SfxCallMode::SYNCHRON);
3986 
3987  rSrcSh.Push(); // save selection for later restoration
3988  rSh.EnterStdMode();
3989  rSh.SwCursorShell::SetCursor(rDragPt, false);
3990 
3991  bool bPasteIntoTable = rSh.GetCursor()->GetNode().GetTableBox() != nullptr;
3992 
3993  // store cursor
3994  ::sw::mark::IMark* pMark = rSh.SetBookmark(
3995  vcl::KeyCode(),
3996  OUString(),
3998 
3999  // paste rows above/columns before
4000  pDispatch->Execute(bTableCol ? FN_TABLE_PASTE_COL_BEFORE : FN_TABLE_PASTE_ROW_BEFORE, SfxCallMode::SYNCHRON);
4001 
4002  // go to the previously inserted table rows and set them to tracked insertion, if needed
4003  bool bNeedTrack = !bTableCol && rSh.getIDocumentRedlineAccess().IsRedlineOn();
4004 
4005  // restore cursor position
4006  if (bNeedTrack && pMark != nullptr)
4007  rSh.GotoMark( pMark );
4008 
4009  if ( !bNeedTrack && !bPasteIntoTable )
4010  {
4011  rSrcSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // restore selection...
4012 
4013  // delete source rows/columns
4014  if (bMove)
4015  pDispatch->Execute(bTableCol
4017  : FN_TABLE_DELETE_ROW, SfxCallMode::SYNCHRON);
4018  }
4019  else
4020  {
4021  const SwTableBox* pBoxStt = rSh.GetCursor()->GetNode().GetTableBox();
4022  SwTableLine* pLine = pBoxStt ? const_cast<SwTableLine*>( pBoxStt->GetUpper()): nullptr;
4023 
4024  for (sal_Int32 nDeleted = 0; bNeedTrack && nDeleted < nSelRows;)
4025  {
4026  // move up text cursor (note: "true" is important for the layout level)
4027  if ( !rSh.Up(false) )
4028  break;
4029 
4030  const SwTableBox* pBox = rSh.GetCursor()->GetNode().GetTableBox();
4031 
4032  if ( !pBox )
4033  break;
4034 
4035  // Up() reaches a new row
4036  if ( pBox->GetUpper() != pLine )
4037  {
4038  //rSh.SelTableRow();
4039  SvxPrintItem aTracked(RES_PRINT, false);
4040  rSh.GetDoc()->SetRowNotTracked( *rSh.GetCursor(), aTracked );
4041  ++nDeleted;
4042  pLine = const_cast<SwTableLine*>(pBox->GetUpper());
4043  }
4044  }
4045 
4046  rSrcSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // restore selection...
4047 
4048  // delete source rows/columns
4049  if (bMove)
4050  {
4051  // restore cursor position
4052  if (pMarkMoveFrom != nullptr)
4053  {
4054  rSh.GotoMark( pMarkMoveFrom );
4055  rSh.getIDocumentMarkAccess()->deleteMark( pMarkMoveFrom );
4056  }
4057 
4058  // set all row as tracked deletion, otherwise go to the first moved row
4059  if ( bNeedTrack || ( bSelUpToDown && nSelRows > 1 ) )
4060  {
4061  pLine = nullptr;
4062 
4063  for (sal_Int32 nDeleted = 0; nDeleted < nSelRows - int(!bNeedTrack);)
4064  {
4065  const SwTableBox* pBox = rSh.GetCursor()->GetNode().GetTableBox();
4066 
4067  if ( !pBox )
4068  break;
4069 
4070  if ( pBox->GetUpper() != pLine )
4071  {
4072  pLine = const_cast<SwTableLine*>(pBox->GetUpper());
4073  if (bNeedTrack)
4074  pDispatch->Execute(bTableCol
4076  : FN_TABLE_DELETE_ROW, SfxCallMode::SYNCHRON);
4077  ++nDeleted;
4078  }
4079 
4080  bool bMoved = false;
4081  if (bSelUpToDown)
4082  bMoved = rSh.Up(false);
4083  else
4084  bMoved = rSh.Down(false);
4085  if (!bMoved)
4086  break;
4087  }
4088  }
4089 
4090  // delete rows without track changes
4091  if ( !bNeedTrack )
4092  {
4093  for (sal_Int32 nDeleted = 0; nDeleted < nSelRows; ++nDeleted)
4094  pDispatch->Execute(bTableCol
4096  : FN_TABLE_DELETE_ROW, SfxCallMode::SYNCHRON);
4097  }
4098  }
4099  }
4100 
4101  // restore cursor position
4102  if (pMark != nullptr)
4103  {
4104  rSh.GotoMark( pMark );
4105  rSh.getIDocumentMarkAccess()->deleteMark( pMark );
4106  }
4107 
4108  rSh.DestroyCursor();
4109  rSh.EndUndo();
4110  rSh.EndAction();
4111  rSh.EndAction();
4112  return true;
4113  }
4114 
4115  if ( bMove && rSrcSh.HasWholeTabSelection() )
4116  bTableMove = true;
4117  }
4118  else if( rSrcSh.IsSelFrameMode() || rSrcSh.IsObjSelected() )
4119  {
4120  // don't move position-protected objects!
4122  return false;
4123 
4124  bFrameSel = true;
4125  }
4126 
4127  const SelectionType nSel = rSrcSh.GetSelectionType();
4128 
4130 
4131  SwRewriter aRewriter;
4132 
4133  aRewriter.AddRule(UndoArg1, rSrcSh.GetSelDescr());
4134 
4135  if(rSrcSh.GetDoc() != rSh.GetDoc())
4136  rSrcSh.StartUndo( eUndoId, &aRewriter );
4137  rSh.StartUndo( eUndoId, &aRewriter );
4138 
4139  rSh.StartAction();
4140  rSrcSh.StartAction();
4141 
4142  if( &rSrcSh != &rSh )
4143  {
4144  rSh.EnterStdMode();
4145  rSh.SwCursorShell::SetCursor( rDragPt, true );
4146  cWord = rSrcSh.IntelligentCut( nSel, false );
4147  }
4148  else if( !bTableSel && !bFrameSel )
4149  {
4150  if( !rSh.IsAddMode() )
4151  {
4152  // #i87233#
4153  if ( rSh.IsBlockMode() )
4154  {
4155  // preserve order of cursors for block mode
4156  rSh.GoPrevCursor();
4157  }
4158 
4159  rSh.SwCursorShell::CreateCursor();
4160  }
4161  rSh.SwCursorShell::SetCursor( rDragPt, true, false );
4162  rSh.GoPrevCursor();
4163  cWord = rSh.IntelligentCut( rSh.GetSelectionType(), false );
4164  rSh.GoNextCursor();
4165  }
4166 
4167  bInWrd = rSh.IsInWord();
4168  bEndWrd = rSh.IsEndWrd();
4169  bSttWrd = !bEndWrd && rSh.IsStartWord();
4170  bSttPara= rSh.IsSttPara();
4171 
4173 
4174  // at first, select InetFields!
4176  {
4177  if( &rSrcSh == &rSh )
4178  {
4179  rSh.GoPrevCursor();
4180  rSh.SwCursorShell::SetCursor( aSttPt, true );
4182  if( rSh.TestCurrPam( rDragPt ) )
4183  {
4184  // don't copy/move inside of yourself
4185  rSh.DestroyCursor();
4186  rSh.EndUndo();
4187  rSh.EndAction();
4188  rSh.EndAction();
4189  return false;
4190  }
4191  rSh.GoNextCursor();
4192  }
4193  else
4194  {
4195  rSrcSh.SwCursorShell::SetCursor( aSttPt, true );
4197  }
4198 
4199  // is there a URL attribute at the insert point? Then replace that,
4200  // so simply put up a selection?
4201  rSh.DelINetAttrWithText();
4202  g_bDDINetAttr = true;
4203  }
4204 
4205  if ( rSrcSh.IsSelFrameMode() )
4206  {
4207  //Hack: fool the special treatment
4208  aSttPt = rSrcSh.GetObjRect().Pos();
4209  }
4210 
4211  bool bRet = rSrcSh.SwFEShell::Copy(rSh, aSttPt, rDragPt, bMove,
4212  !bIsXSelection);
4213 
4214  if( !bIsXSelection )
4215  {
4216  rSrcSh.Push();
4217  if ( bRet && bMove && !bFrameSel )
4218  {
4219  if ( bTableSel )
4220  {
4221  /* delete table contents not cells */
4222  rSrcSh.Delete();
4223  }
4224  else
4225  {
4226  //SmartCut, take one of the blanks along.
4227  rSh.SwCursorShell::DestroyCursor();
4228  if ( cWord == SwWrtShell::WORD_SPACE_BEFORE )
4229  rSh.ExtendSelection( false );
4230  else if ( cWord == SwWrtShell::WORD_SPACE_AFTER )
4231  rSh.ExtendSelection();
4232  rSrcSh.DelRight();
4233  }
4234  }
4235  rSrcSh.KillPams();
4237 
4238  /* after dragging a table selection inside one shell
4239  set cursor to the drop position. */
4240  if( &rSh == &rSrcSh && ( bTableSel || rSh.IsBlockMode() ) )
4241  {
4242  rSrcSh.CalcLayout();
4243  rSrcSh.SwCursorShell::SetCursor(rDragPt);
4244  rSrcSh.GetCursor()->SetMark();
4245  }
4246  }
4247 
4248  if( bRet && !bTableSel && !bFrameSel )
4249  {
4250  if( (bInWrd || bEndWrd) &&
4251  (cWord == SwWrtShell::WORD_SPACE_AFTER ||
4252  cWord == SwWrtShell::WORD_SPACE_BEFORE) )
4253  {
4254  if ( bSttWrd || (bInWrd && !bEndWrd))
4255  rSh.SwEditShell::Insert(' ', bIsXSelection);
4256  if ( !bSttWrd || (bInWrd && !bSttPara) )
4257  {
4258  rSh.SwapPam();
4259  if ( !bSttWrd )
4260  rSh.SwEditShell::Insert(' ', bIsXSelection);
4261  rSh.SwapPam();
4262  }
4263  }
4264 
4265  if( bIsXSelection )
4266  {
4267  if( &rSrcSh == &rSh && !rSh.IsAddMode() )
4268  {
4269  rSh.SwCursorShell::DestroyCursor();
4270  rSh.GoPrevCursor();
4271  }
4272  else
4273  {
4274  rSh.SwapPam();
4275  rSh.SwCursorShell::ClearMark();
4276  }
4277  }
4278  else
4279  {
4280  if( rSh.IsAddMode() )
4281  rSh.SwCursorShell::CreateCursor();
4282  else
4283  {
4284  // turn on selection mode
4285  rSh.SttSelect();
4286  rSh.EndSelect();
4287  }
4288  }
4289  }
4290  else if ( bRet && bTableMove )
4291  {
4292  SfxDispatcher* pDispatch = rSrcSh.GetView().GetViewFrame()->GetDispatcher();
4293  pDispatch->Execute(FN_TABLE_DELETE_TABLE, SfxCallMode::SYNCHRON);
4294  }
4295 
4296  if( bRet && bMove && bFrameSel )
4297  rSrcSh.LeaveSelFrameMode();
4298 
4299  if( rSrcSh.GetDoc() != rSh.GetDoc() )
4300  rSrcSh.EndUndo();
4301  rSh.EndUndo();
4302 
4303  // put the shell in the right state
4304  if( &rSrcSh != &rSh && ( rSh.IsFrameSelected() || rSh.IsObjSelected() ))
4305  rSh.EnterSelFrameMode();
4306 
4307  rSrcSh.EndAction();
4308  rSh.EndAction();
4309  return true;
4310 }
4311 
4312 // Interfaces for Selection
4314  const SwFrameShell * _pCreatorView )
4315 {
4316  SwModule *pMod = SW_MOD();
4318 
4319  pNew->m_pCreatorView = _pCreatorView;
4320 
4321  pMod->m_pXSelection = pNew.get();
4322  pNew->CopyToPrimarySelection();
4323 }
4324 
4326  const SwFrameShell * _pCreatorView)
4327 {
4328  SwModule *pMod = SW_MOD();
4329  if( pMod->m_pXSelection &&
4330  ((!pMod->m_pXSelection->m_pWrtShell) || (pMod->m_pXSelection->m_pWrtShell == &rSh)) &&
4331  (!_pCreatorView || (pMod->m_pXSelection->m_pCreatorView == _pCreatorView)) )
4332  {
4334  }
4335 }
4336 
4337 const Sequence< sal_Int8 >& SwTransferable::getUnoTunnelId()
4338 {
4339  static const comphelper::UnoIdInit theSwTransferableUnoTunnelId;
4340  return theSwTransferableUnoTunnelId.getSeq();
4341 }
4342 
4343 sal_Int64 SwTransferable::getSomething( const Sequence< sal_Int8 >& rId )
4344 {
4345  return comphelper::getSomethingImpl(rId, this,
4347 }
4348 
4350 {
4351  return comphelper::getFromUnoTunnel<SwTransferable>(rData.GetTransferable());
4352 }
4353 
4354 SwTransferDdeLink::SwTransferDdeLink( SwTransferable& rTrans, SwWrtShell& rSh )
4355  : m_rTransfer(rTrans)
4356  , m_pDocShell(nullptr)
4357  , m_nOldTimeOut(0)
4358  , m_bDelBookmark(false)
4359  , m_bInDisconnect(false)
4360 {
4361  // we only end up here with table- or text selection
4363  {
4364  SwFrameFormat* pFormat = rSh.GetTableFormat();
4365  if( pFormat )
4366  m_sName = pFormat->GetName();
4367  }
4368  else
4369  {
4370  // creating a temp. bookmark without undo
4371  bool bUndo = rSh.DoesUndo();
4372  rSh.DoUndo( false );
4373  bool bIsModified = rSh.IsModified();
4374 
4375  ::sw::mark::IMark* pMark = rSh.SetBookmark(
4376  vcl::KeyCode(),
4377  OUString(),
4379  if(pMark)
4380  {
4381  m_sName = pMark->GetName();
4382  m_bDelBookmark = true;
4383  if( !bIsModified )
4384  rSh.ResetModified();
4385  }
4386  else
4387  m_sName.clear();
4388  rSh.DoUndo( bUndo );
4389  }
4390 
4391  if( m_sName.isEmpty() ||
4392  nullptr == ( m_pDocShell = rSh.GetDoc()->GetDocShell() ))
4393  return;
4394 
4395  // then we create our "server" and connect to it
4396  m_xRefObj = m_pDocShell->DdeCreateLinkSource( m_sName );
4397  if( m_xRefObj.is() )
4398  {
4399  m_xRefObj->AddConnectAdvise( this );
4400  m_xRefObj->AddDataAdvise( this,
4401  OUString(),
4402  ADVISEMODE_NODATA | ADVISEMODE_ONLYONCE );
4403  m_nOldTimeOut = m_xRefObj->GetUpdateTimeout();
4404  m_xRefObj->SetUpdateTimeout( 0 );
4405  }
4406 }
4407 
4408 SwTransferDdeLink::~SwTransferDdeLink()
4409 {
4410  if( m_xRefObj.is() )
4411  Disconnect( true );
4412 }
4413 
4414 ::sfx2::SvBaseLink::UpdateResult SwTransferDdeLink::DataChanged( const OUString& ,
4415  const uno::Any& )
4416 {
4417  // well, that's it with the link
4418  if( !m_bInDisconnect )
4419  {
4420  if( FindDocShell() && m_pDocShell->GetView() )
4421  m_rTransfer.RemoveDDELinkFormat( m_pDocShell->GetView()->GetEditWin() );
4422  Disconnect( false );
4423  }
4424  return SUCCESS;
4425 }
4426 
4427 bool SwTransferDdeLink::WriteData( SvStream& rStrm )
4428 {
4429  if( !m_xRefObj.is() || !FindDocShell() )
4430  return false;
4431 
4432  rtl_TextEncoding eEncoding = osl_getThreadTextEncoding();
4433  const OString aAppNm(OUStringToOString(
4434  Application::GetAppName(), eEncoding));
4435  const OString aTopic(OUStringToOString(
4436  m_pDocShell->GetTitle(SFX_TITLE_FULLNAME), eEncoding));
4437  const OString aName(OUStringToOString(m_sName, eEncoding));
4438 
4439  std::unique_ptr<char[]> pMem(new char[ aAppNm.getLength() + aTopic.getLength() + aName.getLength() + 4 ]);
4440 
4441  sal_Int32 nLen = aAppNm.getLength();
4442  memcpy( pMem.get(), aAppNm.getStr(), nLen );
4443  pMem[ nLen++ ] = 0;
4444  memcpy( pMem.get() + nLen, aTopic.getStr(), aTopic.getLength() );
4445  nLen = nLen + aTopic.getLength();
4446  pMem[ nLen++ ] = 0;
4447  memcpy( pMem.get() + nLen, aName.getStr(), aName.getLength() );
4448  nLen = nLen + aName.getLength();
4449  pMem[ nLen++ ] = 0;
4450  pMem[ nLen++ ] = 0;
4451 
4452  rStrm.WriteBytes( pMem.get(), nLen );
4453  pMem.reset();
4454 
4455  IDocumentMarkAccess* const pMarkAccess = m_pDocShell->GetDoc()->getIDocumentMarkAccess();
4456  IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(m_sName);
4457  if(ppMark != pMarkAccess->getAllMarksEnd()
4459  {
4460  // the mark is still a DdeBookmark
4461  // we replace it with a Bookmark, so it will get saved etc.
4462  ::sw::mark::IMark* const pMark = *ppMark;
4463  ::sfx2::SvLinkSource* p = m_xRefObj.get();
4464  SwServerObject& rServerObject = dynamic_cast<SwServerObject&>(*p);
4465 
4466  // collecting state of old mark
4467  SwPaM aPaM(pMark->GetMarkStart());
4468  *aPaM.GetPoint() = pMark->GetMarkStart();
4469  if(pMark->IsExpanded())
4470  {
4471  aPaM.SetMark();
4472  *aPaM.GetMark() = pMark->GetMarkEnd();
4473  }
4474  OUString sMarkName = pMark->GetName();
4475 
4476  // remove mark
4477  rServerObject.SetNoServer(); // this removes the connection between SwServerObject and mark
4478  // N.B. ppMark was not loaded from file and cannot have xml:id
4479  pMarkAccess->deleteMark(ppMark, false);
4480 
4481  // recreate as Bookmark
4482  ::sw::mark::IMark* const pNewMark = pMarkAccess->makeMark(
4483  aPaM,
4484  sMarkName,
4487  rServerObject.SetDdeBookmark(*pNewMark);
4488  }
4489 
4490  m_bDelBookmark = false;
4491  return true;
4492 }
4493 
4494 void SwTransferDdeLink::Disconnect( bool bRemoveDataAdvise )
4495 {
4496  // don't accept DataChanged anymore, when already in Disconnect!
4497  // (DTOR from Bookmark sends a DataChanged!)
4498  bool bOldDisconnect = m_bInDisconnect;
4499  m_bInDisconnect = true;
4500 
4501  // destroy the unused bookmark again (without Undo!)?
4502  if( m_bDelBookmark && m_xRefObj.is() && FindDocShell() )
4503  {
4504  SwDoc* pDoc = m_pDocShell->GetDoc();
4505  ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
4506 
4507  // #i58448#
4508  Link<bool,void> aSavedOle2Link( pDoc->GetOle2Link() );
4509  pDoc->SetOle2Link( Link<bool,void>() );
4510 
4511  bool bIsModified = pDoc->getIDocumentState().IsModified();
4512 
4513  IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
4514  pMarkAccess->deleteMark(pMarkAccess->findMark(m_sName), false);
4515 
4516  if( !bIsModified )
4517  pDoc->getIDocumentState().ResetModified();
4518  // #i58448#
4519  pDoc->SetOle2Link( aSavedOle2Link );
4520 
4521  m_bDelBookmark = false;
4522  }
4523 
4524  if( m_xRefObj.is() )
4525  {
4526  m_xRefObj->SetUpdateTimeout( m_nOldTimeOut );
4527  m_xRefObj->RemoveConnectAdvise( this );
4528  if( bRemoveDataAdvise )
4529  // in a DataChanged the SelectionObject must NEVER be deleted
4530  // is already handled by the base class
4531  // (ADVISEMODE_ONLYONCE!!!!)
4532  // but always in normal Disconnect!
4533  m_xRefObj->RemoveAllDataAdvise( this );
4534  m_xRefObj.clear();
4535  }
4536  m_bInDisconnect = bOldDisconnect;
4537 }
4538 
4539 bool SwTransferDdeLink::FindDocShell()
4540 {
4541  SfxObjectShell* pTmpSh = SfxObjectShell::GetFirst( checkSfxObjectShell<SwDocShell> );
4542  while( pTmpSh )
4543  {
4544  if( pTmpSh == m_pDocShell ) // that's what we want to have
4545  {
4546  if( m_pDocShell->GetDoc() )
4547  return true;
4548  break; // the Doc is not there anymore, so leave!
4549  }
4550  pTmpSh = SfxObjectShell::GetNext( *pTmpSh, checkSfxObjectShell<SwDocShell> );
4551  }
4552 
4553  m_pDocShell = nullptr;
4554  return false;
4555 }
4556 
4557 void SwTransferDdeLink::Closed()
4558 {
4559  if( !m_bInDisconnect && m_xRefObj.is() )
4560  {
4561  m_xRefObj->RemoveAllDataAdvise( this );
4562  m_xRefObj->RemoveConnectAdvise( this );
4563  m_xRefObj.clear();
4564  }
4565 }
4566 
4567 /* 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:64
BitmapEx GetBitmapEx(BitmapEx const &rBitmapEx, DrawModeFlags nDrawMode)
SfxViewFrame * GetViewFrame() const
bool UnloadObject()
Definition: ndole.cxx:996
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:241
bool InsertField2(SwField const &, SwPaM *pAnnotationRange=nullptr)
Definition: wrtsh2.cxx:63
bool is() const
void StopShellTimer()
Definition: view.cxx:1811
static bool IsPasteOwnFormat(const TransferableDataHelper &)
Definition: swdtflvr.cxx:3370
SwWrtShell * GetShell()
Definition: swdtflvr.hxx:223
#define EXCHG_IN_ACTION_COPY
#define FN_DB_CONNECTION_ANY
Definition: cmdid.h:752
bool Paste(SwDoc &rClpDoc, bool bNestedTable=false)
Definition: fecopy.cxx:828
#define FN_DB_DATA_SOURCE_ANY
Definition: cmdid.h:754
virtual void SetVisArea(const tools::Rectangle &rVisArea)
const ::utl::TransliterationWrapper & GetAppCmpStrIgnore()
Definition: init.cxx:786
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:1022
URL aURL
void SetDataForDragAndDrop(const Point &rSttPos)
Definition: swdtflvr.cxx:3574
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:224
static SwTransferable * GetSwTransferable(const TransferableDataHelper &rData)
Definition: swdtflvr.cxx:4349
const Value & back() const
#define FN_TABLE_INSERT_COL_BEFORE
Definition: cmdid.h:370
bool hasValue()
sal_Int32 nIndex
SwTransferable(const SwTransferable &)=delete
static tools::Long GetDDStartPosX()
Definition: edtwin.hxx:250
const SwSelBoxes & GetSelectedBoxes() const
Definition: swcrsr.hxx:280
#define EXCHG_OUT_ACTION_INSERT_STRING
virtual const OUString & GetName() const =0
Marks a position in the document model.
Definition: pam.hxx:36
SwTransferable * m_pXSelection
Definition: swmodule.hxx:128
TransferableObjectDescriptor m_aObjDesc
Definition: swdtflvr.hxx:79
constexpr tools::Long constOleWidthInMm
Definition: swdtflvr.cxx:140
css::uno::Any GetAny(SotClipboardFormatId nFormat, const OUString &rDestDoc) const
bool SetBitmapEx(const BitmapEx &rBitmap, const css::datatransfer::DataFlavor &rFlavor)
bool isContentExtractionLocked() const
SdrView * GetDrawView()
Definition: vnew.cxx:373
void AutoCaption(const sal_uInt16 nType, const SvGlobalName *pOleId=nullptr)
Definition: viewdlg2.cxx:180
constexpr TypedWhichId< SvxPrintItem > RES_PRINT(98)
virtual bool DoSaveCompleted(SfxMedium *pNewStor=nullptr, bool bRegisterRecent=true)
const OUString & GetImageURL() const
void readGraphic(Graphic &rGraphic)
void SaveTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:870
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:754
void InsertDDETable(const SwInsertTableOptions &rInsTableOpts, SwDDEFieldType *pDDEType, sal_uInt16 nRows, sal_uInt16 nCols)
Definition: edtab.cxx:226
tools::SvRef< sfx2::SvBaseLink > m_xDdeLink
Definition: swdtflvr.hxx:80
SAL_DLLPRIVATE void SetProtectFlag(bool const bFlag)
Definition: section.hxx:104
SwTable::SearchType GetTableInsertMode() const
Definition: fesh.hxx:648
void SetLinkFileName(OUString const &rNew)
Definition: section.hxx:116
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:295
const OUString & GetText() const
Definition: ndtxt.hxx:218
std::unique_ptr< SwPaM > m_pPaM
Definition: swdtflvr.cxx:221
bool GoNextCursor()
go to the next SSelection
Definition: crsrsh.cxx:1357
SwUndoId
Definition: swundo.hxx:29
SwDocShell * GetDocShell()
Definition: doc.hxx:1351
bool g_bExecuteDrag
Definition: edtdd.cxx:46
bool GetURLFromButton(OUString &rURL, OUString &rDescr) const
Definition: wrtsh3.cxx:309
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
const OUString & GetTargetURL() const
static void ClearSelection(const SwWrtShell &rSh, const SwFrameShell *pCreator=nullptr)
Definition: swdtflvr.cxx:4325
void AddTransferable(SwTransferable &rTransferable)
Definition: view.cxx:1919
constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_DRAWMODEL
Definition: swdtflvr.cxx:149
constexpr SwTwips DOCUMENTBORDER
Definition: swtypes.hxx:79
signed char sal_Int8
virtual void SetRedlineFlags_intern(RedlineFlags eMode)=0
Set a new redline mode.
bool GetINetImage(SotClipboardFormatId nFormat, INetImage &rINtImg) const
static bool PasteAsHyperlink(const TransferableDataHelper &rData, SwWrtShell &rSh, SotClipboardFormatId nFormat)
Definition: swdtflvr.cxx:3052
SwNodeIndex nNode
Definition: pam.hxx:38
static bool PasteFileList(const TransferableDataHelper &rData, SwWrtShell &rSh, bool bLink, const Point *pPt, bool bMsg)
Definition: swdtflvr.cxx:3297
bool IsTableMode() const
Definition: crsrsh.hxx:648
static bool PasteGrf(const TransferableDataHelper &rData, SwWrtShell &rSh, SotClipboardFormatId nFormat, SwPasteSdr nAction, const Point *pPt, SotExchangeActionFlags nActionFlags, sal_Int8 nDropAction, bool bNeedToSelectBeforePaste, RndStdIds nAnchorType=RndStdIds::FLY_AT_PARA)
Definition: swdtflvr.cxx:2788
bool IsSttPara() const
Definition: crsrsh.cxx:1095
bool SetSmartURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
bool Is() const
#define FN_TABLE_DELETE_TABLE
Definition: cmdid.h:384
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:956
static bool IsPaste(const SwWrtShell &, const TransferableDataHelper &)
Definition: swdtflvr.cxx:1374
::std::vector< DataFlavorEx > DataFlavorExVector
sal_uIntPtr sal_uLong
long Long
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_RICHTEXT
Definition: swdtflvr.cxx:155
void SetPrefMapMode(const MapMode &rPrefMapMode)
Size GetObjSize() const
Definition: feshview.cxx:2392
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:474
bool PrivateDrop(SwWrtShell &rSh, const Point &rDragPt, bool bMove, bool bIsXSelection)
Definition: swdtflvr.cxx:3869
const SfxPoolItem * pAttr
Definition: crsrsh.hxx:102
static bool PasteDBData(const TransferableDataHelper &rData, SwWrtShell &rSh, SotClipboardFormatId nFormat, bool bLink, const Point *pDragPt, bool bMsg)
Definition: swdtflvr.cxx:3197
static bool PasteFileContent(const TransferableDataHelper &, SwWrtShell &rSh, SotClipboardFormatId nFormat, bool bMsg, bool bIgnoreComments=false)
Definition: swdtflvr.cxx:2131
void DeleteTable()
Definition: fetab.cxx:310
bool Pop(SwCursorShell::PopMode=SwCursorShell::PopMode::DeleteStack)
Definition: wrtsh1.cxx:1993
bool SetTransferableObjectDescriptor(const TransferableObjectDescriptor &rDesc)
#define EXCHG_OUT_ACTION_INSERT_DDE
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
#define CNT_HasGrf(USH)
Definition: editsh.hxx:135
bool IsModified() const
Changes in document?
Definition: edws.cxx:65
#define SOFFICE_FILEFORMAT_CURRENT
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
sal_Int64 n
Provides access to the marks of a document.
static bool PasteFormat(SwWrtShell &rSh, TransferableDataHelper &rData, SotClipboardFormatId nFormat)
Definition: swdtflvr.cxx:3375
SwSection const * InsertSection(SwSectionData &rNewData, SfxItemSet const *const =nullptr)
Definition: edsect.cxx:35
bool IsSupportedGraphic() const
static bool PasteDDE(const TransferableDataHelper &rData, SwWrtShell &rWrtShell, bool bReReadGrf, bool bMsg)
Definition: swdtflvr.cxx:2589
Definition: doc.hxx:187
bool HasFormat(SotClipboardFormatId nFormat)
void SetOle2Link(const Link< bool, void > &rLink)
Definition: doc.hxx:1327
const SwShellTableCursor * GetTableCursor() const
Definition: crsrsh.hxx:650
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:1410
aBuf
#define EXCHG_OUT_ACTION_REPLACE_SVXB
sal_Int16 nId
bool IsInsideSelectedObj(const Point &rPt)
returns enum values
Definition: feshview.cxx:1364
ObjCntType
Definition: fesh.hxx:121
SvStream * IsValid(SvStream &)
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
#define DND_ACTION_COPYMOVE
#define FN_DB_DATA_COMMAND_ANY
Definition: cmdid.h:755
#define SO3_SW_CLASSID
SwTableLine is one table row in the document model.
Definition: swtable.hxx:357
OUString GetSelDescr() const
Definition: wrtsh1.cxx:2039
SwNode & GetNode() const
Definition: ndindex.hxx:128
void SetTmpDocShell(SfxObjectShellLock rLock)
in case during copying of embedded object a new shell is created, it should be set here and cleaned l...
Definition: doc.hxx:1357
void EnterStdMode()
Definition: select.cxx:551
SwEditWin & GetEditWin()
Definition: view.hxx:416
void DestroyCursor()
transform TableCursor to normal cursor, nullify Tablemode
Definition: crsrsh.cxx:152
void Pos(const Point &rNew)
Definition: swrect.hxx:171
ErrCode Write(WriterRef const &rxWriter, const OUString *=nullptr)
Definition: shellio.cxx:731
void DoUndo(bool bOn=true)
Undo.
Definition: edws.cxx:200
void ReplaceCompatibilityOptions(const SwDoc &rSource)
Definition: docnew.cxx:876
SotExchangeDest
void SetReadUTF8(bool bSet)
Definition: shellio.hxx:259
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1792
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
size_t GetIMapObjectCount() const
void NavigatorPaste(const NaviContentBookmark &rBkmk, const sal_uInt16 nAction)
Definition: wrtsh2.cxx:569
void InsertGraphic(const OUString &rPath, const OUString &rFilter, const Graphic &, SwFlyFrameAttrMgr *=nullptr, RndStdIds nAnchorType=RndStdIds::FLY_AT_PARA)
Definition: wrtsh1.cxx:271
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
sal_uInt16 Which() const
Definition: txatbase.hxx:116
sal_uInt16 Count() const
void SetClipBoard(bool bNew)
Definition: doc.hxx:964
comphelper::OInterfaceContainerHelper3< css::text::XPasteListener > & GetPasteListeners()
Definition: fecopy.cxx:1212
#define EXCHG_OUT_ACTION_MOVE_PRIVATE
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
bool InsertOleObject(const svt::EmbeddedObjectRef &xObj, SwFlyFrameFormat **pFlyFrameFormat=nullptr)
Definition: wrtsh1.cxx:494
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
bool HasFormat(SotClipboardFormatId nFormat) const
void EndAllAction()
Definition: edws.cxx:97
#define FN_PASTE_NESTED_TABLE
Definition: cmdid.h:310
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
void ReplaceStyles(const SwDoc &rSource, bool bIncludePageStyles=true)
Definition: docfmt.cxx:1558
bool SetINetBookmark(const INetBookmark &rBmk, const css::datatransfer::DataFlavor &rFlavor)
bool SetObject(void *pUserObject, sal_uInt32 nUserObjectId, const css::datatransfer::DataFlavor &rFlavor)
void StartInsertRegionDialog(const SwSectionData &)
Definition: regionsw.cxx:155
css::uno::Reference< css::document::XDocumentProperties > getDocProperties() const
bool DelRight()
Definition: delete.cxx:294
static bool isMediaURL(std::u16string_view rURL, const OUString &rReferer, bool bDeep=false, rtl::Reference< PlayerListener > xPreferredPixelSizeListener=nullptr)
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:155
Degree10 getRotation() const
const Value & front() const
virtual void LockExpFields()=0
#define DND_ACTION_MOVE
void SwapPam()
Definition: crsrsh.cxx:976
#define EXCHG_IN_ACTION_DEFAULT
Used by the UI to modify the document model.
Definition: wrtsh.hxx:96
bool CopyGlossary(SwTextBlocks &rGlossary, const OUString &rStr)
Definition: swdtflvr.cxx:1229
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:164
void AddFormat(SotClipboardFormatId nFormat)
constexpr tools::Long Width() const
static void SelectPasteFormat(TransferableDataHelper &rData, sal_uInt8 &nAction, SotClipboardFormatId &nFormat)
Definition: swdtflvr.cxx:1415
HashMap_OWString_Interface aMap
static UITestLogger & getInstance()
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:357
SdrObjectUniquePtr CreateXFormsControl(const svx::OXFormsDescriptor &_rDesc)
void logEvent(const EventDescription &rDescription)
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: swdtflvr.cxx:4337
#define EXCHG_OUT_ACTION_INSERT_IMAGEMAP
sal_uInt16 sal_Unicode
Reader * ReadXML
Definition: fltini.cxx:46
tools::Long ResetSelect(const Point *, bool)
Definition: select.cxx:333
bool GotoFly(const OUString &rName, FlyCntType eType=FLYCNTTYPE_ALL, bool bSelFrame=true)
Definition: move.cxx:599
OUString m_sName
const SwView & GetView() const
Definition: wrtsh.hxx:437
virtual const_iterator_t findMark(const OUString &rMark) const =0
Finds a mark by name.
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)