Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/app/sdxfer.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 <sal/config.h>
21
22
#include <com/sun/star/embed/XEmbeddedObject.hpp>
23
#include <com/sun/star/embed/XTransactedObject.hpp>
24
#include <com/sun/star/embed/XEmbedPersist.hpp>
25
#include <com/sun/star/embed/ElementModes.hpp>
26
#include <com/sun/star/lang/XComponent.hpp>
27
#include <comphelper/fileformat.h>
28
#include <unotools/ucbstreamhelper.hxx>
29
#include <unotools/tempfile.hxx>
30
#include <editeng/flditem.hxx>
31
#include <svx/svdpagv.hxx>
32
#include <svx/svdoole2.hxx>
33
#include <svx/svdograf.hxx>
34
#include <svx/svdotext.hxx>
35
#include <editeng/outlobj.hxx>
36
#include <sot/storage.hxx>
37
#include <editeng/editobj.hxx>
38
#include <o3tl/safeint.hxx>
39
#include <svx/svdobjkind.hxx>
40
#include <svx/svdouno.hxx>
41
#include <svx/ImageMapInfo.hxx>
42
#include <sot/formats.hxx>
43
#include <svl/urlbmk.hxx>
44
#include <comphelper/diagnose_ex.hxx>
45
46
#include <com/sun/star/form/FormButtonType.hpp>
47
#include <com/sun/star/beans/XPropertySet.hpp>
48
#include <unotools/streamwrap.hxx>
49
50
#include <svx/svdotable.hxx>
51
#include <svx/unomodel.hxx>
52
#include <svx/svditer.hxx>
53
#include <sfx2/docfile.hxx>
54
#include <comphelper/storagehelper.hxx>
55
#include <comphelper/servicehelper.hxx>
56
#include <svtools/embedtransfer.hxx>
57
#include <DrawDocShell.hxx>
58
#include <View.hxx>
59
#include <sdmod.hxx>
60
#include <sdpage.hxx>
61
#include <drawdoc.hxx>
62
#include <stlpool.hxx>
63
#include <sdxfer.hxx>
64
#include <unomodel.hxx>
65
#include <vcl/virdev.hxx>
66
#include <vcl/svapp.hxx>
67
68
using namespace ::com::sun::star;
69
using namespace ::com::sun::star::uno;
70
using namespace ::com::sun::star::io;
71
using namespace ::com::sun::star::datatransfer;
72
73
constexpr sal_uInt32 SDTRANSFER_OBJECTTYPE_DRAWMODEL = 1;
74
constexpr sal_uInt32 SDTRANSFER_OBJECTTYPE_DRAWOLE   = 2;
75
76
SdTransferable::SdTransferable( SdDrawDocument* pSrcDoc, ::sd::View* pWorkView, bool bInitOnGetData )
77
0
:   mpPageDocShell( nullptr )
78
0
,   mpSdView( pWorkView )
79
0
,   mpSdViewIntern( pWorkView )
80
0
,   mpSdDrawDocument( nullptr )
81
0
,   mpSdDrawDocumentIntern( nullptr )
82
0
,   mpSourceDoc( pSrcDoc )
83
0
,   mpVDev( nullptr )
84
0
,   mbInternalMove( false )
85
0
,   mbOwnDocument( false )
86
0
,   mbOwnView( false )
87
0
,   mbLateInit( bInitOnGetData )
88
0
,   mbPageTransferable( false )
89
0
,   mbPageTransferablePersistent( false )
90
0
{
91
0
    if( mpSourceDoc )
92
0
        StartListening( *mpSourceDoc );
93
94
0
    if( pWorkView )
95
0
        StartListening( *pWorkView );
96
97
0
    if( !mbLateInit )
98
0
        CreateData();
99
0
}
100
101
SdTransferable::~SdTransferable()
102
0
{
103
0
    SolarMutexGuard g;
104
105
0
    if( mpSourceDoc )
106
0
        EndListening( *mpSourceDoc );
107
108
0
    if( mpSdView )
109
0
        EndListening( *const_cast< sd::View *>( mpSdView) );
110
111
0
    ObjectReleased();
112
113
0
    if( mbOwnView )
114
0
        delete mpSdViewIntern;
115
116
0
    mpOLEDataHelper.reset();
117
118
0
    if( maDocShellRef.is() )
119
0
    {
120
0
        SfxObjectShell* pObj = maDocShellRef.get();
121
0
        ::sd::DrawDocShell* pDocSh = static_cast< ::sd::DrawDocShell*>(pObj);
122
0
        pDocSh->DoClose();
123
0
    }
124
125
0
    maDocShellRef.clear();
126
127
0
    if( mbOwnDocument )
128
0
        delete mpSdDrawDocumentIntern;
129
130
0
    moGraphic.reset();
131
0
    moBookmark.reset();
132
0
    mpImageMap.reset();
133
134
0
    mpVDev.disposeAndClear();
135
0
    mpObjDesc.reset();
136
137
    //call explicitly at end of dtor to be covered by above SolarMutex
138
0
    maUserData.clear();
139
0
}
140
141
void SdTransferable::CreateObjectReplacement( SdrObject* pObj )
142
0
{
143
0
    if( !pObj )
144
0
        return;
145
146
0
    mpOLEDataHelper.reset();
147
0
    moGraphic.reset();
148
0
    moBookmark.reset();
149
0
    mpImageMap.reset();
150
151
0
    if( auto pOleObj = dynamic_cast< SdrOle2Obj* >( pObj ) )
152
0
    {
153
0
        try
154
0
        {
155
0
            uno::Reference < embed::XEmbeddedObject > xObj = pOleObj->GetObjRef();
156
0
            uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
157
0
            if( xObj.is() && xPersist.is() && xPersist->hasEntry() )
158
0
            {
159
0
                mpOLEDataHelper.reset( new TransferableDataHelper( new SvEmbedTransferHelper( xObj, pOleObj->GetGraphic(), pOleObj->GetAspect() ) ) );
160
161
                // TODO/LATER: the standalone handling of the graphic should not be used any more in future
162
                // The EmbedDataHelper should bring the graphic in future
163
0
                const Graphic* pObjGr = pOleObj->GetGraphic();
164
0
                if ( pObjGr )
165
0
                    moGraphic.emplace(*pObjGr);
166
0
            }
167
0
        }
168
0
        catch( uno::Exception& )
169
0
        {}
170
0
    }
171
0
    else if( dynamic_cast< const SdrGrafObj *>( pObj ) !=  nullptr && (mpSourceDoc && !SdDrawDocument::GetAnimationInfo( pObj )) )
172
0
    {
173
0
        moGraphic.emplace( static_cast< SdrGrafObj* >( pObj )->GetTransformedGraphic() );
174
0
    }
175
0
    else if( pObj->IsUnoObj() && SdrInventor::FmForm == pObj->GetObjInventor() && ( pObj->GetObjIdentifier() == SdrObjKind::FormButton ) )
176
0
    {
177
0
        SdrUnoObj* pUnoCtrl = static_cast< SdrUnoObj* >( pObj );
178
179
0
        if (SdrInventor::FmForm == pUnoCtrl->GetObjInventor())
180
0
        {
181
0
            const Reference< css::awt::XControlModel >& xControlModel( pUnoCtrl->GetUnoControlModel() );
182
183
0
            if( !xControlModel.is() )
184
0
                return;
185
186
0
            Reference< css::beans::XPropertySet > xPropSet( xControlModel, UNO_QUERY );
187
188
0
            if( !xPropSet.is() )
189
0
                return;
190
191
0
            css::form::FormButtonType  eButtonType;
192
0
            Any                                     aTmp( xPropSet->getPropertyValue( u"ButtonType"_ustr ) );
193
194
0
            if( aTmp >>= eButtonType )
195
0
            {
196
0
                OUString aLabel, aURL;
197
198
0
                xPropSet->getPropertyValue( u"Label"_ustr ) >>= aLabel;
199
0
                xPropSet->getPropertyValue( u"TargetURL"_ustr ) >>= aURL;
200
201
0
                moBookmark.emplace( aURL, aLabel );
202
0
            }
203
0
        }
204
0
    }
205
0
    else if( auto pTextObj = DynCastSdrTextObj( pObj ) )
206
0
    {
207
0
        const OutlinerParaObject* pPara;
208
209
0
        if( (pPara = pTextObj->GetOutlinerParaObject()) != nullptr )
210
0
        {
211
0
            const SvxFieldItem* pField;
212
213
0
            if( (pField = pPara->GetTextObject().GetField()) != nullptr )
214
0
            {
215
0
                const SvxFieldData* pData = pField->GetField();
216
217
0
                if( auto pURL = dynamic_cast< const SvxURLField *>( pData ) )
218
0
                {
219
                    // #i63399# This special code identifies TextFrames which have just a URL
220
                    // as content and directly add this to the clipboard, probably to avoid adding
221
                    // an unnecessary DrawObject to the target where paste may take place. This is
222
                    // wanted only for SdrObjects with no fill and no line, else it is necessary to
223
                    // use the whole SdrObject. Test here for Line/FillStyle and take shortcut only
224
                    // when both are unused
225
0
                    if(!pObj->HasFillStyle() && !pObj->HasLineStyle())
226
0
                    {
227
0
                        moBookmark.emplace( pURL->GetURL(), pURL->GetRepresentation() );
228
0
                    }
229
0
                }
230
0
            }
231
0
        }
232
0
    }
233
234
0
    SvxIMapInfo* pInfo = SvxIMapInfo::GetIMapInfo( pObj );
235
236
0
    if( pInfo )
237
0
        mpImageMap.reset( new ImageMap( pInfo->GetImageMap() ) );
238
0
}
239
240
void SdTransferable::CreateData()
241
0
{
242
0
    if( mpSdDrawDocument && !mpSdViewIntern )
243
0
    {
244
0
        mbOwnView = true;
245
246
0
        SdPage* pPage = mpSdDrawDocument->GetSdPage(0, PageKind::Standard);
247
248
0
        if( pPage && 1 == pPage->GetObjCount() )
249
0
            CreateObjectReplacement( pPage->GetObj( 0 ) );
250
251
0
        mpVDev = VclPtr<VirtualDevice>::Create( *Application::GetDefaultDevice() );
252
0
        mpVDev->SetMapMode(MapMode(mpSdDrawDocumentIntern->GetScaleUnit()));
253
0
        mpSdViewIntern = new ::sd::View( *mpSdDrawDocumentIntern, mpVDev );
254
0
        mpSdViewIntern->EndListening(*mpSdDrawDocumentIntern );
255
0
        mpSdViewIntern->hideMarkHandles();
256
0
        SdrPageView* pPageView = mpSdViewIntern->ShowSdrPage(pPage);
257
0
        mpSdViewIntern->MarkAllObj(pPageView);
258
0
    }
259
0
    else if( mpSdView && !mpSdDrawDocumentIntern )
260
0
    {
261
0
        const SdrMarkList& rMarkList = mpSdView->GetMarkedObjectList();
262
263
0
        if( rMarkList.GetMarkCount() == 1 )
264
0
            CreateObjectReplacement( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
265
266
0
        if( mpSourceDoc )
267
0
            mpSourceDoc->CreatingDataObj(this);
268
0
        mpSdDrawDocumentIntern = static_cast<SdDrawDocument*>( mpSdView->CreateMarkedObjModel().release() );
269
0
        if( mpSourceDoc )
270
0
            mpSourceDoc->CreatingDataObj(nullptr);
271
272
0
        if( !maDocShellRef.is() && mpSdDrawDocumentIntern->GetDocSh() )
273
0
            maDocShellRef = mpSdDrawDocumentIntern->GetDocSh();
274
275
0
        if( !maDocShellRef.is() )
276
0
        {
277
0
            OSL_FAIL( "SdTransferable::CreateData(), failed to create a model with persist, clipboard operation will fail for OLE objects!" );
278
0
            mbOwnDocument = true;
279
0
        }
280
281
        // Use dimension of source page
282
0
        SdrPageView*        pPgView = mpSdView->GetSdrPageView();
283
0
        SdPage*             pOldPage = static_cast<SdPage*>( pPgView->GetPage() );
284
0
        SdStyleSheetPool*   pOldStylePool = static_cast<SdStyleSheetPool*>(mpSdView->GetModel().GetStyleSheetPool());
285
0
        SdStyleSheetPool*   pNewStylePool = static_cast<SdStyleSheetPool*>( mpSdDrawDocumentIntern->GetStyleSheetPool() );
286
0
        SdPage*             pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PageKind::Standard );
287
0
        OUString            aOldLayoutName( pOldPage->GetLayoutName() );
288
289
0
        pPage->SetSize( pOldPage->GetSize() );
290
0
        pPage->SetLayoutName( aOldLayoutName );
291
0
        pNewStylePool->CopyGraphicSheets( *pOldStylePool );
292
0
        pNewStylePool->CopyCellSheets( *pOldStylePool );
293
0
        pNewStylePool->CopyTableStyles( *pOldStylePool );
294
0
        sal_Int32 nPos = aOldLayoutName.indexOf( SD_LT_SEPARATOR );
295
0
        if( nPos != -1 )
296
0
            aOldLayoutName = aOldLayoutName.copy( 0, nPos );
297
0
        StyleSheetCopyResultVector aCreatedSheets;
298
0
        pNewStylePool->CopyLayoutSheets( aOldLayoutName, *pOldStylePool, aCreatedSheets );
299
0
    }
300
301
    // set VisArea and adjust objects if necessary
302
0
    if( !(maVisArea.IsEmpty() &&
303
0
        mpSdDrawDocumentIntern && mpSdViewIntern &&
304
0
        mpSdDrawDocumentIntern->GetPageCount()) )
305
0
        return;
306
307
0
    SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PageKind::Standard );
308
309
0
    if( 1 == mpSdDrawDocumentIntern->GetPageCount() )
310
0
    {
311
        // #112978# need to use GetAllMarkedBoundRect instead of GetAllMarkedRect to get
312
        // fat lines correctly
313
0
        maVisArea = mpSdViewIntern->GetAllMarkedBoundRect();
314
0
        Point   aOrigin( maVisArea.TopLeft() );
315
0
        Size    aVector( -aOrigin.X(), -aOrigin.Y() );
316
317
0
        for (const rtl::Reference<SdrObject>& pObj : *pPage)
318
0
            pObj->NbcMove( aVector );
319
0
    }
320
0
    else
321
0
        maVisArea.SetSize( pPage->GetSize() );
322
323
    // output is at the zero point
324
0
    maVisArea.SetPos( Point() );
325
0
}
326
327
static bool lcl_HasOnlyControls( SdrModel* pModel )
328
0
{
329
0
    bool bOnlyControls = false;         // default if there are no objects
330
331
0
    if ( pModel )
332
0
    {
333
0
        SdrPage* pPage = pModel->GetPage(0);
334
0
        if (pPage)
335
0
        {
336
0
            SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups );
337
0
            SdrObject* pObj = aIter.Next();
338
0
            if ( pObj )
339
0
            {
340
0
                bOnlyControls = true;   // only set if there are any objects at all
341
0
                while ( pObj )
342
0
                {
343
0
                    if (dynamic_cast< const SdrUnoObj *>( pObj ) ==  nullptr)
344
0
                    {
345
0
                        bOnlyControls = false;
346
0
                        break;
347
0
                    }
348
0
                    pObj = aIter.Next();
349
0
                }
350
0
            }
351
0
        }
352
0
    }
353
354
0
    return bOnlyControls;
355
0
}
356
357
static bool lcl_HasOnlyOneTable( SdrModel* pModel )
358
0
{
359
0
    if ( pModel )
360
0
    {
361
0
        SdrPage* pPage = pModel->GetPage(0);
362
0
        if (pPage && pPage->GetObjCount() == 1 )
363
0
        {
364
0
            if( dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) ) != nullptr )
365
0
                return true;
366
0
        }
367
0
    }
368
0
    return false;
369
0
}
370
371
void SdTransferable::AddSupportedFormats()
372
0
{
373
0
    if( mbPageTransferable && !mbPageTransferablePersistent )
374
0
        return;
375
376
0
    if( !mbLateInit )
377
0
        CreateData();
378
379
0
    if( mpObjDesc )
380
0
        AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
381
382
0
    if( mpOLEDataHelper )
383
0
    {
384
0
        AddFormat( SotClipboardFormatId::EMBED_SOURCE );
385
386
0
        DataFlavorExVector              aVector( mpOLEDataHelper->GetDataFlavorExVector() );
387
388
0
        for( const auto& rItem : aVector )
389
0
            AddFormat( rItem );
390
0
    }
391
0
    else if( moGraphic )
392
0
    {
393
        // #i25616#
394
0
        AddFormat( SotClipboardFormatId::DRAWING );
395
396
0
        AddFormat( SotClipboardFormatId::SVXB );
397
398
0
        if( moGraphic->GetType() == GraphicType::Bitmap )
399
0
        {
400
0
            AddFormat( SotClipboardFormatId::PNG );
401
0
            AddFormat( SotClipboardFormatId::BITMAP );
402
0
            AddFormat( SotClipboardFormatId::GDIMETAFILE );
403
0
        }
404
0
        else
405
0
        {
406
0
            AddFormat( SotClipboardFormatId::GDIMETAFILE );
407
0
            AddFormat( SotClipboardFormatId::PNG );
408
0
            AddFormat( SotClipboardFormatId::BITMAP );
409
0
        }
410
0
    }
411
0
    else if( moBookmark )
412
0
    {
413
0
        AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
414
0
        AddFormat( SotClipboardFormatId::STRING );
415
0
    }
416
0
    else
417
0
    {
418
0
        AddFormat( SotClipboardFormatId::EMBED_SOURCE );
419
0
        AddFormat( SotClipboardFormatId::DRAWING );
420
0
        if( !mpSdDrawDocument || !lcl_HasOnlyControls( mpSdDrawDocument ) )
421
0
        {
422
0
            AddFormat( SotClipboardFormatId::GDIMETAFILE );
423
0
            AddFormat( SotClipboardFormatId::PNG );
424
0
            AddFormat( SotClipboardFormatId::BITMAP );
425
0
        }
426
427
0
        if( lcl_HasOnlyOneTable( mpSdDrawDocument ) ) {
428
0
            AddFormat( SotClipboardFormatId::RTF );
429
0
            AddFormat( SotClipboardFormatId::RICHTEXT );
430
0
        }
431
0
    }
432
433
0
    if( mpImageMap )
434
0
        AddFormat( SotClipboardFormatId::SVIM );
435
0
}
436
437
bool SdTransferable::GetData( const DataFlavor& rFlavor, const OUString& rDestDoc )
438
0
{
439
0
    if (SdModule::get() == nullptr)
440
0
        return false;
441
442
0
    SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
443
0
    bool        bOK = false;
444
445
0
    CreateData();
446
447
0
    if( nFormat == SotClipboardFormatId::RTF && lcl_HasOnlyOneTable( mpSdDrawDocument ) )
448
0
    {
449
0
        bOK = SetTableRTF( mpSdDrawDocument );
450
0
    }
451
0
    else if( mpOLEDataHelper && mpOLEDataHelper->HasFormat( rFlavor ) )
452
0
    {
453
        // TODO/LATER: support all the graphical formats, the embedded object scenario should not have separated handling
454
0
        if( nFormat == SotClipboardFormatId::GDIMETAFILE && moGraphic )
455
0
            bOK = SetGDIMetaFile( moGraphic->GetGDIMetaFile() );
456
0
        else
457
0
            bOK = SetAny( mpOLEDataHelper->GetAny(rFlavor, rDestDoc) );
458
0
    }
459
0
    else if( HasFormat( nFormat ) )
460
0
    {
461
0
        if( ( nFormat == SotClipboardFormatId::LINKSRCDESCRIPTOR || nFormat == SotClipboardFormatId::OBJECTDESCRIPTOR ) && mpObjDesc )
462
0
        {
463
0
            bOK = SetTransferableObjectDescriptor( *mpObjDesc );
464
0
        }
465
0
        else if( nFormat == SotClipboardFormatId::DRAWING )
466
0
        {
467
0
            SfxObjectShellRef aOldRef( maDocShellRef );
468
469
0
            maDocShellRef.clear();
470
471
0
            if( mpSdViewIntern )
472
0
            {
473
0
                SdDrawDocument& rInternDoc = mpSdViewIntern->GetDoc();
474
0
                rInternDoc.CreatingDataObj(this);
475
0
                SdDrawDocument* pDoc = dynamic_cast< SdDrawDocument* >( mpSdViewIntern->CreateMarkedObjModel().release() );
476
0
                rInternDoc.CreatingDataObj(nullptr);
477
478
0
                bOK = SetObject( pDoc, SDTRANSFER_OBJECTTYPE_DRAWMODEL, rFlavor );
479
480
0
                if( maDocShellRef.is() )
481
0
                {
482
0
                    maDocShellRef->DoClose();
483
0
                }
484
0
                else
485
0
                {
486
0
                    delete pDoc;
487
0
                }
488
0
            }
489
490
0
            maDocShellRef = std::move(aOldRef);
491
0
        }
492
0
        else if( nFormat == SotClipboardFormatId::GDIMETAFILE )
493
0
        {
494
0
            if (mpSdViewIntern)
495
0
            {
496
0
                const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell();
497
0
                if (bToggleOnlineSpell)
498
0
                    mpSdDrawDocumentIntern->SetOnlineSpell(false);
499
0
                bOK = SetGDIMetaFile( mpSdViewIntern->GetMarkedObjMetaFile( true ) );
500
0
                if (bToggleOnlineSpell)
501
0
                    mpSdDrawDocumentIntern->SetOnlineSpell(true);
502
0
            }
503
0
        }
504
0
        else if( SotClipboardFormatId::BITMAP == nFormat || SotClipboardFormatId::PNG == nFormat )
505
0
        {
506
0
            if (mpSdViewIntern)
507
0
            {
508
0
                const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell();
509
0
                if (bToggleOnlineSpell)
510
0
                    mpSdDrawDocumentIntern->SetOnlineSpell(false);
511
0
                bOK = SetBitmap(mpSdViewIntern->GetMarkedObjBitmap(true), rFlavor);
512
0
                if (bToggleOnlineSpell)
513
0
                    mpSdDrawDocumentIntern->SetOnlineSpell(true);
514
0
            }
515
0
        }
516
0
        else if( ( nFormat == SotClipboardFormatId::STRING ) && moBookmark )
517
0
        {
518
0
            bOK = SetString( moBookmark->GetURL() );
519
0
        }
520
0
        else if( ( nFormat == SotClipboardFormatId::SVXB ) && moGraphic )
521
0
        {
522
0
            bOK = SetGraphic( *moGraphic );
523
0
        }
524
0
        else if( ( nFormat == SotClipboardFormatId::SVIM ) && mpImageMap )
525
0
        {
526
0
            bOK = SetImageMap( *mpImageMap );
527
0
        }
528
0
        else if( moBookmark )
529
0
        {
530
0
            bOK = SetINetBookmark( *moBookmark, rFlavor );
531
0
        }
532
0
        else if( nFormat == SotClipboardFormatId::EMBED_SOURCE )
533
0
        {
534
0
            if( mpSdDrawDocumentIntern )
535
0
            {
536
0
                if( !maDocShellRef.is() )
537
0
                {
538
0
                    maDocShellRef = new ::sd::DrawDocShell(
539
0
                        mpSdDrawDocumentIntern,
540
0
                        SfxObjectCreateMode::EMBEDDED,
541
0
                        true,
542
0
                        mpSdDrawDocumentIntern->GetDocumentType());
543
0
                    mbOwnDocument = false;
544
0
                    maDocShellRef->DoInitNew();
545
0
                }
546
547
0
                maDocShellRef->SetVisArea( maVisArea );
548
0
                bOK = SetObject( maDocShellRef.get(), SDTRANSFER_OBJECTTYPE_DRAWOLE, rFlavor );
549
0
            }
550
0
        }
551
0
    }
552
553
0
    return bOK;
554
0
}
555
556
bool SdTransferable::WriteObject( SvStream& rOStm, void* pObject, sal_uInt32 nObjectType, const DataFlavor& )
557
0
{
558
0
    bool bRet = false;
559
560
0
    switch( nObjectType )
561
0
    {
562
0
        case SDTRANSFER_OBJECTTYPE_DRAWMODEL:
563
0
        {
564
0
            try
565
0
            {
566
0
                static const bool bDontBurnInStyleSheet = ( getenv( "AVOID_BURN_IN_FOR_GALLERY_THEME" ) != nullptr );
567
0
                SdDrawDocument* pDoc = static_cast<SdDrawDocument*>(pObject);
568
0
                if ( !bDontBurnInStyleSheet )
569
0
                    pDoc->BurnInStyleSheetAttributes();
570
0
                rOStm.SetBufferSize( 16348 );
571
572
0
                rtl::Reference< SdXImpressDocument > xComponent( new SdXImpressDocument( pDoc, true ) );
573
0
                pDoc->setUnoModel( xComponent );
574
575
0
                {
576
0
                    css::uno::Reference<css::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( rOStm ) );
577
0
                    SvxDrawingLayerExport( pDoc, xDocOut, xComponent, (pDoc->GetDocumentType() == DocumentType::Impress) ? "com.sun.star.comp.Impress.XMLClipboardExporter" : "com.sun.star.comp.DrawingLayer.XMLExporter" );
578
0
                }
579
580
0
                xComponent->dispose();
581
0
                bRet = ( rOStm.GetError() == ERRCODE_NONE );
582
0
            }
583
0
            catch( Exception& )
584
0
            {
585
0
                TOOLS_WARN_EXCEPTION( "sd", "sd::SdTransferable::WriteObject()" );
586
0
                bRet = false;
587
0
            }
588
0
        }
589
0
        break;
590
591
0
        case SDTRANSFER_OBJECTTYPE_DRAWOLE:
592
0
        {
593
0
            SfxObjectShell*   pEmbObj = static_cast<SfxObjectShell*>(pObject);
594
0
            ::utl::TempFileFast aTempFile;
595
0
            SvStream* pTempStream = aTempFile.GetStream(StreamMode::READWRITE);
596
597
0
            try
598
0
            {
599
0
                uno::Reference< embed::XStorage > xWorkStore =
600
0
                    ::comphelper::OStorageHelper::GetStorageFromStream( new utl::OStreamWrapper(*pTempStream), embed::ElementModes::READWRITE );
601
602
                // write document storage
603
0
                pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
604
                // mba: no relative URLs for clipboard!
605
0
                SfxMedium aMedium( xWorkStore, OUString() );
606
0
                pEmbObj->DoSaveObjectAs( aMedium, false );
607
0
                pEmbObj->DoSaveCompleted();
608
609
0
                uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
610
0
                if ( xTransact.is() )
611
0
                    xTransact->commit();
612
613
0
                rOStm.SetBufferSize( 0xff00 );
614
0
                rOStm.WriteStream( *pTempStream );
615
616
0
                bRet = true;
617
0
            }
618
0
            catch ( Exception& )
619
0
            {}
620
0
        }
621
622
0
        break;
623
624
0
        default:
625
0
        break;
626
0
    }
627
628
0
    return bRet;
629
0
}
630
631
void SdTransferable::DragFinished( sal_Int8 nDropAction )
632
0
{
633
0
    if( mpSdView )
634
0
        const_cast< ::sd::View* >(mpSdView)->DragFinished( nDropAction );
635
0
}
636
637
void SdTransferable::ObjectReleased()
638
0
{
639
0
    SdModule* pModule = SdModule::get();
640
0
    if (!pModule)
641
0
        return;
642
643
0
    if( this == pModule->pTransferClip )
644
0
        pModule->pTransferClip = nullptr;
645
646
0
    if( this == pModule->pTransferDrag )
647
0
        pModule->pTransferDrag = nullptr;
648
649
0
    if( this == pModule->pTransferSelection )
650
0
        pModule->pTransferSelection = nullptr;
651
0
}
652
653
void SdTransferable::SetObjectDescriptor( std::unique_ptr<TransferableObjectDescriptor> pObjDesc )
654
0
{
655
0
    mpObjDesc = std::move(pObjDesc);
656
0
    PrepareOLE( *mpObjDesc );
657
0
}
658
659
void SdTransferable::SetPageBookmarks( std::vector<OUString> && rPageBookmarks, bool bPersistent, bool bMergeMasterPagesOnly )
660
0
{
661
0
    if( !mpSourceDoc )
662
0
        return;
663
664
0
    if( mpSdViewIntern )
665
0
        mpSdViewIntern->HideSdrPage();
666
667
0
    mpSdDrawDocument->ClearModel(false);
668
669
0
    mpPageDocShell = nullptr;
670
671
0
    maPageBookmarks.clear();
672
673
0
    if( bPersistent )
674
0
    {
675
0
        mpSdDrawDocument->CreateFirstPages(mpSourceDoc);
676
0
        mpSdDrawDocument->ImportDocumentPages(rPageBookmarks, 1, mpSourceDoc->GetDocSh(), bMergeMasterPagesOnly);
677
0
    }
678
0
    else
679
0
    {
680
0
        mpPageDocShell = mpSourceDoc->GetDocSh();
681
0
        maPageBookmarks = std::move(rPageBookmarks);
682
0
    }
683
684
0
    if( mpSdViewIntern )
685
0
    {
686
0
        SdPage* pPage = mpSdDrawDocument->GetSdPage( 0, PageKind::Standard );
687
688
0
        if( pPage )
689
0
        {
690
0
            mpSdViewIntern->MarkAllObj( mpSdViewIntern->ShowSdrPage( pPage ) );
691
0
        }
692
0
    }
693
694
    // set flags for page transferable; if ( mbPageTransferablePersistent == sal_False ),
695
    // don't offer any formats => it's just for internal purposes
696
0
    mbPageTransferable = true;
697
0
    mbPageTransferablePersistent = bPersistent;
698
0
}
699
700
void SdTransferable::AddUserData (const std::shared_ptr<UserData>& rpData)
701
0
{
702
0
    maUserData.push_back(rpData);
703
0
}
704
705
sal_Int32 SdTransferable::GetUserDataCount() const
706
0
{
707
0
    return maUserData.size();
708
0
}
709
710
std::shared_ptr<SdTransferable::UserData> SdTransferable::GetUserData (const sal_Int32 nIndex) const
711
0
{
712
0
    if (nIndex>=0 && o3tl::make_unsigned(nIndex)<maUserData.size())
713
0
        return maUserData[nIndex];
714
0
    else
715
0
        return std::shared_ptr<UserData>();
716
0
}
717
718
SdTransferable* SdTransferable::getImplementation( const Reference< XInterface >& rxData ) noexcept
719
0
{
720
0
    return dynamic_cast<SdTransferable*>(rxData.get());
721
0
}
722
723
void SdTransferable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
724
0
{
725
0
    if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
726
0
    {
727
0
        const SdrHint* pSdrHint = static_cast< const SdrHint* >( &rHint );
728
0
        if( SdrHintKind::ModelCleared == pSdrHint->GetKind() )
729
0
        {
730
0
            EndListening(*mpSourceDoc);
731
0
            mpSourceDoc = nullptr;
732
0
        }
733
0
    }
734
0
    else
735
0
    {
736
0
        if( rHint.GetId() == SfxHintId::Dying )
737
0
        {
738
0
            if( &rBC == mpSourceDoc )
739
0
                mpSourceDoc = nullptr;
740
0
            if( &rBC == mpSdViewIntern )
741
0
                mpSdViewIntern = nullptr;
742
0
            if( &rBC == mpSdView )
743
0
                mpSdView = nullptr;
744
0
        }
745
0
    }
746
0
}
747
748
void SdTransferable::SetView(const ::sd::View* pView)
749
0
{
750
0
    if (mpSdView)
751
0
        EndListening(*const_cast<sd::View*>(mpSdView));
752
0
    mpSdView = pView;
753
0
    if (mpSdView)
754
0
        StartListening(*const_cast<sd::View*>(mpSdView));
755
0
}
756
757
bool SdTransferable::SetTableRTF( SdDrawDocument* pModel )
758
0
{
759
0
    if ( pModel )
760
0
    {
761
0
        SdrPage* pPage = pModel->GetPage(0);
762
0
        if (pPage && pPage->GetObjCount() == 1 )
763
0
        {
764
0
            sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) );
765
0
            if( pTableObj )
766
0
            {
767
0
                SvMemoryStream aMemStm( 65535, 65535 );
768
0
                sdr::table::ExportAsRTF( aMemStm, *pTableObj );
769
0
                return SetAny( Any( Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.TellEnd() ) ) );
770
0
            }
771
0
        }
772
0
    }
773
774
0
    return false;
775
0
}
776
777
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */