1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
22 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
23 #include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
24 #include <com/sun/star/lang/XComponent.hpp>
25 #include <sot/filelist.hxx>
26 #include <editeng/editdata.hxx>
27 #include <svx/xfillit0.hxx>
28 #include <svx/xflclit.hxx>
29 #include <svx/xlnclit.hxx>
30 #include <svx/svdpagv.hxx>
31 #include <sfx2/docfile.hxx>
32 #include <sfx2/mieclip.hxx>
33 #include <svx/svdoole2.hxx>
34 #include <svx/svdograf.hxx>
35 #include <svx/svdundo.hxx>
36 #include <svl/itempool.hxx>
37 #include <sot/formats.hxx>
38 #include <editeng/outliner.hxx>
39 #include <svx/obj3d.hxx>
40 #include <svx/e3dundo.hxx>
41 #include <svx/unomodel.hxx>
42 #include <svx/ImageMapInfo.hxx>
43 #include <unotools/streamwrap.hxx>
44 #include <vcl/graph.hxx>
45 #include <vcl/metaact.hxx>
46 #include <vcl/pdfread.hxx>
47 #include <vcl/TypeSerializer.hxx>
48 #include <svx/svxids.hrc>
49 #include <toolkit/helper/vclunohelper.hxx>
50 #include <svtools/embedhlp.hxx>
51 #include <osl/diagnose.h>
52 #include <DrawDocShell.hxx>
54 #include <tablefunction.hxx>
58 #include <drawdoc.hxx>
60 #include <sdresid.hxx>
61 #include <strings.hrc>
62 #include <SlideSorterViewShell.hxx>
63 #include <unomodel.hxx>
64 #include <ViewClipboard.hxx>
65 #include <sfx2/ipclient.hxx>
66 #include <sfx2/classificationhelper.hxx>
67 #include <comphelper/sequenceashashmap.hxx>
68 #include <comphelper/storagehelper.hxx>
69 #include <comphelper/processfactory.hxx>
70 #include <svx/sdrhittesthelper.hxx>
71 #include <svx/xbtmpit.hxx>
75 using namespace ::com::sun::star
;
76 using namespace ::com::sun::star::lang
;
77 using namespace ::com::sun::star::uno
;
78 using namespace ::com::sun::star::io
;
79 using namespace ::com::sun::star::datatransfer
;
83 #define CHECK_FORMAT_TRANS( _def_Type ) ( ( nFormat == (_def_Type) || nFormat == SotClipboardFormatId::NONE ) && rDataHelper.HasFormat( _def_Type ) )
85 /*************************************************************************
89 \************************************************************************/
93 struct ImpRememberOrigAndClone
101 static SdrObject
* ImpGetClone(std::vector
<ImpRememberOrigAndClone
>& aConnectorContainer
, SdrObject
const * pConnObj
)
103 for(const ImpRememberOrigAndClone
& rImp
: aConnectorContainer
)
105 if(pConnObj
== rImp
.pOrig
)
111 // restrict movement to WorkArea
112 static void ImpCheckInsertPos(Point
& rPos
, const Size
& rSize
, const ::tools::Rectangle
& rWorkArea
)
114 if(rWorkArea
.IsEmpty())
117 ::tools::Rectangle
aMarkRect(Point(rPos
.X() - (rSize
.Width() / 2), rPos
.Y() - (rSize
.Height() / 2)), rSize
);
119 if(aMarkRect
.Contains(rWorkArea
))
122 if(aMarkRect
.Left() < rWorkArea
.Left())
124 rPos
.AdjustX(rWorkArea
.Left() - aMarkRect
.Left() );
127 if(aMarkRect
.Right() > rWorkArea
.Right())
129 rPos
.AdjustX( -(aMarkRect
.Right() - rWorkArea
.Right()) );
132 if(aMarkRect
.Top() < rWorkArea
.Top())
134 rPos
.AdjustY(rWorkArea
.Top() - aMarkRect
.Top() );
137 if(aMarkRect
.Bottom() > rWorkArea
.Bottom())
139 rPos
.AdjustY( -(aMarkRect
.Bottom() - rWorkArea
.Bottom()) );
143 bool View::InsertMetaFile( const TransferableDataHelper
& rDataHelper
, const Point
& rPos
, ImageMap
const * pImageMap
, bool bOptimize
)
147 if( !rDataHelper
.GetGDIMetaFile( SotClipboardFormatId::GDIMETAFILE
, aMtf
) )
150 bool bVector
= false;
153 // check if metafile only contains a pixel image, if so insert a bitmap instead
156 MetaAction
* pAction
= aMtf
.FirstAction();
157 while( pAction
&& !bVector
)
159 switch( pAction
->GetType() )
161 case MetaActionType::POINT
:
162 case MetaActionType::LINE
:
163 case MetaActionType::RECT
:
164 case MetaActionType::ROUNDRECT
:
165 case MetaActionType::ELLIPSE
:
166 case MetaActionType::ARC
:
167 case MetaActionType::PIE
:
168 case MetaActionType::CHORD
:
169 case MetaActionType::POLYLINE
:
170 case MetaActionType::POLYGON
:
171 case MetaActionType::POLYPOLYGON
:
172 case MetaActionType::TEXT
:
173 case MetaActionType::TEXTARRAY
:
174 case MetaActionType::STRETCHTEXT
:
175 case MetaActionType::TEXTRECT
:
176 case MetaActionType::GRADIENT
:
177 case MetaActionType::HATCH
:
178 case MetaActionType::WALLPAPER
:
179 case MetaActionType::EPS
:
180 case MetaActionType::TEXTLINE
:
181 case MetaActionType::FLOATTRANSPARENT
:
182 case MetaActionType::GRADIENTEX
:
183 case MetaActionType::BMPSCALEPART
:
184 case MetaActionType::BMPEXSCALEPART
:
187 case MetaActionType::BMP
:
188 case MetaActionType::BMPSCALE
:
189 case MetaActionType::BMPEX
:
190 case MetaActionType::BMPEXSCALE
:
191 if( aGraphic
.GetType() != GraphicType::NONE
)
195 else switch( pAction
->GetType() )
197 case MetaActionType::BMP
:
199 MetaBmpAction
* pBmpAction
= dynamic_cast< MetaBmpAction
* >( pAction
);
201 aGraphic
= Graphic(BitmapEx(pBmpAction
->GetBitmap()));
204 case MetaActionType::BMPSCALE
:
206 MetaBmpScaleAction
* pBmpScaleAction
= dynamic_cast< MetaBmpScaleAction
* >( pAction
);
207 if( pBmpScaleAction
)
208 aGraphic
= Graphic(BitmapEx(pBmpScaleAction
->GetBitmap()));
211 case MetaActionType::BMPEX
:
213 MetaBmpExAction
* pBmpExAction
= dynamic_cast< MetaBmpExAction
* >( pAction
);
215 aGraphic
= Graphic(pBmpExAction
->GetBitmapEx() );
218 case MetaActionType::BMPEXSCALE
:
220 MetaBmpExScaleAction
* pBmpExScaleAction
= dynamic_cast< MetaBmpExScaleAction
* >( pAction
);
221 if( pBmpExScaleAction
)
222 aGraphic
= Graphic( pBmpExScaleAction
->GetBitmapEx() );
231 pAction
= aMtf
.NextAction();
235 // it is not a vector metafile but it also has no graphic?
236 if( !bVector
&& (aGraphic
.GetType() == GraphicType::NONE
) )
239 // restrict movement to WorkArea
240 Point
aInsertPos( rPos
);
241 Size aImageSize
= bVector
? aMtf
.GetPrefSize() : aGraphic
.GetSizePixel();
242 ImpCheckInsertPos(aInsertPos
, aImageSize
, GetWorkArea());
245 aGraphic
= Graphic( aMtf
);
247 aGraphic
.SetPrefMapMode( aMtf
.GetPrefMapMode() );
248 aGraphic
.SetPrefSize( aMtf
.GetPrefSize() );
249 InsertGraphic( aGraphic
, mnAction
, aInsertPos
, nullptr, pImageMap
);
254 bool View::InsertData( const TransferableDataHelper
& rDataHelper
,
255 const Point
& rPos
, sal_Int8
& rDnDAction
, bool bDrag
,
256 SotClipboardFormatId nFormat
, sal_uInt16 nPage
, SdrLayerID nLayer
)
259 mnAction
= rDnDAction
;
260 mbIsDropAllowed
= false;
262 bool bLink
= ( ( mnAction
& DND_ACTION_LINK
) != 0 );
263 bool bCopy
= ( ( ( mnAction
& DND_ACTION_COPY
) != 0 ) || bLink
);
264 SdrInsertFlags nPasteOptions
= SdrInsertFlags::SETDEFLAYER
;
266 if (mpViewSh
!= nullptr)
268 OSL_ASSERT (mpViewSh
->GetViewShell()!=nullptr);
269 SfxInPlaceClient
* pIpClient
= mpViewSh
->GetViewShell()->GetIPClient();
270 if( dynamic_cast< ::sd::slidesorter::SlideSorterViewShell
*>( mpViewSh
) != nullptr
271 || (pIpClient
!=nullptr && pIpClient
->IsObjectInPlaceActive()))
272 nPasteOptions
|= SdrInsertFlags::DONTMARK
;
275 SdrObject
* pPickObj
= nullptr;
278 SdrPageView
* pPV
= nullptr;
279 pPickObj
= PickObj(rPos
, getHitTolLog(), pPV
);
282 SdPage
* pPage
= nullptr;
283 if( nPage
!= SDRPAGE_NOTFOUND
)
284 pPage
= static_cast<SdPage
*>( mrDoc
.GetPage( nPage
) );
286 SdTransferable
* pOwnData
= nullptr;
287 SdTransferable
* pImplementation
= SdTransferable::getImplementation( rDataHelper
.GetTransferable() );
289 if(pImplementation
&& (rDnDAction
& DND_ACTION_LINK
))
291 // suppress own data when it's intention is to use it as fill information
292 pImplementation
= nullptr;
295 bool bSelfDND
= false;
297 // try to get own transfer data
298 if( pImplementation
)
300 SdModule
* mod
= SdModule::get();
301 if (mod
->pTransferClip
== pImplementation
)
302 pOwnData
= mod
->pTransferClip
;
303 else if (mod
->pTransferDrag
== pImplementation
)
305 pOwnData
= mod
->pTransferDrag
;
308 else if (mod
->pTransferSelection
== pImplementation
)
309 pOwnData
= mod
->pTransferSelection
;
312 const bool bGroupUndoFromDragWithDrop
= bSelfDND
&& mpDragSrcMarkList
&& IsUndoEnabled();
313 if (bGroupUndoFromDragWithDrop
)
315 OUString
aStr(SdResId(STR_UNDO_DRAGDROP
));
316 BegUndo(aStr
+ " " + mpDragSrcMarkList
->GetMarkDescription());
320 std::unique_ptr
<ImageMap
> pImageMap
;
321 if (!pOwnData
&& rDataHelper
.HasFormat(SotClipboardFormatId::SVIM
))
323 if (std::unique_ptr
<SvStream
> xStm
= rDataHelper
.GetSotStorageStream( SotClipboardFormatId::SVIM
) )
325 pImageMap
.reset(new ImageMap
);
326 // mba: clipboard always must contain absolute URLs (could be from alien source)
327 pImageMap
->Read( *xStm
);
332 // check special cases for pasting table formats as RTL
333 if( !bLink
&& (nFormat
== SotClipboardFormatId::NONE
|| (nFormat
== SotClipboardFormatId::RTF
) || (nFormat
== SotClipboardFormatId::RICHTEXT
)) )
335 // if the object supports rtf and there is a table involved, default is to create a table
336 bool bIsRTF
= rDataHelper
.HasFormat(SotClipboardFormatId::RTF
);
337 if( ( bIsRTF
|| rDataHelper
.HasFormat( SotClipboardFormatId::RICHTEXT
) )
338 && ! rDataHelper
.HasFormat( SotClipboardFormatId::DRAWING
) )
340 auto nFormatId
= bIsRTF
? SotClipboardFormatId::RTF
: SotClipboardFormatId::RICHTEXT
;
341 if (std::unique_ptr
<SvStream
> xStm
= rDataHelper
.GetSotStorageStream(nFormatId
))
346 while (xStm
->ReadLine(aLine
))
348 size_t x
= std::string_view(aLine
).find( "\\trowd" );
349 if (x
!= std::string_view::npos
)
352 nFormat
= bIsRTF
? SotClipboardFormatId::RTF
: SotClipboardFormatId::RICHTEXT
;
360 // Changed the whole decision tree to be dependent of bReturn as a flag that
361 // the work was done; this allows to check multiple formats and not just fail
362 // when a CHECK_FORMAT_TRANS(*format*) detected format does not work. This is
363 // e.g. necessary for SotClipboardFormatId::BITMAP
365 bool bReturn
= false;
368 // Paste only if SfxClassificationHelper recommends so.
369 const SfxObjectShellRef
& pSource
= pOwnData
->GetDocShell();
370 SfxObjectShell
* pDestination
= mrDoc
.GetDocSh();
371 if (pSource
.is() && pDestination
)
373 SfxClassificationCheckPasteResult eResult
= SfxClassificationHelper::CheckPaste(pSource
->getDocProperties(), pDestination
->getDocProperties());
374 if (!SfxClassificationHelper::ShowPasteInfo(eResult
))
379 if( !bReturn
&& pOwnData
&& nFormat
== SotClipboardFormatId::NONE
)
381 const View
* pSourceView
= pOwnData
->GetView();
383 if( pOwnData
->GetDocShell().is() && pOwnData
->IsPageTransferable() )
385 mpClipboard
->HandlePageDrop (*pOwnData
);
388 else if( pSourceView
)
390 if( pSourceView
== this )
393 if( nLayer
!= SDRLAYER_NOTFOUND
)
395 // drop on layer tab bar
396 SdrLayerAdmin
& rLayerAdmin
= mrDoc
.GetLayerAdmin();
397 SdrLayer
* pLayer
= rLayerAdmin
.GetLayerPerID( nLayer
);
398 SdrPageView
* pPV
= GetSdrPageView();
399 OUString aLayer
= pLayer
->GetName();
401 if( !pPV
->IsLayerLocked( aLayer
) )
403 pOwnData
->SetInternalMove( true );
404 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
405 rMarkList
.ForceSort();
407 for( size_t nM
= 0; nM
< rMarkList
.GetMarkCount(); ++nM
)
409 SdrMark
* pM
= rMarkList
.GetMark( nM
);
410 SdrObject
* pO
= pM
->GetMarkedSdrObj();
415 if( IsUndoEnabled() )
417 BegUndo(SdResId(STR_MODIFYLAYER
));
418 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoObjectLayerChange(*pO
, pO
->GetLayer(), nLayer
));
422 pO
->SetLayer( nLayer
);
431 SdrPageView
* pPV
= GetSdrPageView();
432 bool bDropOnTabBar
= true;
434 if( !pPage
&& pPV
->GetPage()->GetPageNum() != mnDragSrcPgNum
)
436 pPage
= static_cast<SdPage
*>( pPV
->GetPage() );
437 bDropOnTabBar
= false;
442 // drop on other page
443 OUString aActiveLayer
= GetActiveLayer();
445 if( !pPV
->IsLayerLocked( aActiveLayer
) )
447 if( !IsPresObjSelected() )
449 SdrMarkList
* pMarkList
;
451 if( (mnDragSrcPgNum
!= SDRPAGE_NOTFOUND
) && (mnDragSrcPgNum
!= pPV
->GetPage()->GetPageNum()) )
453 pMarkList
= mpDragSrcMarkList
.get();
457 // actual mark list is used
458 pMarkList
= new SdrMarkList( GetMarkedObjectList());
461 pMarkList
->ForceSort();
463 // stuff to remember originals and clones
464 std::vector
<ImpRememberOrigAndClone
> aConnectorContainer
;
465 size_t nConnectorCount
= 0;
468 // calculate real position of current
469 // source objects, if necessary (#103207)
470 if (pOwnData
== SdModule::get()->pTransferSelection
)
472 ::tools::Rectangle aCurBoundRect
;
474 if( pMarkList
->TakeBoundRect( pPV
, aCurBoundRect
) )
475 aCurPos
= aCurBoundRect
.TopLeft();
477 aCurPos
= pOwnData
->GetStartPos();
480 aCurPos
= pOwnData
->GetStartPos();
482 const Size
aVector( maDropPos
.X() - aCurPos
.X(), maDropPos
.Y() - aCurPos
.Y() );
484 std::unordered_set
<rtl::OUString
> aNameSet
;
485 for(size_t a
= 0; a
< pMarkList
->GetMarkCount(); ++a
)
487 SdrMark
* pM
= pMarkList
->GetMark(a
);
488 rtl::Reference
<SdrObject
> pObj(pM
->GetMarkedSdrObj()->CloneSdrObject(pPage
->getSdrModelFromSdrPage()));
494 // do a NbcMove(...) instead of setting SnapRects here
495 pObj
->NbcMove(aVector
);
498 SdrObject
* pMarkParent
= pM
->GetMarkedSdrObj()->getParentSdrObjectFromSdrObject();
499 if (bCopy
|| (pMarkParent
&& pMarkParent
->IsGroupObject()))
500 pPage
->InsertObjectThenMakeNameUnique(pObj
.get(), aNameSet
);
502 pPage
->InsertObject(pObj
.get());
504 if( IsUndoEnabled() )
506 BegUndo(SdResId(STR_UNDO_DRAGDROP
));
507 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pObj
));
511 ImpRememberOrigAndClone aRem
;
512 aRem
.pOrig
= pM
->GetMarkedSdrObj();
513 aRem
.pClone
= pObj
.get();
514 aConnectorContainer
.push_back(aRem
);
516 if(dynamic_cast< SdrEdgeObj
*>( pObj
.get() ) != nullptr)
521 // try to re-establish connections at clones
524 for(size_t a
= 0; a
< aConnectorContainer
.size(); ++a
)
526 ImpRememberOrigAndClone
* pRem
= &aConnectorContainer
[a
];
528 if(auto pCloneEdge
= dynamic_cast<SdrEdgeObj
*>( pRem
->pClone
))
530 SdrEdgeObj
* pOrigEdge
= static_cast<SdrEdgeObj
*>(pRem
->pOrig
);
532 // test first connection
533 SdrObjConnection
& rConn0
= pOrigEdge
->GetConnection(false);
534 SdrObject
* pConnObj
= rConn0
.GetSdrObject();
537 SdrObject
* pConnClone
= ImpGetClone(aConnectorContainer
, pConnObj
);
540 // if dest obj was cloned, too, re-establish connection
541 pCloneEdge
->ConnectToNode(false, pConnClone
);
542 pCloneEdge
->GetConnection(false).SetConnectorId(rConn0
.GetConnectorId());
546 // set position of connection point of original connected object
547 const SdrGluePointList
* pGlueList
= pConnObj
->GetGluePointList();
550 sal_uInt16 nInd
= pGlueList
->FindGluePoint(rConn0
.GetConnectorId());
552 if(SDRGLUEPOINT_NOTFOUND
!= nInd
)
554 const SdrGluePoint
& rGluePoint
= (*pGlueList
)[nInd
];
555 Point aPosition
= rGluePoint
.GetAbsolutePos(*pConnObj
);
556 aPosition
.AdjustX(aVector
.Width() );
557 aPosition
.AdjustY(aVector
.Height() );
558 pCloneEdge
->SetTailPoint(false, aPosition
);
564 // test second connection
565 SdrObjConnection
& rConn1
= pOrigEdge
->GetConnection(true);
566 pConnObj
= rConn1
.GetSdrObject();
569 SdrObject
* pConnClone
= ImpGetClone(aConnectorContainer
, pConnObj
);
572 // if dest obj was cloned, too, re-establish connection
573 pCloneEdge
->ConnectToNode(true, pConnClone
);
574 pCloneEdge
->GetConnection(true).SetConnectorId(rConn1
.GetConnectorId());
578 // set position of connection point of original connected object
579 const SdrGluePointList
* pGlueList
= pConnObj
->GetGluePointList();
582 sal_uInt16 nInd
= pGlueList
->FindGluePoint(rConn1
.GetConnectorId());
584 if(SDRGLUEPOINT_NOTFOUND
!= nInd
)
586 const SdrGluePoint
& rGluePoint
= (*pGlueList
)[nInd
];
587 Point aPosition
= rGluePoint
.GetAbsolutePos(*pConnObj
);
588 aPosition
.AdjustX(aVector
.Width() );
589 aPosition
.AdjustY(aVector
.Height() );
590 pCloneEdge
->SetTailPoint(true, aPosition
);
599 if( pMarkList
!= mpDragSrcMarkList
.get() )
606 maDropErrorIdle
.Start();
613 pOwnData
->SetInternalMove( true );
614 MoveAllMarked( Size( maDropPos
.X() - pOwnData
->GetStartPos().X(),
615 maDropPos
.Y() - pOwnData
->GetStartPos().Y() ), bCopy
);
623 if( !pSourceView
->IsPresObjSelected() )
625 // model is owned by from AllocModel() created DocShell
626 SdDrawDocument
* pSourceDoc
= static_cast<SdDrawDocument
*>(&pSourceView
->GetModel());
627 pSourceDoc
->CreatingDataObj( pOwnData
);
628 SdDrawDocument
* pModel
= static_cast<SdDrawDocument
*>( pSourceView
->CreateMarkedObjModel().release() );
629 bReturn
= Paste(*pModel
, maDropPos
, pPage
, nPasteOptions
);
632 pPage
= static_cast<SdPage
*>( GetSdrPageView()->GetPage() );
634 OUString aLayout
= pPage
->GetLayoutName();
635 sal_Int32 nPos
= aLayout
.indexOf(SD_LT_SEPARATOR
);
637 aLayout
= aLayout
.copy(0, nPos
);
638 pPage
->SetPresentationLayout( aLayout
, false, false );
639 pSourceDoc
->CreatingDataObj( nullptr );
643 maDropErrorIdle
.Start();
650 SdDrawDocument
* pWorkModel
= const_cast<SdDrawDocument
*>(pOwnData
->GetWorkDocument());
651 SdPage
* pWorkPage
= pWorkModel
->GetSdPage( 0, PageKind::Standard
);
653 pWorkPage
->SetSdrObjListRectsDirty();
655 // #i120393# Clipboard data uses full object geometry range
656 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
658 maDropPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
659 maDropPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
661 // delete pages, that are not of any interest for us
662 for( ::tools::Long i
= pWorkModel
->GetPageCount() - 1; i
>= 0; i
-- )
664 SdPage
* pP
= static_cast< SdPage
* >( pWorkModel
->GetPage( static_cast<sal_uInt16
>(i
) ) );
666 if( pP
->GetPageKind() != PageKind::Standard
)
667 pWorkModel
->DeletePage( static_cast<sal_uInt16
>(i
) );
670 bReturn
= Paste(*pWorkModel
, maDropPos
, pPage
, nPasteOptions
);
673 pPage
= static_cast<SdPage
*>( GetSdrPageView()->GetPage() );
675 OUString aLayout
= pPage
->GetLayoutName();
676 sal_Int32 nPos
= aLayout
.indexOf(SD_LT_SEPARATOR
);
678 aLayout
= aLayout
.copy(0, nPos
);
679 pPage
->SetPresentationLayout( aLayout
, false, false );
683 if(!bReturn
&& CHECK_FORMAT_TRANS( SotClipboardFormatId::PDF
))
685 if (std::unique_ptr
<SvStream
> xStm
= rDataHelper
.GetSotStorageStream( SotClipboardFormatId::PDF
))
687 Point
aInsertPos(rPos
);
689 if (vcl::ImportPDF(*xStm
, aGraphic
))
691 const sal_uInt64
nGraphicContentSize(xStm
->Tell());
693 BinaryDataContainer
aGraphicContent(*xStm
, nGraphicContentSize
);
694 aGraphic
.SetGfxLink(std::make_shared
<GfxLink
>(aGraphicContent
, GfxLinkType::NativePdf
));
696 InsertGraphic(aGraphic
, mnAction
, aInsertPos
, nullptr, nullptr);
702 if(!bReturn
&& CHECK_FORMAT_TRANS( SotClipboardFormatId::DRAWING
))
704 if (std::unique_ptr
<SvStream
> xStm
= rDataHelper
.GetSotStorageStream( SotClipboardFormatId::DRAWING
))
706 DrawDocShellRef xShell
= new DrawDocShell(SfxObjectCreateMode::INTERNAL
, false, DocumentType::Impress
);
709 SdDrawDocument
* pModel
= xShell
->GetDoc();
710 pModel
->InsertPage(pModel
->AllocPage(false).get());
712 Reference
< XComponent
> xComponent
= xShell
->GetModel();
715 css::uno::Reference
< css::io::XInputStream
> xInputStream( new utl::OInputStreamWrapper( *xStm
) );
716 bReturn
= SvxDrawingLayerImport( pModel
, xInputStream
, xComponent
, "com.sun.star.comp.Impress.XMLOasisImporter" );
718 if( pModel
->GetPageCount() == 0 )
720 OSL_FAIL("empty or invalid drawing xml document on clipboard!" );
724 bool bChanged
= false;
726 if (bReturn
&& (mnAction
& (DND_ACTION_MOVE
| DND_ACTION_LINK
)))
728 if( pModel
->GetSdPage( 0, PageKind::Standard
)->GetObjCount() == 1 )
731 SdrObject
* pObj
= pModel
->GetSdPage( 0, PageKind::Standard
)->GetObj( 0 );
732 SdrPageView
* pPV
= nullptr;
733 SdrObject
* pPickObj2
= PickObj(rPos
, getHitTolLog(), pPV
);
735 if( ( mnAction
& DND_ACTION_MOVE
) && pPickObj2
&& pObj
)
738 SdrPage
* pWorkPage
= GetSdrPageView()->GetPage();
739 rtl::Reference
<SdrObject
> pNewObj(pObj
->CloneSdrObject(pWorkPage
->getSdrModelFromSdrPage()));
740 ::tools::Rectangle
aPickObjRect( pPickObj2
->GetCurrentBoundRect() );
741 Size
aPickObjSize( aPickObjRect
.GetSize() );
742 Point
aVec( aPickObjRect
.TopLeft() );
743 ::tools::Rectangle
aObjRect( pNewObj
->GetCurrentBoundRect() );
744 Size
aObjSize( aObjRect
.GetSize() );
746 Fraction
aScaleWidth( aPickObjSize
.Width(), aObjSize
.Width() );
747 Fraction
aScaleHeight( aPickObjSize
.Height(), aObjSize
.Height() );
748 pNewObj
->NbcResize( aObjRect
.TopLeft(), aScaleWidth
, aScaleHeight
);
750 aVec
-= aObjRect
.TopLeft();
751 pNewObj
->NbcMove( Size( aVec
.X(), aVec
.Y() ) );
753 const bool bUndo
= IsUndoEnabled();
756 BegUndo(SdResId(STR_UNDO_DRAGDROP
));
757 pNewObj
->NbcSetLayer( pPickObj2
->GetLayer() );
758 pWorkPage
->InsertObject( pNewObj
.get() );
761 AddUndo( mrDoc
.GetSdrUndoFactory().CreateUndoNewObject( *pNewObj
) );
762 AddUndo( mrDoc
.GetSdrUndoFactory().CreateUndoDeleteObject( *pPickObj2
) );
764 pWorkPage
->RemoveObject( pPickObj2
->GetOrdNum() );
772 mnAction
= DND_ACTION_COPY
;
774 else if( ( mnAction
& DND_ACTION_LINK
) && pPickObj2
&& pObj
&&
775 dynamic_cast< const SdrGrafObj
*>( pPickObj2
) == nullptr &&
776 dynamic_cast< const SdrOle2Obj
*>( pPickObj2
) == nullptr )
778 SfxItemSet
aSet( mrDoc
.GetPool() );
780 // set new attributes to object
781 const bool bUndo
= IsUndoEnabled();
784 BegUndo( SdResId(STR_UNDO_DRAGDROP
) );
785 AddUndo( mrDoc
.GetSdrUndoFactory().CreateUndoAttrObject( *pPickObj2
) );
788 aSet
.Put( pObj
->GetMergedItemSet() );
790 /* Do not take over corner radius. There are
791 gradients (rectangles) in the gallery with corner
792 radius of 0. We should not use that on the
794 aSet
.ClearItem( SDRATTR_CORNER_RADIUS
);
796 const SdrGrafObj
* pSdrGrafObj
= dynamic_cast< const SdrGrafObj
* >(pObj
);
800 // If we have a graphic as source object, use its graphic
801 // content as fill style
802 aSet
.Put(XFillStyleItem(drawing::FillStyle_BITMAP
));
803 aSet
.Put(XFillBitmapItem(pSdrGrafObj
->GetGraphic()));
806 pPickObj2
->SetMergedItemSetAndBroadcast( aSet
);
808 if( DynCastE3dObject( pPickObj2
) && DynCastE3dObject( pObj
) )
810 // handle 3D attribute in addition
811 SfxItemSetFixed
<SID_ATTR_3D_START
, SID_ATTR_3D_END
> aNewSet( mrDoc
.GetPool() );
812 SfxItemSetFixed
<SID_ATTR_3D_START
, SID_ATTR_3D_END
> aOldSet( mrDoc
.GetPool() );
814 aOldSet
.Put(pPickObj2
->GetMergedItemSet());
815 aNewSet
.Put( pObj
->GetMergedItemSet() );
819 std::make_unique
<E3dAttributesUndoAction
>(
820 *static_cast< E3dObject
* >(pPickObj2
),
823 pPickObj2
->SetMergedItemSetAndBroadcast( aNewSet
);
835 SdrPage
* pWorkPage
= pModel
->GetSdPage( 0, PageKind::Standard
);
837 pWorkPage
->SetSdrObjListRectsDirty();
841 // #i120393# Clipboard data uses full object geometry range
842 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
844 maDropPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
845 maDropPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
848 bReturn
= Paste(*pModel
, maDropPos
, pPage
, nPasteOptions
);
856 if(!bReturn
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::SBA_FIELDDATAEXCHANGE
))
860 if (rDataHelper
.GetString(SotClipboardFormatId::SBA_FIELDDATAEXCHANGE
, aOUString
))
862 rtl::Reference
<SdrObject
> pObj
= CreateFieldControl( aOUString
);
866 ::tools::Rectangle
aRect( pObj
->GetLogicRect() );
867 Size
aSize( aRect
.GetSize() );
869 maDropPos
.AdjustX( -( aSize
.Width() >> 1 ) );
870 maDropPos
.AdjustY( -( aSize
.Height() >> 1 ) );
872 aRect
.SetPos( maDropPos
);
873 pObj
->SetLogicRect( aRect
);
874 InsertObjectAtView( pObj
.get(), *GetSdrPageView(), SdrInsertFlags::SETDEFLAYER
);
882 (CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBED_SOURCE
) || CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBEDDED_OBJ
)) &&
883 rDataHelper
.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR
))
885 //TODO/LATER: is it possible that this format is binary?! (from old versions of SO)
886 uno::Reference
< io::XInputStream
> xStm
;
887 TransferableObjectDescriptor aObjDesc
;
889 if (rDataHelper
.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR
, aObjDesc
))
891 OUString aDocShellID
= SfxObjectShell::CreateShellID(mrDoc
.GetDocSh());
892 xStm
= rDataHelper
.GetInputStream(nFormat
!= SotClipboardFormatId::NONE
? nFormat
: SotClipboardFormatId::EMBED_SOURCE
, aDocShellID
);
894 xStm
= rDataHelper
.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ
, aDocShellID
);
899 if( mrDoc
.GetDocSh() && ( mrDoc
.GetDocSh()->GetClassName() == aObjDesc
.maClassName
) )
901 uno::Reference
< embed::XStorage
> xStore( ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm
) );
902 ::sd::DrawDocShellRef
xDocShRef( new ::sd::DrawDocShell( SfxObjectCreateMode::EMBEDDED
, true, mrDoc
.GetDocumentType() ) );
904 // mba: BaseURL doesn't make sense for clipboard functionality
905 SfxMedium
*pMedium
= new SfxMedium( xStore
, OUString() );
906 if( xDocShRef
->DoLoad( pMedium
) )
908 SdDrawDocument
* pModel
= xDocShRef
->GetDoc();
909 SdPage
* pWorkPage
= pModel
->GetSdPage( 0, PageKind::Standard
);
911 pWorkPage
->SetSdrObjListRectsDirty();
915 // #i120393# Clipboard data uses full object geometry range
916 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
918 maDropPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
919 maDropPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
922 // delete pages, that are not of any interest for us
923 for( ::tools::Long i
= pModel
->GetPageCount() - 1; i
>= 0; i
-- )
925 SdPage
* pP
= static_cast< SdPage
* >( pModel
->GetPage( static_cast<sal_uInt16
>(i
) ) );
927 if( pP
->GetPageKind() != PageKind::Standard
)
928 pModel
->DeletePage( static_cast<sal_uInt16
>(i
) );
931 bReturn
= Paste(*pModel
, maDropPos
, pPage
, nPasteOptions
);
934 pPage
= static_cast<SdPage
*>(GetSdrPageView()->GetPage());
936 OUString aLayout
= pPage
->GetLayoutName();
937 sal_Int32 nPos
= aLayout
.indexOf(SD_LT_SEPARATOR
);
939 aLayout
= aLayout
.copy(0, nPos
);
940 pPage
->SetPresentationLayout( aLayout
, false, false );
943 xDocShRef
->DoClose();
950 uno::Reference
< embed::XEmbeddedObject
> xObj
= mpDocSh
->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
953 svt::EmbeddedObjectRef
aObjRef( xObj
, aObjDesc
.mnViewAspect
);
956 if ( aObjDesc
.mnViewAspect
== embed::Aspects::MSOLE_ICON
)
958 if( aObjDesc
.maSize
.Width() && aObjDesc
.maSize
.Height() )
959 aSize
= aObjDesc
.maSize
;
962 MapMode
aMapMode( MapUnit::Map100thMM
);
963 aSize
= aObjRef
.GetSize( &aMapMode
);
969 MapUnit aMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( aObjDesc
.mnViewAspect
) );
970 if( aObjDesc
.maSize
.Width() && aObjDesc
.maSize
.Height() )
972 Size
aTmp(OutputDevice::LogicToLogic(aObjDesc
.maSize
, MapMode(MapUnit::Map100thMM
), MapMode(aMapUnit
)));
973 aSz
.Width
= aTmp
.Width();
974 aSz
.Height
= aTmp
.Height();
975 xObj
->setVisualAreaSize( aObjDesc
.mnViewAspect
, aSz
);
980 aSz
= xObj
->getVisualAreaSize( aObjDesc
.mnViewAspect
);
982 catch( embed::NoVisualAreaSizeException
& )
984 // if the size still was not set the default size will be set later
987 aSize
= Size( aSz
.Width
, aSz
.Height
);
989 if( !aSize
.Width() || !aSize
.Height() )
991 aSize
.setWidth( 14100 );
992 aSize
.setHeight( 10000 );
993 aSize
= OutputDevice::LogicToLogic(Size(14100, 10000), MapMode(MapUnit::Map100thMM
), MapMode(aMapUnit
));
994 aSz
.Width
= aSize
.Width();
995 aSz
.Height
= aSize
.Height();
996 xObj
->setVisualAreaSize( aObjDesc
.mnViewAspect
, aSz
);
999 aSize
= OutputDevice::LogicToLogic(aSize
, MapMode(aMapUnit
), MapMode(MapUnit::Map100thMM
));
1002 Size
aMaxSize( mrDoc
.GetMaxObjSize() );
1004 maDropPos
.AdjustX( -(std::min( aSize
.Width(), aMaxSize
.Width() ) >> 1) );
1005 maDropPos
.AdjustY( -(std::min( aSize
.Height(), aMaxSize
.Height() ) >> 1) );
1007 ::tools::Rectangle
aRect( maDropPos
, aSize
);
1008 rtl::Reference
<SdrOle2Obj
> pObj
= new SdrOle2Obj(
1009 getSdrModelFromSdrView(),
1013 SdrPageView
* pPV
= GetSdrPageView();
1014 SdrInsertFlags nOptions
= SdrInsertFlags::SETDEFLAYER
;
1016 if (mpViewSh
!=nullptr)
1018 OSL_ASSERT (mpViewSh
->GetViewShell()!=nullptr);
1019 SfxInPlaceClient
* pIpClient
1020 = mpViewSh
->GetViewShell()->GetIPClient();
1021 if (pIpClient
!=nullptr && pIpClient
->IsObjectInPlaceActive())
1022 nOptions
|= SdrInsertFlags::DONTMARK
;
1025 // bInserted of false means that pObj has been deleted
1026 bool bInserted
= InsertObjectAtView( pObj
.get(), *pPV
, nOptions
);
1028 if (bInserted
&& pImageMap
)
1029 pObj
->AppendUserData( std::unique_ptr
<SdrObjUserData
>(new SvxIMapInfo( *pImageMap
)) );
1031 if (bInserted
&& pObj
->IsChart())
1033 bool bDisableDataTableDialog
= false;
1034 svt::EmbeddedObjectRef::TryRunningState( xObj
);
1035 uno::Reference
< beans::XPropertySet
> xProps( xObj
->getComponent(), uno::UNO_QUERY
);
1037 ( xProps
->getPropertyValue( u
"DisableDataTableDialog"_ustr
) >>= bDisableDataTableDialog
) &&
1038 bDisableDataTableDialog
)
1040 xProps
->setPropertyValue( u
"DisableDataTableDialog"_ustr
, uno::Any( false ) );
1041 xProps
->setPropertyValue( u
"DisableComplexChartTypes"_ustr
, uno::Any( false ) );
1042 uno::Reference
< util::XModifiable
> xModifiable( xProps
, uno::UNO_QUERY
);
1043 if ( xModifiable
.is() )
1045 xModifiable
->setModified( true );
1058 (CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBEDDED_OBJ_OLE
) || CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBED_SOURCE_OLE
)) &&
1059 rDataHelper
.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR_OLE
))
1061 // online insert ole if format is forced or no gdi metafile is available
1062 if( (nFormat
!= SotClipboardFormatId::NONE
) || !rDataHelper
.HasFormat( SotClipboardFormatId::GDIMETAFILE
) )
1064 uno::Reference
< io::XInputStream
> xStm
;
1065 TransferableObjectDescriptor aObjDesc
;
1067 if ( rDataHelper
.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE
, aObjDesc
) )
1069 uno::Reference
< embed::XEmbeddedObject
> xObj
;
1072 xStm
= rDataHelper
.GetInputStream(nFormat
!= SotClipboardFormatId::NONE
? nFormat
: SotClipboardFormatId::EMBED_SOURCE_OLE
, OUString());
1074 xStm
= rDataHelper
.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE
, OUString());
1078 xObj
= mpDocSh
->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
1084 uno::Reference
< embed::XStorage
> xTmpStor
= ::comphelper::OStorageHelper::GetTemporaryStorage();
1085 uno::Reference
< embed::XEmbedObjectClipboardCreator
> xClipboardCreator
=
1086 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
1088 embed::InsertedObjectInfo aInfo
= xClipboardCreator
->createInstanceInitFromClipboard(
1091 uno::Sequence
< beans::PropertyValue
>() );
1093 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
1094 // for example whether the object should be an iconified one
1095 xObj
= aInfo
.Object
;
1097 mpDocSh
->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj
, aName
);
1099 catch( uno::Exception
& )
1105 svt::EmbeddedObjectRef
aObjRef( xObj
, aObjDesc
.mnViewAspect
);
1107 // try to get the replacement image from the clipboard
1109 SotClipboardFormatId nGrFormat
= SotClipboardFormatId::NONE
;
1111 // (for Selection Manager in Trusted Solaris)
1113 if (rDataHelper
.GetGraphic(SotClipboardFormatId::SVXB
, aGraphic
))
1114 nGrFormat
= SotClipboardFormatId::SVXB
;
1115 else if (rDataHelper
.GetGraphic(SotClipboardFormatId::GDIMETAFILE
, aGraphic
))
1116 nGrFormat
= SotClipboardFormatId::GDIMETAFILE
;
1117 else if (rDataHelper
.GetGraphic(SotClipboardFormatId::BITMAP
, aGraphic
))
1118 nGrFormat
= SotClipboardFormatId::BITMAP
;
1121 // insert replacement image ( if there is one ) into the object helper
1122 if ( nGrFormat
!= SotClipboardFormatId::NONE
)
1124 datatransfer::DataFlavor aDataFlavor
;
1125 SotExchange::GetFormatDataFlavor( nGrFormat
, aDataFlavor
);
1126 aObjRef
.SetGraphic( aGraphic
, aDataFlavor
.MimeType
);
1130 if ( aObjDesc
.mnViewAspect
== embed::Aspects::MSOLE_ICON
)
1132 if( aObjDesc
.maSize
.Width() && aObjDesc
.maSize
.Height() )
1133 aSize
= aObjDesc
.maSize
;
1136 MapMode
aMapMode( MapUnit::Map100thMM
);
1137 aSize
= aObjRef
.GetSize( &aMapMode
);
1142 MapUnit aMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( aObjDesc
.mnViewAspect
) );
1146 aSz
= xObj
->getVisualAreaSize( aObjDesc
.mnViewAspect
);
1148 catch( embed::NoVisualAreaSizeException
& )
1150 // the default size will be set later
1153 if( aObjDesc
.maSize
.Width() && aObjDesc
.maSize
.Height() )
1155 Size
aTmp(OutputDevice::LogicToLogic(aObjDesc
.maSize
, MapMode(MapUnit::Map100thMM
), MapMode(aMapUnit
)));
1156 if ( aSz
.Width
!= aTmp
.Width() || aSz
.Height
!= aTmp
.Height() )
1158 aSz
.Width
= aTmp
.Width();
1159 aSz
.Height
= aTmp
.Height();
1160 xObj
->setVisualAreaSize( aObjDesc
.mnViewAspect
, aSz
);
1164 aSize
= Size( aSz
.Width
, aSz
.Height
);
1166 if( !aSize
.Width() || !aSize
.Height() )
1168 aSize
= OutputDevice::LogicToLogic(Size(14100, 10000), MapMode(MapUnit::Map100thMM
), MapMode(aMapUnit
));
1169 aSz
.Width
= aSize
.Width();
1170 aSz
.Height
= aSize
.Height();
1171 xObj
->setVisualAreaSize( aObjDesc
.mnViewAspect
, aSz
);
1174 aSize
= OutputDevice::LogicToLogic(aSize
, MapMode(aMapUnit
), MapMode(MapUnit::Map100thMM
));
1177 Size
aMaxSize( mrDoc
.GetMaxObjSize() );
1179 maDropPos
.AdjustX( -(std::min( aSize
.Width(), aMaxSize
.Width() ) >> 1) );
1180 maDropPos
.AdjustY( -(std::min( aSize
.Height(), aMaxSize
.Height() ) >> 1) );
1182 ::tools::Rectangle
aRect( maDropPos
, aSize
);
1183 rtl::Reference
<SdrOle2Obj
> pObj
= new SdrOle2Obj(
1184 getSdrModelFromSdrView(),
1188 SdrPageView
* pPV
= GetSdrPageView();
1189 SdrInsertFlags nOptions
= SdrInsertFlags::SETDEFLAYER
;
1191 if (mpViewSh
!=nullptr)
1193 OSL_ASSERT (mpViewSh
->GetViewShell()!=nullptr);
1194 SfxInPlaceClient
* pIpClient
1195 = mpViewSh
->GetViewShell()->GetIPClient();
1196 if (pIpClient
!=nullptr && pIpClient
->IsObjectInPlaceActive())
1197 nOptions
|= SdrInsertFlags::DONTMARK
;
1200 bReturn
= InsertObjectAtView( pObj
.get(), *pPV
, nOptions
);
1205 pObj
->AppendUserData( std::unique_ptr
<SdrObjUserData
>(new SvxIMapInfo( *pImageMap
)) );
1207 // let the object stay in loaded state after insertion
1214 if (!bReturn
&& rDataHelper
.HasFormat(SotClipboardFormatId::GDIMETAFILE
))
1216 // if no object was inserted, insert a picture
1217 InsertMetaFile(rDataHelper
, rPos
, pImageMap
.get(), true);
1222 if(!bReturn
&& (!bLink
|| pPickObj
) && CHECK_FORMAT_TRANS(SotClipboardFormatId::SVXB
))
1224 if (std::unique_ptr
<SvStream
> xStm
= rDataHelper
.GetSotStorageStream( SotClipboardFormatId::SVXB
))
1226 Point
aInsertPos( rPos
);
1229 TypeSerializer
aSerializer(*xStm
);
1230 aSerializer
.readGraphic(aGraphic
);
1232 if( pOwnData
&& pOwnData
->GetWorkDocument() )
1234 const SdDrawDocument
* pWorkModel
= pOwnData
->GetWorkDocument();
1235 SdrPage
* pWorkPage
= const_cast<SdrPage
*>( ( pWorkModel
->GetPageCount() > 1 ) ?
1236 pWorkModel
->GetSdPage( 0, PageKind::Standard
) :
1237 pWorkModel
->GetPage( 0 ) );
1239 pWorkPage
->SetSdrObjListRectsDirty();
1241 // #i120393# Clipboard data uses full object geometry range
1242 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
1244 aInsertPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
1245 aInsertPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
1248 // restrict movement to WorkArea
1249 Size aImageMapSize
= OutputDevice::LogicToLogic(aGraphic
.GetPrefSize(),
1250 aGraphic
.GetPrefMapMode(), MapMode(MapUnit::Map100thMM
));
1252 ImpCheckInsertPos(aInsertPos
, aImageMapSize
, GetWorkArea());
1254 InsertGraphic( aGraphic
, mnAction
, aInsertPos
, nullptr, pImageMap
.get() );
1259 if(!bReturn
&& (!bLink
|| pPickObj
) && CHECK_FORMAT_TRANS(SotClipboardFormatId::GDIMETAFILE
))
1261 Point
aInsertPos( rPos
);
1263 if( pOwnData
&& pOwnData
->GetWorkDocument() )
1266 const SdDrawDocument
* pWorkModel
= pOwnData
->GetWorkDocument();
1267 SdrPage
* pWorkPage
= const_cast<SdrPage
*>( ( pWorkModel
->GetPageCount() > 1 ) ?
1268 pWorkModel
->GetSdPage( 0, PageKind::Standard
) :
1269 pWorkModel
->GetPage( 0 ) );
1271 pWorkPage
->SetSdrObjListRectsDirty();
1273 // #i120393# Clipboard data uses full object geometry range
1274 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
1276 aInsertPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
1277 aInsertPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
1280 bReturn
= InsertMetaFile( rDataHelper
, aInsertPos
, pImageMap
.get(), nFormat
== SotClipboardFormatId::NONE
);
1283 if(!bReturn
&& (!bLink
|| pPickObj
) && CHECK_FORMAT_TRANS(SotClipboardFormatId::BITMAP
))
1287 // get basic Bitmap data
1288 rDataHelper
.GetBitmapEx(SotClipboardFormatId::BITMAP
, aBmpEx
);
1290 if(aBmpEx
.IsEmpty())
1292 // if this did not work, try to get graphic formats and convert these to bitmap
1295 if (rDataHelper
.GetGraphic(SotClipboardFormatId::GDIMETAFILE
, aGraphic
))
1297 aBmpEx
= aGraphic
.GetBitmapEx();
1299 else if (rDataHelper
.GetGraphic(SotClipboardFormatId::SVXB
, aGraphic
))
1301 aBmpEx
= aGraphic
.GetBitmapEx();
1303 else if (rDataHelper
.GetGraphic(SotClipboardFormatId::BITMAP
, aGraphic
))
1305 aBmpEx
= aGraphic
.GetBitmapEx();
1309 if(!aBmpEx
.IsEmpty())
1311 Point
aInsertPos( rPos
);
1313 if( pOwnData
&& pOwnData
->GetWorkDocument() )
1315 const SdDrawDocument
* pWorkModel
= pOwnData
->GetWorkDocument();
1316 SdrPage
* pWorkPage
= const_cast<SdrPage
*>( ( pWorkModel
->GetPageCount() > 1 ) ?
1317 pWorkModel
->GetSdPage( 0, PageKind::Standard
) :
1318 pWorkModel
->GetPage( 0 ) );
1320 pWorkPage
->SetSdrObjListRectsDirty();
1322 // #i120393# Clipboard data uses full object geometry range
1323 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
1325 aInsertPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
1326 aInsertPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
1329 // restrict movement to WorkArea
1330 Size
aImageMapSize(aBmpEx
.GetPrefSize());
1331 ImpCheckInsertPos(aInsertPos
, aImageMapSize
, GetWorkArea());
1333 InsertGraphic( aBmpEx
, mnAction
, aInsertPos
, nullptr, pImageMap
.get() );
1338 if(!bReturn
&& pPickObj
&& CHECK_FORMAT_TRANS( SotClipboardFormatId::XFA
) )
1340 uno::Any
const data(rDataHelper
.GetAny(SotClipboardFormatId::XFA
, u
""_ustr
));
1341 uno::Sequence
<beans::NamedValue
> props
;
1344 if( IsUndoEnabled() )
1346 BegUndo( SdResId(STR_UNDO_DRAGDROP
) );
1347 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoAttrObject(*pPickObj
));
1351 ::comphelper::SequenceAsHashMap
const map(props
);
1352 drawing::FillStyle
eFill(drawing::FillStyle_BITMAP
); // default to something that's ignored
1353 Color
aColor(COL_BLACK
);
1354 auto it
= map
.find(u
"FillStyle"_ustr
);
1355 if (it
!= map
.end())
1357 XFillStyleItem style
;
1358 style
.PutValue(it
->second
, 0);
1359 eFill
= style
.GetValue();
1361 it
= map
.find(u
"FillColor"_ustr
);
1362 if (it
!= map
.end())
1364 XFillColorItem color
;
1365 color
.PutValue(it
->second
, 0);
1366 aColor
= color
.GetColorValue();
1369 if( eFill
== drawing::FillStyle_SOLID
|| eFill
== drawing::FillStyle_NONE
)
1371 SfxItemSet
aSet( mrDoc
.GetPool() );
1372 bool bClosed
= pPickObj
->IsClosedObj();
1373 ::sd::Window
* pWin
= mpViewSh
->GetActiveWindow();
1374 double fHitLog
= pWin
->PixelToLogic(Size(FuPoor::HITPIX
, 0 ) ).Width();
1375 const ::tools::Long n2HitLog
= fHitLog
* 2;
1376 Point
aHitPosR( rPos
);
1377 Point
aHitPosL( rPos
);
1378 Point
aHitPosT( rPos
);
1379 Point
aHitPosB( rPos
);
1380 const SdrLayerIDSet
* pVisiLayer
= &GetSdrPageView()->GetVisibleLayers();
1382 aHitPosR
.AdjustX(n2HitLog
);
1383 aHitPosL
.AdjustX( -n2HitLog
);
1384 aHitPosT
.AdjustY(n2HitLog
);
1385 aHitPosB
.AdjustY( -n2HitLog
);
1388 SdrObjectPrimitiveHit(*pPickObj
, aHitPosR
, {fHitLog
, fHitLog
}, *GetSdrPageView(), pVisiLayer
, false) &&
1389 SdrObjectPrimitiveHit(*pPickObj
, aHitPosL
, {fHitLog
, fHitLog
}, *GetSdrPageView(), pVisiLayer
, false) &&
1390 SdrObjectPrimitiveHit(*pPickObj
, aHitPosT
, {fHitLog
, fHitLog
}, *GetSdrPageView(), pVisiLayer
, false) &&
1391 SdrObjectPrimitiveHit(*pPickObj
, aHitPosB
, {fHitLog
, fHitLog
}, *GetSdrPageView(), pVisiLayer
, false) )
1394 if(eFill
== drawing::FillStyle_SOLID
)
1395 aSet
.Put(XFillColorItem(u
""_ustr
, aColor
));
1397 aSet
.Put( XFillStyleItem( eFill
) );
1400 aSet
.Put( XLineColorItem( u
""_ustr
, aColor
) );
1403 pPickObj
->SetMergedItemSetAndBroadcast( aSet
);
1409 if(!bReturn
&& !bLink
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::HTML
))
1411 if (std::unique_ptr
<SvStream
> xStm
= rDataHelper
.GetSotStorageStream( SotClipboardFormatId::HTML
))
1415 OStringBuffer aLine
;
1416 while (xStm
->ReadLine(aLine
))
1418 if (std::string_view(aLine
).find( "<table>" ) != std::string_view::npos
||
1419 std::string_view(aLine
).find( "<table " ) != std::string_view::npos
)
1429 bReturn
= PasteHTMLTable(*xStm
, pPage
, nPasteOptions
);
1433 // mba: clipboard always must contain absolute URLs (could be from alien source)
1434 bReturn
= SdrView::Paste( *xStm
, EETextFormat::Html
, maDropPos
, pPage
, nPasteOptions
);
1439 if(!bReturn
&& !bLink
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT
))
1441 if (std::unique_ptr
<SvStream
> xStm
= rDataHelper
.GetSotStorageStream( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT
))
1443 OutlinerView
* pOLV
= GetTextEditOutlinerView();
1449 ::tools::Rectangle
aRect( pOLV
->GetOutputArea() );
1450 Point
aPos( pOLV
->GetWindow()->PixelToLogic( maDropPos
) );
1452 if( aRect
.Contains( aPos
) || ( !bDrag
&& IsTextEdit() ) )
1454 // mba: clipboard always must contain absolute URLs (could be from alien source)
1455 pOLV
->Read( *xStm
, EETextFormat::Xml
, mpDocSh
->GetHeaderAttributes() );
1461 // mba: clipboard always must contain absolute URLs (could be from alien source)
1462 bReturn
= SdrView::Paste( *xStm
, EETextFormat::Xml
, maDropPos
, pPage
, nPasteOptions
);
1466 if(!bReturn
&& !bLink
)
1468 bool bIsHtmlSimple
= CHECK_FORMAT_TRANS(SotClipboardFormatId::HTML_SIMPLE
);
1471 if (std::unique_ptr
<SvStream
> xStm
= rDataHelper
.GetSotStorageStream(SotClipboardFormatId::HTML_SIMPLE
))
1475 OutlinerView
* pOLV
= GetTextEditOutlinerView();
1476 MSE40HTMLClipFormatObj aMSE40HTMLClipFormatObj
;
1477 SvStream
* pHtmlStream
= aMSE40HTMLClipFormatObj
.IsValid(*xStm
);
1481 ::tools::Rectangle
aRect(pOLV
->GetOutputArea());
1482 Point
aPos(pOLV
->GetWindow()->PixelToLogic(maDropPos
));
1484 if (aRect
.Contains(aPos
) || (!bDrag
&& IsTextEdit()))
1486 // mba: clipboard always must contain absolute URLs (could be from alien source)
1487 pOLV
->Read(*pHtmlStream
, EETextFormat::Html
, mpDocSh
->GetHeaderAttributes());
1493 // mba: clipboard always must contain absolute URLs (could be from alien source)
1494 bReturn
= SdrView::Paste(*pHtmlStream
, EETextFormat::Html
, maDropPos
, pPage
, nPasteOptions
);
1498 bool bIsRTF
= CHECK_FORMAT_TRANS(SotClipboardFormatId::RTF
);
1499 if (!bReturn
&& (bIsRTF
|| CHECK_FORMAT_TRANS(SotClipboardFormatId::RICHTEXT
)))
1501 auto nFormatId
= bIsRTF
? SotClipboardFormatId::RTF
: SotClipboardFormatId::RICHTEXT
;
1502 if (std::unique_ptr
<SvStream
> xStm
= rDataHelper
.GetSotStorageStream(nFormatId
))
1508 bReturn
= PasteRTFTable( *xStm
, pPage
, nPasteOptions
);
1512 OutlinerView
* pOLV
= GetTextEditOutlinerView();
1516 ::tools::Rectangle
aRect( pOLV
->GetOutputArea() );
1517 Point
aPos( pOLV
->GetWindow()->PixelToLogic( maDropPos
) );
1519 if( aRect
.Contains( aPos
) || ( !bDrag
&& IsTextEdit() ) )
1521 // mba: clipboard always must contain absolute URLs (could be from alien source)
1522 pOLV
->Read( *xStm
, EETextFormat::Rtf
, mpDocSh
->GetHeaderAttributes() );
1528 // mba: clipboard always must contain absolute URLs (could be from alien source)
1529 bReturn
= SdrView::Paste( *xStm
, EETextFormat::Rtf
, maDropPos
, pPage
, nPasteOptions
);
1536 if(!bReturn
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::FILE_LIST
))
1538 FileList aDropFileList
;
1540 if (rDataHelper
.GetFileList(SotClipboardFormatId::FILE_LIST
, aDropFileList
))
1542 maDropFileVector
.clear();
1544 for( sal_uLong i
= 0, nCount
= aDropFileList
.Count(); i
< nCount
; i
++ )
1545 maDropFileVector
.push_back( aDropFileList
.GetFile( i
) );
1547 maDropInsertFileIdle
.Start();
1553 if(!bReturn
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::SIMPLE_FILE
))
1557 if (rDataHelper
.GetString(SotClipboardFormatId::SIMPLE_FILE
, aDropFile
))
1559 maDropFileVector
.clear();
1560 maDropFileVector
.push_back( aDropFile
);
1561 maDropInsertFileIdle
.Start();
1567 if(!bReturn
&& !bLink
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::STRING
))
1569 if( ( SotClipboardFormatId::STRING
== nFormat
) ||
1570 ( !rDataHelper
.HasFormat( SotClipboardFormatId::SOLK
) &&
1571 !rDataHelper
.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK
) &&
1572 !rDataHelper
.HasFormat( SotClipboardFormatId::FILENAME
) ) )
1576 if (rDataHelper
.GetString(SotClipboardFormatId::STRING
, aOUString
))
1578 OutlinerView
* pOLV
= GetTextEditOutlinerView();
1582 pOLV
->InsertText( aOUString
);
1587 bReturn
= SdrView::Paste( aOUString
, maDropPos
, pPage
, nPasteOptions
);
1592 MarkListHasChanged();
1593 mbIsDropAllowed
= true;
1594 rDnDAction
= mnAction
;
1596 if (bGroupUndoFromDragWithDrop
)
1598 // this is called eventually by the underlying toolkit anyway in the case of a self-dnd
1599 // but we call it early in this case to group its undo actions into this open dnd undo group
1600 // and rely on that repeated calls to View::DragFinished are safe to do
1601 DragFinished(mnAction
);
1608 bool View::PasteRTFTable( SvStream
& rStm
, SdrPage
* pPage
, SdrInsertFlags nPasteOptions
)
1610 DrawDocShellRef xShell
= new DrawDocShell(SfxObjectCreateMode::INTERNAL
, false, DocumentType::Impress
);
1611 xShell
->DoInitNew();
1613 SdDrawDocument
* pModel
= xShell
->GetDoc();
1614 pModel
->GetItemPool().SetDefaultMetric(MapUnit::Map100thMM
);
1615 pModel
->InsertPage(pModel
->AllocPage(false).get());
1617 CreateTableFromRTF(rStm
, pModel
);
1618 bool bRet
= Paste(*pModel
, maDropPos
, pPage
, nPasteOptions
);
1625 bool View::PasteHTMLTable( SvStream
& rStm
, SdrPage
* pPage
, SdrInsertFlags nPasteOptions
)
1627 DrawDocShellRef xShell
= new DrawDocShell(SfxObjectCreateMode::INTERNAL
, false, DocumentType::Impress
);
1628 xShell
->DoInitNew();
1630 SdDrawDocument
* pModel
= xShell
->GetDoc();
1631 pModel
->GetItemPool().SetDefaultMetric(MapUnit::Map100thMM
);
1632 pModel
->InsertPage(pModel
->AllocPage(false).get());
1634 CreateTableFromHTML(rStm
, pModel
);
1635 bool bRet
= Paste(*pModel
, maDropPos
, pPage
, nPasteOptions
);
1641 } // end of namespace sd
1643 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */