cid#1607171 Data race condition
[LibreOffice.git] / sd / source / ui / view / sdview2.cxx
blob8f5937172c0cdb8cee62f07f2ff2f6eab409cc33
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <View.hxx>
22 #include <vector>
23 #include <com/sun/star/embed/XEmbedPersist.hpp>
24 #include <com/sun/star/embed/XEmbeddedObject.hpp>
25 #include <comphelper/sequenceashashmap.hxx>
26 #include <tools/urlobj.hxx>
27 #include <svx/svdoole2.hxx>
28 #include <svx/svxdlg.hxx>
29 #include <sfx2/docfile.hxx>
30 #include <svx/svdundo.hxx>
31 #include <svx/svdpagv.hxx>
32 #include <svl/urlbmk.hxx>
33 #include <editeng/outliner.hxx>
34 #include <svx/xflclit.hxx>
35 #include <sot/formats.hxx>
36 #include <editeng/editeng.hxx>
38 #include <svtools/embedtransfer.hxx>
39 #include <tools/debug.hxx>
41 #include <anminfo.hxx>
42 #include <strings.hrc>
43 #include <sdxfer.hxx>
44 #include <sdresid.hxx>
45 #include <sdmod.hxx>
46 #include <sdtreelb.hxx>
47 #include <DrawViewShell.hxx>
48 #include <DrawDocShell.hxx>
49 #include <fudraw.hxx>
50 #include <drawdoc.hxx>
51 #include <Window.hxx>
52 #include <sdpage.hxx>
53 #include <unoaprms.hxx>
54 #include <helpids.h>
55 #include <vcl/svapp.hxx>
57 #include <slideshow.hxx>
58 #include <memory>
60 namespace sd {
62 using namespace ::com::sun::star;
64 namespace {
66 struct SdNavigatorDropEvent : public ExecuteDropEvent
68 VclPtr< ::sd::Window> mpTargetWindow;
70 SdNavigatorDropEvent (
71 const ExecuteDropEvent& rEvt,
72 ::sd::Window* pTargetWindow )
73 : ExecuteDropEvent( rEvt ),
74 mpTargetWindow( pTargetWindow )
80 css::uno::Reference< css::datatransfer::XTransferable > View::CreateClipboardDataObject()
82 // since SdTransferable::CopyToClipboard is called, this
83 // dynamically created object is destroyed automatically
84 rtl::Reference<SdTransferable> pTransferable = new SdTransferable( &mrDoc, nullptr, false );
86 SdModule::get()->pTransferClip = pTransferable.get();
88 mrDoc.CreatingDataObj( pTransferable.get() );
89 pTransferable->SetWorkDocument( static_cast<SdDrawDocument*>(CreateMarkedObjModel().release()) );
90 mrDoc.CreatingDataObj( nullptr );
92 // #112978# need to use GetAllMarkedBoundRect instead of GetAllMarkedRect to get
93 // fat lines correctly
94 const ::tools::Rectangle aMarkRect( GetAllMarkedBoundRect() );
95 std::unique_ptr<TransferableObjectDescriptor> pObjDesc(new TransferableObjectDescriptor);
96 SdrOle2Obj* pSdrOleObj = nullptr;
97 SdrPageView* pPgView = GetSdrPageView();
98 SdPage* pOldPage = pPgView ? static_cast<SdPage*>( pPgView->GetPage() ) : nullptr;
99 SdPage* pNewPage = const_cast<SdPage*>(static_cast<const SdPage*>( pTransferable->GetWorkDocument()->GetPage( 0 ) ));
101 if( pOldPage )
103 pNewPage->SetSize( pOldPage->GetSize() );
104 pNewPage->SetLayoutName( pOldPage->GetLayoutName() );
107 const SdrMarkList& rMarkList = GetMarkedObjectList();
108 if( rMarkList.GetMarkCount() == 1 )
110 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
112 if( auto pOle2Obj = dynamic_cast<SdrOle2Obj *>( pObj ) )
113 if( pOle2Obj->GetObjRef() )
115 // If object has no persistence it must be copied as part of the document
118 uno::Reference< embed::XEmbedPersist > xPersObj( pOle2Obj->GetObjRef(), uno::UNO_QUERY );
119 if ( xPersObj.is() && xPersObj->hasEntry() )
120 pSdrOleObj = pOle2Obj;
122 catch( uno::Exception& )
127 if( pSdrOleObj )
128 SvEmbedTransferHelper::FillTransferableObjectDescriptor( *pObjDesc, pSdrOleObj->GetObjRef(), pSdrOleObj->GetGraphic(), pSdrOleObj->GetAspect() );
129 else
130 pTransferable->GetWorkDocument()->GetDocSh()->FillTransferableObjectDescriptor( *pObjDesc );
132 if( mpDocSh )
133 pObjDesc->maDisplayName = mpDocSh->GetMedium()->GetURLObject().GetURLNoPass();
135 pObjDesc->maSize = aMarkRect.GetSize();
137 pTransferable->SetStartPos( aMarkRect.TopLeft() );
138 pTransferable->SetObjectDescriptor( std::move(pObjDesc) );
139 pTransferable->CopyToClipboard( mpViewSh->GetActiveWindow() );
141 return pTransferable;
144 css::uno::Reference< css::datatransfer::XTransferable > View::CreateDragDataObject( View* pWorkView, vcl::Window& rWindow, const Point& rDragPos )
146 rtl::Reference<SdTransferable> pTransferable = new SdTransferable( &mrDoc, pWorkView, false );
148 SdModule::get()->pTransferDrag = pTransferable.get();
150 std::unique_ptr<TransferableObjectDescriptor> pObjDesc(new TransferableObjectDescriptor);
151 OUString aDisplayName;
152 SdrOle2Obj* pSdrOleObj = nullptr;
154 const SdrMarkList& rMarkList = GetMarkedObjectList();
155 if( rMarkList.GetMarkCount() == 1 )
157 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
159 if( auto pOle2Obj = dynamic_cast<SdrOle2Obj *>( pObj ) )
160 if( pOle2Obj->GetObjRef() )
162 // If object has no persistence it must be copied as part of the document
165 uno::Reference< embed::XEmbedPersist > xPersObj( pOle2Obj->GetObjRef(), uno::UNO_QUERY );
166 if ( xPersObj.is() && xPersObj->hasEntry() )
167 pSdrOleObj = pOle2Obj;
169 catch( uno::Exception& )
174 if( mpDocSh )
175 aDisplayName = mpDocSh->GetMedium()->GetURLObject().GetURLNoPass();
177 if( pSdrOleObj )
178 SvEmbedTransferHelper::FillTransferableObjectDescriptor( *pObjDesc, pSdrOleObj->GetObjRef(), pSdrOleObj->GetGraphic(), pSdrOleObj->GetAspect() );
179 else if (mpDocSh)
180 mpDocSh->FillTransferableObjectDescriptor( *pObjDesc );
182 pObjDesc->maSize = GetAllMarkedRect().GetSize();
183 pObjDesc->maDragStartPos = rDragPos;
184 pObjDesc->maDisplayName = aDisplayName;
186 pTransferable->SetStartPos( rDragPos );
187 pTransferable->SetObjectDescriptor( std::move(pObjDesc) );
188 pTransferable->StartDrag( &rWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
190 return pTransferable;
193 css::uno::Reference< css::datatransfer::XTransferable > View::CreateSelectionDataObject( View* pWorkView )
195 rtl::Reference<SdTransferable> pTransferable = new SdTransferable( &mrDoc, pWorkView, true );
196 std::unique_ptr<TransferableObjectDescriptor> pObjDesc(new TransferableObjectDescriptor);
197 const ::tools::Rectangle aMarkRect( GetAllMarkedRect() );
199 SdModule::get()->pTransferSelection = pTransferable.get();
201 if( mpDocSh )
203 mpDocSh->FillTransferableObjectDescriptor( *pObjDesc );
204 pObjDesc->maDisplayName = mpDocSh->GetMedium()->GetURLObject().GetURLNoPass();
207 pObjDesc->maSize = aMarkRect.GetSize();
209 pTransferable->SetStartPos( aMarkRect.TopLeft() );
210 pTransferable->SetObjectDescriptor( std::move(pObjDesc) );
211 pTransferable->CopyToPrimarySelection();
213 return pTransferable;
216 void View::UpdateSelectionClipboard() // false case
218 if (!mpViewSh)
219 return;
220 if (!mpViewSh->GetActiveWindow())
221 return;
222 const SdrMarkList& rMarkList = GetMarkedObjectList();
223 if (rMarkList.GetMarkCount())
224 CreateSelectionDataObject( this );
225 else
226 ClearSelectionClipboard();
229 void View::ClearSelectionClipboard() // true case
231 if (!mpViewSh)
232 return;
233 if (!mpViewSh->GetActiveWindow())
234 return;
235 SdModule* mod = SdModule::get();
236 if (mod->pTransferSelection && mod->pTransferSelection->GetView() == this)
238 TransferableHelper::ClearPrimarySelection();
239 mod->pTransferSelection = nullptr;
243 void View::DoCut()
245 const OutlinerView* pOLV = GetTextEditOutlinerView();
247 const SdrMarkList& rMarkList = GetMarkedObjectList();
248 if( pOLV )
249 const_cast<OutlinerView*>(pOLV)->Cut();
250 else if( rMarkList.GetMarkCount() != 0 )
252 OUString aStr(SdResId(STR_UNDO_CUT));
254 DoCopy();
255 BegUndo(aStr + " " + rMarkList.GetMarkDescription());
256 DeleteMarked();
257 EndUndo();
261 void View::DoCopy()
263 const OutlinerView* pOLV = GetTextEditOutlinerView();
265 const SdrMarkList& rMarkList = GetMarkedObjectList();
266 if( pOLV )
267 const_cast<OutlinerView*>(pOLV)->Copy();
268 else if( rMarkList.GetMarkCount() != 0 )
270 BrkAction();
271 CreateClipboardDataObject();
275 void View::DoPaste (::sd::Window* pWindow)
277 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( mpViewSh->GetActiveWindow() ) );
278 if( !aDataHelper.GetTransferable().is() )
279 return; // empty clipboard?
281 const OutlinerView* pOLV = GetTextEditOutlinerView();
283 if( pOLV && EditEngine::HasValidData( aDataHelper.GetTransferable() ) )
285 const_cast< OutlinerView* >(pOLV)->PasteSpecial();
287 SdrObject* pObj = GetTextEditObject();
288 SdPage* pPage = static_cast<SdPage*>( pObj ? pObj->getSdrPageFromSdrObject() : nullptr );
289 ::Outliner* pOutliner = pOLV->GetOutliner();
291 if( pOutliner)
293 if( pObj && pPage && pPage->GetPresObjKind(pObj) == PresObjKind::Title )
295 // remove all hard linebreaks from the title
296 if (pOutliner->GetParagraphCount() > 1)
298 bool bOldUpdateMode = pOutliner->SetUpdateLayout( false );
300 const EditEngine& rEdit = pOutliner->GetEditEngine();
301 const sal_Int32 nParaCount = rEdit.GetParagraphCount();
303 for( sal_Int32 nPara = nParaCount - 2; nPara >= 0; nPara-- )
305 const sal_Int32 nParaLen = rEdit.GetTextLen( nPara );
306 pOutliner->QuickInsertLineBreak(ESelection(nPara, nParaLen, nPara + 1, 0));
309 DBG_ASSERT( rEdit.GetParagraphCount() <= 1, "Titleobject contains hard line breaks" );
310 pOutliner->SetUpdateLayout(bOldUpdateMode);
314 if( !mrDoc.IsChanged() )
316 if (pOutliner->IsModified())
317 mrDoc.SetChanged();
321 else
323 Point aPos = pWindow->GetVisibleCenter();
324 DrawViewShell* pDrViewSh = static_cast<DrawViewShell*>( mpDocSh->GetViewShell() );
326 if (pDrViewSh != nullptr)
328 sal_Int8 nDnDAction = DND_ACTION_COPY;
329 if( !InsertData( aDataHelper, aPos, nDnDAction, false ) )
331 INetBookmark aINetBookmark( u""_ustr, u""_ustr );
333 if( ( aDataHelper.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ) &&
334 aDataHelper.GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK, aINetBookmark ) ) ||
335 ( aDataHelper.HasFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR ) &&
336 aDataHelper.GetINetBookmark( SotClipboardFormatId::FILEGRPDESCRIPTOR, aINetBookmark ) ) ||
337 ( aDataHelper.HasFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR ) &&
338 aDataHelper.GetINetBookmark( SotClipboardFormatId::UNIFORMRESOURCELOCATOR, aINetBookmark ) ) )
340 pDrViewSh->InsertURLField( aINetBookmark.GetURL(), aINetBookmark.GetDescription(), u""_ustr );
347 void View::StartDrag( const Point& rStartPos, vcl::Window* pWindow )
349 const SdrMarkList& rMarkList = GetMarkedObjectList();
350 if (rMarkList.GetMarkCount() == 0 || !IsAction() || !mpViewSh || !pWindow)
351 return;
353 BrkAction();
355 if( IsTextEdit() )
356 SdrEndTextEdit();
358 if (DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(mpDocSh ? mpDocSh->GetViewShell() : nullptr))
360 const rtl::Reference<FuPoor>& xFunction(pDrawViewShell->GetCurrentFunction());
361 if (FuDraw* pFunction = dynamic_cast<FuDraw*>(xFunction.get()))
362 pFunction->ForcePointer();
365 mpDragSrcMarkList.reset( new SdrMarkList(GetMarkedObjectList()) );
366 mnDragSrcPgNum = GetSdrPageView()->GetPage()->GetPageNum();
368 CreateDragDataObject( this, *pWindow, rStartPos );
371 void View::DragFinished( sal_Int8 nDropAction )
373 const bool bUndo = IsUndoEnabled();
374 const bool bGroupUndo = bUndo && mpDragSrcMarkList;
375 if (bGroupUndo)
377 OUString aStr(SdResId(STR_UNDO_DRAGDROP));
378 BegUndo(aStr + " " + mpDragSrcMarkList->GetMarkDescription());
381 SdTransferable* pDragTransferable = SdModule::get()->pTransferDrag;
383 if( pDragTransferable )
384 pDragTransferable->SetView( nullptr );
386 if( ( nDropAction & DND_ACTION_MOVE ) &&
387 pDragTransferable && !pDragTransferable->IsInternalMove() &&
388 mpDragSrcMarkList && mpDragSrcMarkList->GetMarkCount() &&
389 !IsPresObjSelected() )
391 mpDragSrcMarkList->ForceSort();
393 if( bUndo )
394 BegUndo();
396 const size_t nCnt = mpDragSrcMarkList->GetMarkCount();
398 for( size_t nm = nCnt; nm>0; )
400 --nm;
401 SdrMark* pM=mpDragSrcMarkList->GetMark(nm);
402 if( bUndo )
403 AddUndo(mrDoc.GetSdrUndoFactory().CreateUndoDeleteObject(*pM->GetMarkedSdrObj()));
406 mpDragSrcMarkList->GetMark(0)->GetMarkedSdrObj()->GetOrdNum();
408 for (size_t nm = nCnt; nm>0;)
410 --nm;
411 SdrMark* pM=mpDragSrcMarkList->GetMark(nm);
412 SdrObject* pObj=pM->GetMarkedSdrObj();
414 if( pObj && pObj->getSdrPageFromSdrObject() )
416 const size_t nOrdNum = pObj->GetOrdNumDirect();
417 rtl::Reference<SdrObject> pChkObj = pObj->getSdrPageFromSdrObject()->RemoveObject(nOrdNum);
418 DBG_ASSERT(pChkObj.get()==pObj,"pChkObj!=pObj in RemoveObject()");
422 if( bUndo )
423 EndUndo();
426 if( pDragTransferable )
427 pDragTransferable->SetInternalMove( false );
429 if (bGroupUndo)
430 EndUndo();
431 mnDragSrcPgNum = SDRPAGE_NOTFOUND;
432 mpDragSrcMarkList.reset();
435 sal_Int8 View::AcceptDrop( const AcceptDropEvent& rEvt, DropTargetHelper& rTargetHelper,
436 SdrLayerID nLayer )
438 OUString aLayerName = GetActiveLayer();
439 SdrPageView* pPV = GetSdrPageView();
440 sal_Int8 nDropAction = rEvt.mnAction;
441 sal_Int8 nRet = DND_ACTION_NONE;
443 if( nLayer != SDRLAYER_NOTFOUND )
445 SdrLayerAdmin& rLayerAdmin = mrDoc.GetLayerAdmin();
446 SdrLayer* pLayer = rLayerAdmin.GetLayerPerID(nLayer);
447 assert(pLayer && "layer missing");
448 aLayerName = pLayer->GetName();
451 if( mbIsDropAllowed && !pPV->IsLayerLocked( aLayerName ) && pPV->IsLayerVisible( aLayerName ) )
453 const OutlinerView* pOLV = GetTextEditOutlinerView();
454 bool bIsInsideOutlinerView = false;
456 if( pOLV )
458 ::tools::Rectangle aRect( pOLV->GetOutputArea() );
460 const SdrMarkList& rMarkList = GetMarkedObjectList();
461 if (rMarkList.GetMarkCount() == 1)
463 SdrMark* pMark = rMarkList.GetMark(0);
464 SdrObject* pObj = pMark->GetMarkedSdrObj();
465 aRect.Union( pObj->GetLogicRect() );
468 if( aRect.Contains( pOLV->GetWindow()->PixelToLogic( rEvt.maPosPixel ) ) )
470 bIsInsideOutlinerView = true;
474 if( !bIsInsideOutlinerView )
476 SdTransferable* pDragTransferable = SdModule::get()->pTransferDrag;
478 if(pDragTransferable && (nDropAction & DND_ACTION_LINK))
480 // suppress own data when it's intention is to use it as fill information
481 pDragTransferable = nullptr;
484 if( pDragTransferable )
486 const View* pSourceView = pDragTransferable->GetView();
488 if( pDragTransferable->IsPageTransferable() )
490 nRet = DND_ACTION_COPY;
492 else if( pSourceView )
494 if( !( nDropAction & DND_ACTION_LINK ) ||
495 !pSourceView->GetDocSh()->GetMedium()->GetName().isEmpty() )
497 nRet = nDropAction;
501 else
503 const bool bDrawing = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::DRAWING );
504 const bool bGraphic = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::SVXB );
505 const bool bMtf = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::GDIMETAFILE );
506 const bool bBitmap = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::BITMAP );
507 bool bBookmark = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::NETSCAPE_BOOKMARK );
508 bool bXFillExchange = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::XFA );
510 // check handle insert
511 if ((bXFillExchange && (SdrDragMode::Gradient == GetDragMode()))
512 || (SdrDragMode::Transparence == GetDragMode()))
514 const SdrHdlList& rHdlList = GetHdlList();
516 for( size_t n = 0; n < rHdlList.GetHdlCount(); ++n )
518 SdrHdl* pIAOHandle = rHdlList.GetHdl( n );
520 if( pIAOHandle && ( SdrHdlKind::Color == pIAOHandle->GetKind() ) )
522 if(pIAOHandle->getOverlayObjectList().isHitPixel(rEvt.maPosPixel))
524 nRet = nDropAction;
525 static_cast< SdrHdlColor* >( pIAOHandle )->SetSize( SDR_HANDLE_COLOR_SIZE_SELECTED );
527 else
529 static_cast< SdrHdlColor* >( pIAOHandle )->SetSize( SDR_HANDLE_COLOR_SIZE_NORMAL );
535 // check object insert
536 if( !nRet && ( bXFillExchange || ( ( bDrawing || bGraphic || bMtf || bBitmap || bBookmark ) && ( nDropAction & DND_ACTION_LINK ) ) ) )
538 SdrPageView* pPageView = nullptr;
539 ::sd::Window* pWindow = mpViewSh->GetActiveWindow();
540 Point aPos( pWindow->PixelToLogic( rEvt.maPosPixel ) );
541 SdrObject* pPickObj = PickObj(aPos, getHitTolLog(), pPageView);
542 bool bIsPresTarget = false;
544 if (pPickObj && (pPickObj->IsEmptyPresObj() || pPickObj->GetUserCall()))
546 SdPage* pPage = static_cast<SdPage*>( pPickObj->getSdrPageFromSdrObject() );
548 if( pPage && pPage->IsMasterPage() )
549 bIsPresTarget = pPage->IsPresObj( pPickObj );
552 if (pPickObj && !bIsPresTarget && (bGraphic || bMtf || bBitmap || bXFillExchange))
554 if( mpDropMarkerObj != pPickObj )
556 mpDropMarkerObj = pPickObj;
557 ImplClearDrawDropMarker();
559 if(mpDropMarkerObj)
561 mpDropMarker.reset( new SdrDropMarkerOverlay(*this, *mpDropMarkerObj) );
565 nRet = nDropAction;
567 else
568 bXFillExchange = false;
571 // check normal insert
572 if( !nRet )
574 const bool bSBAFormat = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::SVX_FORMFIELDEXCH );
575 const bool bEditEngineODF = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT );
576 const bool bString = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::STRING );
577 const bool bRTF = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::RTF );
578 const bool bFile = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE );
579 const bool bFileList = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::FILE_LIST );
581 if( mpDropMarker )
583 ImplClearDrawDropMarker();
584 mpDropMarkerObj = nullptr;
587 if( bBookmark && bFile && ( nDropAction & DND_ACTION_MOVE ) && mpViewSh
588 && ( SlideShow::IsRunning(mpViewSh->GetViewShellBase())
589 && !SlideShow::IsInteractiveSlideshow(&mpViewSh->GetViewShellBase()) )) // IASS
590 bBookmark = false;
592 if( bDrawing || bGraphic || bMtf || bBitmap || bBookmark || bFile || bFileList || bXFillExchange || bSBAFormat || bEditEngineODF || bString || bRTF )
593 nRet = nDropAction;
595 // For entries from the navigator, change action copy.
596 if (bBookmark
597 && rTargetHelper.IsDropFormatSupported(
598 SdPageObjsTLV::SdPageObjsTransferable::GetListBoxDropFormatId())
599 && (nDropAction & DND_ACTION_MOVE)!=0)
601 nRet = DND_ACTION_COPY;
608 // destroy drop marker if this is a leaving event
609 if( rEvt.mbLeaving && mpDropMarker )
611 ImplClearDrawDropMarker();
612 mpDropMarkerObj = nullptr;
615 return nRet;
618 sal_Int8 View::ExecuteDrop( const ExecuteDropEvent& rEvt,
619 ::sd::Window* pTargetWindow, sal_uInt16 nPage, SdrLayerID nLayer )
621 SdrPageView* pPV = GetSdrPageView();
622 OUString aActiveLayer = GetActiveLayer();
623 sal_Int8 nDropAction = rEvt.mnAction;
624 sal_Int8 nRet = DND_ACTION_NONE;
626 // destroy drop marker if it is shown
627 if( mpDropMarker )
629 ImplClearDrawDropMarker();
630 mpDropMarkerObj = nullptr;
633 if( !pPV->IsLayerLocked( aActiveLayer ) )
635 const OutlinerView* pOLV = GetTextEditOutlinerView();
636 bool bIsInsideOutlinerView = false;
638 if( pOLV )
640 ::tools::Rectangle aRect( pOLV->GetOutputArea() );
642 const SdrMarkList& rMarkList = GetMarkedObjectList();
643 if( rMarkList.GetMarkCount() == 1 )
645 SdrMark* pMark = rMarkList.GetMark(0);
646 SdrObject* pObj = pMark->GetMarkedSdrObj();
647 aRect.Union( pObj->GetLogicRect() );
650 Point aPos( pOLV->GetWindow()->PixelToLogic( rEvt.maPosPixel ) );
652 if( aRect.Contains( aPos ) )
654 bIsInsideOutlinerView = true;
658 if( !bIsInsideOutlinerView )
660 Point aPos;
661 TransferableDataHelper aDataHelper( rEvt.maDropEvent.Transferable );
663 if( pTargetWindow )
664 aPos = pTargetWindow->PixelToLogic( rEvt.maPosPixel );
666 // handle insert?
667 if ((SdrDragMode::Gradient == GetDragMode())
668 || ((SdrDragMode::Transparence == GetDragMode())
669 && aDataHelper.HasFormat(SotClipboardFormatId::XFA)))
671 const SdrHdlList& rHdlList = GetHdlList();
673 for( size_t n = 0; !nRet && n < rHdlList.GetHdlCount(); ++n )
675 SdrHdl* pIAOHandle = rHdlList.GetHdl( n );
677 if( pIAOHandle && ( SdrHdlKind::Color == pIAOHandle->GetKind() ) )
679 if(pIAOHandle->getOverlayObjectList().isHitPixel(rEvt.maPosPixel))
681 uno::Any const data(aDataHelper.GetAny(SotClipboardFormatId::XFA, u""_ustr));
682 uno::Sequence<beans::NamedValue> props;
683 if (data >>= props)
685 ::comphelper::SequenceAsHashMap const map(props);
686 Color aColor(COL_BLACK);
687 auto const it = map.find(u"FillColor"_ustr);
688 if (it != map.end())
690 XFillColorItem color;
691 color.PutValue(it->second, 0);
692 aColor = color.GetColorValue();
694 static_cast< SdrHdlColor* >( pIAOHandle )->SetColor( aColor, true );
695 nRet = nDropAction;
702 // standard insert?
703 if( !nRet && InsertData( aDataHelper, aPos, nDropAction, true, SotClipboardFormatId::NONE, nPage, nLayer ) )
704 nRet = nDropAction;
706 // special insert?
707 if( !nRet && mpViewSh )
709 INetBookmark aINetBookmark( (OUString()), (OUString()) );
711 // insert bookmark
712 if( aDataHelper.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ) &&
713 aDataHelper.GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK, aINetBookmark ) )
715 SdPageObjsTLV::SdPageObjsTransferable* pPageObjsTransferable = SdPageObjsTLV::SdPageObjsTransferable::getImplementation( aDataHelper.GetXTransferable() );
717 if( pPageObjsTransferable &&
718 ( NAVIGATOR_DRAGTYPE_LINK == pPageObjsTransferable->GetDragType() ||
719 NAVIGATOR_DRAGTYPE_EMBEDDED == pPageObjsTransferable->GetDragType() ) )
721 // insert bookmark from own navigator (handled async. due to possible message box )
722 Application::PostUserEvent( LINK( this, View, ExecuteNavigatorDrop ),
723 new SdNavigatorDropEvent( rEvt, pTargetWindow ) );
724 nRet = nDropAction;
726 else
728 SdrPageView* pPageView = nullptr;
730 SdrObject* pPickObj = PickObj(aPos, getHitTolLog(), pPageView);
731 if (pPickObj)
733 // insert as clip action => jump
734 OUString aBookmark( aINetBookmark.GetURL() );
735 SdAnimationInfo* pInfo = SdDrawDocument::GetAnimationInfo( pPickObj );
737 if( !aBookmark.isEmpty() )
739 bool bCreated = false;
741 presentation::ClickAction eClickAction = presentation::ClickAction_DOCUMENT;
743 sal_Int32 nIndex = aBookmark.indexOf( '#' );
744 if( nIndex != -1 )
746 const std::u16string_view aDocName( aBookmark.subView( 0, nIndex ) );
748 if (mpDocSh->GetMedium()->GetName() == aDocName || aDocName == mpDocSh->GetName())
750 // internal jump, only use the part after and including '#'
751 eClickAction = presentation::ClickAction_BOOKMARK;
752 aBookmark = aBookmark.copy( nIndex+1 );
756 if( !pInfo )
758 pInfo = SdDrawDocument::GetShapeUserData( *pPickObj, true );
759 bCreated = true;
762 // create undo action with old and new sizes
763 std::unique_ptr<SdAnimationPrmsUndoAction> pAction(new SdAnimationPrmsUndoAction(&mrDoc, pPickObj, bCreated));
764 pAction->SetActive(pInfo->mbActive, pInfo->mbActive);
765 pAction->SetEffect(pInfo->meEffect, pInfo->meEffect);
766 pAction->SetTextEffect(pInfo->meTextEffect, pInfo->meTextEffect);
767 pAction->SetSpeed(pInfo->meSpeed, pInfo->meSpeed);
768 pAction->SetDim(pInfo->mbDimPrevious, pInfo->mbDimPrevious);
769 pAction->SetDimColor(pInfo->maDimColor, pInfo->maDimColor);
770 pAction->SetDimHide(pInfo->mbDimHide, pInfo->mbDimHide);
771 pAction->SetSoundOn(pInfo->mbSoundOn, pInfo->mbSoundOn);
772 pAction->SetSound(pInfo->maSoundFile, pInfo->maSoundFile);
773 pAction->SetPlayFull(pInfo->mbPlayFull, pInfo->mbPlayFull);
774 pAction->SetClickAction(pInfo->meClickAction, eClickAction);
775 pAction->SetBookmark(pInfo->GetBookmark(), aBookmark);
776 pAction->SetVerb(pInfo->mnVerb, pInfo->mnVerb);
777 pAction->SetSecondEffect(pInfo->meSecondEffect, pInfo->meSecondEffect);
778 pAction->SetSecondSpeed(pInfo->meSecondSpeed, pInfo->meSecondSpeed);
779 pAction->SetSecondSoundOn(pInfo->mbSecondSoundOn, pInfo->mbSecondSoundOn);
780 pAction->SetSecondPlayFull(pInfo->mbSecondPlayFull, pInfo->mbSecondPlayFull);
782 OUString aString(SdResId(STR_UNDO_ANIMATION));
783 pAction->SetComment(aString);
784 mpDocSh->GetUndoManager()->AddUndoAction(std::move(pAction));
785 pInfo->meClickAction = eClickAction;
786 pInfo->SetBookmark( aBookmark );
787 mrDoc.SetChanged();
789 nRet = nDropAction;
792 else if( auto pDrawViewShell = dynamic_cast< DrawViewShell *>( mpViewSh ) )
794 // insert as normal URL button
795 pDrawViewShell->InsertURLButton( aINetBookmark.GetURL(), aINetBookmark.GetDescription(), OUString(), &aPos );
796 nRet = nDropAction;
804 return nRet;
807 IMPL_LINK( View, ExecuteNavigatorDrop, void*, p, void )
809 SdNavigatorDropEvent* pSdNavigatorDropEvent = static_cast<SdNavigatorDropEvent*>(p);
810 TransferableDataHelper aDataHelper( pSdNavigatorDropEvent->maDropEvent.Transferable );
811 SdPageObjsTLV::SdPageObjsTransferable* pPageObjsTransferable = SdPageObjsTLV::SdPageObjsTransferable::getImplementation( aDataHelper.GetXTransferable() );
812 INetBookmark aINetBookmark;
814 if( pPageObjsTransferable && aDataHelper.GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK, aINetBookmark ) )
816 Point aPos;
817 OUString aBookmark;
818 SdPage* pPage = static_cast<SdPage*>( GetSdrPageView()->GetPage() );
819 sal_uInt16 nPgPos = 0xFFFF;
821 if( pSdNavigatorDropEvent->mpTargetWindow )
822 aPos = pSdNavigatorDropEvent->mpTargetWindow->PixelToLogic( pSdNavigatorDropEvent->maPosPixel );
824 const OUString& aURL( aINetBookmark.GetURL() );
825 sal_Int32 nIndex = aURL.indexOf( '#' );
826 if( nIndex != -1 )
827 aBookmark = aURL.copy( nIndex+1 );
829 std::vector<OUString> aExchangeList;
830 std::vector<OUString> aBookmarkList(1,aBookmark);
832 if( !pPage->IsMasterPage() )
834 if( pPage->GetPageKind() == PageKind::Standard )
835 nPgPos = pPage->GetPageNum() + 2;
836 else if( pPage->GetPageKind() == PageKind::Notes )
837 nPgPos = pPage->GetPageNum() + 1;
840 /* In order t ensure unique page names, we test the ones we want to
841 insert. If necessary. we put them into and replacement list (bNameOK
842 == sal_False -> User canceled). */
843 bool bLink = pPageObjsTransferable->GetDragType() == NAVIGATOR_DRAGTYPE_LINK;
844 bool bNameOK = GetExchangeList( aExchangeList, aBookmarkList, 2 );
846 /* Since we don't know the type (page or object), we fill a list with
847 pages and objects.
848 Of course we have problems if there are pages and objects with the
849 same name!!! */
850 if( bNameOK )
852 mrDoc.InsertBookmark( aBookmarkList, aExchangeList,
853 bLink, nPgPos,
854 &pPageObjsTransferable->GetDocShell(),
855 &aPos );
859 delete pSdNavigatorDropEvent;
862 bool View::GetExchangeList (std::vector<OUString> &rExchangeList,
863 std::vector<OUString> &rBookmarkList,
864 const sal_uInt16 nType)
866 assert(rExchangeList.empty());
868 bool bListIdentical = true; ///< Bookmark list and exchange list are identical
869 bool bNameOK = true; ///< name is unique
871 for ( const auto& rBookmark : rBookmarkList )
873 OUString aNewName = rBookmark;
875 if( nType == 0 || nType == 2 )
876 bNameOK = mpDocSh->CheckPageName(mpViewSh->GetFrameWeld(), aNewName);
878 if( bNameOK && ( nType == 1 || nType == 2 ) )
880 if( mrDoc.GetObj( aNewName ) )
882 OUString aTitle(SdResId(STR_TITLE_NAMEGROUP));
883 OUString aDesc(SdResId(STR_DESC_NAMEGROUP));
885 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
886 ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(mpViewSh->GetFrameWeld(), aNewName, aDesc));
888 pDlg->SetEditHelpId( HID_SD_NAMEDIALOG_OBJECT );
890 bNameOK = false;
891 pDlg->SetText( aTitle );
893 while( !bNameOK && pDlg->Execute() == RET_OK )
895 aNewName = pDlg->GetName();
897 if( !mrDoc.GetObj( aNewName ) )
898 bNameOK = true;
903 bListIdentical = rBookmark == aNewName;
905 rExchangeList.push_back(aNewName);
907 if (!bNameOK)
908 break;
911 // Exchange list is identical to bookmark list
912 if( !rExchangeList.empty() && bListIdentical )
913 rExchangeList.clear();
915 return bNameOK;
918 } // end of namespace sd
920 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */