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>
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>
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>
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>
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
143 constOleWidthInMm * 100, // convert from mm to 100mm
144 3000 // 3 cm
145);
146
148
149constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_DRAWMODEL = 0x00000001;
150constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_HTML = 0x00000002;
151constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_RTF = 0x00000004;
152constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_STRING = 0x00000008;
153constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_SWOLE = 0x00000010;
154constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_DDE = 0x00000020;
155constexpr sal_uInt32 SWTRANSFER_OBJECTTYPE_RICHTEXT = 0x00000040;
156
157using namespace ::svx;
158using namespace ::com::sun::star;
159using namespace ::com::sun::star::uno;
160using namespace ::com::sun::star::datatransfer;
161namespace {
162
163void 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
176namespace {
177
178class 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
192protected:
193 virtual ~SwTransferDdeLink() override;
194
195public:
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{
212public:
213 SwPasteContext(SwWrtShell& rWrtShell);
215
216 void remember();
217 void forget();
218
219private:
221 std::optional<SwPaM> m_oPaM;
222 sal_Int32 m_nStartContent = 0;
223};
224
225namespace {
226
227// helper class for Action and Undo enclosing
228class SwTrnsfrActionAndUndo
229{
230 SwWrtShell *pSh;
231public:
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 );
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
321static 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 {
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
358uno::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
396namespace
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()->GetNodeIndex();
441 nIndex <= rPaM.GetPoint()->GetNodeIndex(); ++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
474bool 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_oClpGraphic.emplace();
498 if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_oClpGraphic ))
500 m_oClpBitmap.emplace();
501 if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_oClpBitmap ))
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 {
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() )
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_oClpGraphic->GetGDIMetaFile() );
640 break;
641 case SotClipboardFormatId::BITMAP:
642 case SotClipboardFormatId::PNG:
643 // Neither pClpBitmap nor pClpGraphic are necessarily set
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();
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::TempFileFast aTempFile;
742 SvStream* pTempStream = aTempFile.GetStream(StreamMode::READWRITE);
743 uno::Reference< embed::XStorage > xWorkStore =
744 ::comphelper::OStorageHelper::GetStorageFromStream( new utl::OStreamWrapper(*pTempStream), 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 xStream->SetBufferSize( 0xff00 );
758 xStream->WriteStream( *pTempStream );
759
760 xWorkStore->dispose();
761 xWorkStore.clear();
762 }
763 catch (const uno::Exception&)
764 {
765 }
766
767 bRet = ( xStream->GetError() == ERRCODE_NONE );
768 }
769 break;
770
772 {
773 xStream->SetBufferSize( 1024 );
774 SwTransferDdeLink* pDdeLnk = static_cast<SwTransferDdeLink*>(pObject);
775 if( pDdeLnk->WriteData( *xStream ) )
776 {
777 bRet = ERRCODE_NONE == xStream->GetError();
778 }
779 }
780 break;
781
783 {
784 // LOK is interested in getting images embedded for copy/paste support.
785 GetHTMLWriter( comphelper::LibreOfficeKit::isActive() ? OUString("EmbedImages;NoLineLimit") : OUString(), OUString(), xWrt );
786 break;
787 }
788
791 GetRTFWriter(std::u16string_view(), OUString(), xWrt);
792 break;
793
795 GetASCWriter(std::u16string_view(), OUString(), xWrt);
796 if( xWrt.is() )
797 {
798 SwAsciiOptions aAOpt;
799 aAOpt.SetCharSet( RTL_TEXTENCODING_UTF8 );
800 xWrt->SetAsciiOptions( aAOpt );
801
802 // no start char for clipboard
803 xWrt->m_bUCS2_WithStartChar = false;
804 }
805 break;
806 default: break;
807 }
808
809 if( xWrt.is() )
810 {
811 SwDoc* pDoc = static_cast<SwDoc*>(pObject);
812 xWrt->m_bWriteClipboardDoc = true;
813 xWrt->m_bWriteOnlyFirstTable = bool(TransferBufferType::Table & m_eBufferType);
814 xWrt->SetShowProgress(false);
815
816#if defined(DEBUGPASTE)
817 SvFileStream aPasteDebug(OUString(
818 "PASTEBUFFER.debug"), StreamMode::WRITE|StreamMode::TRUNC);
819 SwWriter aDbgWrt( aPasteDebug, *pDoc );
820 aDbgWrt.Write( xWrt );
821#endif
822
823 SwWriter aWrt( *xStream, *pDoc );
824 if( ! aWrt.Write( xWrt ).IsError() )
825 {
826 xStream->WriteChar( '\0' ); // terminate with a zero
827 bRet = true;
828 }
829 }
830
831 return bRet;
832}
833
835{
836 int nRet = Copy( true );
837 if( nRet )
839 collectUIInformation("CUT", "parameter");
840 return nRet;
841}
842
844{
845 if(!m_pWrtShell)
846 return;
847 // ask for type of selection before action-bracketing
848 const SelectionType nSelection = m_pWrtShell->GetSelectionType();
849 // cut rows or columns selected by enhanced table selection and wholly selected tables
850 bool bCutMode = ( SelectionType::TableCell & nSelection ) && ( (SelectionType::TableRow | SelectionType::TableCol) & nSelection ||
852
854 if( bCutMode )
855 {
856 if( !(SelectionType::TableCol & nSelection) )
858 else
859 {
861 pDispatch->Execute(FN_TABLE_DELETE_COL, SfxCallMode::SYNCHRON);
862 }
863 }
864 else
865 {
866 if( ( SelectionType::Text | SelectionType::Table ) & nSelection )
867 m_pWrtShell->IntelligentCut( nSelection );
869 }
871}
872
873static void DeleteDDEMarks(SwDoc & rDest)
874{
875 IDocumentMarkAccess *const pMarkAccess = rDest.getIDocumentMarkAccess();
876 std::vector< ::sw::mark::IMark* > vDdeMarks;
877 // find all DDE-Bookmarks
878 for (IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
879 ppMark != pMarkAccess->getAllMarksEnd();
880 ++ppMark)
881 {
883 {
884 vDdeMarks.push_back(*ppMark);
885 }
886 }
887 // remove all DDE-Bookmarks, they are invalid inside the clipdoc!
888 for (const auto& rpMark : vDdeMarks)
889 {
890 pMarkAccess->deleteMark(rpMark);
891 }
892}
893
895{
896 std::optional<SwWait> oWait;
897 if (m_pWrtShell->ShouldWait())
898 {
899 oWait.emplace( *m_pWrtShell->GetView().GetDocShell(), true );
900 }
901
902 m_pClpDocFac.reset(new SwDocFac);
903
904 SwDoc& rDest(lcl_GetDoc(*m_pClpDocFac));
905 rDest.getIDocumentFieldsAccess().LockExpFields(); // Never update fields - leave text as is
906 {
907 SwDoc const& rSrc(*m_pWrtShell->GetDoc());
908 assert(&rSrc == &rPaM.GetDoc());
909
910 rDest.ReplaceCompatibilityOptions(rSrc);
911 rDest.ReplaceDefaults(rSrc);
912
913 //It would probably make most sense here to only insert the styles used
914 //by the selection, e.g. apply SwDoc::IsUsed on styles ?
915 rDest.ReplaceStyles(rSrc, false);
916
917 // relevant bits of rSrcWrtShell.Copy(rDest);
918 rDest.GetIDocumentUndoRedo().DoUndo(false); // always false!
920
921 SwNodeIndex const aIdx(rDest.GetNodes().GetEndOfContent(), -1);
922 SwContentNode *const pContentNode(aIdx.GetNode().GetContentNode());
923 SwPosition aPos(aIdx, pContentNode, pContentNode ? pContentNode->Len() : 0);
924
926
928
930 }
931
932 DeleteDDEMarks(rDest);
933
934 // a new one was created in core (OLE objects copied!)
936 if (m_aDocShellRef.Is())
938 rDest.SetTmpDocShell( nullptr );
939
940 // let's add some formats
941 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
942 AddFormat( SotClipboardFormatId::RTF );
943#if HAVE_FEATURE_DESKTOP
944 AddFormat( SotClipboardFormatId::RICHTEXT );
945 AddFormat( SotClipboardFormatId::HTML );
946#endif
947 AddFormat( SotClipboardFormatId::STRING );
948}
949
951{
952 int nRet = 1;
953 if(!m_pWrtShell)
954 return 0;
955
958
960 m_pWrtShell->SetTableCopied( false );
961
962 OUString sGrfNm;
963 const SelectionType nSelection = m_pWrtShell->GetSelectionType();
964 if( nSelection == SelectionType::Graphic )
965 {
966 m_oClpGraphic.emplace();
967 if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_oClpGraphic ))
969 m_oClpBitmap.emplace();
970 if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_oClpBitmap ))
972
973 m_pClpDocFac.reset(new SwDocFac);
974 SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
975 m_pWrtShell->Copy(rDoc);
976
977#if HAVE_FEATURE_DESKTOP
979 AddFormat( SotClipboardFormatId::SVXB );
980#endif
981
983 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
984
985 const Graphic* pGrf = m_pWrtShell->GetGraphic();
986 if( pGrf && pGrf->IsSupportedGraphic() )
987 {
988 AddFormat( SotClipboardFormatId::PNG );
989#if HAVE_FEATURE_DESKTOP
990 AddFormat( SotClipboardFormatId::GDIMETAFILE );
991 AddFormat( SotClipboardFormatId::BITMAP );
992#endif
993 }
995 m_pWrtShell->GetGrfNms( &sGrfNm, nullptr );
996 }
997 else if ( nSelection == SelectionType::Ole )
998 {
999 m_pClpDocFac.reset(new SwDocFac);
1000 SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
1001 m_aDocShellRef = new SwDocShell(rDoc, SfxObjectCreateMode::EMBEDDED);
1003 m_pWrtShell->Copy(rDoc);
1004
1005 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
1006
1007 // --> OD #i98753#
1008 // set size of embedded object at the object description structure
1010
1011 // <--
1013
1014#if HAVE_FEATURE_DESKTOP
1015 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
1016 AddFormat( SotClipboardFormatId::GDIMETAFILE );
1017
1018 // Fetch the formats supported via embedtransferhelper as well
1019 sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
1020 uno::Reference < embed::XEmbeddedObject > xObj = FindOLEObj( nAspect );
1021 const Graphic* pOLEGraph = FindOLEReplacementGraphic();
1022 if( xObj.is() )
1023 {
1024 TransferableDataHelper aD( new SvEmbedTransferHelper( xObj, pOLEGraph, nAspect ) );
1025 if ( aD.GetTransferable().is() )
1026 {
1028
1029 for( const auto& rItem : aVector )
1030 AddFormat( rItem );
1031 }
1032 }
1033#endif
1035 }
1036 // Is there anything to provide anyway?
1039 {
1040 std::optional<SwWait> oWait;
1041 if( m_pWrtShell->ShouldWait() )
1042 oWait.emplace( *m_pWrtShell->GetView().GetDocShell(), true );
1043
1044 m_pClpDocFac.reset(new SwDocFac);
1045
1046 // create additional cursor so that equal treatment of keyboard
1047 // and mouse selection is possible.
1048 // In AddMode with keyboard selection, the new cursor is not created
1049 // before the cursor is moved after end of selection.
1050 if( m_pWrtShell->IsAddMode() && m_pWrtShell->SwCursorShell::HasSelection() )
1052
1053 SwDoc& rTmpDoc = lcl_GetDoc(*m_pClpDocFac);
1054
1055 rTmpDoc.getIDocumentFieldsAccess().LockExpFields(); // Never update fields - leave text as is
1056 lclOverWriteDoc(*m_pWrtShell, rTmpDoc);
1057
1058 DeleteDDEMarks(rTmpDoc);
1059
1060 // a new one was created in CORE (OLE objects copied!)
1061 m_aDocShellRef = rTmpDoc.GetTmpDocShell();
1062 if( m_aDocShellRef.Is() )
1064 rTmpDoc.SetTmpDocShell( nullptr );
1065
1066 if( m_pWrtShell->IsObjSelected() )
1068 else
1069 {
1071 if (m_pWrtShell->IntelligentCut(nSelection, false) != SwWrtShell::NO_WORD)
1073 }
1074
1075 bool bDDELink = m_pWrtShell->IsSelection();
1076 if( nSelection & SelectionType::TableCell )
1077 {
1079 bDDELink = m_pWrtShell->HasWholeTabSelection();
1080
1082
1083 if ( bIsCut && (SelectionType::TableRow | SelectionType::TableCol) & nSelection )
1085 }
1086
1087#if HAVE_FEATURE_DESKTOP
1088 //When someone needs it, we 'OLE' him something
1089 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
1090#endif
1091
1092 //put RTF ahead of the OLE's Metafile to have less loss
1093 if( !m_pWrtShell->IsObjSelected() )
1094 {
1095 AddFormat( SotClipboardFormatId::RTF );
1096#if HAVE_FEATURE_DESKTOP
1097 AddFormat( SotClipboardFormatId::RICHTEXT );
1098 AddFormat( SotClipboardFormatId::HTML );
1099#endif
1100 }
1101 if( m_pWrtShell->IsSelection() )
1102 AddFormat( SotClipboardFormatId::STRING );
1103
1104 if( nSelection & ( SelectionType::DrawObject | SelectionType::DbForm ))
1105 {
1106 AddFormat( SotClipboardFormatId::DRAWING );
1107 if ( nSelection & SelectionType::DrawObject )
1108 {
1109#if HAVE_FEATURE_DESKTOP
1110 AddFormat( SotClipboardFormatId::GDIMETAFILE );
1111 AddFormat( SotClipboardFormatId::BITMAP );
1112#endif
1113 AddFormat( SotClipboardFormatId::PNG );
1114 }
1116
1117 m_oClpGraphic.emplace();
1118 if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::GDIMETAFILE, *m_oClpGraphic ))
1120 m_oClpBitmap.emplace();
1121 if( !m_pWrtShell->GetDrawObjGraphic( SotClipboardFormatId::BITMAP, *m_oClpBitmap ))
1123
1124 // is it a URL-Button ?
1125 OUString sURL;
1126 OUString sDesc;
1127 if( m_pWrtShell->GetURLFromButton( sURL, sDesc ) )
1128 {
1129 AddFormat( SotClipboardFormatId::STRING );
1130#if HAVE_FEATURE_DESKTOP
1131 AddFormat( SotClipboardFormatId::SOLK );
1132 AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
1133 AddFormat( SotClipboardFormatId::FILECONTENT );
1134 AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
1135#endif
1136 AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
1138 nRet = 1;
1139 }
1140 }
1141
1142 // at Cut, DDE-Link doesn't make sense!!
1143 SwDocShell* pDShell;
1144 if( !bIsCut && bDDELink &&
1145 nullptr != ( pDShell = m_pWrtShell->GetDoc()->GetDocShell()) &&
1146 SfxObjectCreateMode::STANDARD == pDShell->GetCreateMode() )
1147 {
1148#if HAVE_FEATURE_DESKTOP
1149 AddFormat( SotClipboardFormatId::LINK );
1150#endif
1151 m_xDdeLink = new SwTransferDdeLink( *this, *m_pWrtShell );
1152 }
1153
1154 //ObjectDescriptor was already filly from the old DocShell.
1155 //Now adjust it. Thus in GetData the first query can still
1156 //be answered with delayed rendering.
1158
1160#if HAVE_FEATURE_DESKTOP
1161 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
1162#endif
1163 }
1164 else
1165 nRet = 0;
1166
1168 {
1171 const SwFormatURL& rURL = aSet.Get( RES_URL );
1172 if( rURL.GetMap() )
1173 {
1174 m_pImageMap.reset( new ImageMap( *rURL.GetMap() ) );
1175 AddFormat( SotClipboardFormatId::SVIM );
1176 }
1177 else if( !rURL.GetURL().isEmpty() )
1178 {
1179 m_pTargetURL.reset(new INetImage( sGrfNm, rURL.GetURL(),
1180 rURL.GetTargetFrameName() ));
1181 AddFormat( SotClipboardFormatId::INET_IMAGE );
1182 }
1183 }
1184
1185 return nRet;
1186}
1187
1188int SwTransferable::Copy( bool bIsCut )
1189{
1191 return 0;
1192
1193 int nRet = PrepareForCopy( bIsCut );
1194 if ( nRet )
1195 {
1197 }
1198
1199 if( !bIsCut ){
1200 collectUIInformation("COPY", "parameter");
1201 }
1202
1203 return nRet;
1204}
1205
1207{
1208 if(!m_pWrtShell)
1209 return;
1210 SwWait aWait( *m_pWrtShell->GetView().GetDocShell(), true );
1211
1212 OUString aStr( m_pWrtShell->Calculate() );
1213
1214 m_pClpDocFac.reset(new SwDocFac);
1215 SwDoc& rDoc = lcl_GetDoc(*m_pClpDocFac);
1216 m_pWrtShell->Copy(rDoc, &aStr);
1218 AddFormat( SotClipboardFormatId::STRING );
1219
1221}
1222
1223bool SwTransferable::CopyGlossary( SwTextBlocks& rGlossary, const OUString& rStr )
1224{
1225 if(!m_pWrtShell)
1226 return false;
1227 SwWait aWait( *m_pWrtShell->GetView().GetDocShell(), true );
1228
1229 m_pClpDocFac.reset(new SwDocFac);
1230 SwDoc& rCDoc = lcl_GetDoc(*m_pClpDocFac);
1231
1232 SwNodes& rNds = rCDoc.GetNodes();
1233 SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() );
1234 SwContentNode* pCNd = rNds.GoNext( &aNodeIdx ); // go to 1st ContentNode
1235 SwPaM aPam( *pCNd );
1236
1237 rCDoc.getIDocumentFieldsAccess().LockExpFields(); // never update fields - leave text as it is
1238
1239 rCDoc.InsertGlossary( rGlossary, rStr, aPam );
1240
1241 // a new one was created in CORE (OLE-Objects copied!)
1243 if( m_aDocShellRef.Is() )
1245 rCDoc.SetTmpDocShell( nullptr );
1246
1248
1249 //When someone needs it, we 'OLE' her something.
1250 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
1251 AddFormat( SotClipboardFormatId::RTF );
1252 AddFormat( SotClipboardFormatId::RICHTEXT );
1253 AddFormat( SotClipboardFormatId::HTML );
1254 AddFormat( SotClipboardFormatId::STRING );
1255
1256 //ObjectDescriptor was already filled from the old DocShell.
1257 //Now adjust it. Thus in GetData the first query can still
1258 //be answered with delayed rendering.
1260
1262 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
1263
1265
1266 return true;
1267}
1268
1269static uno::Reference < XTransferable > * lcl_getTransferPointer ( uno::Reference < XTransferable > &xRef )
1270{
1271 return &xRef;
1272}
1273
1275 : m_rWrtShell(rWrtShell)
1276{
1277 remember();
1278}
1279
1281{
1283 return;
1284
1285 SwPaM* pCursor = m_rWrtShell.GetCursor();
1286 if (!pCursor)
1287 return;
1288
1289 // Set point to the previous node, so it is not moved.
1290 const SwNode& rNode = pCursor->GetPoint()->GetNode();
1291 m_oPaM.emplace(rNode, rNode, SwNodeOffset(0), SwNodeOffset(-1));
1293}
1294
1296
1298{
1299 try
1300 {
1302 return;
1303
1304 beans::PropertyValue aPropertyValue;
1305
1306 switch (m_rWrtShell.GetView().GetShellMode())
1307 {
1308 case ShellMode::Graphic:
1309 {
1311 if (!pFormat)
1312 return;
1313
1314 aPropertyValue.Name = "TextGraphicObject";
1315 aPropertyValue.Value
1316 <<= uno::Reference<text::XTextContent>(SwXTextGraphicObject::CreateXTextGraphicObject(*pFormat->GetDoc(), pFormat));
1317 break;
1318 }
1319
1320 default:
1321 {
1322 if (!m_oPaM)
1323 return;
1324
1325 SwPaM* pCursor = m_rWrtShell.GetCursor();
1326 if (!pCursor)
1327 return;
1328
1329 if (!pCursor->GetPoint()->GetNode().IsTextNode())
1330 // Non-text was pasted.
1331 return;
1332
1333 // Update mark after paste.
1334 *m_oPaM->GetMark() = *pCursor->GetPoint();
1335
1336 // Restore point.
1337 m_oPaM->GetPoint()->Adjust(SwNodeOffset(1));
1338 SwNode& rNode = m_oPaM->GetPointNode();
1339 if (!rNode.IsTextNode())
1340 // Starting point is no longer text.
1341 return;
1342
1343 m_oPaM->GetPoint()->SetContent(m_nStartContent);
1344
1345 aPropertyValue.Name = "TextRange";
1347 m_oPaM->GetDoc(), *m_oPaM->GetPoint(), m_oPaM->GetMark());
1348 aPropertyValue.Value <<= uno::Reference<text::XTextRange>(xTextRange);
1349 break;
1350 }
1351 }
1352
1353 if (aPropertyValue.Name.isEmpty())
1354 return;
1355
1356 // Invoke the listeners.
1357 uno::Sequence<beans::PropertyValue> aEvent{ aPropertyValue };
1358 m_rWrtShell.GetPasteListeners().notifyEach( &css::text::XPasteListener::notifyPasteEvent, aEvent );
1359 }
1360 catch (const uno::Exception& rException)
1361 {
1362 SAL_WARN("sw",
1363 "SwPasteContext::~SwPasteContext: uncaught exception: " << rException.Message);
1364 }
1365}
1366
1368 const TransferableDataHelper& rData )
1369{
1370 // Check the common case first: We can always paste our own data!
1371 // If _only_ the internal format can be pasted, this check will
1372 // yield 'true', while the one below would give a (wrong) result 'false'.
1373
1374 bool bIsPaste = ( GetSwTransferable( rData ) != nullptr );
1375
1376 // if it's not our own data, we need to have a closer look:
1377 if( ! bIsPaste )
1378 {
1379 // determine the proper paste action, and return true if we find one
1380 uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
1381
1383 sal_uInt16 nSourceOptions =
1384 (( SotExchangeDest::DOC_TEXTFRAME == nDestination ||
1385 SotExchangeDest::SWDOC_FREE_AREA == nDestination ||
1386 SotExchangeDest::DOC_TEXTFRAME_WEB == nDestination ||
1387 SotExchangeDest::SWDOC_FREE_AREA_WEB == nDestination )
1390
1391 SotClipboardFormatId nFormat; // output param for GetExchangeAction
1392 sal_uInt8 nEventAction; // output param for GetExchangeAction
1394 rData.GetDataFlavorExVector(),
1395 nDestination,
1396 nSourceOptions, /* ?? */
1397 EXCHG_IN_ACTION_DEFAULT, /* ?? */
1398 nFormat, nEventAction, SotClipboardFormatId::NONE,
1399 lcl_getTransferPointer ( xTransferable ) );
1400
1401 // if we find a suitable action, we can paste!
1402 bIsPaste = (EXCHG_INOUT_ACTION_NONE != nAction);
1403 }
1404
1405 return bIsPaste;
1406}
1407
1409 SotClipboardFormatId& nFormat)
1410{
1411 if (nFormat != SotClipboardFormatId::RICHTEXT)
1412 {
1413 return;
1414 }
1415
1416 if (!rData.HasFormat(SotClipboardFormatId::EMBED_SOURCE))
1417 {
1418 return;
1419 }
1420
1421 if (!rData.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
1422 {
1423 return;
1424 }
1425
1427 if (!rData.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc))
1428 {
1429 return;
1430 }
1431
1432 if (aObjDesc.maClassName != SvGlobalName(SO3_SW_CLASSID))
1433 {
1434 return;
1435 }
1436
1437 // At this point we know that we paste from Writer to Writer and the clipboard has the content
1438 // in both RTF and ODF formats. Prefer ODF in this case.
1440 nFormat = SotClipboardFormatId::EMBED_SOURCE;
1441}
1442
1443// get HTML indentation level by counting tabulator characters before the index
1444// (also index value -1 returns with 0)
1445static sal_Int32 lcl_getLevel(OUString& sText, sal_Int32 nIdx)
1446{
1447 sal_Int32 nRet = 0;
1448 while ( nIdx-- > 0 && sText[nIdx] == '\t' )
1449 {
1450 nRet++;
1451 }
1452 return nRet;
1453}
1454
1455bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndStdIds nAnchorType, bool bIgnoreComments, PasteTableType ePasteTable)
1456{
1457 SwPasteContext aPasteContext(rSh);
1458
1459 sal_uInt8 nAction=0;
1461 SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
1462 SotExchangeActionFlags nActionFlags = SotExchangeActionFlags::NONE;
1463 bool bSingleCellTable = false;
1464
1465 if( GetSwTransferable( rData ) )
1466 {
1468 }
1469 else
1470 {
1471 sal_uInt16 nSourceOptions =
1472 (( SotExchangeDest::DOC_TEXTFRAME == nDestination ||
1473 SotExchangeDest::SWDOC_FREE_AREA == nDestination ||
1474 SotExchangeDest::DOC_TEXTFRAME_WEB == nDestination ||
1475 SotExchangeDest::SWDOC_FREE_AREA_WEB == nDestination )
1478 uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
1479 sal_uInt8 nEventAction;
1481 rData.GetDataFlavorExVector(),
1482 nDestination,
1483 nSourceOptions, /* ?? */
1484 EXCHG_IN_ACTION_DEFAULT, /* ?? */
1485 nFormat, nEventAction, SotClipboardFormatId::NONE,
1486 lcl_getTransferPointer ( xTransferable ),
1487 &nActionFlags );
1488 }
1489
1490 // when HTML is just an image don't generate new section
1491 if (rData.HasFormat(SotClipboardFormatId::HTML_SIMPLE) && rData.HasFormat(SotClipboardFormatId::HTML_NO_COMMENT)
1492 && rData.HasFormat(SotClipboardFormatId::BITMAP) && nFormat == SotClipboardFormatId::FILE_LIST)
1493 nFormat = SotClipboardFormatId::BITMAP;
1494
1495 // tdf#37223 avoid non-native insertion of Calc worksheets in the following cases:
1496 // content of 1-cell worksheets are inserted as simple text using RTF format,
1497 // bigger worksheets within native (Writer) table cells are inserted as native tables,
1498 // ie. cell by cell instead of embedding the worksheet in a single cell of the Writer table
1499 if ( EXCHG_IN_ACTION_COPY == nAction && ( rData.HasFormat( SotClipboardFormatId::SYLK ) ||
1500 rData.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS ) ) )
1501 {
1502 // is it a 1-cell worksheet?
1503 OUString aExpand;
1504 if( rData.GetString( SotClipboardFormatId::STRING, aExpand ))
1505 {
1506 const sal_Int32 nNewlines{comphelper::string::getTokenCount(aExpand, '\n')};
1507 const sal_Int32 nRows = nNewlines ? nNewlines-1 : 0;
1508 if ( nRows == 1 )
1509 {
1510 const sal_Int32 nCols = comphelper::string::getTokenCount(o3tl::getToken(aExpand, 0, '\n'), '\t');
1511 if (nCols == 1)
1512 bSingleCellTable = true;
1513 }
1514 }
1515
1516 // convert the worksheet to a temporary native table using HTML format, and copy that into the original native table
1517 if (!bSingleCellTable && rData.HasFormat( SotClipboardFormatId::HTML ) &&
1518 SwDoc::IsInTable(rSh.GetCursor()->GetPointNode()) != nullptr && rSh.DoesUndo())
1519 {
1520 SfxDispatcher* pDispatch = rSh.GetView().GetViewFrame()->GetDispatcher();
1521 sal_uInt32 nLevel = 0;
1522 // within Writer table cells, inserting worksheets using HTML format results only plain text, not a native table,
1523 // so remove all outer nested tables temporary to get a working insertion point
1524 // (RTF format has no such problem, but that inserts the hidden rows of the original Calc worksheet, too)
1525 do
1526 {
1527 // insert a random character to redo the place of the insertion at the end
1528 pDispatch->Execute(FN_INSERT_NNBSP, SfxCallMode::SYNCHRON);
1529 pDispatch->Execute(FN_TABLE_DELETE_TABLE, SfxCallMode::SYNCHRON);
1530 nLevel++;
1531 } while (SwDoc::IsInTable(rSh.GetCursor()->GetPointNode()) != nullptr);
1532 if ( SwTransferable::PasteData( rData, rSh, EXCHG_OUT_ACTION_INSERT_STRING, nActionFlags, SotClipboardFormatId::HTML,
1533 nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext, ePasteTable) )
1534 {
1535 bool bFoundTemporaryTable = false;
1536 pDispatch->Execute(FN_LINE_UP, SfxCallMode::SYNCHRON);
1537 if (SwDoc::IsInTable(rSh.GetCursor()->GetPointNode()) != nullptr)
1538 {
1539 bFoundTemporaryTable = true;
1540 pDispatch->Execute(FN_TABLE_SELECT_ALL, SfxCallMode::SYNCHRON);
1541 pDispatch->Execute(SID_COPY, SfxCallMode::SYNCHRON);
1542 }
1543 for(sal_uInt32 a = 0; a < 1 + (nLevel * 2); a++)
1544 pDispatch->Execute(SID_UNDO, SfxCallMode::SYNCHRON);
1545 // clipboard content hasn't changed (limit potential infinite
1546 // recursion with the same non-native table, as was in tdf#138688)
1547 if (!bFoundTemporaryTable)
1548 return false;
1549 if (ePasteTable == PasteTableType::PASTE_TABLE)
1550 pDispatch->Execute(FN_PASTE_NESTED_TABLE, SfxCallMode::SYNCHRON);
1551 else if (ePasteTable == PasteTableType::PASTE_ROW)
1552 pDispatch->Execute(FN_TABLE_PASTE_ROW_BEFORE, SfxCallMode::SYNCHRON);
1553 else if (ePasteTable == PasteTableType::PASTE_COLUMN)
1554 pDispatch->Execute(FN_TABLE_PASTE_COL_BEFORE, SfxCallMode::SYNCHRON);
1555 else
1556 pDispatch->Execute(SID_PASTE, SfxCallMode::SYNCHRON);
1557 return true;
1558 } else {
1559 for(sal_uInt32 a = 0; a < (nLevel * 2); a++)
1560 pDispatch->Execute(SID_UNDO, SfxCallMode::SYNCHRON);
1561 }
1562 }
1563 }
1564 // insert clipboard content as new table rows/columns before the actual row/column instead of overwriting it
1565 else if ( (rSh.GetTableInsertMode() != SwTable::SEARCH_NONE || ePasteTable == PasteTableType::PASTE_ROW || ePasteTable == PasteTableType::PASTE_COLUMN) &&
1566 rData.HasFormat( SotClipboardFormatId::HTML ) &&
1567 SwDoc::IsInTable(rSh.GetCursor()->GetPointNode()) != nullptr )
1568 {
1569 OUString aExpand;
1570 sal_Int32 nIdx;
1571 bool bRowMode = rSh.GetTableInsertMode() == SwTable::SEARCH_ROW || ePasteTable == PasteTableType::PASTE_ROW;
1572 if( rData.GetString( SotClipboardFormatId::HTML, aExpand ) && (nIdx = aExpand.indexOf("<table")) > -1 )
1573 {
1574 // calculate table row/column count by analysing indentation of the HTML table extract
1575
1576 // calculate indentation level of <table>, which is the base of the next calculations
1577 // (tdf#148791 table alignment can enlarge it using first level <center>, <div> or <dl>)
1578 sal_Int32 nTableLevel = lcl_getLevel(aExpand, nIdx);
1579 // table rows repeated heading use extra indentation, too:
1580 // <thead> is always used here, and the first table with <thead> is not nested,
1581 // if its indentation level is greater only by 1, than indentation level of the table
1582 bool bShifted = lcl_getLevel(aExpand, aExpand.indexOf("<thead")) == nTableLevel + 1;
1583 // calculate count of selected rows or columns
1584 sal_Int32 nSelectedRowsOrCols = 0;
1585 const OUString sSearchRowOrCol = bRowMode ? OUString("</tr>") : OUString("<col ");
1586 while((nIdx = aExpand.indexOf(sSearchRowOrCol, nIdx)) > -1)
1587 {
1588 // skip rows/columns of nested tables, based on HTML indentation
1589 if ( lcl_getLevel(aExpand, nIdx) == nTableLevel + (bShifted ? 2 : 1) &&
1590 // skip also strange hidden empty rows <tr></tr>
1591 !aExpand.match("<tr></tr>", nIdx - 4) )
1592 {
1593 ++nSelectedRowsOrCols;
1594 }
1595 ++nIdx;
1596 }
1597 // are we at the beginning of the cell?
1598 bool bStartTableBoxNode =
1599 // first paragraph of the cell?
1601 // beginning of the paragraph?
1602 !rSh.GetCursor()->GetPoint()->GetContentIndex();
1603 SfxDispatcher* pDispatch = rSh.GetView().GetViewFrame()->GetDispatcher();
1604
1605 // go start of the cell
1606 if (!bStartTableBoxNode)
1607 pDispatch->Execute(FN_START_OF_DOCUMENT, SfxCallMode::SYNCHRON);
1608
1609 // store cursor position in row mode
1610 ::sw::mark::IMark* pMark = (!bRowMode || nSelectedRowsOrCols == 0) ? nullptr : rSh.SetBookmark(
1611 vcl::KeyCode(),
1612 OUString(),
1614
1615 // add a new empty row/column before the actual table row/column and go there
1616 // (without setting the rows to tracked table row insertion here, do that at the end
1617 // to avoid layout problems and unnecessary insertion of dummy characters for empty rows)
1619 if ( eOld & RedlineFlags::On )
1621
1622 const sal_uInt16 nDispatchSlot = bRowMode ? FN_TABLE_INSERT_ROW_BEFORE : FN_TABLE_INSERT_COL_BEFORE;
1623 pDispatch->Execute(nDispatchSlot, SfxCallMode::SYNCHRON);
1624 pDispatch->Execute(bRowMode ? FN_LINE_UP : FN_CHAR_LEFT, SfxCallMode::SYNCHRON);
1625
1626 // add the other new empty rows/columns after the actual table row/column
1627 if ( nSelectedRowsOrCols > 1 )
1628 {
1629 SfxInt16Item aCountItem( nDispatchSlot, nSelectedRowsOrCols-1 );
1630 SfxBoolItem aAfter( FN_PARAM_INSERT_AFTER, true );
1631 pDispatch->ExecuteList(nDispatchSlot,
1632 SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
1633 { &aCountItem, &aAfter });
1634 }
1635
1636 if ( eOld & RedlineFlags::On )
1638
1639 // paste rows
1640 bool bResult = SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat,
1641 nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext );
1642
1643 // set tracked insertion, if it's not in a drag & drop action
1644 if ( !rSh.ActionPend() && ( eOld & RedlineFlags::On) )
1645 {
1646 SvxPrintItem aTracked(RES_PRINT, false);
1647 rSh.GetDoc()->SetRowNotTracked( *rSh.GetCursor(), aTracked );
1648 }
1649
1650 // restore cursor position
1651 if (pMark != nullptr)
1652 {
1653 rSh.GotoMark( pMark );
1654 rSh.getIDocumentMarkAccess()->deleteMark( pMark );
1655 }
1656
1657 return bResult;
1658 }
1659 }
1660
1661 // special case for tables from draw application or 1-cell tables
1662 if( EXCHG_OUT_ACTION_INSERT_DRAWOBJ == nAction || bSingleCellTable )
1663 {
1664 if( rData.HasFormat( SotClipboardFormatId::RTF ) )
1665 {
1667 nFormat = SotClipboardFormatId::RTF;
1668 }
1669 else if( rData.HasFormat( SotClipboardFormatId::RICHTEXT ) )
1670 {
1672 nFormat = SotClipboardFormatId::RICHTEXT;
1673 }
1674 }
1675
1676 // Tweak the format if necessary: the source application can be considered in this context,
1677 // while not in sot/ code.
1678 SwTransferable::SelectPasteFormat(rData, nAction, nFormat);
1679
1680 collectUIInformation("PASTE", "parameter");
1681
1682 return EXCHG_INOUT_ACTION_NONE != nAction &&
1683 SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat,
1684 nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext, ePasteTable);
1685}
1686
1688 SwWrtShell& rSh, sal_uInt8 nAction, SotExchangeActionFlags nActionFlags,
1689 SotClipboardFormatId nFormat,
1690 SotExchangeDest nDestination, bool bIsPasteFormat,
1691 bool bIsDefault,
1692 const Point* pPt, sal_Int8 nDropAction,
1693 bool bPasteSelection, RndStdIds nAnchorType,
1694 bool bIgnoreComments,
1695 SwPasteContext* pContext,
1696 PasteTableType ePasteTable )
1697{
1698 SwWait aWait( *rSh.GetView().GetDocShell(), false );
1699 std::unique_ptr<SwTrnsfrActionAndUndo, o3tl::default_delete<SwTrnsfrActionAndUndo>> pAction;
1700 SwModule* pMod = SW_MOD();
1701
1702 bool bRet = false;
1703 bool bCallAutoCaption = false;
1704
1705 if( pPt )
1706 {
1707 // external Drop
1708 if( bPasteSelection ? !pMod->m_pXSelection : !pMod->m_pDragDrop )
1709 {
1710 switch( nDestination )
1711 {
1712 case SotExchangeDest::DOC_LNKD_GRAPH_W_IMAP:
1713 case SotExchangeDest::DOC_LNKD_GRAPHOBJ:
1714 case SotExchangeDest::DOC_GRAPH_W_IMAP:
1715 case SotExchangeDest::DOC_GRAPHOBJ:
1716 case SotExchangeDest::DOC_OLEOBJ:
1717 case SotExchangeDest::DOC_DRAWOBJ:
1718 case SotExchangeDest::DOC_URLBUTTON:
1719 case SotExchangeDest::DOC_GROUPOBJ:
1720 // select frames/objects
1721 SwTransferable::SetSelInShell( rSh, true, pPt );
1722 break;
1723
1724 default:
1725 SwTransferable::SetSelInShell( rSh, false, pPt );
1726 break;
1727 }
1728 }
1729 }
1730 else if( ( !GetSwTransferable( rData ) || bIsPasteFormat ) &&
1731 !rSh.IsTableMode() && rSh.HasSelection() )
1732 {
1733 // then delete the selections
1734
1735 //don't delete selected content
1736 // - at table-selection
1737 // - at ReRead of a graphic/DDEData
1738 // - at D&D, for the right selection was taken care of
1739 // in Drop-Handler
1740 bool bDelSel = false;
1741 switch( nDestination )
1742 {
1743 case SotExchangeDest::DOC_TEXTFRAME:
1744 case SotExchangeDest::SWDOC_FREE_AREA:
1745 case SotExchangeDest::DOC_TEXTFRAME_WEB:
1746 case SotExchangeDest::SWDOC_FREE_AREA_WEB:
1747 bDelSel = true;
1748 break;
1749 default:
1750 break;
1751 }
1752
1753 if( bDelSel )
1754 // #i34830#
1755 pAction.reset(new SwTrnsfrActionAndUndo(&rSh, true, pContext));
1756 }
1757
1758 SwTransferable *pTrans=nullptr, *pTunneledTrans=GetSwTransferable( rData );
1759
1760 // check for private drop
1761 bool bPrivateDrop(pPt);
1762 if (bPrivateDrop)
1763 {
1764 if (bPasteSelection)
1765 pTrans = pMod->m_pXSelection;
1766 else
1767 pTrans = pMod->m_pDragDrop;
1768 bPrivateDrop = nullptr != pTrans;
1769 }
1770 bool bNeedToSelectBeforePaste(false);
1771
1772 if(bPrivateDrop && DND_ACTION_LINK == nDropAction)
1773 {
1774 // internal drop on object, suppress bPrivateDrop to change internal fill
1775 bPrivateDrop = false;
1776 bNeedToSelectBeforePaste = true;
1777 }
1778
1779 if(bPrivateDrop && pPt && DND_ACTION_MOVE == nDropAction)
1780 {
1781 // check if dragged over a useful target. If yes, use as content exchange
1782 // drop as if from external
1783 const SwFrameFormat* pSwFrameFormat = rSh.GetFormatFromObj(*pPt);
1784
1785 if(dynamic_cast< const SwDrawFrameFormat* >(pSwFrameFormat))
1786 {
1787 bPrivateDrop = false;
1788 bNeedToSelectBeforePaste = true;
1789 }
1790 }
1791
1792 if(bPrivateDrop)
1793 {
1794 // then internal Drag & Drop or XSelection
1795 bRet = pTrans->PrivateDrop( rSh, *pPt, DND_ACTION_MOVE == nDropAction,
1796 bPasteSelection );
1797 }
1798 else if( !pPt && pTunneledTrans &&
1800 {
1801 // then internal paste
1802 bRet = pTunneledTrans->PrivatePaste(rSh, pContext, ePasteTable);
1803 }
1804 else if( EXCHG_INOUT_ACTION_NONE != nAction )
1805 {
1806 if( !pAction )
1807 {
1808 pAction.reset(new SwTrnsfrActionAndUndo( &rSh ));
1809 }
1810
1811 // in Drag&Drop MessageBoxes must not be showed
1812 bool bMsg = nullptr == pPt;
1813
1814 // delete selections
1815
1816 switch( nAction )
1817 {
1819 OSL_ENSURE( pPt, "EXCHG_OUT_ACTION_INSERT_PRIVATE: what should happen here?" );
1820 break;
1821
1823 OSL_ENSURE( pPt, "EXCHG_OUT_ACTION_MOVE_PRIVATE: what should happen here?" );
1824 break;
1825
1833
1834 // then we have to use the format
1835 switch( nFormat )
1836 {
1837 case SotClipboardFormatId::DRAWING:
1838 bRet = SwTransferable::PasteSdrFormat( rData, rSh,
1839 SwPasteSdr::Insert, pPt,
1840 nActionFlags, bNeedToSelectBeforePaste);
1841 break;
1842
1843 case SotClipboardFormatId::HTML:
1844 case SotClipboardFormatId::HTML_SIMPLE:
1845 case SotClipboardFormatId::HTML_NO_COMMENT:
1846 case SotClipboardFormatId::RTF:
1847 case SotClipboardFormatId::RICHTEXT:
1848 case SotClipboardFormatId::STRING:
1849 bRet = SwTransferable::PasteFileContent( rData, rSh,
1850 nFormat, bMsg, bIgnoreComments );
1851 break;
1852
1853 case SotClipboardFormatId::NETSCAPE_BOOKMARK:
1854 {
1855 INetBookmark aBkmk;
1856 if( rData.GetINetBookmark( nFormat, aBkmk ) )
1857 {
1858 SwFormatINetFormat aFormat( aBkmk.GetURL(), OUString() );
1859 rSh.InsertURL( aFormat, aBkmk.GetDescription() );
1860 bRet = true;
1861 }
1862 }
1863 break;
1864
1865 case SotClipboardFormatId::SD_OLE:
1866 bRet = SwTransferable::PasteOLE( rData, rSh, nFormat,
1867 nActionFlags, bMsg );
1868 break;
1869
1870 case SotClipboardFormatId::SVIM:
1871 bRet = SwTransferable::PasteImageMap( rData, rSh );
1872 break;
1873
1874 case SotClipboardFormatId::SVXB:
1875 case SotClipboardFormatId::BITMAP:
1876 case SotClipboardFormatId::PNG:
1877 case SotClipboardFormatId::GDIMETAFILE:
1878 bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
1880 nActionFlags, nDropAction, bNeedToSelectBeforePaste);
1881 break;
1882
1883 case SotClipboardFormatId::XFORMS:
1884 case SotClipboardFormatId::SBA_FIELDDATAEXCHANGE:
1885 case SotClipboardFormatId::SBA_DATAEXCHANGE:
1886 case SotClipboardFormatId::SBA_CTRLDATAEXCHANGE:
1887 bRet = SwTransferable::PasteDBData( rData, rSh, nFormat,
1888 EXCHG_IN_ACTION_LINK == nAction,
1889 pPt, bMsg );
1890 break;
1891
1892 case SotClipboardFormatId::SIMPLE_FILE:
1893 bRet = SwTransferable::PasteFileName( rData, rSh, nFormat,
1894 ( EXCHG_IN_ACTION_MOVE == nAction
1896 : EXCHG_IN_ACTION_LINK == nAction
1899 pPt, nActionFlags, nullptr );
1900 break;
1901
1902 case SotClipboardFormatId::FILE_LIST:
1903 // then insert as graphics only
1904 bRet = SwTransferable::PasteFileList( rData, rSh,
1905 EXCHG_IN_ACTION_LINK == nAction,
1906 pPt, bMsg );
1907 break;
1908
1909 case SotClipboardFormatId::SONLK:
1910 if( pPt )
1911 {
1912 NaviContentBookmark aBkmk;
1913 if( aBkmk.Paste( rData ) )
1914 {
1915 if(bIsDefault)
1916 {
1917 switch(aBkmk.GetDefaultDragType())
1918 {
1919 case RegionMode::NONE: nAction = EXCHG_IN_ACTION_COPY; break;
1920 case RegionMode::EMBEDDED: nAction = EXCHG_IN_ACTION_MOVE; break;
1921 case RegionMode::LINK: nAction = EXCHG_IN_ACTION_LINK; break;
1922 }
1923 }
1924 rSh.NavigatorPaste( aBkmk, nAction );
1925 bRet = true;
1926 }
1927 }
1928 break;
1929
1930 case SotClipboardFormatId::INET_IMAGE:
1931 case SotClipboardFormatId::NETSCAPE_IMAGE:
1932 bRet = SwTransferable::PasteTargetURL( rData, rSh,
1934 pPt, true );
1935 break;
1936
1937 default:
1938 OSL_ENSURE( pPt, "unknown format" );
1939 }
1940 break;
1941
1943 {
1944 bool graphicInserted;
1945 bRet = SwTransferable::PasteFileName( rData, rSh, nFormat,
1946 SwPasteSdr::Insert, pPt,
1947 nActionFlags,
1948 &graphicInserted );
1949 if( graphicInserted )
1950 bCallAutoCaption = true;
1951 }
1952 break;
1953
1955 bRet = SwTransferable::PasteOLE( rData, rSh, nFormat,
1956 nActionFlags,bMsg );
1957 break;
1958
1960 {
1961 bool bReRead = 0 != CNT_HasGrf( rSh.GetCntType() );
1962 bRet = SwTransferable::PasteDDE( rData, rSh, bReRead, bMsg );
1963 }
1964 break;
1965
1967 {
1968 OUString sURL, sDesc;
1969 if( SotClipboardFormatId::SIMPLE_FILE == nFormat )
1970 {
1971 if( rData.GetString( nFormat, sURL ) && !sURL.isEmpty() )
1972 {
1973 SwTransferable::CheckForURLOrLNKFile( rData, sURL, &sDesc );
1974 if( sDesc.isEmpty() )
1975 sDesc = sURL;
1976 bRet = true;
1977 }
1978 }
1979 else
1980 {
1981 INetBookmark aBkmk;
1982 if( rData.GetINetBookmark( nFormat, aBkmk ) )
1983 {
1984 sURL = aBkmk.GetURL();
1985 sDesc = aBkmk.GetDescription();
1986 bRet = true;
1987 }
1988 }
1989
1990 if( bRet )
1991 {
1992 SwFormatINetFormat aFormat( sURL, OUString() );
1993 rSh.InsertURL( aFormat, sDesc );
1994 }
1995 }
1996 break;
1997
1999 switch( nFormat )
2000 {
2001 case SotClipboardFormatId::DRAWING:
2002 bRet = SwTransferable::PasteSdrFormat( rData, rSh,
2004 nActionFlags, bNeedToSelectBeforePaste);
2005 break;
2006 case SotClipboardFormatId::SVXB:
2007 case SotClipboardFormatId::GDIMETAFILE:
2008 case SotClipboardFormatId::BITMAP:
2009 case SotClipboardFormatId::PNG:
2010 case SotClipboardFormatId::NETSCAPE_BOOKMARK:
2011 case SotClipboardFormatId::SIMPLE_FILE:
2012 case SotClipboardFormatId::FILEGRPDESCRIPTOR:
2013 case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
2014 bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
2016 nActionFlags, nDropAction, bNeedToSelectBeforePaste);
2017 break;
2018 default:
2019 OSL_FAIL( "unknown format" );
2020 }
2021
2022 break;
2023
2025 bRet = SwTransferable::PasteSdrFormat( rData, rSh,
2026 SwPasteSdr::Insert, pPt,
2027 nActionFlags, bNeedToSelectBeforePaste);
2028 break;
2033 bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
2034 SwPasteSdr::Insert, pPt,
2035 nActionFlags, nDropAction, bNeedToSelectBeforePaste, nAnchorType );
2036 break;
2037
2039 bRet = SwTransferable::PasteSdrFormat( rData, rSh,
2041 nActionFlags, bNeedToSelectBeforePaste);
2042 break;
2043
2048 bRet = SwTransferable::PasteGrf( rData, rSh, nFormat,
2050 nActionFlags, nDropAction, bNeedToSelectBeforePaste);
2051 break;
2052
2054 bRet = SwTransferable::PasteAsHyperlink( rData, rSh, nFormat );
2055 break;
2056
2057 default:
2058 OSL_FAIL("unknown action" );
2059 }
2060 }
2061
2062 if( !bPasteSelection && rSh.IsFrameSelected() )
2063 {
2064 rSh.EnterSelFrameMode();
2065 //force ::SelectShell
2066 rSh.GetView().StopShellTimer();
2067 }
2068
2069 pAction.reset();
2070 if( bCallAutoCaption )
2072
2073 return bRet;
2074}
2075
2077{
2078 SotExchangeDest nRet = SotExchangeDest::NONE;
2079
2080 ObjCntType eOType = rSh.GetObjCntTypeOfSelection();
2081
2082 switch( eOType )
2083 {
2084 case OBJCNT_GRF:
2085 {
2086 bool bIMap, bLink;
2087 bIMap = nullptr != rSh.GetFlyFrameFormat()->GetURL().GetMap();
2088 OUString aDummy;
2089 rSh.GetGrfNms( &aDummy, nullptr );
2090 bLink = !aDummy.isEmpty();
2091
2092 if( bLink && bIMap )
2093 nRet = SotExchangeDest::DOC_LNKD_GRAPH_W_IMAP;
2094 else if( bLink )
2095 nRet = SotExchangeDest::DOC_LNKD_GRAPHOBJ;
2096 else if( bIMap )
2097 nRet = SotExchangeDest::DOC_GRAPH_W_IMAP;
2098 else
2099 nRet = SotExchangeDest::DOC_GRAPHOBJ;
2100 }
2101 break;
2102
2103 case OBJCNT_FLY:
2104 if( dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr )
2105 nRet = SotExchangeDest::DOC_TEXTFRAME_WEB;
2106 else
2107 nRet = SotExchangeDest::DOC_TEXTFRAME;
2108 break;
2109 case OBJCNT_OLE: nRet = SotExchangeDest::DOC_OLEOBJ; break;
2110
2111 case OBJCNT_CONTROL: /* no Action avail */
2112 case OBJCNT_SIMPLE: nRet = SotExchangeDest::DOC_DRAWOBJ; break;
2113 case OBJCNT_URLBUTTON: nRet = SotExchangeDest::DOC_URLBUTTON; break;
2114 case OBJCNT_GROUPOBJ: nRet = SotExchangeDest::DOC_GROUPOBJ; break;
2115
2116 // what do we do at multiple selections???
2117 default:
2118 {
2119 if( dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr )
2120 nRet = SotExchangeDest::SWDOC_FREE_AREA_WEB;
2121 else
2122 nRet = SotExchangeDest::SWDOC_FREE_AREA;
2123 }
2124 }
2125
2126 return nRet;
2127}
2128
2130 SwWrtShell& rSh, SotClipboardFormatId nFormat, bool bMsg, bool bIgnoreComments )
2131{
2132 TranslateId pResId = STR_CLPBRD_FORMAT_ERROR;
2133 bool bRet = false;
2134
2135 MSE40HTMLClipFormatObj aMSE40ClpObj;
2136
2138 SvStream* pStream = nullptr;
2139 Reader* pRead = nullptr;
2140 OUString sData;
2141 switch( nFormat )
2142 {
2143 case SotClipboardFormatId::STRING:
2144 {
2145 pRead = ReadAscii;
2146 if( rData.GetString( nFormat, sData ) )
2147 {
2148 pStream = new SvMemoryStream( const_cast<sal_Unicode *>(sData.getStr()),
2149 sData.getLength() * sizeof( sal_Unicode ),
2150 StreamMode::READ );
2151#ifdef OSL_BIGENDIAN
2152 pStream->SetEndian( SvStreamEndian::BIG );
2153#else
2154 pStream->SetEndian( SvStreamEndian::LITTLE );
2155#endif
2156
2157 SwAsciiOptions aAOpt;
2158 aAOpt.SetCharSet( RTL_TEXTENCODING_UCS2 );
2159 pRead->GetReaderOpt().SetASCIIOpts( aAOpt );
2160 break;
2161 }
2162 }
2163 [[fallthrough]]; // because then test if we get a stream
2164
2165 default:
2166 if( rData.GetSotStorageStream( nFormat, xStrm ) )
2167 {
2168 if( ( SotClipboardFormatId::HTML_SIMPLE == nFormat ) ||
2169 ( SotClipboardFormatId::HTML_NO_COMMENT == nFormat ) )
2170 {
2171 pStream = aMSE40ClpObj.IsValid( *xStrm );
2172 pRead = ReadHTML;
2173 pRead->SetReadUTF8( true );
2174
2175 bool bNoComments =
2176 ( nFormat == SotClipboardFormatId::HTML_NO_COMMENT );
2177 pRead->SetIgnoreHTMLComments( bNoComments );
2178 }
2179 else
2180 {
2181 pStream = xStrm.get();
2182 if( SotClipboardFormatId::RTF == nFormat || SotClipboardFormatId::RICHTEXT == nFormat)
2184 else if( !pRead )
2185 {
2186 pRead = ReadHTML;
2187 pRead->SetReadUTF8( true );
2188 }
2189 }
2190 }
2191 break;
2192 }
2193
2194 if( pStream && pRead )
2195 {
2196 Link<LinkParamNone*,void> aOldLink( rSh.GetChgLnk() );
2198
2199 const SwPosition& rInsPos = *rSh.GetCursor()->Start();
2200 SwReader aReader(*pStream, OUString(), OUString(), *rSh.GetCursor());
2201 rSh.SaveTableBoxContent( &rInsPos );
2202
2203 if (bIgnoreComments)
2204 pRead->SetIgnoreHTMLComments(true);
2205
2206 if( aReader.Read( *pRead ).IsError() )
2207 pResId = STR_ERROR_CLPBRD_READ;
2208 else
2209 {
2210 pResId = TranslateId();
2211 bRet = true;
2212 }
2213
2214 rSh.SetChgLnk( aOldLink );
2215 if( bRet )
2216 rSh.CallChgLnk();
2217 }
2218 else
2219 pResId = STR_CLPBRD_FORMAT_ERROR;
2220
2221 // Exist a SvMemoryStream? (data in the OUString and xStrm is empty)
2222 if( pStream && !xStrm.is() )
2223 delete pStream;
2224
2225 if (bMsg && pResId)
2226 {
2227 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2228 VclMessageType::Info, VclButtonsType::Ok,
2229 SwResId(pResId)));
2230 xBox->run();
2231 }
2232 return bRet;
2233}
2234
2236 SotClipboardFormatId nFormat, SotExchangeActionFlags nActionFlags, bool bMsg )
2237{
2238 bool bRet = false;
2240 uno::Reference < io::XInputStream > xStrm;
2241 uno::Reference < embed::XStorage > xStore;
2242 Reader* pRead = nullptr;
2243
2244 // Get the preferred format
2246 if( rData.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ ) )
2247 nId = SotClipboardFormatId::EMBEDDED_OBJ;
2248 else if( rData.HasFormat( SotClipboardFormatId::EMBED_SOURCE ) &&
2249 rData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ))
2250 nId = SotClipboardFormatId::EMBED_SOURCE;
2251 else
2252 nId = SotClipboardFormatId::NONE;
2253
2254 if (nId != SotClipboardFormatId::NONE)
2255 {
2256 SwDocShell* pDocSh = rSh.GetDoc()->GetDocShell();
2257 xStrm = rData.GetInputStream(nId, SfxObjectShell::CreateShellID(pDocSh));
2258 }
2259
2260 if (xStrm.is())
2261 {
2262 // if there is an embedded object, first try if it's a writer object
2263 // this will be inserted into the document by using a Reader
2264 try
2265 {
2267 switch( SotStorage::GetFormatID( xStore ) )
2268 {
2269 case SotClipboardFormatId::STARWRITER_60:
2270 case SotClipboardFormatId::STARWRITERWEB_60:
2271 case SotClipboardFormatId::STARWRITERGLOB_60:
2272 case SotClipboardFormatId::STARWRITER_8:
2273 case SotClipboardFormatId::STARWRITERWEB_8:
2274 case SotClipboardFormatId::STARWRITERGLOB_8:
2275 pRead = ReadXML;
2276 break;
2277 default:
2278 try
2279 {
2280 xStore->dispose();
2281 xStore = nullptr;
2282 }
2283 catch (const uno::Exception&)
2284 {
2285 }
2286
2287 break;
2288 }
2289 }
2290 catch (const uno::Exception&)
2291 {
2292 // it wasn't a storage, but maybe it's a useful stream
2293 }
2294 }
2295
2296 if( pRead )
2297 {
2298 SwPaM &rPAM = *rSh.GetCursor();
2299 SwReader aReader(xStore, OUString(), rPAM);
2300 if( ! aReader.Read( *pRead ).IsError() )
2301 bRet = true;
2302 else if( bMsg )
2303 {
2304 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2305 VclMessageType::Info, VclButtonsType::Ok,
2306 SwResId(STR_ERROR_CLPBRD_READ)));
2307 xBox->run();
2308 }
2309 }
2310 else
2311 {
2312 // temporary storage until the object is inserted
2313 uno::Reference< embed::XStorage > xTmpStor;
2314 uno::Reference < embed::XEmbeddedObject > xObj;
2315 OUString aName;
2317
2318 if ( xStrm.is() )
2319 {
2320 if ( !rData.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDesc ) )
2321 {
2322 OSL_ENSURE( !xStrm.is(), "An object without descriptor in clipboard!");
2323 }
2324 }
2325 else
2326 {
2327 if( rData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE ) && rData.GetTransferableObjectDescriptor( nFormat, aObjDesc ) )
2328 {
2329 xStrm = rData.GetInputStream(SotClipboardFormatId::EMBED_SOURCE_OLE, OUString());
2330 if (!xStrm.is())
2331 xStrm = rData.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE, OUString());
2332
2333 if ( !xStrm.is() )
2334 {
2335 // This is MSOLE object that should be created by direct using of system clipboard
2336 try
2337 {
2339 uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator =
2340 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
2341
2342 embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
2343 xTmpStor,
2344 "DummyName",
2345 uno::Sequence< beans::PropertyValue >() );
2346
2347 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
2348 // for example whether the object should be an iconified one
2349 xObj = aInfo.Object;
2350 }
2351 catch (const uno::Exception&)
2352 {
2353 }
2354 }
2355 }
2356 else if (rData.HasFormat(SotClipboardFormatId::SIMPLE_FILE))
2357 {
2358 OUString sFile;
2359 if (rData.GetString(nFormat, sFile) && !sFile.isEmpty())
2360 {
2361 // Copied from sd::View::DropInsertFileHdl
2362 uno::Sequence< beans::PropertyValue > aMedium{ comphelper::makePropertyValue(
2363 "URL", sFile) };
2364 SwDocShell* pDocSh = rSh.GetDoc()->GetDocShell();
2365 xObj = pDocSh->GetEmbeddedObjectContainer().InsertEmbeddedObject(aMedium, aName);
2366 }
2367 }
2368 }
2369
2370 if ( xStrm.is() && !xObj.is() )
2371 xObj = aCnt.InsertEmbeddedObject( xStrm, aName );
2372
2373 if( xObj.is() )
2374 {
2375 svt::EmbeddedObjectRef xObjRef( xObj, aObjDesc.mnViewAspect );
2376
2377 // try to get the replacement image from the clipboard
2378 Graphic aGraphic;
2379 SotClipboardFormatId nGrFormat = SotClipboardFormatId::NONE;
2380
2381 // limit the size of the preview metafile to 100000 actions
2382 GDIMetaFile aMetafile;
2383 if (rData.GetGDIMetaFile(SotClipboardFormatId::GDIMETAFILE, aMetafile, 100000))
2384 {
2385 nGrFormat = SotClipboardFormatId::GDIMETAFILE;
2386 aGraphic = aMetafile;
2387 }
2388
2389 // insert replacement image ( if there is one ) into the object helper
2390 if ( nGrFormat != SotClipboardFormatId::NONE )
2391 {
2392 DataFlavor aDataFlavor;
2393 SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
2394 xObjRef.SetGraphic( aGraphic, aDataFlavor.MimeType );
2395 }
2396 else if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
2397 {
2398 // it is important to have an icon, let an empty graphic be used
2399 // if no other graphic is provided
2400 // TODO/LATER: in future a default bitmap could be used
2401 MapMode aMapMode( MapUnit::Map100thMM );
2402 aGraphic.SetPrefSize( Size( 2500, 2500 ) );
2403 aGraphic.SetPrefMapMode( aMapMode );
2404 xObjRef.SetGraphic( aGraphic, OUString() );
2405 }
2406
2407 //set size. This is a hack because of handing over, size should be
2408 //passed to the InsertOle!!!!!!!!!!
2409 Size aSize;
2410 if ( aObjDesc.mnViewAspect == embed::Aspects::MSOLE_ICON )
2411 {
2412 if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
2413 aSize = aObjDesc.maSize;
2414 else
2415 {
2416 MapMode aMapMode( MapUnit::Map100thMM );
2417 aSize = xObjRef.GetSize( &aMapMode );
2418 }
2419 }
2420 else if( aObjDesc.maSize.Width() && aObjDesc.maSize.Height() )
2421 {
2422 aSize = aObjDesc.maSize; //always 100TH_MM
2423 MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( aObjDesc.mnViewAspect ) );
2424 aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(aUnit));
2425 awt::Size aSz;
2426 try
2427 {
2428 aSz = xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
2429 }
2430 catch (const embed::NoVisualAreaSizeException&)
2431 {
2432 // in this case the provided size is used
2433 }
2434
2435 if ( aSz.Width != aSize.Width() || aSz.Height != aSize.Height() )
2436 {
2437 aSz.Width = aSize.Width();
2438 aSz.Height = aSize.Height();
2439 xObj->setVisualAreaSize( aObjDesc.mnViewAspect, aSz );
2440 }
2441 }
2442 else
2443 {
2444 // the descriptor contains the wrong object size
2445 // the following call will let the MSOLE objects cache the size if it is possible
2446 // it should be done while the object is running
2447 try
2448 {
2449 xObj->getVisualAreaSize( aObjDesc.mnViewAspect );
2450 }
2451 catch (const uno::Exception&)
2452 {
2453 }
2454 }
2455 //End of Hack!
2456
2457 rSh.InsertOleObject( xObjRef );
2458 bRet = true;
2459
2460 if( bRet && ( nActionFlags & SotExchangeActionFlags::InsertTargetUrl) )
2461 SwTransferable::PasteTargetURL( rData, rSh, SwPasteSdr::NONE, nullptr, false );
2462
2463 // let the object be unloaded if possible
2464 SwOLEObj::UnloadObject( xObj, rSh.GetDoc(), embed::Aspects::MSOLE_CONTENT );
2465 }
2466 }
2467 return bRet;
2468}
2469
2471 SwWrtShell& rSh, SwPasteSdr nAction,
2472 const Point* pPt, bool bInsertGRF )
2473{
2474 bool bRet = false;
2475 INetImage aINetImg;
2476 if( ( rData.HasFormat( SotClipboardFormatId::INET_IMAGE ) &&
2477 rData.GetINetImage( SotClipboardFormatId::INET_IMAGE, aINetImg )) ||
2478 ( rData.HasFormat( SotClipboardFormatId::NETSCAPE_IMAGE ) &&
2479 rData.GetINetImage( SotClipboardFormatId::NETSCAPE_IMAGE, aINetImg )) )
2480 {
2481 if( !aINetImg.GetImageURL().isEmpty() && bInsertGRF )
2482 {
2483 OUString sURL( aINetImg.GetImageURL() );
2485
2487 Graphic aGraphic;
2489 bRet = ERRCODE_NONE == GraphicFilter::LoadGraphic(sURL, OUString(), aGraphic, &rFlt);
2490
2491 if( bRet )
2492 {
2493 //Check and Perform rotation if needed
2494 lclCheckAndPerformRotation(aGraphic);
2495
2496 switch( nAction )
2497 {
2498 case SwPasteSdr::Insert:
2499 SwTransferable::SetSelInShell( rSh, false, pPt );
2500 rSh.InsertGraphic(sURL, OUString(), aGraphic);
2501 break;
2502
2504 if( rSh.IsObjSelected() )
2505 {
2506 rSh.ReplaceSdrObj( sURL, &aGraphic );
2507 Point aPt( pPt ? *pPt : rSh.GetCursorDocPos() );
2508 SwTransferable::SetSelInShell( rSh, true, &aPt );
2509 }
2510 else
2511 rSh.ReRead(sURL, OUString(), &aGraphic);
2512 break;
2513
2515 if( rSh.IsObjSelected() )
2516 rSh.Paste( aGraphic, OUString() );
2517 else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() )
2518 rSh.ReRead(sURL, OUString(), &aGraphic);
2519 else
2520 {
2521 SwTransferable::SetSelInShell( rSh, false, pPt );
2522 rSh.InsertGraphic(sURL, OUString(), aGraphic);
2523 }
2524 break;
2525 default:
2526 bRet = false;
2527 }
2528 }
2529 }
2530 else
2531 bRet = true;
2532 }
2533
2534 if( bRet )
2535 {
2537 rSh.GetFlyFrameAttr( aSet );
2538 SwFormatURL aURL( aSet.Get( RES_URL ) );
2539
2540 if( aURL.GetURL() != aINetImg.GetTargetURL() ||
2541 aURL.GetTargetFrameName() != aINetImg.GetTargetFrame() )
2542 {
2543 aURL.SetURL( aINetImg.GetTargetURL(), false );
2544 aURL.SetTargetFrameName( aINetImg.GetTargetFrame() );
2545 aSet.Put( aURL );
2546 rSh.SetFlyFrameAttr( aSet );
2547 }
2548 }
2549 return bRet;
2550}
2551
2552void SwTransferable::SetSelInShell( SwWrtShell& rSh, bool bSelectFrame,
2553 const Point* pPt )
2554{
2555 if( bSelectFrame )
2556 {
2557 // select frames/objects
2558 if( pPt && !rSh.GetView().GetViewFrame()->GetDispatcher()->IsLocked() )
2559 {
2560 rSh.GetView().NoRotate();
2561 if( rSh.SelectObj( *pPt ))
2562 {
2563 rSh.HideCursor();
2564 rSh.EnterSelFrameMode( pPt );
2565 g_bFrameDrag = true;
2566 }
2567 }
2568 }
2569 else
2570 {
2571 if( rSh.IsFrameSelected() || rSh.IsObjSelected() )
2572 {
2573 rSh.UnSelectFrame();
2574 rSh.LeaveSelFrameMode();
2576 g_bFrameDrag = false;
2577 }
2578 else if( rSh.GetView().GetDrawFuncPtr() )
2580
2581 rSh.EnterStdMode();
2582 if( pPt )
2583 rSh.SwCursorShell::SetCursor( *pPt, true );
2584 }
2585}
2586
2588 SwWrtShell& rWrtShell, bool bReReadGrf,
2589 bool bMsg )
2590{
2591 // data from Clipboardformat
2592 OUString aApp, aTopic, aItem;
2593
2594 {
2596 if( !rData.GetSotStorageStream( SotClipboardFormatId::LINK, xStrm ))
2597 {
2598 OSL_ENSURE( false, "DDE Data not found." );
2599 return false;
2600 } // report useful error!!
2601
2602 rtl_TextEncoding eEncoding = osl_getThreadTextEncoding();
2603 aApp = read_zeroTerminated_uInt8s_ToOUString(*xStrm, eEncoding);
2604 aTopic = read_zeroTerminated_uInt8s_ToOUString(*xStrm, eEncoding);
2605 aItem = read_zeroTerminated_uInt8s_ToOUString(*xStrm, eEncoding);
2606 }
2607
2608 OUString aCmd;
2609 sfx2::MakeLnkName( aCmd, &aApp, aTopic, aItem );
2610
2611 // do we want to read in a graphic now?
2612 SotClipboardFormatId nFormat;
2613 if( !rData.HasFormat( SotClipboardFormatId::RTF ) &&
2614 !rData.HasFormat( SotClipboardFormatId::RICHTEXT ) &&
2615 !rData.HasFormat( SotClipboardFormatId::HTML ) &&
2616 !rData.HasFormat( SotClipboardFormatId::STRING ) &&
2617 (rData.HasFormat( nFormat = SotClipboardFormatId::GDIMETAFILE ) ||
2618 rData.HasFormat( nFormat = SotClipboardFormatId::BITMAP )) )
2619 {
2620 Graphic aGrf;
2621 bool bRet = rData.GetGraphic( nFormat, aGrf );
2622 if( bRet )
2623 {
2624 OUString sLnkTyp("DDE");
2625 if ( bReReadGrf )
2626 rWrtShell.ReRead( aCmd, sLnkTyp, &aGrf );
2627 else
2628 rWrtShell.InsertGraphic( aCmd, sLnkTyp, aGrf );
2629 }
2630 return bRet;
2631 }
2632
2633 SwFieldType* pTyp = nullptr;
2634 size_t i = 1;
2635 size_t j;
2636 OUString aName;
2637 bool bDoublePaste = false;
2638 const size_t nSize = rWrtShell.GetFieldTypeCount();
2639 const ::utl::TransliterationWrapper& rColl = ::GetAppCmpStrIgnore();
2640
2641 do {
2642 aName = aApp + OUString::number( i );
2643 for( j = INIT_FLDTYPES; j < nSize; j++ )
2644 {
2645 pTyp = rWrtShell.GetFieldType( j );
2646 if( SwFieldIds::Dde == pTyp->Which() )
2647 {
2648 if( rColl.isEqual( static_cast<SwDDEFieldType*>(pTyp)->GetCmd(), aCmd ) &&
2649 SfxLinkUpdateMode::ALWAYS == static_cast<SwDDEFieldType*>(pTyp)->GetType() )
2650 {
2651 aName = pTyp->GetName();
2652 bDoublePaste = true;
2653 break;
2654 }
2655 else if( rColl.isEqual( aName, pTyp->GetName() ) )
2656 break;
2657 }
2658 }
2659 if( j == nSize )
2660 break;
2661 ++i;
2662 }
2663 while( !bDoublePaste );
2664
2665 if( !bDoublePaste )
2666 {
2667 SwDDEFieldType aType( aName, aCmd, SfxLinkUpdateMode::ALWAYS );
2668 pTyp = rWrtShell.InsertFieldType( aType );
2669 }
2670
2671 SwDDEFieldType* pDDETyp = static_cast<SwDDEFieldType*>(pTyp);
2672
2673 OUString aExpand;
2674 if( rData.GetString( SotClipboardFormatId::STRING, aExpand ))
2675 {
2676 do { // middle checked loop
2677
2678 const sal_Int32 nNewlines{comphelper::string::getTokenCount(aExpand, '\n')};
2679 // When data comes from a spreadsheet, we add a DDE-table
2680 if( !aExpand.isEmpty() &&
2681 ( rData.HasFormat( SotClipboardFormatId::SYLK ) ||
2682 rData.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS ) ) )
2683 {
2684 sal_Int32 nRows = nNewlines ? nNewlines-1 : 0;
2685 if (!aExpand.endsWith("\n"))
2686 ++nRows; // last row has no newline, e.g. one single cell
2687 const sal_Int32 nCols = comphelper::string::getTokenCount(o3tl::getToken(aExpand, 0, '\n'), '\t');
2688
2689 // don't try to insert tables that are too large for writer
2690 if (nRows > SAL_MAX_UINT16 || nCols > SAL_MAX_UINT16)
2691 {
2692 if( bMsg )
2693 {
2694 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2695 VclMessageType::Info, VclButtonsType::Ok,
2696 SwResId(STR_TABLE_TOO_LARGE)));
2697 xBox->run();
2698 }
2699 pDDETyp = nullptr;
2700 break;
2701 }
2702
2703 // at least one column & row must be there
2704 if( !nRows || !nCols )
2705 {
2706 if( bMsg )
2707 {
2708 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
2709 VclMessageType::Info, VclButtonsType::Ok,
2710 SwResId(STR_NO_TABLE)));
2711 xBox->run();
2712 }
2713 pDDETyp = nullptr;
2714 break;
2715 }
2716
2717 rWrtShell.InsertDDETable(
2718 SwInsertTableOptions( SwInsertTableFlags::SplitLayout, 1 ), // TODO MULTIHEADER
2719 pDDETyp, nRows, nCols );
2720 }
2721 else if( nNewlines > 1 )
2722 {
2723 // multiple paragraphs -> insert a protected section
2724 if( rWrtShell.HasSelection() )
2725 rWrtShell.DelRight();
2726
2728 aSect.SetLinkFileName( aCmd );
2729 aSect.SetProtectFlag(true);
2730 rWrtShell.InsertSection( aSect );
2731
2732 pDDETyp = nullptr; // remove FieldTypes again
2733 }
2734 else
2735 {
2736 // insert
2737 SwDDEField aSwDDEField( pDDETyp );
2738 rWrtShell.InsertField2( aSwDDEField );
2739 }
2740
2741 } while( false );
2742 }
2743 else
2744 pDDETyp = nullptr; // remove FieldTypes again
2745
2746 if( !pDDETyp && !bDoublePaste )
2747 {
2748 // remove FieldType again - error occurred!
2749 for( j = nSize; j >= INIT_FLDTYPES; --j )
2750 if( pTyp == rWrtShell.GetFieldType( j ) )
2751 {
2752 rWrtShell.RemoveFieldType( j );
2753 break;
2754 }
2755 }
2756
2757 return true;
2758}
2759
2761 SwWrtShell& rSh, SwPasteSdr nAction,
2762 const Point* pPt, SotExchangeActionFlags nActionFlags, bool bNeedToSelectBeforePaste)
2763{
2764 bool bRet = false;
2766 if( rData.GetSotStorageStream( SotClipboardFormatId::DRAWING, xStrm ))
2767 {
2768 xStrm->SetVersion( SOFFICE_FILEFORMAT_50 );
2769
2770 if(bNeedToSelectBeforePaste && pPt)
2771 {
2772 // if this is an internal drag, need to set the target right (select it), else
2773 // still the source will be selected
2774 SwTransferable::SetSelInShell( rSh, true, pPt );
2775 }
2776
2777 rSh.Paste( *xStrm, nAction, pPt );
2778 bRet = true;
2779
2780 if( bRet && ( nActionFlags & SotExchangeActionFlags::InsertTargetUrl ))
2781 SwTransferable::PasteTargetURL( rData, rSh, SwPasteSdr::NONE, nullptr, false );
2782 }
2783 return bRet;
2784}
2785
2787 SotClipboardFormatId nFormat, SwPasteSdr nAction, const Point* pPt,
2788 SotExchangeActionFlags nActionFlags, sal_Int8 nDropAction, bool bNeedToSelectBeforePaste, RndStdIds nAnchorType )
2789{
2790 bool bRet = false;
2791
2792 Graphic aGraphic;
2793 INetBookmark aBkmk;
2794 bool bCheckForGrf = false, bCheckForImageMap = false;
2795
2796 switch( nFormat )
2797 {
2798 case SotClipboardFormatId::BITMAP:
2799 case SotClipboardFormatId::PNG:
2800 case SotClipboardFormatId::GDIMETAFILE:
2801 bRet = rData.GetGraphic( nFormat, aGraphic );
2802 break;
2803
2804 case SotClipboardFormatId::SVXB:
2805 {
2807
2808 if(rData.GetSotStorageStream(SotClipboardFormatId::SVXB, xStm))
2809 {
2810 TypeSerializer aSerializer(*xStm);
2811 aSerializer.readGraphic(aGraphic);
2812 bRet = (GraphicType::NONE != aGraphic.GetType() && GraphicType::Default != aGraphic.GetType());
2813 }
2814
2815 break;
2816 }
2817
2818 case SotClipboardFormatId::NETSCAPE_BOOKMARK:
2819 case SotClipboardFormatId::FILEGRPDESCRIPTOR:
2820 case SotClipboardFormatId::UNIFORMRESOURCELOCATOR:
2821 bRet = rData.GetINetBookmark( nFormat, aBkmk );
2822 if( bRet )
2823 {
2824 if( SwPasteSdr::SetAttr == nAction )
2825 nFormat = SotClipboardFormatId::NETSCAPE_BOOKMARK;
2826 else
2827 bCheckForGrf = true;
2828 }
2829 break;
2830
2831 case SotClipboardFormatId::SIMPLE_FILE:
2832 {
2833 OUString sText;
2834 bRet = rData.GetString( nFormat, sText );
2835 if( bRet )
2836 {
2837 OUString sDesc;
2838 SwTransferable::CheckForURLOrLNKFile( rData, sText, &sDesc );
2839
2841 false);
2842
2843#ifdef _WIN32
2844 // Now that the path could be modified after SwTransferable::CheckForURLOrLNKFile,
2845 // where it could have been converted to URL, and made sure it's actually converted
2846 // to URL in URIHelper::SmartRel2Abs, we can finally convert file: URL back to
2847 // system path to make sure we don't use short path.
2848 // It looks not optimal, when we could apply GetLongPathNameW right to the original
2849 // pasted filename. But I don't know if (1) all arriving strings are system paths;
2850 // and (2) if SwTransferable::CheckForURLOrLNKFile could result in a different short
2851 // path, so taking a safe route.
2852 if (sText.startsWithIgnoreAsciiCase("file:"))
2853 {
2854 // tdf#124500: Convert short path to long path which should be used in links
2855 OUString sSysPath;
2856 osl::FileBase::getSystemPathFromFileURL(sText, sSysPath);
2857 std::unique_ptr<sal_Unicode[]> aBuf(new sal_Unicode[32767]);
2858 DWORD nCopied = GetLongPathNameW(o3tl::toW(sSysPath.getStr()),
2859 o3tl::toW(aBuf.get()), 32767);
2860 if (nCopied && nCopied < 32767)
2861 sText = URIHelper::SmartRel2Abs(INetURLObject(), OUString(aBuf.get()),
2862 Link<OUString*, bool>(), false);
2863 }
2864#endif
2865
2866 aBkmk = INetBookmark(sText, sDesc);
2867 bCheckForGrf = true;
2868 bCheckForImageMap = SwPasteSdr::Replace == nAction;
2869 }
2870 }
2871 break;
2872
2873 default:
2874 bRet = rData.GetGraphic( nFormat, aGraphic );
2875 break;
2876 }
2877
2878 if( bCheckForGrf )
2879 {
2882 bRet = ERRCODE_NONE == GraphicFilter::LoadGraphic(aBkmk.GetURL(), OUString(),
2883 aGraphic, &rFlt );
2884
2885 if( !bRet && SwPasteSdr::SetAttr == nAction &&
2886 SotClipboardFormatId::SIMPLE_FILE == nFormat &&
2887 // only at frame selection
2888 rSh.IsFrameSelected() )
2889 {
2890 // then set as hyperlink after the graphic
2891 nFormat = SotClipboardFormatId::NETSCAPE_BOOKMARK;
2892 bRet = true;
2893 }
2894 }
2895
2896 if(pPt && bNeedToSelectBeforePaste)
2897 {
2898 // when using internal D&Ds, still the source object is selected and
2899 // this is necessary to get the correct source data which is also
2900 // dependent from selection. After receiving the drag data it is
2901 // now time to select the correct target object
2902 SwTransferable::SetSelInShell( rSh, true, pPt );
2903 }
2904
2905 if( bRet )
2906 {
2907 //Check and Perform rotation if needed
2908 lclCheckAndPerformRotation(aGraphic);
2909
2910 OUString sURL;
2911 if( dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) != nullptr
2912 // #i123922# if link action is noted, also take URL
2913 || DND_ACTION_LINK == nDropAction)
2914 {
2915 sURL = aBkmk.GetURL();
2916 }
2917
2918 switch( nAction )
2919 {
2920 case SwPasteSdr::Insert:
2921 {
2922 SwTransferable::SetSelInShell( rSh, false, pPt );
2923 rSh.InsertGraphic(sURL, OUString(), aGraphic, nullptr, nAnchorType);
2924 break;
2925 }
2926
2928 {
2929 if( rSh.IsObjSelected() )
2930 {
2931 // #i123922# for D&D on draw objects, do for now the same for
2932 // SwPasteSdr::Replace (D&D) as for SwPasteSdr::SetAttr (D&D and
2933 // CTRL+SHIFT). The code below replaces the draw object with
2934 // a writer graphic; maybe this is an option later again if wanted
2935 rSh.Paste( aGraphic, sURL );
2936
2937 // rSh.ReplaceSdrObj(sURL, OUString(), &aGraphic);
2938 // Point aPt( pPt ? *pPt : rSh.GetCursorDocPos() );
2939 // SwTransferable::SetSelInShell( rSh, true, &aPt );
2940 }
2941 else
2942 {
2943 // set graphic at writer graphic without link
2944 rSh.ReRead(sURL, OUString(), &aGraphic);
2945 }
2946
2947 break;
2948 }
2949
2951 {
2952 if( SotClipboardFormatId::NETSCAPE_BOOKMARK == nFormat )
2953 {
2954 if( rSh.IsFrameSelected() )
2955 {
2957 rSh.GetFlyFrameAttr( aSet );
2958 SwFormatURL aURL( aSet.Get( RES_URL ) );
2959 aURL.SetURL( aBkmk.GetURL(), false );
2960 aSet.Put( aURL );
2961 rSh.SetFlyFrameAttr( aSet );
2962 }
2963 }
2964 else if( rSh.IsObjSelected() )
2965 {
2966 // set as attribute at DrawObject
2967 rSh.Paste( aGraphic, sURL );
2968 }
2969 else if( OBJCNT_GRF == rSh.GetObjCntTypeOfSelection() )
2970 {
2971 // set as linked graphic at writer graphic frame
2972 rSh.ReRead(sURL, OUString(), &aGraphic);
2973 }
2974 else
2975 {
2976 SwTransferable::SetSelInShell( rSh, false, pPt );
2977 rSh.InsertGraphic(aBkmk.GetURL(), OUString(), aGraphic);
2978 }
2979 break;
2980 }
2981 default:
2982 {
2983 bRet = false;
2984 break;
2985 }
2986 }
2987 }
2988
2989 if( bRet )
2990 {
2991
2992 if( nActionFlags &
2993 ( SotExchangeActionFlags::InsertImageMap | SotExchangeActionFlags::ReplaceImageMap ) )
2994 SwTransferable::PasteImageMap( rData, rSh );
2995
2996 if( nActionFlags & SotExchangeActionFlags::InsertTargetUrl )
2997 SwTransferable::PasteTargetURL( rData, rSh, SwPasteSdr::NONE, nullptr, false );
2998 }
2999 else if( bCheckForImageMap )
3000 {
3001 // or should the file be an ImageMap-File?
3002 ImageMap aMap;
3003 SfxMedium aMed( INetURLObject(aBkmk.GetURL()).GetFull(),
3004 StreamMode::STD_READ );
3005 SvStream* pStream = aMed.GetInStream();
3006 if( pStream != nullptr &&
3007 !pStream->GetError() &&
3008 // mba: no BaseURL for clipboard functionality
3009 aMap.Read( *pStream, IMapFormat::Detect ) == IMAP_ERR_OK &&
3010 aMap.GetIMapObjectCount() )
3011 {
3013 rSh.GetFlyFrameAttr( aSet );
3014 SwFormatURL aURL( aSet.Get( RES_URL ) );
3015 aURL.SetMap( &aMap );
3016 aSet.Put( aURL );
3017 rSh.SetFlyFrameAttr( aSet );
3018 bRet = true;
3019 }
3020 }
3021
3022 return bRet;
3023}
3024
3026 SwWrtShell& rSh )
3027{
3028 bool bRet = false;
3029 if( rData.HasFormat( SotClipboardFormatId::SVIM ))
3030 {
3032 rSh.GetFlyFrameAttr( aSet );
3033 SwFormatURL aURL( aSet.Get( RES_URL ) );
3034 const ImageMap* pOld = aURL.GetMap();
3035
3036 // set or replace, that is the question
3037 ImageMap aImageMap;
3038 if( rData.GetImageMap( SotClipboardFormatId::SVIM, aImageMap ) &&
3039 ( !pOld || aImageMap != *pOld ))
3040 {
3041 aURL.SetMap( &aImageMap );
3042 aSet.Put( aURL );
3043 rSh.SetFlyFrameAttr( aSet );
3044 }
3045 bRet = true;
3046 }
3047 return bRet;
3048}
3049
3051 SwWrtShell& rSh, SotClipboardFormatId nFormat )
3052{
3053 bool bRet = false;
3054 OUString sFile;
3055 if( rData.GetString( nFormat, sFile ) && !sFile.isEmpty() )
3056 {
3057 OUString sDesc;
3058 SwTransferable::CheckForURLOrLNKFile( rData, sFile, &sDesc );
3059
3060 // first, make the URL absolute
3062 aURL.SetSmartProtocol( INetProtocol::File );
3063 aURL.SetSmartURL( sFile );
3064 sFile = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
3065
3066 switch( rSh.GetObjCntTypeOfSelection() )
3067 {
3068 case OBJCNT_FLY:
3069 case OBJCNT_GRF:
3070 case OBJCNT_OLE:
3071 {
3073 rSh.GetFlyFrameAttr( aSet );
3074 SwFormatURL aURL2( aSet.Get( RES_URL ) );
3075 aURL2.SetURL( sFile, false );
3076 if( aURL2.GetName().isEmpty() )
3077 aURL2.SetName( sFile );
3078 aSet.Put( aURL2 );
3079 rSh.SetFlyFrameAttr( aSet );
3080 }
3081 break;
3082
3083 default:
3084 {
3085 rSh.InsertURL( SwFormatINetFormat( sFile, OUString() ),
3086 sDesc.isEmpty() ? sFile : sDesc);
3087 }
3088 }
3089 bRet = true;
3090 }
3091 return bRet;
3092}
3093
3095 SwWrtShell& rSh, SotClipboardFormatId nFormat,
3096 SwPasteSdr nAction, const Point* pPt,
3097 SotExchangeActionFlags nActionFlags,
3098 bool * graphicInserted)
3099{
3100 bool bRet = SwTransferable::PasteGrf( rData, rSh, nFormat, nAction,
3101 pPt, nActionFlags, 0, false);
3102 if (graphicInserted != nullptr) {
3103 *graphicInserted = bRet;
3104 }
3105 if( !bRet )
3106 {
3107 OUString sFile, sDesc;
3108 if( rData.GetString( nFormat, sFile ) && !sFile.isEmpty() )
3109 {
3110#if HAVE_FEATURE_AVMEDIA
3111 INetURLObject aMediaURL;
3112
3113 aMediaURL.SetSmartURL( sFile );
3114 const OUString aMediaURLStr( aMediaURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
3115
3116 if( ::avmedia::MediaWindow::isMediaURL( aMediaURLStr, ""/*TODO?*/ ) )
3117 {
3118 const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aMediaURLStr );
3120 SID_INSERT_AVMEDIA, SfxCallMode::SYNCHRON,
3121 { &aMediaURLItem });
3122 }
3123#else
3124 if (false)
3125 {
3126 }
3127#endif
3128 else
3129 {
3130 bool bIsURLFile = SwTransferable::CheckForURLOrLNKFile( rData, sFile, &sDesc );
3131
3132 //Own FileFormat? --> insert, not for StarWriter/Web
3133 OUString sFileURL = URIHelper::SmartRel2Abs(INetURLObject(), sFile, Link<OUString *, bool>(), false );
3134 std::shared_ptr<const SfxFilter> pFlt = SwPasteSdr::SetAttr == nAction
3135 ? nullptr : SwIoSystem::GetFileFilter(sFileURL);
3136 if( pFlt && dynamic_cast< const SwWebDocShell *>( rSh.GetView().GetDocShell() ) == nullptr )
3137 {
3138 // and then pull up the insert-region-dialog
3139 SwSectionData aSect(
3141 rSh.GetDoc()->GetUniqueSectionName() );
3142 aSect.SetLinkFileName( sFileURL );
3143 aSect.SetProtectFlag( true );
3144
3145 rSh.StartInsertRegionDialog( aSect ); // starts dialog asynchronously
3146 bRet = true;
3147 }
3148 else if (SwPasteSdr::Insert == nAction && rData.HasFormat(SotClipboardFormatId::SIMPLE_FILE))
3149 {
3150 // insert file as OLE
3151 PasteOLE(rData, rSh, nFormat, nActionFlags, nullptr == pPt);
3152 }
3153 else if( SwPasteSdr::SetAttr == nAction ||
3154 ( bIsURLFile && SwPasteSdr::Insert == nAction ))
3155 {
3156 //we can insert foreign files as links after all
3157
3158 // first, make the URL absolute
3160 aURL.SetSmartProtocol( INetProtocol::File );
3161 aURL.SetSmartURL( sFile );
3162 sFile = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
3163
3164 switch( rSh.GetObjCntTypeOfSelection() )
3165 {
3166 case OBJCNT_FLY:
3167 case OBJCNT_GRF:
3168 case OBJCNT_OLE:
3169 {
3171 rSh.GetFlyFrameAttr( aSet );
3172 SwFormatURL aURL2( aSet.Get( RES_URL ) );
3173 aURL2.SetURL( sFile, false );
3174 if( aURL2.GetName().isEmpty() )
3175 aURL2.SetName( sFile );
3176 aSet.Put( aURL2 );
3177 rSh.SetFlyFrameAttr( aSet );
3178 }
3179 break;
3180
3181 default:
3182 {
3183 rSh.InsertURL( SwFormatINetFormat( sFile, OUString() ),
3184 sDesc.isEmpty() ? sFile : sDesc );
3185 }
3186 }
3187 bRet = true;
3188 }
3189 }
3190 }
3191 }
3192 return bRet;
3193}
3194
3196 SwWrtShell& rSh, SotClipboardFormatId nFormat, bool bLink,
3197 const Point* pDragPt, bool bMsg )
3198{
3199 bool bRet = false;
3200 OUString sText;
3201 if( rData.GetString( nFormat, sText ) && !sText.isEmpty() )
3202 {
3203 sal_uInt16 nWh = SotClipboardFormatId::SBA_CTRLDATAEXCHANGE == nFormat
3204 ? 0
3205 : SotClipboardFormatId::SBA_DATAEXCHANGE == nFormat
3206 ? (bLink
3208 : FN_QRY_INSERT)
3209 : (bLink
3210 ? 0
3212 const DataFlavorExVector& rVector = rData.GetDataFlavorExVector();
3213 bool bHaveColumnDescriptor = OColumnTransferable::canExtractColumnDescriptor(rVector, ColumnTransferFormatFlags::COLUMN_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE);
3214 if ( SotClipboardFormatId::XFORMS == nFormat )
3215 {
3216 rSh.MakeDrawView();
3217 FmFormView* pFmView = dynamic_cast<FmFormView*>( rSh.GetDrawView() );
3218 if (pFmView && pDragPt)
3219 {
3220 const OXFormsDescriptor &rDesc = OXFormsTransferable::extractDescriptor(rData);
3221 rtl::Reference<SdrObject> pObj = pFmView->CreateXFormsControl(rDesc);
3222 if(pObj)
3223 {
3224 rSh.SwFEShell::InsertDrawObj( *pObj, *pDragPt );
3225 }
3226 }
3227 }
3228 else if( nWh )
3229 {
3230 std::unique_ptr<SfxUnoAnyItem> pConnectionItem;
3231 std::unique_ptr<SfxUnoAnyItem> pCursorItem;
3232 std::unique_ptr<SfxUnoAnyItem> pColumnItem;
3233 std::unique_ptr<SfxUnoAnyItem> pSourceItem;
3234 std::unique_ptr<SfxUnoAnyItem> pCommandItem;
3235 std::unique_ptr<SfxUnoAnyItem> pCommandTypeItem;
3236 std::unique_ptr<SfxUnoAnyItem> pColumnNameItem;
3237 std::unique_ptr<SfxUnoAnyItem> pSelectionItem;
3238
3239 bool bDataAvailable = true;
3240 ODataAccessDescriptor aDesc;
3241 if(bHaveColumnDescriptor)
3242 aDesc = OColumnTransferable::extractColumnDescriptor(rData);
3243 else if(ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
3244 aDesc = ODataAccessObjectTransferable::extractObjectDescriptor(rData);
3245 else
3246 bDataAvailable = false;
3247
3248 if ( bDataAvailable )
3249 {
3250 pConnectionItem.reset(new SfxUnoAnyItem(FN_DB_CONNECTION_ANY, aDesc[DataAccessDescriptorProperty::Connection]));
3251 pColumnItem.reset(new SfxUnoAnyItem(FN_DB_COLUMN_ANY, aDesc[DataAccessDescriptorProperty::ColumnObject]));
3252 pSourceItem.reset(new SfxUnoAnyItem(FN_DB_DATA_SOURCE_ANY, Any(aDesc.getDataSource())));
3253 pCommandItem.reset(new SfxUnoAnyItem(FN_DB_DATA_COMMAND_ANY, aDesc[DataAccessDescriptorProperty::Command]));
3254 pCommandTypeItem.reset(new SfxUnoAnyItem(FN_DB_DATA_COMMAND_TYPE_ANY, aDesc[DataAccessDescriptorProperty::CommandType]));
3255 pColumnNameItem.reset(new SfxUnoAnyItem(FN_DB_DATA_COLUMN_NAME_ANY, aDesc[DataAccessDescriptorProperty::ColumnName]));
3256 pSelectionItem.reset(new SfxUnoAnyItem(FN_DB_DATA_SELECTION_ANY, aDesc[DataAccessDescriptorProperty::Selection]));
3257 pCursorItem.reset(new SfxUnoAnyItem(FN_DB_DATA_CURSOR_ANY, aDesc[DataAccessDescriptorProperty::Cursor]));
3258 }
3259
3260 SwView& rView = rSh.GetView();
3261 //force ::SelectShell
3262 rView.StopShellTimer();
3263
3264 SfxStringItem aDataDesc( nWh, sText );
3266 nWh, SfxCallMode::ASYNCHRON,
3267 { &aDataDesc, pConnectionItem.get(), pColumnItem.get(),
3268 pSourceItem.get(), pCommandItem.get(), pCommandTypeItem.get(),
3269 pColumnNameItem.get(), pSelectionItem.get(),
3270 pCursorItem.get() });
3271 }
3272 else
3273 {
3274 rSh.MakeDrawView();
3275 FmFormView* pFmView = dynamic_cast<FmFormView*>( rSh.GetDrawView() );
3276 if (pFmView && bHaveColumnDescriptor && pDragPt)
3277 {
3278 rtl::Reference<SdrObject> pObj = pFmView->CreateFieldControl( OColumnTransferable::extractColumnDescriptor(rData) );
3279 if (pObj)
3280 rSh.SwFEShell::InsertDrawObj( *pObj, *pDragPt );
3281 }
3282 }
3283 bRet = true;
3284 }
3285 else if( bMsg )
3286 {
3287 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
3288 VclMessageType::Info, VclButtonsType::Ok,
3289 SwResId(STR_CLPBRD_FORMAT_ERROR)));
3290 xBox->run();
3291 }
3292 return bRet;
3293}
3294
3296 SwWrtShell& rSh, bool bLink,
3297 const Point* pPt, bool bMsg )
3298{
3299 bool bRet = false;
3300 FileList aFileList;
3301 if( rData.GetFileList( SotClipboardFormatId::FILE_LIST, aFileList ) &&
3302 aFileList.Count() )
3303 {
3305 OUString sFlyNm;
3306 // iterate over the filelist
3307 for( sal_uLong n = 0, nEnd = aFileList.Count(); n < nEnd; ++n )
3308 {
3310 pHlp->CopyString( SotClipboardFormatId::SIMPLE_FILE, aFileList.GetFile( n ));
3312
3313 if( SwTransferable::PasteFileName( aData, rSh, SotClipboardFormatId::SIMPLE_FILE, nAct,
3314 pPt, SotExchangeActionFlags::NONE, nullptr ))
3315 {
3316 if( bLink )
3317 {
3318 sFlyNm = rSh.GetFlyName();
3319 SwTransferable::SetSelInShell( rSh, false, pPt );
3320 }
3321 bRet = true;
3322 }
3323 }
3324 if( !sFlyNm.isEmpty() )
3325 rSh.GotoFly( sFlyNm );
3326 }
3327 else if( bMsg )
3328 {
3329 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
3330 VclMessageType::Info, VclButtonsType::Ok,
3331 SwResId(STR_CLPBRD_FORMAT_ERROR)));
3332 xBox->run();
3333 }
3334 return bRet;
3335}
3336
3338 OUString& rFileName, OUString* pTitle )
3339{
3340 bool bIsURLFile = false;
3341 INetBookmark aBkmk;
3342 if( rData.GetINetBookmark( SotClipboardFormatId::SOLK, aBkmk ) )
3343 {
3344 rFileName = aBkmk.GetURL();
3345 if( pTitle )
3346 *pTitle = aBkmk.GetDescription();
3347 bIsURLFile = true;
3348 }
3349 else
3350 {
3351 if( rFileName.getLength()>4 && rFileName.endsWithIgnoreAsciiCase(".url") )
3352 {
3353 OSL_ENSURE( false, "how do we read today .URL - Files?" );
3354 }
3355 }
3356 return bIsURLFile;
3357}
3358
3360 const TransferableDataHelper& rData )
3361{
3362 // we can paste-special if there's an entry in the paste-special-format list
3364 FillClipFormatItem( rWrtShell, rData, aClipboardFormatItem);
3365 return aClipboardFormatItem.Count() > 0;
3366}
3367
3369{
3370 return ( GetSwTransferable( rData ) != nullptr );
3371}
3372
3375 SotClipboardFormatId nFormat )
3376{
3377 SwWait aWait( *rSh.GetView().GetDocShell(), false );
3378 bool bRet = false;
3379
3380 SotClipboardFormatId nPrivateFormat = SotClipboardFormatId::PRIVATE;
3381 SwTransferable *pClipboard = GetSwTransferable( rData );
3382 if( pClipboard &&
3384 nPrivateFormat = SotClipboardFormatId::EMBED_SOURCE;
3385
3386 if( pClipboard && nPrivateFormat == nFormat )
3387 bRet = pClipboard->PrivatePaste( rSh );
3388 else if( rData.HasFormat( nFormat ) )
3389 {
3390 uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
3391 sal_uInt8 nEventAction;
3393 sal_uInt16 nSourceOptions =
3394 (( SotExchangeDest::DOC_TEXTFRAME == nDestination ||
3395 SotExchangeDest::SWDOC_FREE_AREA == nDestination ||
3396 SotExchangeDest::DOC_TEXTFRAME_WEB == nDestination ||
3397 SotExchangeDest::SWDOC_FREE_AREA_WEB == nDestination )
3400 SotExchangeActionFlags nActionFlags;
3402 rData.GetDataFlavorExVector(),
3403 nDestination,
3404 nSourceOptions, /* ?? */
3405 EXCHG_IN_ACTION_DEFAULT, /* ?? */
3406 nFormat, nEventAction, nFormat,
3407 lcl_getTransferPointer ( xTransferable ),
3408 &nActionFlags );
3409
3410 if( EXCHG_INOUT_ACTION_NONE != nAction )
3411 bRet = SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat,
3412 nDestination, true, false );
3413 }
3414 return bRet;
3415}
3416
3418 SotClipboardFormatId nFormat, SotExchangeDest nDestination )
3419{
3421 if( rData.HasFormat( nFormat )) {
3422 uno::Reference<XTransferable> xTransferable( rData.GetXTransferable() );
3423 sal_uInt8 nEventAction;
3425 rData.GetDataFlavorExVector(),
3426 nDestination, EXCHG_IN_ACTION_COPY,
3427 EXCHG_IN_ACTION_COPY, nFormat,
3428 nEventAction, nFormat,
3429 lcl_getTransferPointer ( xTransferable ) );
3430 }
3431 return EXCHG_INOUT_ACTION_NONE != nAction;
3432}
3433
3439{
3440 SotClipboardFormatId::HTML,
3441 SotClipboardFormatId::HTML_SIMPLE,
3442 SotClipboardFormatId::HTML_NO_COMMENT,
3443 SotClipboardFormatId::RTF,
3444 SotClipboardFormatId::RICHTEXT,
3445 SotClipboardFormatId::STRING,
3446 SotClipboardFormatId::SONLK,
3447 SotClipboardFormatId::NETSCAPE_BOOKMARK,
3448 SotClipboardFormatId::DRAWING,
3449 SotClipboardFormatId::SVXB,
3450 SotClipboardFormatId::GDIMETAFILE,
3451 SotClipboardFormatId::BITMAP,
3452 SotClipboardFormatId::SVIM,
3453 SotClipboardFormatId::FILEGRPDESCRIPTOR,
3454 SotClipboardFormatId::NONE
3455};
3456
3458{
3459 // Plain text == unformatted
3460 return SwTransferable::PasteFormat( rSh, rData, SotClipboardFormatId::STRING );
3461}
3462
3464{
3465 DataFlavorExVector aFormats( rData.GetDataFlavorExVector() );
3467
3469
3470 SwTransferable *pClipboard = GetSwTransferable( rData );
3471 if( pClipboard )
3472 {
3473 aDesc = pClipboard->m_aObjDesc;
3474 TranslateId pResId;
3476 pResId = STR_PRIVATETEXT;
3477 else if( pClipboard->m_eBufferType & TransferBufferType::Graphic )
3478 pResId = STR_PRIVATEGRAPHIC;
3479 else if( pClipboard->m_eBufferType == TransferBufferType::Ole )
3480 pResId = STR_PRIVATEOLE;
3481
3482 if (pResId)
3483 {
3484 if (STR_PRIVATEOLE == pResId || STR_PRIVATEGRAPHIC == pResId)
3485 {
3486 // add SotClipboardFormatId::EMBED_SOURCE to the formats. This
3487 // format display then the private format name.
3488 DataFlavorEx aFlavorEx;
3489 aFlavorEx.mnSotId = SotClipboardFormatId::EMBED_SOURCE;
3490 aFormats.insert( aFormats.begin(), aFlavorEx );
3491 }
3492 pDlg->SetObjName( pClipboard->m_aObjDesc.maClassName,
3493 SwResId(pResId) );
3494 pDlg->Insert( SotClipboardFormatId::EMBED_SOURCE, OUString() );
3495 }
3496 }
3497 else
3498 {
3499 if( rData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ) )
3500 {
3502 SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc );
3503 }
3504
3505 if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::EMBED_SOURCE, nDest ))
3506 pDlg->Insert( SotClipboardFormatId::EMBED_SOURCE, OUString() );
3507 if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK_SOURCE, nDest ))
3508 pDlg->Insert( SotClipboardFormatId::LINK_SOURCE, OUString() );
3509 }
3510
3511 if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK, nDest ))
3512 pDlg->Insert( SotClipboardFormatId::LINK, SwResId(STR_DDEFORMAT) );
3513
3514 for( SotClipboardFormatId* pIds = aPasteSpecialIds; *pIds != SotClipboardFormatId::NONE; ++pIds )
3515 if( SwTransferable::TestAllowedFormat( rData, *pIds, nDest ))
3516 pDlg->Insert( *pIds, OUString() );
3517}
3518
3520 const TransferableDataHelper& rData,
3521 SvxClipboardFormatItem & rToFill )
3522{
3524
3525 SwTransferable *pClipboard = GetSwTransferable( rData );
3526 if( pClipboard )
3527 {
3528 TranslateId pResId;
3530 pResId = STR_PRIVATETEXT;
3531 else if( pClipboard->m_eBufferType & TransferBufferType::Graphic )
3532 pResId = STR_PRIVATEGRAPHIC;
3533 else if( pClipboard->m_eBufferType == TransferBufferType::Ole )
3534 pResId = STR_PRIVATEOLE;
3535
3536 if (pResId)
3537 rToFill.AddClipbrdFormat(SotClipboardFormatId::EMBED_SOURCE,
3538 SwResId(pResId));
3539 }
3540 else
3541 {
3543 if (rData.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
3544 {
3546 SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc);
3547 }
3548
3549 if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::EMBED_SOURCE, nDest ))
3550 rToFill.AddClipbrdFormat( SotClipboardFormatId::EMBED_SOURCE,
3551 aDesc.maTypeName );
3552 if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK_SOURCE, nDest ))
3553 rToFill.AddClipbrdFormat( SotClipboardFormatId::LINK_SOURCE );
3554
3555 SotClipboardFormatId nFormat;
3556 if ( rData.HasFormat(nFormat = SotClipboardFormatId::EMBED_SOURCE_OLE) || rData.HasFormat(nFormat = SotClipboardFormatId::EMBEDDED_OBJ_OLE) )
3557 {
3558 OUString sName,sSource;
3559 if ( SvPasteObjectHelper::GetEmbeddedName(rData,sName,sSource,nFormat) )
3560 rToFill.AddClipbrdFormat( nFormat, sName );
3561 }
3562 }
3563
3564 if( SwTransferable::TestAllowedFormat( rData, SotClipboardFormatId::LINK, nDest ))
3565 rToFill.AddClipbrdFormat( SotClipboardFormatId::LINK, SwResId(STR_DDEFORMAT) );
3566
3567 for( SotClipboardFormatId* pIds = aPasteSpecialIds; *pIds != SotClipboardFormatId::NONE; ++pIds )
3568 if( SwTransferable::TestAllowedFormat( rData, *pIds, nDest ))
3569 rToFill.AddClipbrdFormat(*pIds, OUString());
3570}
3571
3572void SwTransferable::SetDataForDragAndDrop( const Point& rSttPos )
3573{
3574 if(!m_pWrtShell)
3575 return;
3576 OUString sGrfNm;
3577 const SelectionType nSelection = m_pWrtShell->GetSelectionType();
3578 if( SelectionType::Graphic == nSelection)
3579 {
3580 AddFormat( SotClipboardFormatId::SVXB );
3581 const Graphic* pGrf = m_pWrtShell->GetGraphic();
3582 if ( pGrf && pGrf->IsSupportedGraphic() )
3583 {
3584 AddFormat( SotClipboardFormatId::GDIMETAFILE );
3585 AddFormat( SotClipboardFormatId::PNG );
3586 AddFormat( SotClipboardFormatId::BITMAP );
3587 }
3589 m_pWrtShell->GetGrfNms( &sGrfNm, nullptr );
3590 }
3591 else if( SelectionType::Ole == nSelection )
3592 {
3593 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
3595 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
3596 AddFormat( SotClipboardFormatId::GDIMETAFILE );
3598 }
3599 //Is there anything to provide anyway?
3602 {
3603 if( m_pWrtShell->IsObjSelected() )
3605 else
3606 {
3608 if( SwWrtShell::NO_WORD !=
3609 m_pWrtShell->IntelligentCut( nSelection, false ))
3611 }
3612
3613 if( nSelection & SelectionType::TableCell )
3615
3616 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
3617
3618 //put RTF ahead of the OLE's Metafile for less loss
3619 if( !m_pWrtShell->IsObjSelected() )
3620 {
3621 AddFormat( SotClipboardFormatId::RTF );
3622 AddFormat( SotClipboardFormatId::RICHTEXT );
3623 AddFormat( SotClipboardFormatId::HTML );
3624 }
3625 if( m_pWrtShell->IsSelection() )
3626 AddFormat( SotClipboardFormatId::STRING );
3627
3628 if( nSelection & ( SelectionType::DrawObject | SelectionType::DbForm ))
3629 {
3630 AddFormat( SotClipboardFormatId::DRAWING );
3631 if ( nSelection & SelectionType::DrawObject )
3632 {
3633 AddFormat( SotClipboardFormatId::GDIMETAFILE );
3634 AddFormat( SotClipboardFormatId::PNG );
3635 AddFormat( SotClipboardFormatId::BITMAP );
3636 }
3638
3639 // is it a URL-Button ?
3640 OUString sURL;
3641 OUString sDesc;
3642 if( m_pWrtShell->GetURLFromButton( sURL, sDesc ) )
3643 {
3644 AddFormat( SotClipboardFormatId::STRING );
3645 AddFormat( SotClipboardFormatId::SOLK );
3646 AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
3647 AddFormat( SotClipboardFormatId::FILECONTENT );
3648 AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
3649 AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
3651 }
3652 }
3653
3654 //ObjectDescriptor was already filled from the old DocShell.
3655 //Now adjust it. Thus in GetData the first query can still
3656 //be answered with delayed rendering.
3657 m_aObjDesc.maDragStartPos = rSttPos;
3659
3661 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
3662 }
3663 else if( nSelection & SelectionType::Text && !m_pWrtShell->HasMark() )
3664 {
3665 // is only one field - selected?
3666 SwContentAtPos aContentAtPos( IsAttrAtPos::InetAttr );
3668
3669 if( m_pWrtShell->GetContentAtPos( aPos, aContentAtPos ) )
3670 {
3671 AddFormat( SotClipboardFormatId::STRING );
3672 AddFormat( SotClipboardFormatId::SOLK );
3673 AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
3674 AddFormat( SotClipboardFormatId::FILECONTENT );
3675 AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR );
3676 AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
3678 }
3679 }
3680
3682 return;
3683
3686 const SwFormatURL& rURL = aSet.Get( RES_URL );
3687 if( rURL.GetMap() )
3688 {
3689 m_pImageMap.reset( new ImageMap( *rURL.GetMap() ) );
3690 AddFormat( SotClipboardFormatId::SVIM );
3691 }
3692 else if( !rURL.GetURL().isEmpty() )
3693 {
3694 m_pTargetURL.reset(new INetImage( sGrfNm, rURL.GetURL(),
3695 rURL.GetTargetFrameName() ));
3696 AddFormat( SotClipboardFormatId::INET_IMAGE );
3697 }
3698}
3699
3700void SwTransferable::StartDrag( vcl::Window* pWin, const Point& rPos )
3701{
3702 if(!m_pWrtShell)
3703 return;
3705 m_bCleanUp = true;
3706
3707 m_pWrtShell->GetViewOptions()->SetIdle( false );
3708
3711
3712 SW_MOD()->m_pDragDrop = this;
3713
3714 SetDataForDragAndDrop( rPos );
3715
3717 SwDocShell* pDShell = m_pWrtShell->GetView().GetDocShell();
3718 if( ( pDShell && pDShell->IsReadOnly() ) || m_pWrtShell->HasReadonlySel() )
3719 nDragOptions &= ~DND_ACTION_MOVE;
3720
3721 TransferableHelper::StartDrag( pWin, nDragOptions );
3722}
3723
3725{
3726 //And the last finishing work so that all statuses are right
3727 if( DND_ACTION_MOVE == nAction )
3728 {
3729 if( m_bCleanUp )
3730 {
3731 //It was dropped outside of Writer. We still have to
3732 //delete.
3733
3736 if ( m_pWrtShell->IsTableMode() )
3738 else
3739 {
3741 //SmartCut, take one of the blanks along
3744 }
3747 }
3748 else
3749 {
3750 const SelectionType nSelection = m_pWrtShell->GetSelectionType();
3753 {
3755 }
3756 }
3757 }
3759
3762 else
3764
3766}
3767
3768namespace
3769{
3770
3771bool lcl_checkClassification(SwDoc* pSourceDoc, SwDoc* pDestinationDoc)
3772{
3773 if (!pSourceDoc || !pDestinationDoc)
3774 return true;
3775
3776 SwDocShell* pSourceShell = pSourceDoc->GetDocShell();
3777 SwDocShell* pDestinationShell = pDestinationDoc->GetDocShell();
3778 if (!pSourceShell || !pDestinationShell)
3779 return true;
3780
3783}
3784
3785}
3786
3788{
3789 // first, ask for the SelectionType, then action-bracketing !!!!
3790 // (otherwise it's not pasted into a TableSelection!!!)
3791 OSL_ENSURE( !rShell.ActionPend(), "Paste must never have an ActionPend" );
3792 if ( !m_pClpDocFac )
3793 return false; // the return value of the SwFEShell::Paste also is bool!
3794
3795 const SelectionType nSelection = rShell.GetSelectionType();
3796
3797 SwTrnsfrActionAndUndo aAction( &rShell );
3798
3799 bool bKillPaMs = false;
3800
3801 //Delete selected content, not at table-selection and table in Clipboard, and don't delete hovering graphics.
3802 if( rShell.HasSelection() && !( nSelection & SelectionType::TableCell) && !( nSelection & SelectionType::DrawObject))
3803 {
3804 if (!(nSelection & SelectionType::NumberList))
3805 {
3806 bKillPaMs = true;
3807 rShell.SetRetainSelection( true );
3808 }
3809 if (pContext)
3810 pContext->forget();
3811 rShell.DelRight();
3812 if (pContext)
3813 pContext->remember();
3814 // when a Fly was selected, a valid cursor position has to be found now
3815 // (parked Cursor!)
3818 SelectionType::DbForm ) & nSelection )
3819 {
3820 // position the cursor again
3821 Point aPt( rShell.GetCharRect().Pos() );
3822 rShell.SwCursorShell::SetCursor( aPt, true );
3823 }
3824 if (!(nSelection & SelectionType::NumberList))
3825 {
3826 rShell.SetRetainSelection( false );
3827 }
3828 }
3829 if ( nSelection & SelectionType::DrawObject) //unselect hovering graphics
3830 {
3831 rShell.ResetSelect(nullptr,false);
3832 }
3833
3834 bool bInWrd = false, bEndWrd = false, bSttWrd = false,
3836 if( bSmart )
3837 {
3838 // Why not for other Scripts? If TransferBufferType::DocumentWord is set, we have a word
3839 // in the buffer, word in this context means 'something with spaces at beginning
3840 // and end'. In this case we definitely want these spaces to be inserted here.
3841 bInWrd = rShell.IsInWord();
3842 bEndWrd = rShell.IsEndWrd();
3843 bSmart = bInWrd || bEndWrd;
3844 if( bSmart )
3845 {
3846 bSttWrd = rShell.IsStartWord();
3847 if (!bSttWrd && (bInWrd || bEndWrd))
3848 rShell.SwEditShell::Insert(' ');
3849 }
3850 }
3851
3852 bool bRet = true;
3853 // m_pWrtShell is nullptr when the source document is closed already.
3854 if (!m_pWrtShell || lcl_checkClassification(m_pWrtShell->GetDoc(), rShell.GetDoc()))
3855 bRet = rShell.Paste(m_pClpDocFac->GetDoc(), ePasteTable == PasteTableType::PASTE_TABLE);
3856
3857 if( bKillPaMs )
3858 rShell.KillPams();
3859
3860 // If Smart Paste then insert blank
3861 if( bRet && bSmart && ((bInWrd && !bEndWrd )|| bSttWrd) )
3862 rShell.SwEditShell::Insert(' ');
3863
3864 return bRet;
3865}
3866
3867bool SwTransferable::PrivateDrop( SwWrtShell& rSh, const Point& rDragPt,
3868 bool bMove, bool bIsXSelection )
3869{
3870 int cWord = 0;
3871 bool bInWrd = false;
3872 bool bEndWrd = false;
3873 bool bSttWrd = false;
3874 bool bSttPara = false;
3875 bool bTableSel = false;
3876 bool bTableMove = false;
3877 bool bFrameSel = false;
3878
3879 SwWrtShell& rSrcSh = *GetShell();
3880
3881 rSh.UnSetVisibleCursor();
3882
3884 {
3885 if( rSh.GetFormatFromObj( rDragPt ) )
3886 {
3887 INetBookmark aTmp;
3889 aTmp = *m_pBookmark;
3890
3891 // select target graphic
3892 if( rSh.SelectObj( rDragPt ) )
3893 {
3894 rSh.HideCursor();
3895 rSh.EnterSelFrameMode( &rDragPt );
3896 g_bFrameDrag = true;
3897 }
3898
3899 const SelectionType nSelection = rSh.GetSelectionType();
3900
3901 // not yet consider Draw objects
3902 if( SelectionType::Graphic & nSelection )
3903 {
3905 rSh.GetFlyFrameAttr( aSet );
3906 SwFormatURL aURL( aSet.Get( RES_URL ) );
3907 aURL.SetURL( aTmp.GetURL(), false );
3908 aSet.Put( aURL );
3909 rSh.SetFlyFrameAttr( aSet );
3910 return true;
3911 }
3912
3913 if( SelectionType::DrawObject & nSelection )
3914 {
3915 rSh.LeaveSelFrameMode();
3916 rSh.UnSelectFrame();
3917 rSh.ShowCursor();
3918 g_bFrameDrag = false;
3919 }
3920 }
3921 }
3922
3923 if( &rSh != &rSrcSh && (SelectionType::Graphic & rSh.GetSelectionType()) &&
3925 {
3926 // ReRead the graphic
3927 OUString sGrfNm;
3928 OUString sFltNm;
3929 rSrcSh.GetGrfNms( &sGrfNm, &sFltNm );
3930 rSh.ReRead( sGrfNm, sFltNm, rSrcSh.GetGraphic() );
3931 return true;
3932 }
3933
3934 //not in selections or selected frames
3935 if( rSh.TestCurrPam( rDragPt ) ||
3936 ( rSh.IsSelFrameMode() && rSh.IsInsideSelectedObj( rDragPt )) )
3937 return false;
3938
3939 if( rSrcSh.IsTableMode() )
3940 {
3941 bTableSel = true;
3942 const SelectionType nSelection = rSrcSh.GetSelectionType();
3943 // at enhanced table row/column selection or wholly selected tables,
3944 // paste rows above or columns before, and in the case of moving, remove the selection
3945 // (limit only to the single document case temporarily)
3946 if( rSrcSh.GetDoc() == rSh.GetDoc() &&
3947 ( (( SelectionType::TableRow | SelectionType::TableCol) & nSelection ) || rSrcSh.HasWholeTabSelection() ) )
3948 {
3949 bool bTableCol(SelectionType::TableCol & nSelection);
3950
3951 ::sw::mark::IMark* pMarkMoveFrom = bMove
3952 ? rSh.SetBookmark(
3953 vcl::KeyCode(),
3954 OUString(),
3956 : nullptr;
3957
3958 // row count and direction of the table selection:
3959 // up to down, if the cursor is there in its last table row
3960 const SwSelBoxes& rBoxes = rSrcSh.GetTableCursor()->GetSelectedBoxes();
3961 const SwTableNode* pTableNd = rSh.IsCursorInTable();
3962 sal_Int32 nSelRows = !rBoxes.back()
3963 ? 0
3964 : pTableNd->GetTable().GetTabLines().GetPos( rBoxes.back()->GetUpper() ) -
3965 pTableNd->GetTable().GetTabLines().GetPos( rBoxes.front()->GetUpper() ) + 1;
3966 bool bSelUpToDown = rBoxes.back() && rBoxes.back()->GetUpper() ==
3968
3970
3971 SwRewriter aRewriter;
3972
3973 aRewriter.AddRule(UndoArg1, rSrcSh.GetSelDescr());
3974
3975 if(rSrcSh.GetDoc() != rSh.GetDoc())
3976 rSrcSh.StartUndo( eUndoId, &aRewriter );
3977 rSh.StartUndo( eUndoId, &aRewriter );
3978
3979 rSh.StartAction();
3980 rSrcSh.StartAction();
3981
3982 SfxDispatcher* pDispatch = rSrcSh.GetView().GetViewFrame()->GetDispatcher();
3983 pDispatch->Execute(SID_COPY, SfxCallMode::SYNCHRON);
3984
3985 rSrcSh.Push(); // save selection for later restoration
3986 rSh.EnterStdMode();
3987 rSh.SwCursorShell::SetCursor(rDragPt, false);
3988
3989 bool bPasteIntoTable = rSh.GetCursor()->GetPointNode().GetTableBox() != nullptr;
3990
3991 // store cursor
3992 ::sw::mark::IMark* pMark = rSh.SetBookmark(
3993 vcl::KeyCode(),
3994 OUString(),
3996
3997 // paste rows above/columns before
3998 pDispatch->Execute(bTableCol ? FN_TABLE_PASTE_COL_BEFORE : FN_TABLE_PASTE_ROW_BEFORE, SfxCallMode::SYNCHRON);
3999
4000 // go to the previously inserted table rows and set them to tracked insertion, if needed
4001 bool bNeedTrack = !bTableCol && rSh.getIDocumentRedlineAccess().IsRedlineOn();
4002
4003 // restore cursor position
4004 if (bNeedTrack && pMark != nullptr)
4005 rSh.GotoMark( pMark );
4006
4007 if ( !bNeedTrack && !bPasteIntoTable )
4008 {
4009 rSrcSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // restore selection...
4010
4011 // delete source rows/columns
4012 if (bMove)
4013 pDispatch->Execute(bTableCol
4015 : FN_TABLE_DELETE_ROW, SfxCallMode::SYNCHRON);
4016 }
4017 else
4018 {
4019 const SwTableBox* pBoxStt = rSh.GetCursor()->GetPointNode().GetTableBox();
4020 SwTableLine* pLine = pBoxStt ? const_cast<SwTableLine*>( pBoxStt->GetUpper()): nullptr;
4021
4022 for (sal_Int32 nDeleted = 0; bNeedTrack && nDeleted < nSelRows;)
4023 {
4024 // move up text cursor (note: "true" is important for the layout level)
4025 if ( !rSh.Up(false) )
4026 break;
4027
4028 const SwTableBox* pBox = rSh.GetCursor()->GetPointNode().GetTableBox();
4029
4030 if ( !pBox )
4031 break;
4032
4033 // Up() reaches a new row
4034 if ( pBox->GetUpper() != pLine )
4035 {
4036 //rSh.SelTableRow();
4037 SvxPrintItem aTracked(RES_PRINT, false);
4038 rSh.GetDoc()->SetRowNotTracked( *rSh.GetCursor(), aTracked );
4039 ++nDeleted;
4040 pLine = const_cast<SwTableLine*>(pBox->GetUpper());
4041 }
4042 }
4043
4044 rSrcSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // restore selection...
4045
4046 // delete source rows/columns
4047 if (bMove)
4048 {
4049 // restore cursor position
4050 if (pMarkMoveFrom != nullptr)
4051 {
4052 rSh.GotoMark( pMarkMoveFrom );
4053 rSh.getIDocumentMarkAccess()->deleteMark( pMarkMoveFrom );
4054 }
4055
4056 // set all row as tracked deletion, otherwise go to the first moved row
4057 if ( bNeedTrack || ( bSelUpToDown && nSelRows > 1 ) )
4058 {
4059 pLine = nullptr;
4060
4061 for (sal_Int32 nDeleted = 0; nDeleted < nSelRows - int(!bNeedTrack);)
4062 {
4063 const SwTableBox* pBox = rSh.GetCursor()->GetPointNode().GetTableBox();
4064
4065 if ( !pBox )
4066 break;
4067
4068 if ( pBox->GetUpper() != pLine )
4069 {
4070 pLine = const_cast<SwTableLine*>(pBox->GetUpper());
4071 if (bNeedTrack)
4072 pDispatch->Execute(bTableCol
4074 : FN_TABLE_DELETE_ROW, SfxCallMode::SYNCHRON);
4075 ++nDeleted;
4076 }
4077
4078 bool bMoved = false;
4079 if (bSelUpToDown)
4080 bMoved = rSh.Up(false);
4081 else
4082 bMoved = rSh.Down(false);
4083 if (!bMoved)
4084 break;
4085 }
4086 }
4087
4088 // delete rows without track changes
4089 if ( !bNeedTrack )
4090 {
4091 for (sal_Int32 nDeleted = 0; nDeleted < nSelRows; ++nDeleted)
4092 pDispatch->Execute(bTableCol
4094 : FN_TABLE_DELETE_ROW, SfxCallMode::SYNCHRON);
4095 }
4096 }
4097 }
4098
4099 // restore cursor position
4100 if (pMark != nullptr)
4101 {
4102 rSh.GotoMark( pMark );
4103 rSh.getIDocumentMarkAccess()->deleteMark( pMark );
4104 }
4105
4106 rSh.DestroyCursor();
4107 rSh.EndUndo();
4108 rSh.EndAction();
4109 rSh.EndAction();
4110 return true;
4111 }
4112
4113 if ( bMove && rSrcSh.HasWholeTabSelection() )
4114 bTableMove = true;
4115 }
4116 else if( rSrcSh.IsSelFrameMode() || rSrcSh.IsObjSelected() )
4117 {
4118 // don't move position-protected objects!
4120 return false;
4121
4122 bFrameSel = true;
4123 }
4124
4125 const SelectionType nSel = rSrcSh.GetSelectionType();
4126
4128
4129 SwRewriter aRewriter;
4130
4131 aRewriter.AddRule(UndoArg1, rSrcSh.GetSelDescr());
4132
4133 if(rSrcSh.GetDoc() != rSh.GetDoc())
4134 rSrcSh.StartUndo( eUndoId, &aRewriter );
4135 rSh.StartUndo( eUndoId, &aRewriter );
4136
4137 rSh.StartAction();
4138 rSrcSh.StartAction();
4139
4140 if( &rSrcSh != &rSh )
4141 {
4142 rSh.EnterStdMode();
4143 rSh.SwCursorShell::SetCursor( rDragPt, true );
4144 cWord = rSrcSh.IntelligentCut( nSel, false );
4145 }
4146 else if( !bTableSel && !bFrameSel )
4147 {
4148 if( !rSh.IsAddMode() )
4149 {
4150 // #i87233#
4151 if ( rSh.IsBlockMode() )
4152 {
4153 // preserve order of cursors for block mode
4154 rSh.GoPrevCursor();
4155 }
4156
4157 rSh.SwCursorShell::CreateCursor();
4158 }
4159 rSh.SwCursorShell::SetCursor( rDragPt, true, false );
4160 rSh.GoPrevCursor();
4161 cWord = rSh.IntelligentCut( rSh.GetSelectionType(), false );
4162 rSh.GoNextCursor();
4163 }
4164
4165 bInWrd = rSh.IsInWord();
4166 bEndWrd = rSh.IsEndWrd();
4167 bSttWrd = !bEndWrd && rSh.IsStartWord();
4168 bSttPara= rSh.IsSttPara();
4169
4171
4172 // at first, select InetFields!
4174 {
4175 if( &rSrcSh == &rSh )
4176 {
4177 rSh.GoPrevCursor();
4178 rSh.SwCursorShell::SetCursor( aSttPt, true );
4180 if( rSh.TestCurrPam( rDragPt ) )
4181 {
4182 // don't copy/move inside of yourself
4183 rSh.DestroyCursor();
4184 rSh.EndUndo();
4185 rSh.EndAction();
4186 rSh.EndAction();
4187 return false;
4188 }
4189 rSh.GoNextCursor();
4190 }
4191 else
4192 {
4193 rSrcSh.SwCursorShell::SetCursor( aSttPt, true );
4195 }
4196
4197 // is there a URL attribute at the insert point? Then replace that,
4198 // so simply put up a selection?
4199 rSh.DelINetAttrWithText();
4200 g_bDDINetAttr = true;
4201 }
4202
4203 if ( rSrcSh.IsSelFrameMode() )
4204 {
4205 //Hack: fool the special treatment
4206 aSttPt = rSrcSh.GetObjRect().Pos();
4207 }
4208
4209 bool bRet = rSrcSh.SwFEShell::Copy(rSh, aSttPt, rDragPt, bMove,
4210 !bIsXSelection);
4211
4212 if( !bIsXSelection )
4213 {
4214 rSrcSh.Push();
4215 if ( bRet && bMove && !bFrameSel )
4216 {
4217 if ( bTableSel )
4218 {
4219 /* delete table contents not cells */
4220 rSrcSh.Delete(false);
4221 }
4222 else
4223 {
4224 //SmartCut, take one of the blanks along.
4225 rSh.SwCursorShell::DestroyCursor();
4226 if ( cWord == SwWrtShell::WORD_SPACE_BEFORE )
4227 rSh.ExtendSelection( false );
4228 else if ( cWord == SwWrtShell::WORD_SPACE_AFTER )
4229 rSh.ExtendSelection();
4230 rSrcSh.DelRight();
4231 }
4232 }
4233 rSrcSh.KillPams();
4235
4236 /* after dragging a table selection inside one shell
4237 set cursor to the drop position. */
4238 if( &rSh == &rSrcSh && ( bTableSel || rSh.IsBlockMode() ) )
4239 {
4240 rSrcSh.CalcLayout();
4241 rSrcSh.SwCursorShell::SetCursor(rDragPt);
4242 rSrcSh.GetCursor()->SetMark();
4243 }
4244 }
4245
4246 if( bRet && !bTableSel && !bFrameSel )
4247 {
4248 if( (bInWrd || bEndWrd) &&
4249 (cWord == SwWrtShell::WORD_SPACE_AFTER ||
4251 {
4252 if ( bSttWrd || (bInWrd && !bEndWrd))
4253 rSh.SwEditShell::Insert(' ', bIsXSelection);
4254 if ( !bSttWrd || (bInWrd && !bSttPara) )
4255 {
4256 rSh.SwapPam();
4257 if ( !bSttWrd )
4258 rSh.SwEditShell::Insert(' ', bIsXSelection);
4259 rSh.SwapPam();
4260 }
4261 }
4262
4263 if( bIsXSelection )
4264 {
4265 if( &rSrcSh == &rSh && !rSh.IsAddMode() )
4266 {
4267 rSh.SwCursorShell::DestroyCursor();
4268 rSh.GoPrevCursor();
4269 }
4270 else
4271 {
4272 rSh.SwapPam();
4273 rSh.SwCursorShell::ClearMark();
4274 }
4275 }
4276 else
4277 {
4278 if( rSh.IsAddMode() )
4279 rSh.SwCursorShell::CreateCursor();
4280 else
4281 {
4282 // turn on selection mode
4283 rSh.SttSelect();
4284 rSh.EndSelect();
4285 }
4286 }
4287 }
4288 else if ( bRet && bTableMove )
4289 {
4290 SfxDispatcher* pDispatch = rSrcSh.GetView().GetViewFrame()->GetDispatcher();
4291 pDispatch->Execute(FN_TABLE_DELETE_TABLE, SfxCallMode::SYNCHRON);
4292 }
4293
4294 if( bRet && bMove && bFrameSel )
4295 rSrcSh.LeaveSelFrameMode();
4296
4297 if( rSrcSh.GetDoc() != rSh.GetDoc() )
4298 rSrcSh.EndUndo();
4299 rSh.EndUndo();
4300
4301 // put the shell in the right state
4302 if( &rSrcSh != &rSh && ( rSh.IsFrameSelected() || rSh.IsObjSelected() ))
4303 rSh.EnterSelFrameMode();
4304
4305 rSrcSh.EndAction();
4306 rSh.EndAction();
4307 return true;
4308}
4309
4310// Interfaces for Selection
4312 const SwFrameShell * _pCreatorView )
4313{
4314 SwModule *pMod = SW_MOD();
4316
4317 pNew->m_pCreatorView = _pCreatorView;
4318
4319 pMod->m_pXSelection = pNew.get();
4320 pNew->CopyToPrimarySelection();
4321}
4322
4324 const SwFrameShell * _pCreatorView)
4325{
4326 SwModule *pMod = SW_MOD();
4327 if( pMod->m_pXSelection &&
4328 ((!pMod->m_pXSelection->m_pWrtShell) || (pMod->m_pXSelection->m_pWrtShell == &rSh)) &&
4329 (!_pCreatorView || (pMod->m_pXSelection->m_pCreatorView == _pCreatorView)) )
4330 {
4332 }
4333}
4334
4335const Sequence< sal_Int8 >& SwTransferable::getUnoTunnelId()
4336{
4337 static const comphelper::UnoIdInit theSwTransferableUnoTunnelId;
4338 return theSwTransferableUnoTunnelId.getSeq();
4339}
4340
4341sal_Int64 SwTransferable::getSomething( const Sequence< sal_Int8 >& rId )
4342{
4343 return comphelper::getSomethingImpl(rId, this,
4345}
4346
4348{
4349 return comphelper::getFromUnoTunnel<SwTransferable>(rData.GetTransferable());
4350}
4351
4352SwTransferDdeLink::SwTransferDdeLink( SwTransferable& rTrans, SwWrtShell& rSh )
4353 : m_rTransfer(rTrans)
4354 , m_pDocShell(nullptr)
4355 , m_nOldTimeOut(0)
4356 , m_bDelBookmark(false)
4357 , m_bInDisconnect(false)
4358{
4359 // we only end up here with table- or text selection
4361 {
4362 SwFrameFormat* pFormat = rSh.GetTableFormat();
4363 if( pFormat )
4364 m_sName = pFormat->GetName();
4365 }
4366 else
4367 {
4368 // creating a temp. bookmark without undo
4369 bool bUndo = rSh.DoesUndo();
4370 rSh.DoUndo( false );
4371 bool bIsModified = rSh.IsModified();
4372
4373 ::sw::mark::IMark* pMark = rSh.SetBookmark(
4374 vcl::KeyCode(),
4375 OUString(),
4377 if(pMark)
4378 {
4379 m_sName = pMark->GetName();
4380 m_bDelBookmark = true;
4381 if( !bIsModified )
4382 rSh.ResetModified();
4383 }
4384 else
4385 m_sName.clear();
4386 rSh.DoUndo( bUndo );
4387 }
4388
4389 if( m_sName.isEmpty() ||
4390 nullptr == ( m_pDocShell = rSh.GetDoc()->GetDocShell() ))
4391 return;
4392
4393 // then we create our "server" and connect to it
4394 m_xRefObj = m_pDocShell->DdeCreateLinkSource( m_sName );
4395 if( m_xRefObj.is() )
4396 {
4397 m_xRefObj->AddConnectAdvise( this );
4398 m_xRefObj->AddDataAdvise( this,
4399 OUString(),
4400 ADVISEMODE_NODATA | ADVISEMODE_ONLYONCE );
4401 m_nOldTimeOut = m_xRefObj->GetUpdateTimeout();
4402 m_xRefObj->SetUpdateTimeout( 0 );
4403 }
4404}
4405
4406SwTransferDdeLink::~SwTransferDdeLink()
4407{
4408 if( m_xRefObj.is() )
4409 Disconnect( true );
4410}
4411
4412::sfx2::SvBaseLink::UpdateResult SwTransferDdeLink::DataChanged( const OUString& ,
4413 const uno::Any& )
4414{
4415 // well, that's it with the link
4416 if( !m_bInDisconnect )
4417 {
4418 if( FindDocShell() && m_pDocShell->GetView() )
4419 m_rTransfer.RemoveDDELinkFormat( m_pDocShell->GetView()->GetEditWin() );
4420 Disconnect( false );
4421 }
4422 return SUCCESS;
4423}
4424
4425bool SwTransferDdeLink::WriteData( SvStream& rStrm )
4426{
4427 if( !m_xRefObj.is() || !FindDocShell() )
4428 return false;
4429
4430 rtl_TextEncoding eEncoding = osl_getThreadTextEncoding();
4431 const OString aAppNm(OUStringToOString(
4432 Application::GetAppName(), eEncoding));
4433 const OString aTopic(OUStringToOString(
4434 m_pDocShell->GetTitle(SFX_TITLE_FULLNAME), eEncoding));
4435 const OString aName(OUStringToOString(m_sName, eEncoding));
4436
4437 std::unique_ptr<char[]> pMem(new char[ aAppNm.getLength() + aTopic.getLength() + aName.getLength() + 4 ]);
4438
4439 sal_Int32 nLen = aAppNm.getLength();
4440 memcpy( pMem.get(), aAppNm.getStr(), nLen );
4441 pMem[ nLen++ ] = 0;
4442 memcpy( pMem.get() + nLen, aTopic.getStr(), aTopic.getLength() );
4443 nLen = nLen + aTopic.getLength();
4444 pMem[ nLen++ ] = 0;
4445 memcpy( pMem.get() + nLen, aName.getStr(), aName.getLength() );
4446 nLen = nLen + aName.getLength();
4447 pMem[ nLen++ ] = 0;
4448 pMem[ nLen++ ] = 0;
4449
4450 rStrm.WriteBytes( pMem.get(), nLen );
4451 pMem.reset();
4452
4453 IDocumentMarkAccess* const pMarkAccess = m_pDocShell->GetDoc()->getIDocumentMarkAccess();
4454 IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(m_sName);
4455 if(ppMark != pMarkAccess->getAllMarksEnd()
4457 {
4458 // the mark is still a DdeBookmark
4459 // we replace it with a Bookmark, so it will get saved etc.
4460 ::sw::mark::IMark* const pMark = *ppMark;
4461 ::sfx2::SvLinkSource* p = m_xRefObj.get();
4462 SwServerObject& rServerObject = dynamic_cast<SwServerObject&>(*p);
4463
4464 // collecting state of old mark
4465 SwPaM aPaM(pMark->GetMarkStart());
4466 *aPaM.GetPoint() = pMark->GetMarkStart();
4467 if(pMark->IsExpanded())
4468 {
4469 aPaM.SetMark();
4470 *aPaM.GetMark() = pMark->GetMarkEnd();
4471 }
4472 OUString sMarkName = pMark->GetName();
4473
4474 // remove mark
4475 rServerObject.SetNoServer(); // this removes the connection between SwServerObject and mark
4476 // N.B. ppMark was not loaded from file and cannot have xml:id
4477 pMarkAccess->deleteMark(ppMark, false);
4478
4479 // recreate as Bookmark
4480 ::sw::mark::IMark* const pNewMark = pMarkAccess->makeMark(
4481 aPaM,
4482 sMarkName,
4484 ::sw::mark::InsertMode::New);
4485 rServerObject.SetDdeBookmark(*pNewMark);
4486 }
4487
4488 m_bDelBookmark = false;
4489 return true;
4490}
4491
4492void SwTransferDdeLink::Disconnect( bool bRemoveDataAdvise )
4493{
4494 // don't accept DataChanged anymore, when already in Disconnect!
4495 // (DTOR from Bookmark sends a DataChanged!)
4496 bool bOldDisconnect = m_bInDisconnect;
4497 m_bInDisconnect = true;
4498
4499 // destroy the unused bookmark again (without Undo!)?
4500 if( m_bDelBookmark && m_xRefObj.is() && FindDocShell() )
4501 {
4502 SwDoc* pDoc = m_pDocShell->GetDoc();
4503 ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
4504
4505 // #i58448#
4506 Link<bool,void> aSavedOle2Link( pDoc->GetOle2Link() );
4507 pDoc->SetOle2Link( Link<bool,void>() );
4508
4509 bool bIsModified = pDoc->getIDocumentState().IsModified();
4510
4511 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
4512 pMarkAccess->deleteMark(pMarkAccess->findMark(m_sName), false);
4513
4514 if( !bIsModified )
4516 // #i58448#
4517 pDoc->SetOle2Link( aSavedOle2Link );
4518
4519 m_bDelBookmark = false;
4520 }
4521
4522 if( m_xRefObj.is() )
4523 {
4524 m_xRefObj->SetUpdateTimeout( m_nOldTimeOut );
4525 m_xRefObj->RemoveConnectAdvise( this );
4526 if( bRemoveDataAdvise )
4527 // in a DataChanged the SelectionObject must NEVER be deleted
4528 // is already handled by the base class
4529 // (ADVISEMODE_ONLYONCE!!!!)
4530 // but always in normal Disconnect!
4531 m_xRefObj->RemoveAllDataAdvise( this );
4532 m_xRefObj.clear();
4533 }
4534 m_bInDisconnect = bOldDisconnect;
4535}
4536
4537bool SwTransferDdeLink::FindDocShell()
4538{
4539 SfxObjectShell* pTmpSh = SfxObjectShell::GetFirst( checkSfxObjectShell<SwDocShell> );
4540 while( pTmpSh )
4541 {
4542 if( pTmpSh == m_pDocShell ) // that's what we want to have
4543 {
4544 if( m_pDocShell->GetDoc() )
4545 return true;
4546 break; // the Doc is not there anymore, so leave!
4547 }
4548 pTmpSh = SfxObjectShell::GetNext( *pTmpSh, checkSfxObjectShell<SwDocShell> );
4549 }
4550
4551 m_pDocShell = nullptr;
4552 return false;
4553}
4554
4555void SwTransferDdeLink::Closed()
4556{
4557 if( !m_bInDisconnect && m_xRefObj.is() )
4558 {
4559 m_xRefObj->RemoveAllDataAdvise( this );
4560 m_xRefObj->RemoveConnectAdvise( this );
4561 m_xRefObj.clear();
4562 }
4563}
4564
4565/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ CheckPosInFly
check if target position is in fly anchored at source range
@ On
RedlineFlags on.
@ NONE
no RedlineFlags
@ Ignore
ignore Redlines
@ GRAPHIC_CAP
@ UndoArg1
Definition: SwRewriter.hxx:29
Reference< XInputStream > xStream
AnyEventRef aEvent
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
static OUString GetAppName()
bool IsEmpty() const
bool IsError() const
size_t Count() const
OUString GetFile(size_t nIndex) const
rtl::Reference< SdrObject > CreateXFormsControl(const svx::OXFormsDescriptor &_rDesc)
rtl::Reference< SdrObject > CreateFieldControl(std::u16string_view rFieldDesc) const
static GraphicFilter & GetGraphicFilter()
static ErrCode LoadGraphic(const OUString &rPath, const OUString &rFilter, Graphic &rGraphic, GraphicFilter *pFilter=nullptr, sal_uInt16 *pDeterminedFormat=nullptr)
Degree10 getRotation() const
bool read(Graphic const &rGraphic)
void SetPrefMapMode(const MapMode &rPrefMapMode)
bool IsSupportedGraphic() const
const GDIMetaFile & GetGDIMetaFile() const
GraphicType GetType() const
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
void SetPrefSize(const Size &rPrefSize)
virtual bool CopyRange(SwPaM &rPam, SwPosition &rPos, SwCopyFlags flags) const =0
Copy a selected content range to a position.
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
virtual void LockExpFields()=0
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
Provides access to the marks of a document.
virtual const_iterator_t getAllMarksEnd() const =0
returns a STL-like random access iterator to the end of the sequence of marks.
virtual const_iterator_t findMark(const OUString &rMark) const =0
Finds a mark by name.
virtual ::sw::mark::IMark * makeMark(const SwPaM &rPaM, const OUString &rProposedName, MarkType eMark, ::sw::mark::InsertMode eMode, SwPosition const *pSepPos=nullptr)=0
Generates a new mark in the document for a certain selection.
virtual std::unique_ptr< ILazyDeleter > deleteMark(const IDocumentMarkAccess::const_iterator_t &ppMark, bool isMoveNodes)=0
Deletes a mark.
virtual const_iterator_t getAllMarksBegin() const =0
returns a STL-like random access iterator to the begin of the sequence of marks.
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:476
static bool IsRedlineOn(const RedlineFlags eM)
virtual void SetRedlineFlags_intern(RedlineFlags eMode)=0
Set a new redline mode.
virtual void SetRedlineFlags(RedlineFlags eMode)=0
Set a new redline mode.
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
virtual void ResetModified()=0
virtual bool IsModified() const =0
Changes of document?
const OUString & GetDescription() const
const OUString & GetURL() const
const OUString & GetImageURL() const
const OUString & GetTargetFrame() const
const OUString & GetTargetURL() const
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool SetSmartURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
OUString GetFull() const
SvStream * IsValid(SvStream &)
bool Paste(const TransferableDataHelper &rData)
Definition: content.cxx:5374
RegionMode GetDefaultDragType() const
Definition: navicont.hxx:49
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
void SetReadUTF8(bool bSet)
Definition: shellio.hxx:252
void SetIgnoreHTMLComments(bool bSet)
Definition: shellio.hxx:260
SwgReaderOption & GetReaderOpt()
Definition: shellio.hxx:233
sal_uInt16 GetMasterPageCount() const
const SfxItemPool & GetItemPool() const
const SdrPage * GetPage(sal_uInt16 nPgNum) const
sal_uInt16 GetPageCount() const
SdrObject * Next()
bool IsMore() const
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
void SetMergedItem(const SfxPoolItem &rItem)
static bool ShowPasteInfo(SfxClassificationCheckPasteResult eResult)
static SfxClassificationCheckPasteResult CheckPaste(const css::uno::Reference< css::document::XDocumentProperties > &xSource, const css::uno::Reference< css::document::XDocumentProperties > &xDestination)
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
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 * >())
bool IsLocked() const
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
const INetURLObject & GetURLObject() const
SvStream * GetInStream()
bool Is() const
comphelper::EmbeddedObjectContainer & GetEmbeddedObjectContainer() const
css::uno::Reference< css::document::XDocumentProperties > getDocProperties() const
void FillTransferableObjectDescriptor(TransferableObjectDescriptor &rDesc) const
virtual bool DoSaveCompleted(SfxMedium *pNewStor=nullptr, bool bRegisterRecent=true)
static OUString CreateShellID(const SfxObjectShell *pShell)
virtual void SetVisArea(const tools::Rectangle &rVisArea)
bool isContentExtractionLocked() const
static SfxObjectShell * GetNext(const SfxObjectShell &rPrev, const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
bool IsReadOnly() const
SfxMedium * GetMedium() const
bool DoSaveObjectAs(SfxMedium &rNewStor, bool bCommit)
void SetupStorage(const css::uno::Reference< css::embed::XStorage > &xStorage, sal_Int32 nVersion, bool bTemplate) const
static SfxObjectShell * GetFirst(const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
SfxObjectCreateMode GetCreateMode() const
SfxDispatcher * GetDispatcher()
SfxViewFrame * GetViewFrame() const
virtual SfxObjectShell * GetObjectShell() override
constexpr tools::Long Height() const
constexpr tools::Long Width() const
static bool GetFormatDataFlavor(SotClipboardFormatId nFormat, css::datatransfer::DataFlavor &rFlavor)
static SotClipboardFormatId GetFormat(const css::datatransfer::DataFlavor &rFlavor)
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)
static SotClipboardFormatId GetFormatID(css::uno::Reference< css::embed::XStorage > const &xStorage)
static bool GetEmbeddedName(const TransferableDataHelper &rData, OUString &_rName, OUString &_rSource, SotClipboardFormatId const &_nFormat)
void SetEndian(SvStreamEndian SvStreamEndian)
std::size_t WriteBytes(const void *pData, std::size_t nSize)
ErrCode GetError() const
void AddClipbrdFormat(SotClipboardFormatId nId)
sal_uInt16 Count() const
sal_uInt32 GetHeight() const
void SetCharSet(rtl_TextEncoding nVal)
Definition: shellio.hxx:73
virtual sal_Int32 Len() const
Definition: node.cxx:1263
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2251
void ShowCursor()
Definition: crsrsh.cxx:2410
void StartAction()
Definition: crsrsh.cxx:226
const SwTableNode * IsCursorInTable() const
Definition: crsrsh.hxx:909
bool GoPrevCursor()
go to the previous SSelection
Definition: crsrsh.cxx:1376
void SwapPam()
Definition: crsrsh.cxx:976
const SwRect & GetCharRect() const
Definition: crsrsh.hxx:532
const Link< LinkParamNone *, void > & GetChgLnk() const
Definition: crsrsh.hxx:500
Point & GetCursorDocPos() const
Definition: crsrsh.hxx:919
bool IsInWord(sal_Int16 nWordType=css::i18n::WordType::ANYWORD_IGNOREWHITESPACES) const
Definition: crstrvl1.cxx:36
void HideCursor()
Definition: crsrsh.cxx:2429
::sw::mark::IMark * SetBookmark(const vcl::KeyCode &, const OUString &rName, IDocumentMarkAccess::MarkType eMark=IDocumentMarkAccess::MarkType::BOOKMARK)
Definition: crbm.cxx:78
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
bool ExtendSelection(bool bEnd=true, sal_Int32 nCount=1)
extend current SSelection by n characters
Definition: crsrsh.cxx:2641
bool IsSttPara() const
Definition: crsrsh.cxx:1095
bool ShouldWait() const
Should WaitPtr be switched on for the clipboard?
Definition: crsrsh.cxx:3066
bool GoNextCursor()
go to the next SSelection
Definition: crsrsh.cxx:1357
bool IsSelection() const
Definition: crsrsh.hxx:899
SwPaM * CreateCursor()
delete the current cursor and make the following into the current
Definition: crsrsh.cxx:123
bool HasMark() const
Definition: crsrsh.hxx:897
void EndAction(const bool bIdleEnd=false)
Definition: crsrsh.cxx:243
bool TestCurrPam(const Point &rPt, bool bTstHit=false)
Search in the selected area for a Selection that covers the given point.
Definition: crsrsh.cxx:991
const SwShellTableCursor * GetTableCursor() const
Definition: crsrsh.hxx:661
void CallChgLnk()
Definition: crsrsh.cxx:2544
void DestroyCursor()
transform TableCursor to normal cursor, nullify Tablemode
Definition: crsrsh.cxx:151
void SetChgLnk(const Link< LinkParamNone *, void > &rLnk)
Definition: crsrsh.hxx:499
void KillPams()
Definition: crsrsh.cxx:1022
bool HasReadonlySel(bool isReplace=false) const
Definition: crsrsh.cxx:3359
bool GetContentAtPos(const Point &rPt, SwContentAtPos &rContentAtPos, bool bSetCursor=false, SwRect *pFieldRect=nullptr)
Definition: crstrvl.cxx:1299
bool IsTableMode() const
Definition: crsrsh.hxx:659
bool IsStartWord(sal_Int16 nWordType=css::i18n::WordType::ANYWORD_IGNOREWHITESPACES) const
Definition: crstrvl1.cxx:27
void SaveTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:867
void UnSetVisibleCursor()
Definition: crsrsh.hxx:934
OUString const & GetCmd() const
Definition: ddefld.cxx:195
SfxLinkUpdateMode GetType() const
Definition: ddefld.hxx:82
SwDoc & GetDoc()
Document is created after calling Read(...).
Definition: docfact.cxx:33
Definition: doc.hxx:194
static SwTableNode * IsInTable(const SwNode &)
Definition: ndtbl.cxx:219
void ReplaceDefaults(const SwDoc &rSource)
Definition: docnew.cxx:847
void SetClipBoard(bool bNew)
Definition: doc.hxx:973
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:400
void ReplaceCompatibilityOptions(const SwDoc &rSource)
Definition: docnew.cxx:877
bool InsertGlossary(SwTextBlocks &rBlock, const OUString &rEntry, SwPaM &rPaM, SwCursorShell *pShell=nullptr)
inserts an AutoText block
Definition: docglos.cxx:131
void SetOle2Link(const Link< bool, void > &rLink)
Definition: doc.hxx:1335
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:321
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:150
SwNodes & GetNodes()
Definition: doc.hxx:417
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:363
void SetRowNotTracked(const SwCursor &rCursor, const SvxPrintItem &rNotTracked, bool bAll=false, bool bIns=false)
rNotTracked = false means that the row was deleted or inserted with its tracked cell content bAll: de...
Definition: ndtbl1.cxx:581
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:341
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:1365
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1814
const Link< bool, void > & GetOle2Link() const
Definition: doc.hxx:1336
OUString GetUniqueSectionName(const OUString *pChkStr=nullptr) const
Definition: ndsect.cxx:1399
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:161
const SfxObjectShellLock & GetTmpDocShell() const
Definition: doc.hxx:1366
void ReplaceStyles(const SwDoc &rSource, bool bIncludePageStyles=true)
Definition: docfmt.cxx:1549
::sw::MetaFieldManager & GetMetaFieldManager()
Definition: doc.cxx:129
SwDocShell * GetDocShell()
Definition: doc.hxx:1359
sal_uInt16 GetCntType() const
Determine form of content. Return Type at CurrentCursor->SPoint.
Definition: edws.cxx:126
virtual void CalcLayout() override
To enable set up of StartActions and EndActions.
Definition: edws.cxx:108
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
size_t GetFieldTypeCount(SwFieldIds nResId=SwFieldIds::Unknown) const
count field types with a ResId, if SwFieldIds::Unknown count all
Definition: edfld.cxx:43
bool IsModified() const
Changes in document?
Definition: edws.cxx:65
SwSection const * InsertSection(SwSectionData &rNewData, SfxItemSet const *const =nullptr)
Definition: edsect.cxx:35
void DelINetAttrWithText()
If cursor is in an INetAttribute it will be deleted completely including the descriptive text (needed...
Definition: editsh.cxx:737
void GetGrfNms(OUString *pGrfName, OUString *pFltName, const SwFlyFrameFormat *=nullptr) const
Returns the name and the filter name of a graphic if the pointer is on a graphic.
Definition: editsh.cxx:304
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
bool Delete(bool isArtificialSelection=false)
Delete content of all ranges.
Definition: eddel.cxx:125
void RemoveFieldType(size_t nField)
delete field type
Definition: edfld.cxx:94
OUString Calculate()
Calculates selection.
Definition: editsh.cxx:530
SwFrameFormat * GetTableFormat()
Definition: edws.cxx:183
bool InsertURL(const SwFormatINetFormat &rFormat, const OUString &rStr, bool bKeepSelection=false)
Definition: editsh.cxx:633
void InsertDDETable(const SwInsertTableOptions &rInsTableOpts, SwDDEFieldType *pDDEType, sal_uInt16 nRows, sal_uInt16 nCols)
Definition: edtab.cxx:223
SwFieldType * GetFieldType(size_t nField, SwFieldIds nResId=SwFieldIds::Unknown) const
get field types with a ResId, if 0 get all
Definition: edfld.cxx:64
void ResetModified()
Definition: edws.cxx:75
SwFieldType * InsertFieldType(const SwFieldType &)
insert field type
Definition: edfld.cxx:338
bool DoesUndo() const
Definition: edws.cxx:203
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
void DoUndo(bool bOn=true)
Undo.
Definition: edws.cxx:200
const Graphic * GetGraphic(bool bWait=true) const
Definition: editsh.cxx:238
void EndAllAction()
Definition: edws.cxx:97
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:294
static tools::Long GetDDStartPosX()
Definition: edtwin.hxx:250
static tools::Long GetDDStartPosY()
Definition: edtwin.hxx:251
void DragFinished()
Definition: edtdd.cxx:151
void StopInsFrame()
Definition: edtwin.cxx:752
bool SetFlyFrameAttr(SfxItemSet &rSet)
Definition: fefly1.cxx:1103
FlyProtectFlags IsSelObjProtected(FlyProtectFlags eType) const
Which Protection is set at selected object?
Definition: feshview.cxx:2701
comphelper::OInterfaceContainerHelper3< css::text::XPasteListener > & GetPasteListeners()
Definition: fecopy.cxx:1225
OUString GetFlyName() const
Definition: fefly1.cxx:1481
bool Paste(SwDoc &rClpDoc, bool bNestedTable=false)
Definition: fecopy.cxx:832
bool IsFrameSelected() const
Definition: feshview.cxx:1253
void SetTableInsertMode(SwTable::SearchType eFlag)
Definition: fesh.hxx:649
Size GetObjSize() const
Definition: feshview.cxx:2390
void DeleteTable()
Definition: fetab.cxx:317
void SetTableCopied(bool bCopied)
Definition: fesh.hxx:652
const SwFrameFormat * GetFormatFromObj(const Point &rPt, SwRect **pRectToFill=nullptr) const
Definition: fefly1.cxx:1620
bool DeleteTableSel()
Current selection, may be whole table.
Definition: fetab.cxx:1392
ObjCntType GetObjCntTypeOfSelection() const
Definition: fefly1.cxx:1769
void ReplaceSdrObj(const OUString &rGrfName, const Graphic *pGrf)
Definition: fefly1.cxx:1797
bool GetDrawObjGraphic(SotClipboardFormatId nFormat, Graphic &rGrf) const
Get selected DrawObj as graphics (MetaFile/Bitmap).
Definition: fecopy.cxx:1227
void Copy(SwDoc &rClpDoc, const OUString *pNewClpText=nullptr)
Copy and Paste methods for internal clipboard.
Definition: fecopy.cxx:77
SwRect GetObjRect() const
For adjustment of PosAttr when anchor changes.
Definition: fefly1.cxx:1298
bool HasWholeTabSelection() const
Definition: fetab.cxx:958
bool GetFlyFrameAttr(SfxItemSet &rSet) const
Definition: fefly1.cxx:1061
size_t IsObjSelected() const
Definition: feshview.cxx:1245
bool SelectObj(const Point &rSelPt, sal_uInt8 nFlag=0, SdrObject *pObj=nullptr)
If an object has been given, exactly this object is selected (instead of searching over position).
Definition: feshview.cxx:177
bool IsInsideSelectedObj(const Point &rPt)
returns enum values
Definition: feshview.cxx:1363
SwTable::SearchType GetTableInsertMode() const
Definition: fesh.hxx:648
bool GetTableCopied() const
Definition: fesh.hxx:651
const SwFrameFormat * GetFlyFrameFormat() const
Get FlyFrameFormat; for UI macro linkage at Flys.
Definition: fefly1.cxx:1270
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:242
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:137
SwFieldIds Which() const
Definition: fldbas.hxx:273
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
const ImageMap * GetMap() const
Definition: fmturl.hxx:68
const OUString & GetName() const
Definition: fmturl.hxx:71
void SetName(const OUString &rNm)
Definition: fmturl.hxx:72
const OUString & GetTargetFrameName() const
Definition: fmturl.hxx:65
const OUString & GetURL() const
Definition: fmturl.hxx:66
void SetURL(const OUString &rURL, bool bServerMap)
Definition: atrfrm.cxx:1859
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
const OUString & GetName() const
Definition: format.hxx:131
const SwFormatURL & GetURL(bool=true) const
Definition: fmturl.hxx:78
Style of a layout element.
Definition: frmfmt.hxx:62
static std::shared_ptr< const SfxFilter > GetFileFilter(const OUString &rFileName)
Detect for the given file which filter should be used.
Definition: iodetect.cxx:149
TElementType * Next()
Definition: calbck.hxx:373
TElementType * First()
Definition: calbck.hxx:365
SwTransferable * m_pXSelection
Definition: swmodule.hxx:128
SwTransferable * m_pDragDrop
Definition: swmodule.hxx:128
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:136
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:897
SwNodeOffset GetIndex() const
Definition: node.hxx:312
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:218
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:774
bool IsTextNode() const
Definition: node.hxx:685
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwContentNode * GetContentNode()
Definition: node.hxx:664
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1294
bool UnloadObject()
Definition: ndole.cxx:999
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
SwNode & GetPointNode() const
Definition: pam.hxx:283
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:642
SwDoc & GetDoc() const
Definition: pam.hxx:299
const SwPosition * GetPoint() const
Definition: pam.hxx:261
const SwPosition * Start() const
Definition: pam.hxx:266
Tracks the boundaries of pasted content and notifies listeners.
Definition: swdtflvr.cxx:211
sal_Int32 m_nStartContent
Definition: swdtflvr.cxx:222
SwPasteContext(SwWrtShell &rWrtShell)
Definition: swdtflvr.cxx:1274
SwWrtShell & m_rWrtShell
Definition: swdtflvr.cxx:220
std::optional< SwPaM > m_oPaM
Definition: swdtflvr.cxx:221
ErrCode Read(const Reader &)
Definition: shellio.cxx:91
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Pos(const Point &rNew)
Definition: swrect.hxx:171
tools::Rectangle SVRect() const
Definition: swrect.hxx:292
void AddRule(SwUndoArg eWhat, const OUString &rWith)
Definition: SwRewriter.cxx:25
SAL_DLLPRIVATE void SetProtectFlag(bool const bFlag)
Definition: section.hxx:106
void SetLinkFileName(OUString const &rNew)
Definition: section.hxx:118