Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/view/sdview2.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <View.hxx>
21
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 <svtools/dlgname.hxx>
28
#include <svx/svdoole2.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>
37
38
#include <svtools/embedtransfer.hxx>
39
#include <tools/debug.hxx>
40
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>
56
57
#include <slideshow.hxx>
58
#include <memory>
59
60
namespace sd {
61
62
using namespace ::com::sun::star;
63
64
namespace {
65
66
struct SdNavigatorDropEvent : public ExecuteDropEvent
67
{
68
    VclPtr< ::sd::Window>    mpTargetWindow;
69
70
    SdNavigatorDropEvent (
71
        const ExecuteDropEvent& rEvt,
72
        ::sd::Window* pTargetWindow )
73
0
        : ExecuteDropEvent( rEvt ),
74
0
          mpTargetWindow( pTargetWindow )
75
0
    {}
76
};
77
78
}
79
80
css::uno::Reference< css::datatransfer::XTransferable > View::CreateClipboardDataObject()
81
0
{
82
    // since SdTransferable::CopyToClipboard is called, this
83
    // dynamically created object is destroyed automatically
84
0
    rtl::Reference<SdTransferable> pTransferable = new SdTransferable( &mrDoc, nullptr, false );
85
86
0
    SdModule::get()->pTransferClip = pTransferable.get();
87
88
0
    mrDoc.CreatingDataObj( pTransferable.get() );
89
0
    pTransferable->SetWorkDocument( static_cast<SdDrawDocument*>(CreateMarkedObjModel().release()) );
90
0
    mrDoc.CreatingDataObj( nullptr );
91
92
    // #112978# need to use GetAllMarkedBoundRect instead of GetAllMarkedRect to get
93
    // fat lines correctly
94
0
    const ::tools::Rectangle                 aMarkRect( GetAllMarkedBoundRect() );
95
    // tdf#118171 - snap rectangles of objects without line width
96
0
    const ::tools::Rectangle aMarkBoundRect(GetAllMarkedRect());
97
0
    std::unique_ptr<TransferableObjectDescriptor> pObjDesc(new TransferableObjectDescriptor);
98
0
    SdrOle2Obj*                     pSdrOleObj = nullptr;
99
0
    SdrPageView*                    pPgView = GetSdrPageView();
100
0
    SdPage*                         pOldPage = pPgView ? static_cast<SdPage*>( pPgView->GetPage() ) : nullptr;
101
0
    SdPage*                         pNewPage = const_cast<SdPage*>(static_cast<const SdPage*>( pTransferable->GetWorkDocument()->GetPage( 0 ) ));
102
103
0
    if( pOldPage )
104
0
    {
105
0
        pNewPage->SetSize( pOldPage->GetSize() );
106
0
        pNewPage->SetLayoutName( pOldPage->GetLayoutName() );
107
0
    }
108
109
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
110
0
    if( rMarkList.GetMarkCount() == 1 )
111
0
    {
112
0
        SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
113
114
0
        if( auto pOle2Obj = dynamic_cast<SdrOle2Obj *>( pObj ) )
115
0
            if( pOle2Obj->GetObjRef() )
116
0
            {
117
                // If object has no persistence it must be copied as part of the document
118
0
                try
119
0
                {
120
0
                    uno::Reference< embed::XEmbedPersist > xPersObj( pOle2Obj->GetObjRef(), uno::UNO_QUERY );
121
0
                    if ( xPersObj.is() && xPersObj->hasEntry() )
122
0
                         pSdrOleObj = pOle2Obj;
123
0
                }
124
0
                catch( uno::Exception& )
125
0
                {}
126
0
            }
127
0
    }
128
129
0
    if( pSdrOleObj )
130
0
        SvEmbedTransferHelper::FillTransferableObjectDescriptor( *pObjDesc, pSdrOleObj->GetObjRef(), pSdrOleObj->GetGraphic(), pSdrOleObj->GetAspect() );
131
0
    else
132
0
        pTransferable->GetWorkDocument()->GetDocSh()->FillTransferableObjectDescriptor( *pObjDesc );
133
134
0
    if( mpDocSh )
135
0
        pObjDesc->maDisplayName = mpDocSh->GetMedium()->GetURLObject().GetURLNoPass();
136
137
0
    pObjDesc->maSize = aMarkRect.GetSize();
138
139
0
    pTransferable->SetStartPos( aMarkRect.TopLeft() );
140
0
    pTransferable->SetBoundStartPos(aMarkBoundRect.TopLeft());
141
0
    pTransferable->SetObjectDescriptor( std::move(pObjDesc) );
142
0
    pTransferable->CopyToClipboard( mpViewSh->GetActiveWindow() );
143
144
0
    return pTransferable;
145
0
}
146
147
css::uno::Reference< css::datatransfer::XTransferable > View::CreateDragDataObject( View* pWorkView, vcl::Window& rWindow, const Point& rDragPos )
148
0
{
149
0
    rtl::Reference<SdTransferable> pTransferable = new SdTransferable( &mrDoc, pWorkView, false );
150
151
0
    SdModule::get()->pTransferDrag = pTransferable.get();
152
153
0
    std::unique_ptr<TransferableObjectDescriptor> pObjDesc(new TransferableObjectDescriptor);
154
0
    OUString                        aDisplayName;
155
0
    SdrOle2Obj*                     pSdrOleObj = nullptr;
156
157
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
158
0
    if( rMarkList.GetMarkCount() == 1 )
159
0
    {
160
0
        SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
161
162
0
        if( auto pOle2Obj = dynamic_cast<SdrOle2Obj *>( pObj ) )
163
0
            if( pOle2Obj->GetObjRef() )
164
0
            {
165
                // If object has no persistence it must be copied as part of the document
166
0
                try
167
0
                {
168
0
                    uno::Reference< embed::XEmbedPersist > xPersObj( pOle2Obj->GetObjRef(), uno::UNO_QUERY );
169
0
                    if ( xPersObj.is() && xPersObj->hasEntry() )
170
0
                         pSdrOleObj = pOle2Obj;
171
0
                }
172
0
                catch( uno::Exception& )
173
0
                {}
174
0
            }
175
0
    }
176
177
0
    if( mpDocSh )
178
0
        aDisplayName = mpDocSh->GetMedium()->GetURLObject().GetURLNoPass();
179
180
0
    if( pSdrOleObj )
181
0
        SvEmbedTransferHelper::FillTransferableObjectDescriptor( *pObjDesc, pSdrOleObj->GetObjRef(), pSdrOleObj->GetGraphic(), pSdrOleObj->GetAspect() );
182
0
    else if (mpDocSh)
183
0
        mpDocSh->FillTransferableObjectDescriptor( *pObjDesc );
184
185
0
    pObjDesc->maSize = GetAllMarkedRect().GetSize();
186
0
    pObjDesc->maDragStartPos = rDragPos;
187
0
    pObjDesc->maDisplayName = aDisplayName;
188
189
0
    pTransferable->SetStartPos( rDragPos );
190
0
    pTransferable->SetObjectDescriptor( std::move(pObjDesc) );
191
0
    pTransferable->StartDrag( &rWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
192
193
0
    return pTransferable;
194
0
}
195
196
css::uno::Reference< css::datatransfer::XTransferable > View::CreateSelectionDataObject( View* pWorkView )
197
0
{
198
0
    rtl::Reference<SdTransferable> pTransferable = new SdTransferable( &mrDoc, pWorkView, true );
199
0
    std::unique_ptr<TransferableObjectDescriptor> pObjDesc(new TransferableObjectDescriptor);
200
0
    const ::tools::Rectangle                 aMarkRect( GetAllMarkedRect() );
201
202
0
    SdModule::get()->pTransferSelection = pTransferable.get();
203
204
0
    if( mpDocSh )
205
0
    {
206
0
        mpDocSh->FillTransferableObjectDescriptor( *pObjDesc );
207
0
        pObjDesc->maDisplayName = mpDocSh->GetMedium()->GetURLObject().GetURLNoPass();
208
0
    }
209
210
0
    pObjDesc->maSize = aMarkRect.GetSize();
211
212
0
    pTransferable->SetStartPos( aMarkRect.TopLeft() );
213
0
    pTransferable->SetObjectDescriptor( std::move(pObjDesc) );
214
0
    pTransferable->CopyToPrimarySelection();
215
216
0
    return pTransferable;
217
0
}
218
219
void View::UpdateSelectionClipboard() // false case
220
0
{
221
0
    if (!mpViewSh)
222
0
        return;
223
0
    if (!mpViewSh->GetActiveWindow())
224
0
        return;
225
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
226
0
    if (rMarkList.GetMarkCount())
227
0
        CreateSelectionDataObject( this );
228
0
    else
229
0
        ClearSelectionClipboard();
230
0
}
231
232
void View::ClearSelectionClipboard() // true case
233
0
{
234
0
    if (!mpViewSh)
235
0
        return;
236
0
    if (!mpViewSh->GetActiveWindow())
237
0
        return;
238
0
    SdModule* mod = SdModule::get();
239
0
    if (mod->pTransferSelection && mod->pTransferSelection->GetView() == this)
240
0
    {
241
0
        TransferableHelper::ClearPrimarySelection();
242
0
        mod->pTransferSelection = nullptr;
243
0
    }
244
0
}
245
246
void View::DoCut()
247
0
{
248
0
    const OutlinerView* pOLV = GetTextEditOutlinerView();
249
250
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
251
0
    if( pOLV )
252
0
        const_cast<OutlinerView*>(pOLV)->Cut();
253
0
    else if( rMarkList.GetMarkCount() != 0 )
254
0
    {
255
0
        OUString aStr(SdResId(STR_UNDO_CUT));
256
257
0
        DoCopy();
258
0
        BegUndo(aStr + " " + rMarkList.GetMarkDescription());
259
0
        DeleteMarked();
260
0
        EndUndo();
261
0
    }
262
0
}
263
264
void View::DoCopy(bool /*bMergeMasterPagesOnly*/)
265
0
{
266
0
    const OutlinerView* pOLV = GetTextEditOutlinerView();
267
268
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
269
0
    if( pOLV )
270
0
        const_cast<OutlinerView*>(pOLV)->Copy();
271
0
    else if( rMarkList.GetMarkCount() != 0 )
272
0
    {
273
0
        BrkAction();
274
0
        CreateClipboardDataObject();
275
0
    }
276
0
}
277
278
void View::DoPaste (::sd::Window* pWindow,bool /*bMergeMasterPagesOnly*/)
279
0
{
280
0
    TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( mpViewSh->GetActiveWindow() ) );
281
0
    if( !aDataHelper.GetTransferable().is() )
282
0
        return; // empty clipboard?
283
284
0
    const OutlinerView* pOLV = GetTextEditOutlinerView();
285
286
0
    if( pOLV && EditEngine::HasValidData( aDataHelper.GetTransferable() ) )
287
0
    {
288
0
        SdrObject* pObj = GetTextEditObject();
289
0
        SdPage* pPage = static_cast<SdPage*>(pObj ? pObj->getSdrPageFromSdrObject() : nullptr);
290
        // tdf#139269 - prevent text pasting into readonly areas of master views
291
0
        if (pPage && pPage->IsMasterPage() && pOLV->IsReadOnly())
292
0
            return;
293
294
0
        const_cast< OutlinerView* >(pOLV)->PasteSpecial();
295
0
        ::Outliner& rOutliner = pOLV->GetOutliner();
296
297
0
        if( pObj && pPage && pPage->GetPresObjKind(pObj) == PresObjKind::Title )
298
0
        {
299
            // remove all hard linebreaks from the title
300
0
            if (rOutliner.GetParagraphCount() > 1)
301
0
            {
302
0
                bool bOldUpdateMode = rOutliner.SetUpdateLayout( false );
303
304
0
                const EditEngine& rEdit = rOutliner.GetEditEngine();
305
0
                const sal_Int32 nParaCount = rEdit.GetParagraphCount();
306
307
0
                for( sal_Int32 nPara = nParaCount - 2; nPara >= 0; nPara-- )
308
0
                {
309
0
                    const sal_Int32 nParaLen = rEdit.GetTextLen( nPara );
310
0
                    rOutliner.QuickInsertLineBreak(ESelection(nPara, nParaLen, nPara + 1, 0));
311
0
                }
312
313
0
                DBG_ASSERT( rEdit.GetParagraphCount() <= 1, "Titleobject contains hard line breaks" );
314
0
                rOutliner.SetUpdateLayout(bOldUpdateMode);
315
0
            }
316
0
        }
317
318
0
        if( !mrDoc.IsChanged() )
319
0
        {
320
0
            if (rOutliner.IsModified())
321
0
                mrDoc.SetChanged();
322
0
        }
323
0
    }
324
0
    else
325
0
    {
326
0
        Point aPos = pWindow->GetVisibleCenter();
327
0
        DrawViewShell* pDrViewSh = static_cast<DrawViewShell*>( mpDocSh->GetViewShell() );
328
329
0
        if (pDrViewSh != nullptr)
330
0
        {
331
0
            sal_Int8    nDnDAction = DND_ACTION_COPY;
332
0
            if( !InsertData( aDataHelper, aPos, nDnDAction, false ) )
333
0
            {
334
0
                INetBookmark    aINetBookmark( u""_ustr, u""_ustr );
335
336
0
                if( ( aDataHelper.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ) &&
337
0
                      aDataHelper.GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK, aINetBookmark ) ) ||
338
0
                    ( aDataHelper.HasFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR ) &&
339
0
                      aDataHelper.GetINetBookmark( SotClipboardFormatId::FILEGRPDESCRIPTOR, aINetBookmark ) ) ||
340
0
                    ( aDataHelper.HasFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR ) &&
341
0
                      aDataHelper.GetINetBookmark( SotClipboardFormatId::UNIFORMRESOURCELOCATOR, aINetBookmark ) ) )
342
0
                {
343
0
                    pDrViewSh->InsertURLField(aINetBookmark.GetURL(), aINetBookmark.GetDescription(), u""_ustr, u""_ustr);
344
0
                }
345
0
            }
346
0
        }
347
0
    }
348
0
}
349
350
void View::StartDrag( const Point& rStartPos, vcl::Window* pWindow )
351
0
{
352
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
353
0
    if (rMarkList.GetMarkCount() == 0 || !IsAction() || !mpViewSh || !pWindow)
354
0
        return;
355
356
0
    BrkAction();
357
358
0
    if( IsTextEdit() )
359
0
        SdrEndTextEdit();
360
361
0
    if (DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(mpDocSh ? mpDocSh->GetViewShell() : nullptr))
362
0
    {
363
0
        const rtl::Reference<FuPoor>& xFunction(pDrawViewShell->GetCurrentFunction());
364
0
        if (FuDraw* pFunction = dynamic_cast<FuDraw*>(xFunction.get()))
365
0
            pFunction->ForcePointer();
366
0
    }
367
368
0
    mpDragSrcMarkList.reset( new SdrMarkList(GetMarkedObjectList()) );
369
0
    mnDragSrcPgNum = GetSdrPageView()->GetPage()->GetPageNum();
370
371
0
    CreateDragDataObject( this, *pWindow, rStartPos );
372
0
}
373
374
void View::DragFinished( sal_Int8 nDropAction )
375
0
{
376
0
    const bool bUndo = IsUndoEnabled();
377
0
    const bool bGroupUndo = bUndo && mpDragSrcMarkList;
378
0
    if (bGroupUndo)
379
0
    {
380
0
        OUString aStr(SdResId(STR_UNDO_DRAGDROP));
381
0
        BegUndo(aStr + " " + mpDragSrcMarkList->GetMarkDescription());
382
0
    }
383
384
0
    SdTransferable* pDragTransferable = SdModule::get()->pTransferDrag;
385
386
0
    if( pDragTransferable )
387
0
        pDragTransferable->SetView( nullptr );
388
389
0
    if( ( nDropAction & DND_ACTION_MOVE ) &&
390
0
        pDragTransferable && !pDragTransferable->IsInternalMove() &&
391
0
        mpDragSrcMarkList && mpDragSrcMarkList->GetMarkCount() &&
392
0
        !IsPresObjSelected() )
393
0
    {
394
0
        mpDragSrcMarkList->ForceSort();
395
396
0
        if( bUndo )
397
0
            BegUndo();
398
399
0
        const size_t nCnt = mpDragSrcMarkList->GetMarkCount();
400
401
0
        for( size_t nm = nCnt; nm>0; )
402
0
        {
403
0
            --nm;
404
0
            SdrMark* pM=mpDragSrcMarkList->GetMark(nm);
405
0
            if( bUndo )
406
0
                AddUndo(mrDoc.GetSdrUndoFactory().CreateUndoDeleteObject(*pM->GetMarkedSdrObj()));
407
0
        }
408
409
0
        mpDragSrcMarkList->GetMark(0)->GetMarkedSdrObj()->GetOrdNum();
410
411
0
        for (size_t nm = nCnt; nm>0;)
412
0
        {
413
0
            --nm;
414
0
            SdrMark* pM=mpDragSrcMarkList->GetMark(nm);
415
0
            SdrObject* pObj=pM->GetMarkedSdrObj();
416
417
0
            if( pObj && pObj->getSdrPageFromSdrObject() )
418
0
            {
419
0
                const size_t nOrdNum = pObj->GetOrdNumDirect();
420
0
                rtl::Reference<SdrObject> pChkObj = pObj->getSdrPageFromSdrObject()->RemoveObject(nOrdNum);
421
0
                DBG_ASSERT(pChkObj.get()==pObj,"pChkObj!=pObj in RemoveObject()");
422
0
            }
423
0
        }
424
425
0
        if( bUndo )
426
0
            EndUndo();
427
0
    }
428
429
0
    if( pDragTransferable )
430
0
        pDragTransferable->SetInternalMove( false );
431
432
0
    if (bGroupUndo)
433
0
        EndUndo();
434
0
    mnDragSrcPgNum = SDRPAGE_NOTFOUND;
435
0
    mpDragSrcMarkList.reset();
436
0
}
437
438
sal_Int8 View::AcceptDrop( const AcceptDropEvent& rEvt, DropTargetHelper& rTargetHelper,
439
                           SdrLayerID nLayer )
440
0
{
441
0
    OUString        aLayerName = GetActiveLayer();
442
0
    SdrPageView*    pPV = GetSdrPageView();
443
0
    sal_Int8        nDropAction = rEvt.mnAction;
444
0
    sal_Int8        nRet = DND_ACTION_NONE;
445
446
0
    if( nLayer != SDRLAYER_NOTFOUND )
447
0
    {
448
0
        SdrLayerAdmin& rLayerAdmin = mrDoc.GetLayerAdmin();
449
0
        SdrLayer* pLayer = rLayerAdmin.GetLayerPerID(nLayer);
450
0
        assert(pLayer && "layer missing");
451
0
        aLayerName = pLayer->GetName();
452
0
    }
453
454
0
    if( mbIsDropAllowed && !pPV->IsLayerLocked( aLayerName ) && pPV->IsLayerVisible( aLayerName ) )
455
0
    {
456
0
        const OutlinerView* pOLV = GetTextEditOutlinerView();
457
0
        bool                bIsInsideOutlinerView = false;
458
459
0
        if( pOLV )
460
0
        {
461
0
            ::tools::Rectangle aRect( pOLV->GetOutputArea() );
462
463
0
            const SdrMarkList& rMarkList = GetMarkedObjectList();
464
0
            if (rMarkList.GetMarkCount() == 1)
465
0
            {
466
0
                SdrMark* pMark = rMarkList.GetMark(0);
467
0
                SdrObject* pObj = pMark->GetMarkedSdrObj();
468
0
                aRect.Union( pObj->GetLogicRect() );
469
0
            }
470
471
0
            if( aRect.Contains( pOLV->GetWindow()->PixelToLogic( rEvt.maPosPixel ) ) )
472
0
            {
473
0
                bIsInsideOutlinerView = true;
474
0
            }
475
0
        }
476
477
0
        if( !bIsInsideOutlinerView )
478
0
        {
479
0
            SdTransferable* pDragTransferable = SdModule::get()->pTransferDrag;
480
481
0
            if(pDragTransferable && (nDropAction & DND_ACTION_LINK))
482
0
            {
483
                // suppress own data when it's intention is to use it as fill information
484
0
                pDragTransferable = nullptr;
485
0
            }
486
487
0
            if( pDragTransferable )
488
0
            {
489
0
                const View* pSourceView = pDragTransferable->GetView();
490
491
0
                if( pDragTransferable->IsPageTransferable() )
492
0
                {
493
0
                    nRet = DND_ACTION_COPY;
494
0
                }
495
0
                else if( pSourceView )
496
0
                {
497
0
                    if( !( nDropAction & DND_ACTION_LINK ) ||
498
0
                        !pSourceView->GetDocSh()->GetMedium()->GetName().isEmpty() )
499
0
                    {
500
0
                        nRet = nDropAction;
501
0
                    }
502
0
                }
503
0
            }
504
0
            else
505
0
            {
506
0
                const bool  bDrawing = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::DRAWING );
507
0
                const bool  bGraphic = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::SVXB );
508
0
                const bool  bMtf = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::GDIMETAFILE );
509
0
                const bool  bBitmap = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::BITMAP );
510
0
                bool        bBookmark = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::NETSCAPE_BOOKMARK );
511
0
                bool        bXFillExchange = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::XFA );
512
513
                // check handle insert
514
0
                if ((bXFillExchange && (SdrDragMode::Gradient == GetDragMode()))
515
0
                    || (SdrDragMode::Transparence == GetDragMode()))
516
0
                {
517
0
                    const SdrHdlList& rHdlList = GetHdlList();
518
519
0
                    for( size_t n = 0; n < rHdlList.GetHdlCount(); ++n )
520
0
                    {
521
0
                        SdrHdl* pIAOHandle = rHdlList.GetHdl( n );
522
523
0
                        if( pIAOHandle && ( SdrHdlKind::Color == pIAOHandle->GetKind() ) )
524
0
                        {
525
0
                            if(pIAOHandle->getOverlayObjectList().isHitPixel(rEvt.maPosPixel))
526
0
                            {
527
0
                                nRet = nDropAction;
528
0
                                static_cast< SdrHdlColor* >( pIAOHandle )->SetSize( SDR_HANDLE_COLOR_SIZE_SELECTED );
529
0
                            }
530
0
                            else
531
0
                            {
532
0
                                static_cast< SdrHdlColor* >( pIAOHandle )->SetSize( SDR_HANDLE_COLOR_SIZE_NORMAL );
533
0
                            }
534
0
                        }
535
0
                    }
536
0
                }
537
538
                // check object insert
539
0
                if( !nRet && ( bXFillExchange || ( ( bDrawing || bGraphic || bMtf || bBitmap || bBookmark ) && ( nDropAction & DND_ACTION_LINK ) ) ) )
540
0
                {
541
0
                    SdrPageView*    pPageView = nullptr;
542
0
                    ::sd::Window* pWindow = mpViewSh->GetActiveWindow();
543
0
                    Point           aPos( pWindow->PixelToLogic( rEvt.maPosPixel ) );
544
0
                    SdrObject* pPickObj = PickObj(aPos, getHitTolLog(), pPageView);
545
0
                    bool            bIsPresTarget = false;
546
547
0
                    if (pPickObj && (pPickObj->IsEmptyPresObj() || pPickObj->GetUserCall()))
548
0
                    {
549
0
                        SdPage* pPage = static_cast<SdPage*>( pPickObj->getSdrPageFromSdrObject() );
550
551
0
                        if( pPage && pPage->IsMasterPage() )
552
0
                            bIsPresTarget = pPage->IsPresObj( pPickObj );
553
0
                    }
554
555
0
                    if (pPickObj && !bIsPresTarget && (bGraphic || bMtf || bBitmap || bXFillExchange))
556
0
                    {
557
0
                        if( mpDropMarkerObj != pPickObj )
558
0
                        {
559
0
                            mpDropMarkerObj = pPickObj;
560
0
                            ImplClearDrawDropMarker();
561
562
0
                            if(mpDropMarkerObj)
563
0
                            {
564
0
                                mpDropMarker.reset( new SdrDropMarkerOverlay(*this, *mpDropMarkerObj) );
565
0
                            }
566
0
                        }
567
568
0
                        nRet = nDropAction;
569
0
                    }
570
0
                    else
571
0
                        bXFillExchange = false;
572
0
                }
573
574
                // check normal insert
575
0
                if( !nRet )
576
0
                {
577
0
                    const bool  bSBAFormat = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::SVX_FORMFIELDEXCH );
578
0
                    const bool  bEditEngineODF = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::EDITENGINE_ODF_TEXT_FLAT );
579
0
                    const bool  bString = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::STRING );
580
0
                    const bool  bRTF = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::RTF );
581
0
                    const bool  bFile = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE );
582
0
                    const bool  bFileList = rTargetHelper.IsDropFormatSupported( SotClipboardFormatId::FILE_LIST );
583
584
0
                    if( mpDropMarker )
585
0
                    {
586
0
                        ImplClearDrawDropMarker();
587
0
                        mpDropMarkerObj = nullptr;
588
0
                    }
589
590
0
                    if( bBookmark && bFile && ( nDropAction & DND_ACTION_MOVE ) && mpViewSh
591
0
                        && ( SlideShow::IsRunning(mpViewSh->GetViewShellBase())
592
0
                        && !SlideShow::IsInteractiveSlideshow(mpViewSh->GetViewShellBase()) )) // IASS
593
0
                        bBookmark = false;
594
595
0
                    if( bDrawing || bGraphic || bMtf || bBitmap || bBookmark || bFile || bFileList || bXFillExchange || bSBAFormat || bEditEngineODF || bString || bRTF )
596
0
                        nRet = nDropAction;
597
598
                    // For entries from the navigator, change action copy.
599
0
                    if (bBookmark
600
0
                        && rTargetHelper.IsDropFormatSupported(
601
0
                            SdPageObjsTLV::SdPageObjsTransferable::GetListBoxDropFormatId())
602
0
                        && (nDropAction & DND_ACTION_MOVE)!=0)
603
0
                    {
604
0
                        nRet = DND_ACTION_COPY;
605
0
                    }
606
0
                }
607
0
            }
608
0
        }
609
0
    }
610
611
    // destroy drop marker if this is a leaving event
612
0
    if( rEvt.mbLeaving && mpDropMarker )
613
0
    {
614
0
        ImplClearDrawDropMarker();
615
0
        mpDropMarkerObj = nullptr;
616
0
    }
617
618
0
    return nRet;
619
0
}
620
621
sal_Int8 View::ExecuteDrop( const ExecuteDropEvent& rEvt,
622
                              ::sd::Window* pTargetWindow, sal_uInt16 nPage, SdrLayerID nLayer )
623
0
{
624
0
    SdrPageView*    pPV = GetSdrPageView();
625
0
    OUString        aActiveLayer = GetActiveLayer();
626
0
    sal_Int8        nDropAction = rEvt.mnAction;
627
0
    sal_Int8        nRet = DND_ACTION_NONE;
628
629
    // destroy drop marker if it is shown
630
0
    if( mpDropMarker )
631
0
    {
632
0
        ImplClearDrawDropMarker();
633
0
        mpDropMarkerObj = nullptr;
634
0
    }
635
636
0
    if( !pPV->IsLayerLocked( aActiveLayer ) )
637
0
    {
638
0
        const OutlinerView* pOLV = GetTextEditOutlinerView();
639
0
        bool                bIsInsideOutlinerView = false;
640
641
0
        if( pOLV )
642
0
        {
643
0
            ::tools::Rectangle aRect( pOLV->GetOutputArea() );
644
645
0
            const SdrMarkList& rMarkList = GetMarkedObjectList();
646
0
            if( rMarkList.GetMarkCount() == 1 )
647
0
            {
648
0
                SdrMark* pMark = rMarkList.GetMark(0);
649
0
                SdrObject* pObj = pMark->GetMarkedSdrObj();
650
0
                aRect.Union( pObj->GetLogicRect() );
651
0
            }
652
653
0
            Point aPos( pOLV->GetWindow()->PixelToLogic( rEvt.maPosPixel ) );
654
655
0
            if( aRect.Contains( aPos ) )
656
0
            {
657
0
                bIsInsideOutlinerView = true;
658
0
            }
659
0
        }
660
661
0
        if( !bIsInsideOutlinerView )
662
0
        {
663
0
            Point                   aPos;
664
0
            TransferableDataHelper  aDataHelper( rEvt.maDropEvent.Transferable );
665
666
0
            if( pTargetWindow )
667
0
                aPos = pTargetWindow->PixelToLogic( rEvt.maPosPixel );
668
669
            // handle insert?
670
0
            if ((SdrDragMode::Gradient == GetDragMode())
671
0
                || ((SdrDragMode::Transparence == GetDragMode())
672
0
                    && aDataHelper.HasFormat(SotClipboardFormatId::XFA)))
673
0
            {
674
0
                const SdrHdlList& rHdlList = GetHdlList();
675
676
0
                for( size_t n = 0; !nRet && n < rHdlList.GetHdlCount(); ++n )
677
0
                {
678
0
                    SdrHdl* pIAOHandle = rHdlList.GetHdl( n );
679
680
0
                    if( pIAOHandle && ( SdrHdlKind::Color == pIAOHandle->GetKind() ) )
681
0
                    {
682
0
                        if(pIAOHandle->getOverlayObjectList().isHitPixel(rEvt.maPosPixel))
683
0
                        {
684
0
                            uno::Any const data(aDataHelper.GetAny(SotClipboardFormatId::XFA, u""_ustr));
685
0
                            uno::Sequence<beans::NamedValue> props;
686
0
                            if (data >>= props)
687
0
                            {
688
0
                                ::comphelper::SequenceAsHashMap const map(props);
689
0
                                Color aColor(COL_BLACK);
690
0
                                auto const it = map.find(u"FillColor"_ustr);
691
0
                                if (it != map.end())
692
0
                                {
693
0
                                    XFillColorItem color;
694
0
                                    color.PutValue(it->second, 0);
695
0
                                    aColor = color.GetColorValue();
696
0
                                }
697
0
                                static_cast< SdrHdlColor* >( pIAOHandle )->SetColor( aColor, true );
698
0
                                nRet = nDropAction;
699
0
                            }
700
0
                        }
701
0
                    }
702
0
                }
703
0
            }
704
705
            // standard insert?
706
0
            if( !nRet && InsertData( aDataHelper, aPos, nDropAction, true, SotClipboardFormatId::NONE, nPage, nLayer ) )
707
0
                nRet = nDropAction;
708
709
            // special insert?
710
0
            if( !nRet && mpViewSh )
711
0
            {
712
0
                INetBookmark    aINetBookmark( (OUString()), (OUString()) );
713
714
                // insert bookmark
715
0
                if( aDataHelper.HasFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ) &&
716
0
                    aDataHelper.GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK, aINetBookmark ) )
717
0
                {
718
0
                    SdPageObjsTLV::SdPageObjsTransferable* pPageObjsTransferable = SdPageObjsTLV::SdPageObjsTransferable::getImplementation( aDataHelper.GetXTransferable() );
719
720
0
                    if( pPageObjsTransferable &&
721
0
                        ( NAVIGATOR_DRAGTYPE_LINK == pPageObjsTransferable->GetDragType() ||
722
0
                          NAVIGATOR_DRAGTYPE_EMBEDDED == pPageObjsTransferable->GetDragType() ) )
723
0
                    {
724
                        // insert bookmark from own navigator (handled async. due to possible message box )
725
0
                        Application::PostUserEvent( LINK( this, View, ExecuteNavigatorDrop ),
726
0
                                                    new SdNavigatorDropEvent( rEvt, pTargetWindow ) );
727
0
                        nRet = nDropAction;
728
0
                    }
729
0
                    else
730
0
                    {
731
0
                        SdrPageView*    pPageView = nullptr;
732
733
0
                        SdrObject* pPickObj = PickObj(aPos, getHitTolLog(), pPageView);
734
0
                        if (pPickObj)
735
0
                        {
736
                            // insert as clip action => jump
737
0
                            OUString       aBookmark( aINetBookmark.GetURL() );
738
0
                            SdAnimationInfo*    pInfo = SdDrawDocument::GetAnimationInfo( pPickObj );
739
740
0
                            if( !aBookmark.isEmpty() )
741
0
                            {
742
0
                                bool bCreated = false;
743
744
0
                                presentation::ClickAction eClickAction = presentation::ClickAction_DOCUMENT;
745
746
0
                                sal_Int32 nIndex = aBookmark.indexOf( '#' );
747
0
                                if( nIndex != -1 )
748
0
                                {
749
0
                                    const std::u16string_view aDocName( aBookmark.subView( 0, nIndex ) );
750
751
0
                                    if (mpDocSh->GetMedium()->GetName() == aDocName || aDocName == mpDocSh->GetName())
752
0
                                    {
753
                                        // internal jump, only use the part after and including '#'
754
0
                                        eClickAction = presentation::ClickAction_BOOKMARK;
755
0
                                        aBookmark = aBookmark.copy( nIndex+1 );
756
0
                                    }
757
0
                                }
758
759
0
                                if( !pInfo )
760
0
                                {
761
0
                                    pInfo = SdDrawDocument::GetShapeUserData( *pPickObj, true );
762
0
                                    bCreated = true;
763
0
                                }
764
765
                                // create undo action with old and new sizes
766
0
                                std::unique_ptr<SdAnimationPrmsUndoAction> pAction(new SdAnimationPrmsUndoAction(mrDoc, pPickObj, bCreated));
767
0
                                pAction->SetActive(pInfo->mbActive, pInfo->mbActive);
768
0
                                pAction->SetEffect(pInfo->meEffect, pInfo->meEffect);
769
0
                                pAction->SetTextEffect(pInfo->meTextEffect, pInfo->meTextEffect);
770
0
                                pAction->SetSpeed(pInfo->meSpeed, pInfo->meSpeed);
771
0
                                pAction->SetDim(pInfo->mbDimPrevious, pInfo->mbDimPrevious);
772
0
                                pAction->SetDimColor(pInfo->maDimColor, pInfo->maDimColor);
773
0
                                pAction->SetDimHide(pInfo->mbDimHide, pInfo->mbDimHide);
774
0
                                pAction->SetSoundOn(pInfo->mbSoundOn, pInfo->mbSoundOn);
775
0
                                pAction->SetSound(pInfo->maSoundLink, pInfo->maSoundLink);
776
0
                                pAction->SetPlayFull(pInfo->mbPlayFull, pInfo->mbPlayFull);
777
0
                                pAction->SetClickAction(pInfo->meClickAction, eClickAction);
778
0
                                pAction->SetBookmark(pInfo->GetBookmark(), aBookmark);
779
0
                                pAction->SetVerb(pInfo->mnVerb, pInfo->mnVerb);
780
0
                                pAction->SetSecondEffect(pInfo->meSecondEffect, pInfo->meSecondEffect);
781
0
                                pAction->SetSecondSpeed(pInfo->meSecondSpeed, pInfo->meSecondSpeed);
782
0
                                pAction->SetSecondSoundOn(pInfo->mbSecondSoundOn, pInfo->mbSecondSoundOn);
783
0
                                pAction->SetSecondPlayFull(pInfo->mbSecondPlayFull, pInfo->mbSecondPlayFull);
784
785
0
                                OUString aString(SdResId(STR_UNDO_ANIMATION));
786
0
                                pAction->SetComment(aString);
787
0
                                mpDocSh->GetUndoManager()->AddUndoAction(std::move(pAction));
788
0
                                pInfo->meClickAction = eClickAction;
789
0
                                pInfo->SetBookmark( aBookmark );
790
0
                                mrDoc.SetChanged();
791
792
0
                                nRet = nDropAction;
793
0
                            }
794
0
                        }
795
0
                        else if( auto pDrawViewShell = dynamic_cast< DrawViewShell *>( mpViewSh ) )
796
0
                        {
797
                            // insert as normal URL button
798
0
                            pDrawViewShell->InsertURLButton( aINetBookmark.GetURL(), aINetBookmark.GetDescription(), OUString(), &aPos );
799
0
                            nRet = nDropAction;
800
0
                        }
801
0
                    }
802
0
                }
803
0
            }
804
0
        }
805
0
    }
806
807
0
    return nRet;
808
0
}
809
810
IMPL_LINK( View, ExecuteNavigatorDrop, void*, p, void )
811
0
{
812
0
    SdNavigatorDropEvent*                   pSdNavigatorDropEvent = static_cast<SdNavigatorDropEvent*>(p);
813
0
    TransferableDataHelper                  aDataHelper( pSdNavigatorDropEvent->maDropEvent.Transferable );
814
0
    SdPageObjsTLV::SdPageObjsTransferable*  pPageObjsTransferable = SdPageObjsTLV::SdPageObjsTransferable::getImplementation( aDataHelper.GetXTransferable() );
815
0
    INetBookmark                            aINetBookmark;
816
817
0
    if( pPageObjsTransferable && aDataHelper.GetINetBookmark( SotClipboardFormatId::NETSCAPE_BOOKMARK, aINetBookmark ) )
818
0
    {
819
0
        Point   aPos;
820
0
        OUString  aBookmark;
821
0
        SdPage* pPage = static_cast<SdPage*>( GetSdrPageView()->GetPage() );
822
0
        sal_uInt16  nPgPos = 0xFFFF;
823
824
0
        if( pSdNavigatorDropEvent->mpTargetWindow )
825
0
            aPos = pSdNavigatorDropEvent->mpTargetWindow->PixelToLogic( pSdNavigatorDropEvent->maPosPixel );
826
827
0
        const OUString& aURL( aINetBookmark.GetURL() );
828
0
        sal_Int32 nIndex = aURL.indexOf( '#' );
829
0
        if( nIndex != -1 )
830
0
            aBookmark = aURL.copy( nIndex+1 );
831
832
0
        std::vector<OUString> aExchangeList;
833
0
        std::vector<OUString> aBookmarkList(1,aBookmark);
834
835
0
        if( !pPage->IsMasterPage() )
836
0
        {
837
0
            if( pPage->GetPageKind() == PageKind::Standard )
838
0
                nPgPos = pPage->GetPageNum() + 2;
839
0
            else if( pPage->GetPageKind() == PageKind::Notes )
840
0
                nPgPos = pPage->GetPageNum() + 1;
841
0
        }
842
843
        /* In order t ensure unique page names, we test the ones we want to
844
           insert. If necessary. we put them into and replacement list (bNameOK
845
           == sal_False -> User canceled).  */
846
0
        bool    bLink = pPageObjsTransferable->GetDragType() == NAVIGATOR_DRAGTYPE_LINK;
847
0
        bool    bNameOK = GetExchangeList( aExchangeList, aBookmarkList, 2 );
848
849
        /* Since we don't know the type (page or object), we fill a list with
850
           pages and objects.
851
           Of course we have problems if there are pages and objects with the
852
           same name!!! */
853
0
        if( bNameOK )
854
0
        {
855
0
            mrDoc.InsertBookmark( aBookmarkList, aExchangeList,
856
0
                                  bLink, nPgPos,
857
0
                                  &pPageObjsTransferable->GetDocShell(),
858
0
                                  &aPos );
859
0
        }
860
0
    }
861
862
0
    delete pSdNavigatorDropEvent;
863
0
}
864
865
bool View::GetExchangeList (std::vector<OUString> &rExchangeList,
866
                            std::vector<OUString> &rBookmarkList,
867
                            const sal_uInt16 nType)
868
0
{
869
0
    assert(rExchangeList.empty());
870
871
0
    bool bListIdentical = true; ///< Bookmark list and exchange list are identical
872
0
    bool bNameOK = true;        ///< name is unique
873
874
0
    for ( const auto& rBookmark : rBookmarkList )
875
0
    {
876
0
        OUString aNewName = rBookmark;
877
878
0
        if( nType == 0  || nType == 2 )
879
0
            bNameOK = mpDocSh->CheckPageName(mpViewSh->GetFrameWeld(), aNewName);
880
881
0
        if( bNameOK && ( nType == 1  || nType == 2 ) )
882
0
        {
883
0
            if( mrDoc.GetObj( aNewName ) )
884
0
            {
885
0
                OUString aTitle(SdResId(STR_TITLE_NAMEGROUP));
886
0
                OUString aDesc(SdResId(STR_DESC_NAMEGROUP));
887
888
0
                SvxNameDialog aDlg(mpViewSh->GetFrameWeld(), aNewName, aDesc);
889
890
0
                aDlg.SetEditHelpId(HID_SD_NAMEDIALOG_OBJECT);
891
892
0
                bNameOK = false;
893
0
                aDlg.set_title(aTitle);
894
895
0
                while (!bNameOK && aDlg.run() == RET_OK)
896
0
                {
897
0
                    aNewName = aDlg.GetName();
898
899
0
                    if( !mrDoc.GetObj( aNewName ) )
900
0
                        bNameOK = true;
901
0
                }
902
0
            }
903
0
        }
904
905
0
        bListIdentical = rBookmark == aNewName;
906
907
0
        rExchangeList.push_back(aNewName);
908
909
0
        if (!bNameOK)
910
0
            break;
911
0
    }
912
913
    // Exchange list is identical to bookmark list
914
0
    if( !rExchangeList.empty() && bListIdentical )
915
0
        rExchangeList.clear();
916
917
0
    return bNameOK;
918
0
}
919
920
} // end of namespace sd
921
922
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */