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 <svx/svdoole2.hxx>
33 #include <svx/svdograf.hxx>
34 #include <svx/svdundo.hxx>
35 #include <svl/itempool.hxx>
36 #include <sot/formats.hxx>
37 #include <editeng/outliner.hxx>
38 #include <svx/obj3d.hxx>
39 #include <svx/e3dundo.hxx>
40 #include <svx/unomodel.hxx>
41 #include <svx/ImageMapInfo.hxx>
42 #include <unotools/streamwrap.hxx>
43 #include <vcl/graph.hxx>
44 #include <vcl/metaact.hxx>
45 #include <vcl/pdfread.hxx>
46 #include <vcl/TypeSerializer.hxx>
47 #include <svx/svxids.hrc>
48 #include <toolkit/helper/vclunohelper.hxx>
49 #include <svtools/embedhlp.hxx>
50 #include <osl/diagnose.h>
51 #include <DrawDocShell.hxx>
53 #include <tablefunction.hxx>
57 #include <drawdoc.hxx>
59 #include <sdresid.hxx>
60 #include <strings.hrc>
61 #include <SlideSorterViewShell.hxx>
62 #include <unomodel.hxx>
63 #include <ViewClipboard.hxx>
64 #include <sfx2/ipclient.hxx>
65 #include <sfx2/classificationhelper.hxx>
66 #include <comphelper/sequenceashashmap.hxx>
67 #include <comphelper/storagehelper.hxx>
68 #include <comphelper/processfactory.hxx>
69 #include <svx/sdrhittesthelper.hxx>
70 #include <svx/xbtmpit.hxx>
74 using namespace ::com::sun::star
;
75 using namespace ::com::sun::star::lang
;
76 using namespace ::com::sun::star::uno
;
77 using namespace ::com::sun::star::io
;
78 using namespace ::com::sun::star::datatransfer
;
79 using namespace ::com::sun::star::datatransfer::clipboard
;
83 #define CHECK_FORMAT_TRANS( _def_Type ) ( ( nFormat == (_def_Type) || nFormat == SotClipboardFormatId::NONE ) && aDataHelper.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 TransferableDataHelper
aDataHelper( rDataHelper
);
263 SdrObject
* pPickObj
= nullptr;
264 SdPage
* pPage
= nullptr;
265 std::unique_ptr
<ImageMap
> pImageMap
;
266 bool bReturn
= false;
267 bool bLink
= ( ( mnAction
& DND_ACTION_LINK
) != 0 );
268 bool bCopy
= ( ( ( mnAction
& DND_ACTION_COPY
) != 0 ) || bLink
);
269 SdrInsertFlags nPasteOptions
= SdrInsertFlags::SETDEFLAYER
;
271 if (mpViewSh
!= nullptr)
273 OSL_ASSERT (mpViewSh
->GetViewShell()!=nullptr);
274 SfxInPlaceClient
* pIpClient
= mpViewSh
->GetViewShell()->GetIPClient();
275 if( dynamic_cast< ::sd::slidesorter::SlideSorterViewShell
*>( mpViewSh
) != nullptr
276 || (pIpClient
!=nullptr && pIpClient
->IsObjectInPlaceActive()))
277 nPasteOptions
|= SdrInsertFlags::DONTMARK
;
282 SdrPageView
* pPV
= nullptr;
283 pPickObj
= PickObj(rPos
, getHitTolLog(), pPV
);
286 if( nPage
!= SDRPAGE_NOTFOUND
)
287 pPage
= static_cast<SdPage
*>( mrDoc
.GetPage( nPage
) );
289 SdTransferable
* pOwnData
= nullptr;
290 SdTransferable
* pImplementation
= SdTransferable::getImplementation( aDataHelper
.GetTransferable() );
292 if(pImplementation
&& (rDnDAction
& DND_ACTION_LINK
))
294 // suppress own data when it's intention is to use it as fill information
295 pImplementation
= nullptr;
298 bool bSelfDND
= false;
300 // try to get own transfer data
301 if( pImplementation
)
303 if( SD_MOD()->pTransferClip
== pImplementation
)
304 pOwnData
= SD_MOD()->pTransferClip
;
305 else if( SD_MOD()->pTransferDrag
== pImplementation
)
307 pOwnData
= SD_MOD()->pTransferDrag
;
310 else if( SD_MOD()->pTransferSelection
== pImplementation
)
311 pOwnData
= SD_MOD()->pTransferSelection
;
314 const bool bGroupUndoFromDragWithDrop
= bSelfDND
&& mpDragSrcMarkList
&& IsUndoEnabled();
315 if (bGroupUndoFromDragWithDrop
)
317 OUString
aStr(SdResId(STR_UNDO_DRAGDROP
));
318 BegUndo(aStr
+ " " + mpDragSrcMarkList
->GetMarkDescription());
322 if( !pOwnData
&& aDataHelper
.HasFormat( SotClipboardFormatId::SVIM
) )
324 ::tools::SvRef
<SotTempStream
> xStm
;
326 if( aDataHelper
.GetSotStorageStream( SotClipboardFormatId::SVIM
, xStm
) )
328 pImageMap
.reset(new ImageMap
);
329 // mba: clipboard always must contain absolute URLs (could be from alien source)
330 pImageMap
->Read( *xStm
);
335 // check special cases for pasting table formats as RTL
336 if( !bLink
&& (nFormat
== SotClipboardFormatId::NONE
|| (nFormat
== SotClipboardFormatId::RTF
) || (nFormat
== SotClipboardFormatId::RICHTEXT
)) )
338 // if the object supports rtf and there is a table involved, default is to create a table
339 bool bIsRTF
= aDataHelper
.HasFormat( SotClipboardFormatId::RTF
);
340 if( ( bIsRTF
|| aDataHelper
.HasFormat( SotClipboardFormatId::RICHTEXT
) )
341 && ! aDataHelper
.HasFormat( SotClipboardFormatId::DRAWING
) )
343 ::tools::SvRef
<SotTempStream
> xStm
;
345 if( aDataHelper
.GetSotStorageStream( bIsRTF
? SotClipboardFormatId::RTF
: SotClipboardFormatId::RICHTEXT
, xStm
) )
350 while (xStm
->ReadLine(aLine
))
352 size_t x
= std::string_view(aLine
).find( "\\trowd" );
353 if (x
!= std::string_view::npos
)
356 nFormat
= bIsRTF
? SotClipboardFormatId::RTF
: SotClipboardFormatId::RICHTEXT
;
364 // Changed the whole decision tree to be dependent of bReturn as a flag that
365 // the work was done; this allows to check multiple formats and not just fail
366 // when a CHECK_FORMAT_TRANS(*format*) detected format does not work. This is
367 // e.g. necessary for SotClipboardFormatId::BITMAP
369 if (!bReturn
&& pOwnData
)
371 // Paste only if SfxClassificationHelper recommends so.
372 const SfxObjectShellRef
& pSource
= pOwnData
->GetDocShell();
373 SfxObjectShell
* pDestination
= mrDoc
.GetDocSh();
374 if (pSource
.is() && pDestination
)
376 SfxClassificationCheckPasteResult eResult
= SfxClassificationHelper::CheckPaste(pSource
->getDocProperties(), pDestination
->getDocProperties());
377 if (!SfxClassificationHelper::ShowPasteInfo(eResult
))
382 if( !bReturn
&& pOwnData
&& nFormat
== SotClipboardFormatId::NONE
)
384 const View
* pSourceView
= pOwnData
->GetView();
386 if( pOwnData
->GetDocShell().is() && pOwnData
->IsPageTransferable() )
388 mpClipboard
->HandlePageDrop (*pOwnData
);
391 else if( pSourceView
)
393 if( pSourceView
== this )
396 if( nLayer
!= SDRLAYER_NOTFOUND
)
398 // drop on layer tab bar
399 SdrLayerAdmin
& rLayerAdmin
= mrDoc
.GetLayerAdmin();
400 SdrLayer
* pLayer
= rLayerAdmin
.GetLayerPerID( nLayer
);
401 SdrPageView
* pPV
= GetSdrPageView();
402 OUString aLayer
= pLayer
->GetName();
404 if( !pPV
->IsLayerLocked( aLayer
) )
406 pOwnData
->SetInternalMove( true );
409 for( size_t nM
= 0; nM
< GetMarkedObjectCount(); ++nM
)
411 SdrMark
* pM
= GetSdrMarkByIndex( nM
);
412 SdrObject
* pO
= pM
->GetMarkedSdrObj();
417 if( IsUndoEnabled() )
419 BegUndo(SdResId(STR_MODIFYLAYER
));
420 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoObjectLayerChange(*pO
, pO
->GetLayer(), nLayer
));
424 pO
->SetLayer( nLayer
);
433 SdrPageView
* pPV
= GetSdrPageView();
434 bool bDropOnTabBar
= true;
436 if( !pPage
&& pPV
->GetPage()->GetPageNum() != mnDragSrcPgNum
)
438 pPage
= static_cast<SdPage
*>( pPV
->GetPage() );
439 bDropOnTabBar
= false;
444 // drop on other page
445 OUString aActiveLayer
= GetActiveLayer();
447 if( !pPV
->IsLayerLocked( aActiveLayer
) )
449 if( !IsPresObjSelected() )
451 SdrMarkList
* pMarkList
;
453 if( (mnDragSrcPgNum
!= SDRPAGE_NOTFOUND
) && (mnDragSrcPgNum
!= pPV
->GetPage()->GetPageNum()) )
455 pMarkList
= mpDragSrcMarkList
.get();
459 // actual mark list is used
460 pMarkList
= new SdrMarkList( GetMarkedObjectList());
463 pMarkList
->ForceSort();
465 // stuff to remember originals and clones
466 std::vector
<ImpRememberOrigAndClone
> aConnectorContainer
;
467 size_t nConnectorCount
= 0;
470 // calculate real position of current
471 // source objects, if necessary (#103207)
472 if( pOwnData
== SD_MOD()->pTransferSelection
)
474 ::tools::Rectangle aCurBoundRect
;
476 if( pMarkList
->TakeBoundRect( pPV
, aCurBoundRect
) )
477 aCurPos
= aCurBoundRect
.TopLeft();
479 aCurPos
= pOwnData
->GetStartPos();
482 aCurPos
= pOwnData
->GetStartPos();
484 const Size
aVector( maDropPos
.X() - aCurPos
.X(), maDropPos
.Y() - aCurPos
.Y() );
486 std::unordered_set
<rtl::OUString
> aNameSet
;
487 for(size_t a
= 0; a
< pMarkList
->GetMarkCount(); ++a
)
489 SdrMark
* pM
= pMarkList
->GetMark(a
);
490 rtl::Reference
<SdrObject
> pObj(pM
->GetMarkedSdrObj()->CloneSdrObject(pPage
->getSdrModelFromSdrPage()));
496 // do a NbcMove(...) instead of setting SnapRects here
497 pObj
->NbcMove(aVector
);
500 SdrObject
* pMarkParent
= pM
->GetMarkedSdrObj()->getParentSdrObjectFromSdrObject();
501 if (bCopy
|| (pMarkParent
&& pMarkParent
->IsGroupObject()))
502 pPage
->InsertObjectThenMakeNameUnique(pObj
.get(), aNameSet
);
504 pPage
->InsertObject(pObj
.get());
506 if( IsUndoEnabled() )
508 BegUndo(SdResId(STR_UNDO_DRAGDROP
));
509 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pObj
));
513 ImpRememberOrigAndClone aRem
;
514 aRem
.pOrig
= pM
->GetMarkedSdrObj();
515 aRem
.pClone
= pObj
.get();
516 aConnectorContainer
.push_back(aRem
);
518 if(dynamic_cast< SdrEdgeObj
*>( pObj
.get() ) != nullptr)
523 // try to re-establish connections at clones
526 for(size_t a
= 0; a
< aConnectorContainer
.size(); ++a
)
528 ImpRememberOrigAndClone
* pRem
= &aConnectorContainer
[a
];
530 if(auto pCloneEdge
= dynamic_cast<SdrEdgeObj
*>( pRem
->pClone
))
532 SdrEdgeObj
* pOrigEdge
= static_cast<SdrEdgeObj
*>(pRem
->pOrig
);
534 // test first connection
535 SdrObjConnection
& rConn0
= pOrigEdge
->GetConnection(false);
536 SdrObject
* pConnObj
= rConn0
.GetObject();
539 SdrObject
* pConnClone
= ImpGetClone(aConnectorContainer
, pConnObj
);
542 // if dest obj was cloned, too, re-establish connection
543 pCloneEdge
->ConnectToNode(false, pConnClone
);
544 pCloneEdge
->GetConnection(false).SetConnectorId(rConn0
.GetConnectorId());
548 // set position of connection point of original connected object
549 const SdrGluePointList
* pGlueList
= pConnObj
->GetGluePointList();
552 sal_uInt16 nInd
= pGlueList
->FindGluePoint(rConn0
.GetConnectorId());
554 if(SDRGLUEPOINT_NOTFOUND
!= nInd
)
556 const SdrGluePoint
& rGluePoint
= (*pGlueList
)[nInd
];
557 Point aPosition
= rGluePoint
.GetAbsolutePos(*pConnObj
);
558 aPosition
.AdjustX(aVector
.Width() );
559 aPosition
.AdjustY(aVector
.Height() );
560 pCloneEdge
->SetTailPoint(false, aPosition
);
566 // test second connection
567 SdrObjConnection
& rConn1
= pOrigEdge
->GetConnection(true);
568 pConnObj
= rConn1
.GetObject();
571 SdrObject
* pConnClone
= ImpGetClone(aConnectorContainer
, pConnObj
);
574 // if dest obj was cloned, too, re-establish connection
575 pCloneEdge
->ConnectToNode(true, pConnClone
);
576 pCloneEdge
->GetConnection(true).SetConnectorId(rConn1
.GetConnectorId());
580 // set position of connection point of original connected object
581 const SdrGluePointList
* pGlueList
= pConnObj
->GetGluePointList();
584 sal_uInt16 nInd
= pGlueList
->FindGluePoint(rConn1
.GetConnectorId());
586 if(SDRGLUEPOINT_NOTFOUND
!= nInd
)
588 const SdrGluePoint
& rGluePoint
= (*pGlueList
)[nInd
];
589 Point aPosition
= rGluePoint
.GetAbsolutePos(*pConnObj
);
590 aPosition
.AdjustX(aVector
.Width() );
591 aPosition
.AdjustY(aVector
.Height() );
592 pCloneEdge
->SetTailPoint(true, aPosition
);
601 if( pMarkList
!= mpDragSrcMarkList
.get() )
608 maDropErrorIdle
.Start();
615 pOwnData
->SetInternalMove( true );
616 MoveAllMarked( Size( maDropPos
.X() - pOwnData
->GetStartPos().X(),
617 maDropPos
.Y() - pOwnData
->GetStartPos().Y() ), bCopy
);
625 if( !pSourceView
->IsPresObjSelected() )
627 // model is owned by from AllocModel() created DocShell
628 SdDrawDocument
* pSourceDoc
= static_cast<SdDrawDocument
*>(&pSourceView
->GetModel());
629 pSourceDoc
->CreatingDataObj( pOwnData
);
630 SdDrawDocument
* pModel
= static_cast<SdDrawDocument
*>( pSourceView
->CreateMarkedObjModel().release() );
631 bReturn
= Paste(*pModel
, maDropPos
, pPage
, nPasteOptions
);
634 pPage
= static_cast<SdPage
*>( GetSdrPageView()->GetPage() );
636 OUString aLayout
= pPage
->GetLayoutName();
637 sal_Int32 nPos
= aLayout
.indexOf(SD_LT_SEPARATOR
);
639 aLayout
= aLayout
.copy(0, nPos
);
640 pPage
->SetPresentationLayout( aLayout
, false, false );
641 pSourceDoc
->CreatingDataObj( nullptr );
645 maDropErrorIdle
.Start();
652 SdDrawDocument
* pWorkModel
= const_cast<SdDrawDocument
*>(pOwnData
->GetWorkDocument());
653 SdPage
* pWorkPage
= pWorkModel
->GetSdPage( 0, PageKind::Standard
);
655 pWorkPage
->SetSdrObjListRectsDirty();
657 // #i120393# Clipboard data uses full object geometry range
658 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
660 maDropPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
661 maDropPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
663 // delete pages, that are not of any interest for us
664 for( ::tools::Long i
= pWorkModel
->GetPageCount() - 1; i
>= 0; i
-- )
666 SdPage
* pP
= static_cast< SdPage
* >( pWorkModel
->GetPage( static_cast<sal_uInt16
>(i
) ) );
668 if( pP
->GetPageKind() != PageKind::Standard
)
669 pWorkModel
->DeletePage( static_cast<sal_uInt16
>(i
) );
672 bReturn
= Paste(*pWorkModel
, maDropPos
, pPage
, nPasteOptions
);
675 pPage
= static_cast<SdPage
*>( GetSdrPageView()->GetPage() );
677 OUString aLayout
= pPage
->GetLayoutName();
678 sal_Int32 nPos
= aLayout
.indexOf(SD_LT_SEPARATOR
);
680 aLayout
= aLayout
.copy(0, nPos
);
681 pPage
->SetPresentationLayout( aLayout
, false, false );
685 if(!bReturn
&& CHECK_FORMAT_TRANS( SotClipboardFormatId::PDF
))
687 ::tools::SvRef
<SotTempStream
> xStm
;
688 if( aDataHelper
.GetSotStorageStream( SotClipboardFormatId::PDF
, xStm
) )
690 Point
aInsertPos(rPos
);
692 if (vcl::ImportPDF(*xStm
, aGraphic
))
694 const sal_Int32
nGraphicContentSize(xStm
->Tell());
696 BinaryDataContainer
aGraphicContent(*xStm
, nGraphicContentSize
);
697 aGraphic
.SetGfxLink(std::make_shared
<GfxLink
>(aGraphicContent
, GfxLinkType::NativePdf
));
699 InsertGraphic(aGraphic
, mnAction
, aInsertPos
, nullptr, nullptr);
705 if(!bReturn
&& CHECK_FORMAT_TRANS( SotClipboardFormatId::DRAWING
))
707 ::tools::SvRef
<SotTempStream
> xStm
;
709 if( aDataHelper
.GetSotStorageStream( SotClipboardFormatId::DRAWING
, xStm
) )
711 DrawDocShellRef xShell
= new DrawDocShell(SfxObjectCreateMode::INTERNAL
, false, DocumentType::Impress
);
714 SdDrawDocument
* pModel
= xShell
->GetDoc();
715 pModel
->InsertPage(pModel
->AllocPage(false).get());
717 Reference
< XComponent
> xComponent
= xShell
->GetModel();
720 css::uno::Reference
< css::io::XInputStream
> xInputStream( new utl::OInputStreamWrapper( *xStm
) );
721 bReturn
= SvxDrawingLayerImport( pModel
, xInputStream
, xComponent
, "com.sun.star.comp.Impress.XMLOasisImporter" );
723 if( pModel
->GetPageCount() == 0 )
725 OSL_FAIL("empty or invalid drawing xml document on clipboard!" );
729 bool bChanged
= false;
733 if( pModel
->GetSdPage( 0, PageKind::Standard
)->GetObjCount() == 1 )
736 SdrObject
* pObj
= pModel
->GetSdPage( 0, PageKind::Standard
)->GetObj( 0 );
737 SdrPageView
* pPV
= nullptr;
738 SdrObject
* pPickObj2
= PickObj(rPos
, getHitTolLog(), pPV
);
740 if( ( mnAction
& DND_ACTION_MOVE
) && pPickObj2
&& pObj
)
743 SdrPage
* pWorkPage
= GetSdrPageView()->GetPage();
744 rtl::Reference
<SdrObject
> pNewObj(pObj
->CloneSdrObject(pWorkPage
->getSdrModelFromSdrPage()));
745 ::tools::Rectangle
aPickObjRect( pPickObj2
->GetCurrentBoundRect() );
746 Size
aPickObjSize( aPickObjRect
.GetSize() );
747 Point
aVec( aPickObjRect
.TopLeft() );
748 ::tools::Rectangle
aObjRect( pNewObj
->GetCurrentBoundRect() );
749 Size
aObjSize( aObjRect
.GetSize() );
751 Fraction
aScaleWidth( aPickObjSize
.Width(), aObjSize
.Width() );
752 Fraction
aScaleHeight( aPickObjSize
.Height(), aObjSize
.Height() );
753 pNewObj
->NbcResize( aObjRect
.TopLeft(), aScaleWidth
, aScaleHeight
);
755 aVec
-= aObjRect
.TopLeft();
756 pNewObj
->NbcMove( Size( aVec
.X(), aVec
.Y() ) );
758 const bool bUndo
= IsUndoEnabled();
761 BegUndo(SdResId(STR_UNDO_DRAGDROP
));
762 pNewObj
->NbcSetLayer( pPickObj
->GetLayer() );
763 pWorkPage
->InsertObject( pNewObj
.get() );
766 AddUndo( mrDoc
.GetSdrUndoFactory().CreateUndoNewObject( *pNewObj
) );
767 AddUndo( mrDoc
.GetSdrUndoFactory().CreateUndoDeleteObject( *pPickObj2
) );
769 pWorkPage
->RemoveObject( pPickObj2
->GetOrdNum() );
777 mnAction
= DND_ACTION_COPY
;
779 else if( ( mnAction
& DND_ACTION_LINK
) && pPickObj
&& pObj
&&
780 dynamic_cast< const SdrGrafObj
*>( pPickObj
) == nullptr &&
781 dynamic_cast< const SdrOle2Obj
*>( pPickObj
) == nullptr )
783 SfxItemSet
aSet( mrDoc
.GetPool() );
785 // set new attributes to object
786 const bool bUndo
= IsUndoEnabled();
789 BegUndo( SdResId(STR_UNDO_DRAGDROP
) );
790 AddUndo( mrDoc
.GetSdrUndoFactory().CreateUndoAttrObject( *pPickObj
) );
793 aSet
.Put( pObj
->GetMergedItemSet() );
795 /* Do not take over corner radius. There are
796 gradients (rectangles) in the gallery with corner
797 radius of 0. We should not use that on the
799 aSet
.ClearItem( SDRATTR_CORNER_RADIUS
);
801 const SdrGrafObj
* pSdrGrafObj
= dynamic_cast< const SdrGrafObj
* >(pObj
);
805 // If we have a graphic as source object, use its graphic
806 // content as fill style
807 aSet
.Put(XFillStyleItem(drawing::FillStyle_BITMAP
));
808 aSet
.Put(XFillBitmapItem(pSdrGrafObj
->GetGraphic()));
811 pPickObj
->SetMergedItemSetAndBroadcast( aSet
);
813 if( DynCastE3dObject( pPickObj
) && DynCastE3dObject( pObj
) )
815 // handle 3D attribute in addition
816 SfxItemSetFixed
<SID_ATTR_3D_START
, SID_ATTR_3D_END
> aNewSet( mrDoc
.GetPool() );
817 SfxItemSetFixed
<SID_ATTR_3D_START
, SID_ATTR_3D_END
> aOldSet( mrDoc
.GetPool() );
819 aOldSet
.Put(pPickObj
->GetMergedItemSet());
820 aNewSet
.Put( pObj
->GetMergedItemSet() );
824 std::make_unique
<E3dAttributesUndoAction
>(
825 *static_cast< E3dObject
* >(pPickObj
),
828 pPickObj
->SetMergedItemSetAndBroadcast( aNewSet
);
840 SdrPage
* pWorkPage
= pModel
->GetSdPage( 0, PageKind::Standard
);
842 pWorkPage
->SetSdrObjListRectsDirty();
846 // #i120393# Clipboard data uses full object geometry range
847 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
849 maDropPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
850 maDropPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
853 bReturn
= Paste(*pModel
, maDropPos
, pPage
, nPasteOptions
);
861 if(!bReturn
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::SBA_FIELDDATAEXCHANGE
))
865 if( aDataHelper
.GetString( SotClipboardFormatId::SBA_FIELDDATAEXCHANGE
, aOUString
) )
867 rtl::Reference
<SdrObject
> pObj
= CreateFieldControl( aOUString
);
871 ::tools::Rectangle
aRect( pObj
->GetLogicRect() );
872 Size
aSize( aRect
.GetSize() );
874 maDropPos
.AdjustX( -( aSize
.Width() >> 1 ) );
875 maDropPos
.AdjustY( -( aSize
.Height() >> 1 ) );
877 aRect
.SetPos( maDropPos
);
878 pObj
->SetLogicRect( aRect
);
879 InsertObjectAtView( pObj
.get(), *GetSdrPageView(), SdrInsertFlags::SETDEFLAYER
);
887 (CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBED_SOURCE
) || CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBEDDED_OBJ
)) &&
888 aDataHelper
.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR
))
890 //TODO/LATER: is it possible that this format is binary?! (from old versions of SO)
891 uno::Reference
< io::XInputStream
> xStm
;
892 TransferableObjectDescriptor aObjDesc
;
894 if (aDataHelper
.GetTransferableObjectDescriptor(SotClipboardFormatId::OBJECTDESCRIPTOR
, aObjDesc
))
896 OUString aDocShellID
= SfxObjectShell::CreateShellID(mrDoc
.GetDocSh());
897 xStm
= aDataHelper
.GetInputStream(nFormat
!= SotClipboardFormatId::NONE
? nFormat
: SotClipboardFormatId::EMBED_SOURCE
, aDocShellID
);
899 xStm
= aDataHelper
.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ
, aDocShellID
);
904 if( mrDoc
.GetDocSh() && ( mrDoc
.GetDocSh()->GetClassName() == aObjDesc
.maClassName
) )
906 uno::Reference
< embed::XStorage
> xStore( ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm
) );
907 ::sd::DrawDocShellRef
xDocShRef( new ::sd::DrawDocShell( SfxObjectCreateMode::EMBEDDED
, true, mrDoc
.GetDocumentType() ) );
909 // mba: BaseURL doesn't make sense for clipboard functionality
910 SfxMedium
*pMedium
= new SfxMedium( xStore
, OUString() );
911 if( xDocShRef
->DoLoad( pMedium
) )
913 SdDrawDocument
* pModel
= xDocShRef
->GetDoc();
914 SdPage
* pWorkPage
= pModel
->GetSdPage( 0, PageKind::Standard
);
916 pWorkPage
->SetSdrObjListRectsDirty();
920 // #i120393# Clipboard data uses full object geometry range
921 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
923 maDropPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
924 maDropPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
927 // delete pages, that are not of any interest for us
928 for( ::tools::Long i
= pModel
->GetPageCount() - 1; i
>= 0; i
-- )
930 SdPage
* pP
= static_cast< SdPage
* >( pModel
->GetPage( static_cast<sal_uInt16
>(i
) ) );
932 if( pP
->GetPageKind() != PageKind::Standard
)
933 pModel
->DeletePage( static_cast<sal_uInt16
>(i
) );
936 bReturn
= Paste(*pModel
, maDropPos
, pPage
, nPasteOptions
);
939 pPage
= static_cast<SdPage
*>(GetSdrPageView()->GetPage());
941 OUString aLayout
= pPage
->GetLayoutName();
942 sal_Int32 nPos
= aLayout
.indexOf(SD_LT_SEPARATOR
);
944 aLayout
= aLayout
.copy(0, nPos
);
945 pPage
->SetPresentationLayout( aLayout
, false, false );
948 xDocShRef
->DoClose();
955 uno::Reference
< embed::XEmbeddedObject
> xObj
= mpDocSh
->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
958 svt::EmbeddedObjectRef
aObjRef( xObj
, aObjDesc
.mnViewAspect
);
961 if ( aObjDesc
.mnViewAspect
== embed::Aspects::MSOLE_ICON
)
963 if( aObjDesc
.maSize
.Width() && aObjDesc
.maSize
.Height() )
964 aSize
= aObjDesc
.maSize
;
967 MapMode
aMapMode( MapUnit::Map100thMM
);
968 aSize
= aObjRef
.GetSize( &aMapMode
);
974 MapUnit aMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( aObjDesc
.mnViewAspect
) );
975 if( aObjDesc
.maSize
.Width() && aObjDesc
.maSize
.Height() )
977 Size
aTmp(OutputDevice::LogicToLogic(aObjDesc
.maSize
, MapMode(MapUnit::Map100thMM
), MapMode(aMapUnit
)));
978 aSz
.Width
= aTmp
.Width();
979 aSz
.Height
= aTmp
.Height();
980 xObj
->setVisualAreaSize( aObjDesc
.mnViewAspect
, aSz
);
985 aSz
= xObj
->getVisualAreaSize( aObjDesc
.mnViewAspect
);
987 catch( embed::NoVisualAreaSizeException
& )
989 // if the size still was not set the default size will be set later
992 aSize
= Size( aSz
.Width
, aSz
.Height
);
994 if( !aSize
.Width() || !aSize
.Height() )
996 aSize
.setWidth( 14100 );
997 aSize
.setHeight( 10000 );
998 aSize
= OutputDevice::LogicToLogic(Size(14100, 10000), MapMode(MapUnit::Map100thMM
), MapMode(aMapUnit
));
999 aSz
.Width
= aSize
.Width();
1000 aSz
.Height
= aSize
.Height();
1001 xObj
->setVisualAreaSize( aObjDesc
.mnViewAspect
, aSz
);
1004 aSize
= OutputDevice::LogicToLogic(aSize
, MapMode(aMapUnit
), MapMode(MapUnit::Map100thMM
));
1007 Size
aMaxSize( mrDoc
.GetMaxObjSize() );
1009 maDropPos
.AdjustX( -(std::min( aSize
.Width(), aMaxSize
.Width() ) >> 1) );
1010 maDropPos
.AdjustY( -(std::min( aSize
.Height(), aMaxSize
.Height() ) >> 1) );
1012 ::tools::Rectangle
aRect( maDropPos
, aSize
);
1013 rtl::Reference
<SdrOle2Obj
> pObj
= new SdrOle2Obj(
1014 getSdrModelFromSdrView(),
1018 SdrPageView
* pPV
= GetSdrPageView();
1019 SdrInsertFlags nOptions
= SdrInsertFlags::SETDEFLAYER
;
1021 if (mpViewSh
!=nullptr)
1023 OSL_ASSERT (mpViewSh
->GetViewShell()!=nullptr);
1024 SfxInPlaceClient
* pIpClient
1025 = mpViewSh
->GetViewShell()->GetIPClient();
1026 if (pIpClient
!=nullptr && pIpClient
->IsObjectInPlaceActive())
1027 nOptions
|= SdrInsertFlags::DONTMARK
;
1030 // bInserted of false means that pObj has been deleted
1031 bool bInserted
= InsertObjectAtView( pObj
.get(), *pPV
, nOptions
);
1033 if (bInserted
&& pImageMap
)
1034 pObj
->AppendUserData( std::unique_ptr
<SdrObjUserData
>(new SvxIMapInfo( *pImageMap
)) );
1036 if (bInserted
&& pObj
->IsChart())
1038 bool bDisableDataTableDialog
= false;
1039 svt::EmbeddedObjectRef::TryRunningState( xObj
);
1040 uno::Reference
< beans::XPropertySet
> xProps( xObj
->getComponent(), uno::UNO_QUERY
);
1042 ( xProps
->getPropertyValue( "DisableDataTableDialog" ) >>= bDisableDataTableDialog
) &&
1043 bDisableDataTableDialog
)
1045 xProps
->setPropertyValue( "DisableDataTableDialog" , uno::Any( false ) );
1046 xProps
->setPropertyValue( "DisableComplexChartTypes" , uno::Any( false ) );
1047 uno::Reference
< util::XModifiable
> xModifiable( xProps
, uno::UNO_QUERY
);
1048 if ( xModifiable
.is() )
1050 xModifiable
->setModified( true );
1063 (CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBEDDED_OBJ_OLE
) || CHECK_FORMAT_TRANS(SotClipboardFormatId::EMBED_SOURCE_OLE
)) &&
1064 aDataHelper
.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR_OLE
))
1066 // online insert ole if format is forced or no gdi metafile is available
1067 if( (nFormat
!= SotClipboardFormatId::NONE
) || !aDataHelper
.HasFormat( SotClipboardFormatId::GDIMETAFILE
) )
1069 uno::Reference
< io::XInputStream
> xStm
;
1070 TransferableObjectDescriptor aObjDesc
;
1072 if ( aDataHelper
.GetTransferableObjectDescriptor( SotClipboardFormatId::OBJECTDESCRIPTOR_OLE
, aObjDesc
) )
1074 uno::Reference
< embed::XEmbeddedObject
> xObj
;
1077 xStm
= aDataHelper
.GetInputStream(nFormat
!= SotClipboardFormatId::NONE
? nFormat
: SotClipboardFormatId::EMBED_SOURCE_OLE
, OUString());
1079 xStm
= aDataHelper
.GetInputStream(SotClipboardFormatId::EMBEDDED_OBJ_OLE
, OUString());
1083 xObj
= mpDocSh
->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm
, aName
);
1089 uno::Reference
< embed::XStorage
> xTmpStor
= ::comphelper::OStorageHelper::GetTemporaryStorage();
1090 uno::Reference
< embed::XEmbedObjectClipboardCreator
> xClipboardCreator
=
1091 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() );
1093 embed::InsertedObjectInfo aInfo
= xClipboardCreator
->createInstanceInitFromClipboard(
1096 uno::Sequence
< beans::PropertyValue
>() );
1098 // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
1099 // for example whether the object should be an iconified one
1100 xObj
= aInfo
.Object
;
1102 mpDocSh
->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj
, aName
);
1104 catch( uno::Exception
& )
1110 svt::EmbeddedObjectRef
aObjRef( xObj
, aObjDesc
.mnViewAspect
);
1112 // try to get the replacement image from the clipboard
1114 SotClipboardFormatId nGrFormat
= SotClipboardFormatId::NONE
;
1116 // (for Selection Manager in Trusted Solaris)
1118 if( aDataHelper
.GetGraphic( SotClipboardFormatId::SVXB
, aGraphic
) )
1119 nGrFormat
= SotClipboardFormatId::SVXB
;
1120 else if( aDataHelper
.GetGraphic( SotClipboardFormatId::GDIMETAFILE
, aGraphic
) )
1121 nGrFormat
= SotClipboardFormatId::GDIMETAFILE
;
1122 else if( aDataHelper
.GetGraphic( SotClipboardFormatId::BITMAP
, aGraphic
) )
1123 nGrFormat
= SotClipboardFormatId::BITMAP
;
1126 // insert replacement image ( if there is one ) into the object helper
1127 if ( nGrFormat
!= SotClipboardFormatId::NONE
)
1129 datatransfer::DataFlavor aDataFlavor
;
1130 SotExchange::GetFormatDataFlavor( nGrFormat
, aDataFlavor
);
1131 aObjRef
.SetGraphic( aGraphic
, aDataFlavor
.MimeType
);
1135 if ( aObjDesc
.mnViewAspect
== embed::Aspects::MSOLE_ICON
)
1137 if( aObjDesc
.maSize
.Width() && aObjDesc
.maSize
.Height() )
1138 aSize
= aObjDesc
.maSize
;
1141 MapMode
aMapMode( MapUnit::Map100thMM
);
1142 aSize
= aObjRef
.GetSize( &aMapMode
);
1147 MapUnit aMapUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( aObjDesc
.mnViewAspect
) );
1151 aSz
= xObj
->getVisualAreaSize( aObjDesc
.mnViewAspect
);
1153 catch( embed::NoVisualAreaSizeException
& )
1155 // the default size will be set later
1158 if( aObjDesc
.maSize
.Width() && aObjDesc
.maSize
.Height() )
1160 Size
aTmp(OutputDevice::LogicToLogic(aObjDesc
.maSize
, MapMode(MapUnit::Map100thMM
), MapMode(aMapUnit
)));
1161 if ( aSz
.Width
!= aTmp
.Width() || aSz
.Height
!= aTmp
.Height() )
1163 aSz
.Width
= aTmp
.Width();
1164 aSz
.Height
= aTmp
.Height();
1165 xObj
->setVisualAreaSize( aObjDesc
.mnViewAspect
, aSz
);
1169 aSize
= Size( aSz
.Width
, aSz
.Height
);
1171 if( !aSize
.Width() || !aSize
.Height() )
1173 aSize
= OutputDevice::LogicToLogic(Size(14100, 10000), MapMode(MapUnit::Map100thMM
), MapMode(aMapUnit
));
1174 aSz
.Width
= aSize
.Width();
1175 aSz
.Height
= aSize
.Height();
1176 xObj
->setVisualAreaSize( aObjDesc
.mnViewAspect
, aSz
);
1179 aSize
= OutputDevice::LogicToLogic(aSize
, MapMode(aMapUnit
), MapMode(MapUnit::Map100thMM
));
1182 Size
aMaxSize( mrDoc
.GetMaxObjSize() );
1184 maDropPos
.AdjustX( -(std::min( aSize
.Width(), aMaxSize
.Width() ) >> 1) );
1185 maDropPos
.AdjustY( -(std::min( aSize
.Height(), aMaxSize
.Height() ) >> 1) );
1187 ::tools::Rectangle
aRect( maDropPos
, aSize
);
1188 rtl::Reference
<SdrOle2Obj
> pObj
= new SdrOle2Obj(
1189 getSdrModelFromSdrView(),
1193 SdrPageView
* pPV
= GetSdrPageView();
1194 SdrInsertFlags nOptions
= SdrInsertFlags::SETDEFLAYER
;
1196 if (mpViewSh
!=nullptr)
1198 OSL_ASSERT (mpViewSh
->GetViewShell()!=nullptr);
1199 SfxInPlaceClient
* pIpClient
1200 = mpViewSh
->GetViewShell()->GetIPClient();
1201 if (pIpClient
!=nullptr && pIpClient
->IsObjectInPlaceActive())
1202 nOptions
|= SdrInsertFlags::DONTMARK
;
1205 bReturn
= InsertObjectAtView( pObj
.get(), *pPV
, nOptions
);
1210 pObj
->AppendUserData( std::unique_ptr
<SdrObjUserData
>(new SvxIMapInfo( *pImageMap
)) );
1212 // let the object stay in loaded state after insertion
1219 if( !bReturn
&& aDataHelper
.HasFormat( SotClipboardFormatId::GDIMETAFILE
) )
1221 // if no object was inserted, insert a picture
1222 InsertMetaFile( aDataHelper
, rPos
, pImageMap
.get(), true );
1227 if(!bReturn
&& (!bLink
|| pPickObj
) && CHECK_FORMAT_TRANS(SotClipboardFormatId::SVXB
))
1229 ::tools::SvRef
<SotTempStream
> xStm
;
1231 if( aDataHelper
.GetSotStorageStream( SotClipboardFormatId::SVXB
, xStm
) )
1233 Point
aInsertPos( rPos
);
1236 TypeSerializer
aSerializer(*xStm
);
1237 aSerializer
.readGraphic(aGraphic
);
1239 if( pOwnData
&& pOwnData
->GetWorkDocument() )
1241 const SdDrawDocument
* pWorkModel
= pOwnData
->GetWorkDocument();
1242 SdrPage
* pWorkPage
= const_cast<SdrPage
*>( ( pWorkModel
->GetPageCount() > 1 ) ?
1243 pWorkModel
->GetSdPage( 0, PageKind::Standard
) :
1244 pWorkModel
->GetPage( 0 ) );
1246 pWorkPage
->SetSdrObjListRectsDirty();
1248 // #i120393# Clipboard data uses full object geometry range
1249 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
1251 aInsertPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
1252 aInsertPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
1255 // restrict movement to WorkArea
1256 Size aImageMapSize
= OutputDevice::LogicToLogic(aGraphic
.GetPrefSize(),
1257 aGraphic
.GetPrefMapMode(), MapMode(MapUnit::Map100thMM
));
1259 ImpCheckInsertPos(aInsertPos
, aImageMapSize
, GetWorkArea());
1261 InsertGraphic( aGraphic
, mnAction
, aInsertPos
, nullptr, pImageMap
.get() );
1266 if(!bReturn
&& (!bLink
|| pPickObj
) && CHECK_FORMAT_TRANS(SotClipboardFormatId::GDIMETAFILE
))
1268 Point
aInsertPos( rPos
);
1270 if( pOwnData
&& pOwnData
->GetWorkDocument() )
1273 const SdDrawDocument
* pWorkModel
= pOwnData
->GetWorkDocument();
1274 SdrPage
* pWorkPage
= const_cast<SdrPage
*>( ( pWorkModel
->GetPageCount() > 1 ) ?
1275 pWorkModel
->GetSdPage( 0, PageKind::Standard
) :
1276 pWorkModel
->GetPage( 0 ) );
1278 pWorkPage
->SetSdrObjListRectsDirty();
1280 // #i120393# Clipboard data uses full object geometry range
1281 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
1283 aInsertPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
1284 aInsertPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
1287 bReturn
= InsertMetaFile( aDataHelper
, aInsertPos
, pImageMap
.get(), nFormat
== SotClipboardFormatId::NONE
);
1290 if(!bReturn
&& (!bLink
|| pPickObj
) && CHECK_FORMAT_TRANS(SotClipboardFormatId::BITMAP
))
1294 // get basic Bitmap data
1295 aDataHelper
.GetBitmapEx(SotClipboardFormatId::BITMAP
, aBmpEx
);
1297 if(aBmpEx
.IsEmpty())
1299 // if this did not work, try to get graphic formats and convert these to bitmap
1302 if(aDataHelper
.GetGraphic(SotClipboardFormatId::GDIMETAFILE
, aGraphic
))
1304 aBmpEx
= aGraphic
.GetBitmapEx();
1306 else if(aDataHelper
.GetGraphic(SotClipboardFormatId::SVXB
, aGraphic
))
1308 aBmpEx
= aGraphic
.GetBitmapEx();
1310 else if(aDataHelper
.GetGraphic(SotClipboardFormatId::BITMAP
, aGraphic
))
1312 aBmpEx
= aGraphic
.GetBitmapEx();
1316 if(!aBmpEx
.IsEmpty())
1318 Point
aInsertPos( rPos
);
1320 if( pOwnData
&& pOwnData
->GetWorkDocument() )
1322 const SdDrawDocument
* pWorkModel
= pOwnData
->GetWorkDocument();
1323 SdrPage
* pWorkPage
= const_cast<SdrPage
*>( ( pWorkModel
->GetPageCount() > 1 ) ?
1324 pWorkModel
->GetSdPage( 0, PageKind::Standard
) :
1325 pWorkModel
->GetPage( 0 ) );
1327 pWorkPage
->SetSdrObjListRectsDirty();
1329 // #i120393# Clipboard data uses full object geometry range
1330 const Size
aSize( pWorkPage
->GetAllObjBoundRect().GetSize() );
1332 aInsertPos
.setX( pOwnData
->GetStartPos().X() + ( aSize
.Width() >> 1 ) );
1333 aInsertPos
.setY( pOwnData
->GetStartPos().Y() + ( aSize
.Height() >> 1 ) );
1336 // restrict movement to WorkArea
1337 Size
aImageMapSize(aBmpEx
.GetPrefSize());
1338 ImpCheckInsertPos(aInsertPos
, aImageMapSize
, GetWorkArea());
1340 InsertGraphic( aBmpEx
, mnAction
, aInsertPos
, nullptr, pImageMap
.get() );
1345 if(!bReturn
&& pPickObj
&& CHECK_FORMAT_TRANS( SotClipboardFormatId::XFA
) )
1347 uno::Any
const data(aDataHelper
.GetAny(SotClipboardFormatId::XFA
, ""));
1348 uno::Sequence
<beans::NamedValue
> props
;
1351 if( IsUndoEnabled() )
1353 BegUndo( SdResId(STR_UNDO_DRAGDROP
) );
1354 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoAttrObject(*pPickObj
));
1358 ::comphelper::SequenceAsHashMap
const map(props
);
1359 drawing::FillStyle
eFill(drawing::FillStyle_BITMAP
); // default to something that's ignored
1360 Color
aColor(COL_BLACK
);
1361 auto it
= map
.find("FillStyle");
1362 if (it
!= map
.end())
1364 XFillStyleItem style
;
1365 style
.PutValue(it
->second
, 0);
1366 eFill
= style
.GetValue();
1368 it
= map
.find("FillColor");
1369 if (it
!= map
.end())
1371 XFillColorItem color
;
1372 color
.PutValue(it
->second
, 0);
1373 aColor
= color
.GetColorValue();
1376 if( eFill
== drawing::FillStyle_SOLID
|| eFill
== drawing::FillStyle_NONE
)
1378 SfxItemSet
aSet( mrDoc
.GetPool() );
1379 bool bClosed
= pPickObj
->IsClosedObj();
1380 ::sd::Window
* pWin
= mpViewSh
->GetActiveWindow();
1381 double fHitLog
= pWin
->PixelToLogic(Size(FuPoor::HITPIX
, 0 ) ).Width();
1382 const ::tools::Long n2HitLog
= fHitLog
* 2;
1383 Point
aHitPosR( rPos
);
1384 Point
aHitPosL( rPos
);
1385 Point
aHitPosT( rPos
);
1386 Point
aHitPosB( rPos
);
1387 const SdrLayerIDSet
* pVisiLayer
= &GetSdrPageView()->GetVisibleLayers();
1389 aHitPosR
.AdjustX(n2HitLog
);
1390 aHitPosL
.AdjustX( -n2HitLog
);
1391 aHitPosT
.AdjustY(n2HitLog
);
1392 aHitPosB
.AdjustY( -n2HitLog
);
1395 SdrObjectPrimitiveHit(*pPickObj
, aHitPosR
, {fHitLog
, fHitLog
}, *GetSdrPageView(), pVisiLayer
, false) &&
1396 SdrObjectPrimitiveHit(*pPickObj
, aHitPosL
, {fHitLog
, fHitLog
}, *GetSdrPageView(), pVisiLayer
, false) &&
1397 SdrObjectPrimitiveHit(*pPickObj
, aHitPosT
, {fHitLog
, fHitLog
}, *GetSdrPageView(), pVisiLayer
, false) &&
1398 SdrObjectPrimitiveHit(*pPickObj
, aHitPosB
, {fHitLog
, fHitLog
}, *GetSdrPageView(), pVisiLayer
, false) )
1401 if(eFill
== drawing::FillStyle_SOLID
)
1402 aSet
.Put(XFillColorItem("", aColor
));
1404 aSet
.Put( XFillStyleItem( eFill
) );
1407 aSet
.Put( XLineColorItem( "", aColor
) );
1410 pPickObj
->SetMergedItemSetAndBroadcast( aSet
);
1416 if(!bReturn
&& !bLink
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::HTML
))
1418 ::tools::SvRef
<SotTempStream
> xStm
;
1420 if( aDataHelper
.GetSotStorageStream( SotClipboardFormatId::HTML
, xStm
) )
1423 // mba: clipboard always must contain absolute URLs (could be from alien source)
1424 bReturn
= SdrView::Paste( *xStm
, EETextFormat::Html
, maDropPos
, pPage
, nPasteOptions
);
1428 if(!bReturn
&& !bLink
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT
))
1430 ::tools::SvRef
<SotTempStream
> xStm
;
1431 if( aDataHelper
.GetSotStorageStream( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT
, xStm
) )
1433 OutlinerView
* pOLV
= GetTextEditOutlinerView();
1439 ::tools::Rectangle
aRect( pOLV
->GetOutputArea() );
1440 Point
aPos( pOLV
->GetWindow()->PixelToLogic( maDropPos
) );
1442 if( aRect
.Contains( aPos
) || ( !bDrag
&& IsTextEdit() ) )
1444 // mba: clipboard always must contain absolute URLs (could be from alien source)
1445 pOLV
->Read( *xStm
, EETextFormat::Xml
, mpDocSh
->GetHeaderAttributes() );
1451 // mba: clipboard always must contain absolute URLs (could be from alien source)
1452 bReturn
= SdrView::Paste( *xStm
, EETextFormat::Xml
, maDropPos
, pPage
, nPasteOptions
);
1456 if(!bReturn
&& !bLink
)
1458 bool bIsRTF
= CHECK_FORMAT_TRANS(SotClipboardFormatId::RTF
);
1459 if (bIsRTF
|| CHECK_FORMAT_TRANS(SotClipboardFormatId::RICHTEXT
))
1461 ::tools::SvRef
<SotTempStream
> xStm
;
1463 if( aDataHelper
.GetSotStorageStream( bIsRTF
? SotClipboardFormatId::RTF
: SotClipboardFormatId::RICHTEXT
, xStm
) )
1469 bReturn
= PasteRTFTable( xStm
, pPage
, nPasteOptions
);
1473 OutlinerView
* pOLV
= GetTextEditOutlinerView();
1477 ::tools::Rectangle
aRect( pOLV
->GetOutputArea() );
1478 Point
aPos( pOLV
->GetWindow()->PixelToLogic( maDropPos
) );
1480 if( aRect
.Contains( aPos
) || ( !bDrag
&& IsTextEdit() ) )
1482 // mba: clipboard always must contain absolute URLs (could be from alien source)
1483 pOLV
->Read( *xStm
, EETextFormat::Rtf
, mpDocSh
->GetHeaderAttributes() );
1489 // mba: clipboard always must contain absolute URLs (could be from alien source)
1490 bReturn
= SdrView::Paste( *xStm
, EETextFormat::Rtf
, maDropPos
, pPage
, nPasteOptions
);
1496 if(!bReturn
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::FILE_LIST
))
1498 FileList aDropFileList
;
1500 if( aDataHelper
.GetFileList( SotClipboardFormatId::FILE_LIST
, aDropFileList
) )
1502 maDropFileVector
.clear();
1504 for( sal_uLong i
= 0, nCount
= aDropFileList
.Count(); i
< nCount
; i
++ )
1505 maDropFileVector
.push_back( aDropFileList
.GetFile( i
) );
1507 maDropInsertFileIdle
.Start();
1513 if(!bReturn
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::SIMPLE_FILE
))
1517 if( aDataHelper
.GetString( SotClipboardFormatId::SIMPLE_FILE
, aDropFile
) )
1519 maDropFileVector
.clear();
1520 maDropFileVector
.push_back( aDropFile
);
1521 maDropInsertFileIdle
.Start();
1527 if(!bReturn
&& !bLink
&& CHECK_FORMAT_TRANS(SotClipboardFormatId::STRING
))
1529 if( ( SotClipboardFormatId::STRING
== nFormat
) ||
1530 ( !aDataHelper
.HasFormat( SotClipboardFormatId::SOLK
) &&
1531 !aDataHelper
.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK
) &&
1532 !aDataHelper
.HasFormat( SotClipboardFormatId::FILENAME
) ) )
1536 if( aDataHelper
.GetString( SotClipboardFormatId::STRING
, aOUString
) )
1538 OutlinerView
* pOLV
= GetTextEditOutlinerView();
1542 pOLV
->InsertText( aOUString
);
1547 bReturn
= SdrView::Paste( aOUString
, maDropPos
, pPage
, nPasteOptions
);
1552 MarkListHasChanged();
1553 mbIsDropAllowed
= true;
1554 rDnDAction
= mnAction
;
1556 if (bGroupUndoFromDragWithDrop
)
1558 // this is called eventually by the underlying toolkit anyway in the case of a self-dnd
1559 // but we call it early in this case to group its undo actions into this open dnd undo group
1560 // and rely on that repeated calls to View::DragFinished are safe to do
1561 DragFinished(mnAction
);
1568 bool View::PasteRTFTable( const ::tools::SvRef
<SotTempStream
>& xStm
, SdrPage
* pPage
, SdrInsertFlags nPasteOptions
)
1570 DrawDocShellRef xShell
= new DrawDocShell(SfxObjectCreateMode::INTERNAL
, false, DocumentType::Impress
);
1571 xShell
->DoInitNew();
1573 SdDrawDocument
* pModel
= xShell
->GetDoc();
1574 pModel
->GetItemPool().SetDefaultMetric(MapUnit::Map100thMM
);
1575 pModel
->InsertPage(pModel
->AllocPage(false).get());
1577 CreateTableFromRTF(*xStm
, pModel
);
1578 bool bRet
= Paste(*pModel
, maDropPos
, pPage
, nPasteOptions
);
1585 } // end of namespace sd
1587 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */