Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/func/fuinsfil.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 <fuinsfil.hxx>
21
#include <rtl/ustrbuf.hxx>
22
#include <vcl/svapp.hxx>
23
#include <sfx2/progress.hxx>
24
#include <editeng/outliner.hxx>
25
#include <editeng/outlobj.hxx>
26
#include <editeng/editeng.hxx>
27
#include <editeng/editund2.hxx>
28
#include <svl/stritem.hxx>
29
#include <sfx2/request.hxx>
30
#include <sfx2/app.hxx>
31
#include <vcl/weld/MessageDialog.hxx>
32
#include <vcl/weld/weld.hxx>
33
#include <svx/svdorect.hxx>
34
#include <svx/svdundo.hxx>
35
#include <svx/svdoutl.hxx>
36
#include <sfx2/filedlghelper.hxx>
37
#include <sot/formats.hxx>
38
#include <sfx2/docfile.hxx>
39
#include <sfx2/docfilt.hxx>
40
#include <sfx2/fcontnr.hxx>
41
#include <svx/svdpagv.hxx>
42
#include <svx/svxids.hrc>
43
#include <tools/debug.hxx>
44
#include <com/sun/star/ui/dialogs/XFilterManager.hpp>
45
#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
46
#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
47
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
48
49
#include <sdresid.hxx>
50
#include <drawdoc.hxx>
51
#include <Window.hxx>
52
#include <View.hxx>
53
#include <strings.hrc>
54
#include <sdmod.hxx>
55
#include <sdpage.hxx>
56
#include <ViewShellBase.hxx>
57
#include <DrawViewShell.hxx>
58
#include <OutlineView.hxx>
59
#include <DrawDocShell.hxx>
60
#include <GraphicDocShell.hxx>
61
#include <app.hrc>
62
#include <Outliner.hxx>
63
#include <sdabstdlg.hxx>
64
#include <memory>
65
66
using namespace ::com::sun::star::lang;
67
using namespace ::com::sun::star::uno;
68
using namespace ::com::sun::star::ui::dialogs;
69
using namespace ::com::sun::star;
70
71
typedef ::std::pair< OUString, OUString > FilterDesc;
72
73
namespace
74
{
75
76
OUString lcl_GetExtensionsList ( ::std::vector< FilterDesc > const& rFilterDescList )
77
0
{
78
0
    OUStringBuffer aExtensions;
79
80
0
    for (const auto& rFilterDesc : rFilterDescList)
81
0
    {
82
0
        OUString sWildcard = rFilterDesc.second;
83
84
0
        if ( aExtensions.indexOf( sWildcard ) == -1 )
85
0
        {
86
0
            if ( !aExtensions.isEmpty() )
87
0
                aExtensions.append(";");
88
0
            aExtensions.append(sWildcard);
89
0
        }
90
91
0
    }
92
93
0
    return aExtensions.makeStringAndClear();
94
0
}
95
96
void lcl_AddFilter ( ::std::vector< FilterDesc >& rFilterDescList,
97
                     const std::shared_ptr<const SfxFilter>& pFilter )
98
0
{
99
0
    if (pFilter)
100
0
        rFilterDescList.emplace_back( pFilter->GetUIName(), pFilter->GetDefaultExtension() );
101
0
}
102
103
}
104
105
namespace sd {
106
107
108
FuInsertFile::FuInsertFile (
109
    ViewShell&    rViewSh,
110
    ::sd::Window*      pWin,
111
    ::sd::View*        pView,
112
    SdDrawDocument& rDoc,
113
    SfxRequest&    rReq)
114
0
    : FuPoor(rViewSh, pWin, pView, rDoc, rReq)
115
0
{
116
0
}
117
118
rtl::Reference<FuPoor> FuInsertFile::Create( ViewShell& rViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument& rDoc, SfxRequest& rReq )
119
0
{
120
0
    rtl::Reference<FuPoor> xFunc( new FuInsertFile( rViewSh, pWin, pView, rDoc, rReq ) );
121
0
    xFunc->DoExecute(rReq);
122
0
    return xFunc;
123
0
}
124
125
void FuInsertFile::DoExecute( SfxRequest& rReq )
126
0
{
127
0
    SfxFilterMatcher&       rMatcher = SfxGetpApp()->GetFilterMatcher();
128
0
    ::std::vector< FilterDesc > aFilterVector;
129
0
    ::std::vector< OUString > aOtherFilterVector;
130
0
    const SfxItemSet*       pArgs = rReq.GetArgs ();
131
132
0
    FuInsertFile::GetSupportedFilterVector( aOtherFilterVector );
133
134
0
    if (!pArgs)
135
0
    {
136
0
        sfx2::FileDialogHelper      aFileDialog(
137
0
                ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
138
0
                FileDialogFlags::Insert, mpWindow ? mpWindow->GetFrameWeld() : nullptr);
139
0
        aFileDialog.SetContext(sfx2::FileDialogHelper::DrawImpressInsertFile);
140
0
        Reference< XFilePicker >    xFilePicker( aFileDialog.GetFilePicker() );
141
0
        Reference< XFilterManager > xFilterManager( xFilePicker, UNO_QUERY );
142
0
        OUString aOwnCont;
143
0
        OUString aOtherCont;
144
145
0
        aFileDialog.SetTitle( SdResId(STR_DLG_INSERT_PAGES_FROM_FILE) );
146
147
0
        if( mrDoc.GetDocumentType() == DocumentType::Impress )
148
0
        {
149
0
            aOwnCont = "simpress";
150
0
            aOtherCont = "sdraw";
151
0
        }
152
0
        else
153
0
        {
154
0
            aOtherCont = "simpress";
155
0
            aOwnCont = "sdraw" ;
156
0
        }
157
158
0
        SfxFilterMatcher aMatch( aOwnCont );
159
160
0
        if( xFilterManager.is() )
161
0
        {
162
            // Get filter for current format
163
0
            try
164
0
            {
165
                // Get main filter
166
0
                std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetDefaultFilterFromFactory( aOwnCont );
167
0
                lcl_AddFilter( aFilterVector, pFilter );
168
169
                // get template filter
170
0
                if( mrDoc.GetDocumentType() == DocumentType::Impress )
171
0
                    pFilter = DrawDocShell::Factory().GetTemplateFilter();
172
0
                else
173
0
                    pFilter = GraphicDocShell::Factory().GetTemplateFilter();
174
0
                lcl_AddFilter( aFilterVector, pFilter );
175
176
                // get cross filter
177
0
                pFilter = SfxFilter::GetDefaultFilterFromFactory( aOtherCont );
178
0
                lcl_AddFilter( aFilterVector, pFilter );
179
180
                // get Powerpoint filter
181
0
                pFilter = aMatch.GetFilter4Extension( u".ppt"_ustr );
182
0
                lcl_AddFilter( aFilterVector, pFilter );
183
184
                // Get other draw/impress filters
185
0
                pFilter = aMatch.GetFilter4ClipBoardId( SotClipboardFormatId::STARIMPRESS_60, SfxFilterFlags::IMPORT, SfxFilterFlags::TEMPLATEPATH );
186
0
                lcl_AddFilter( aFilterVector, pFilter );
187
188
0
                pFilter = aMatch.GetFilter4ClipBoardId( SotClipboardFormatId::STARIMPRESS_60, SfxFilterFlags::TEMPLATEPATH );
189
0
                lcl_AddFilter( aFilterVector, pFilter );
190
191
0
                pFilter = aMatch.GetFilter4ClipBoardId( SotClipboardFormatId::STARDRAW_60, SfxFilterFlags::IMPORT, SfxFilterFlags::TEMPLATEPATH  );
192
0
                lcl_AddFilter( aFilterVector, pFilter );
193
194
0
                pFilter = aMatch.GetFilter4ClipBoardId( SotClipboardFormatId::STARDRAW_60, SfxFilterFlags::TEMPLATEPATH  );
195
0
                lcl_AddFilter( aFilterVector, pFilter );
196
197
0
                pFilter = aMatch.GetFilter4ClipBoardId( SotClipboardFormatId::STARDRAW, SfxFilterFlags::IMPORT, SfxFilterFlags::TEMPLATEPATH  );
198
0
                lcl_AddFilter( aFilterVector, pFilter );
199
200
0
                pFilter = aMatch.GetFilter4ClipBoardId( SotClipboardFormatId::STARDRAW, SfxFilterFlags::TEMPLATEPATH  );
201
0
                lcl_AddFilter( aFilterVector, pFilter );
202
203
                // add additional supported filters
204
0
                for( const auto& rOtherFilter : aOtherFilterVector )
205
0
                {
206
0
                    if( ( pFilter = rMatcher.GetFilter4Mime( rOtherFilter ) ) != nullptr )
207
0
                        lcl_AddFilter( aFilterVector, pFilter );
208
0
                }
209
210
                // set "All supported formats" as the default filter
211
0
                OUString aAllSpec( SdResId( STR_ALL_SUPPORTED_FORMATS ) );
212
0
                OUString aExtensions = lcl_GetExtensionsList( aFilterVector );
213
0
                OUString aGUIName = aAllSpec + " (" + aExtensions + ")";
214
215
0
                xFilterManager->appendFilter( aGUIName, aExtensions );
216
0
                xFilterManager->setCurrentFilter( aAllSpec );
217
218
                // append individual filters
219
0
                for( const auto& rFilter : aFilterVector )
220
0
                {
221
0
                    xFilterManager->appendFilter( rFilter.first, rFilter.second );
222
0
                }
223
224
                // end with "All files" as fallback
225
0
                xFilterManager->appendFilter( SdResId( STR_ALL_FILES ), u"*.*"_ustr );
226
0
            }
227
0
            catch (const IllegalArgumentException&)
228
0
            {
229
0
            }
230
0
        }
231
232
0
        if( aFileDialog.Execute() != ERRCODE_NONE )
233
0
            return;
234
0
        else
235
0
        {
236
0
            aFilterName = aFileDialog.GetCurrentFilter();
237
0
            aFile = aFileDialog.GetPath();
238
0
        }
239
0
    }
240
0
    else
241
0
    {
242
0
        const SfxStringItem* pFileName = rReq.GetArg<SfxStringItem>(ID_VAL_DUMMY0);
243
0
        assert(pFileName && "must be present");
244
0
        aFile = pFileName->GetValue();
245
0
        if (const SfxStringItem* pFilterName = rReq.GetArg<SfxStringItem>(ID_VAL_DUMMY1))
246
0
            aFilterName = pFilterName->GetValue();
247
0
    }
248
249
0
    mpDocSh->SetWaitCursor( true );
250
251
0
    std::unique_ptr<SfxMedium>  xMedium(new SfxMedium(aFile, StreamMode::READ | StreamMode::NOCREATE));
252
0
    std::shared_ptr<const SfxFilter> pFilter;
253
254
0
    SfxGetpApp()->GetFilterMatcher().GuessFilter(*xMedium, pFilter);
255
256
0
    bool                bDrawMode = dynamic_cast< const DrawViewShell *>( &mrViewShell ) != nullptr;
257
0
    bool                bInserted = false;
258
259
0
    if( pFilter )
260
0
    {
261
0
        xMedium->SetFilter( pFilter );
262
0
        aFilterName = pFilter->GetFilterName();
263
264
0
        if( xMedium->IsStorage() || ( xMedium->GetInStream() && SotStorage::IsStorageFile( xMedium->GetInStream() ) ) )
265
0
        {
266
0
            if ( pFilter->GetServiceName() == "com.sun.star.presentation.PresentationDocument" ||
267
0
                 pFilter->GetServiceName() == "com.sun.star.drawing.DrawingDocument" )
268
0
            {
269
                // Draw, Impress or PowerPoint document
270
                // the ownership of the Medium is transferred
271
0
                if( bDrawMode )
272
0
                    InsSDDinDrMode(xMedium.release());
273
0
                else
274
0
                    InsSDDinOlMode(xMedium.release());
275
276
                // ownership of pMedium has changed in this case
277
0
                bInserted = true;
278
0
            }
279
0
        }
280
0
        else
281
0
        {
282
0
            bool bFound = ( ::std::find( aOtherFilterVector.begin(), aOtherFilterVector.end(), pFilter->GetMimeType() ) != aOtherFilterVector.end() );
283
0
            if( !bFound &&
284
0
                ( aFilterName.indexOf( "Text" ) != -1 ||
285
0
                aFilterName.indexOf( "Rich" ) != -1 ||
286
0
                aFilterName.indexOf( "RTF" )  != -1 ||
287
0
                aFilterName.indexOf( "HTML" ) != -1 ) )
288
0
            {
289
0
                bFound = true;
290
0
            }
291
292
0
            if( bFound )
293
0
            {
294
0
                if( bDrawMode )
295
0
                    InsTextOrRTFinDrMode(xMedium.get());
296
0
                else
297
0
                    InsTextOrRTFinOlMode(xMedium.get());
298
299
0
                bInserted = true;
300
0
                xMedium.reset();
301
0
            }
302
0
        }
303
0
    }
304
305
0
    mpDocSh->SetWaitCursor( false );
306
307
0
    if( !bInserted )
308
0
    {
309
0
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(mpWindow->GetFrameWeld(),
310
0
                                                       VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR)));
311
0
        xErrorBox->run();
312
0
    }
313
0
}
314
315
bool FuInsertFile::InsSDDinDrMode(SfxMedium* pMedium)
316
0
{
317
0
    bool bOK = false;
318
319
0
    mpDocSh->SetWaitCursor( false );
320
0
    SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
321
0
    weld::Window* pParent = mrViewShell.GetFrameWeld();
322
0
    ScopedVclPtr<AbstractSdInsertPagesObjsDlg> pDlg( pFact->CreateSdInsertPagesObjsDlg(pParent, mrDoc, pMedium, aFile) );
323
324
0
    sal_uInt16 nRet = pDlg->Execute();
325
326
0
    mpDocSh->SetWaitCursor( true );
327
328
0
    if( nRet == RET_OK )
329
0
    {
330
        /* list with page names (if NULL, then all pages)
331
           First, insert pages */
332
0
        std::vector<OUString> aBookmarkList = pDlg->GetList( 1 ); // pages
333
0
        bool bLink = pDlg->IsLink();
334
0
        SdPage* pPage = nullptr;
335
0
        ::sd::View* pView = mrViewShell.GetView();
336
337
0
        if (pView)
338
0
        {
339
0
            if( auto pOutlineView = dynamic_cast<OutlineView *>( pView ))
340
0
            {
341
0
                pPage = pOutlineView->GetActualPage();
342
0
            }
343
0
            else
344
0
            {
345
0
                pPage = static_cast<SdPage*>(pView->GetSdrPageView()->GetPage());
346
0
            }
347
0
        }
348
349
0
        sal_uInt16 nPos = 0xFFFF;
350
351
0
        if (pPage && !pPage->IsMasterPage())
352
0
        {
353
0
            if (pPage->GetPageKind() == PageKind::Standard)
354
0
            {
355
0
                nPos = pPage->GetPageNum() + 2;
356
0
            }
357
0
            else if (pPage->GetPageKind() == PageKind::Notes)
358
0
            {
359
0
                nPos = pPage->GetPageNum() + 1;
360
0
            }
361
0
        }
362
363
0
        bool  bNameOK;
364
0
        std::vector<OUString> aExchangeList;
365
0
        std::vector<OUString> aObjectBookmarkList = pDlg->GetList( 2 ); // objects
366
367
        /* if pBookmarkList is NULL, we insert selected pages, and/or selected
368
           objects or everything. */
369
0
        if( !aBookmarkList.empty() || aObjectBookmarkList.empty() )
370
0
        {
371
            /* To ensure that all page names are unique, we check the ones we
372
               want to insert and insert them into a substitution list if
373
               necessary.
374
               bNameOK is sal_False if the user has canceled. */
375
0
            bNameOK = mpView->GetExchangeList( aExchangeList, aBookmarkList, 0 );
376
377
0
            if( bNameOK )
378
0
                bOK = mrDoc.InsertFileAsPage( aBookmarkList, &aExchangeList,
379
0
                                    bLink, nPos, nullptr );
380
381
0
            aBookmarkList.clear();
382
0
            aExchangeList.clear();
383
0
        }
384
385
        // to ensure ... (see above)
386
0
        bNameOK = mpView->GetExchangeList( aExchangeList, aObjectBookmarkList, 1 );
387
388
0
        if( bNameOK )
389
0
            bOK = mrDoc.InsertBookmarkAsObject( aObjectBookmarkList, aExchangeList,
390
0
                                nullptr, nullptr, false );
391
392
0
        if( pDlg->IsRemoveUnnecessaryMasterPages() )
393
0
            mrDoc.RemoveUnnecessaryMasterPages();
394
0
    }
395
396
0
    return bOK;
397
0
}
398
399
void FuInsertFile::InsTextOrRTFinDrMode(SfxMedium* pMedium)
400
0
{
401
0
    SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
402
0
    ScopedVclPtr<AbstractSdInsertPagesObjsDlg> pDlg( pFact->CreateSdInsertPagesObjsDlg(mrViewShell.GetFrameWeld(), mrDoc, nullptr, aFile) );
403
404
0
    mpDocSh->SetWaitCursor( false );
405
406
0
    sal_uInt16 nRet = pDlg->Execute();
407
0
    mpDocSh->SetWaitCursor( true );
408
409
0
    if( nRet != RET_OK )
410
0
        return;
411
412
    // selected file format: text, RTF or HTML (default is text)
413
0
    EETextFormat nFormat = EETextFormat::Text;
414
415
0
    if( aFilterName.indexOf( "Rich") != -1 )
416
0
        nFormat = EETextFormat::Rtf;
417
0
    else if( aFilterName.indexOf( "HTML" ) != -1 )
418
0
        nFormat = EETextFormat::Html;
419
420
    /* create our own outline since:
421
       - it is possible that the document outliner is actually used in the
422
         structuring mode
423
       - the draw outliner of the drawing engine has to draw something in
424
         between
425
       - the global outliner could be used in SdPage::CreatePresObj */
426
0
    SdOutliner aOutliner( mrDoc, OutlinerMode::TextObject );
427
428
    // set reference device
429
0
    aOutliner.SetRefDevice(SdModule::get()->GetVirtualRefDevice());
430
431
0
    SdPage* pPage = static_cast<DrawViewShell*>(&mrViewShell)->GetActualPage();
432
0
    aLayoutName = pPage->GetLayoutName();
433
0
    sal_Int32 nIndex = aLayoutName.indexOf(SD_LT_SEPARATOR);
434
0
    if( nIndex != -1 )
435
0
        aLayoutName = aLayoutName.copy(0, nIndex);
436
437
0
    aOutliner.SetPaperSize(pPage->GetSize());
438
439
0
    SvStream* pStream = pMedium->GetInStream();
440
0
    assert(pStream && "No InStream!");
441
0
    pStream->Seek( 0 );
442
443
0
    ErrCode nErr = aOutliner.Read( *pStream, pMedium->GetBaseURL(), nFormat, mpDocSh->GetHeaderAttributes() );
444
445
0
    if (nErr || !aOutliner.GetEditEngine().HasText())
446
0
    {
447
0
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(mpWindow->GetFrameWeld(),
448
0
                                                       VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR)));
449
0
        xErrorBox->run();
450
0
    }
451
0
    else
452
0
    {
453
        // is it a master page?
454
0
        if (static_cast<DrawViewShell*>(&mrViewShell)->GetEditMode() == EditMode::MasterPage &&
455
0
            !pPage->IsMasterPage())
456
0
        {
457
0
            pPage = static_cast<SdPage*>(&(pPage->TRG_GetMasterPage()));
458
0
        }
459
460
0
        assert(pPage && "page not found");
461
462
        // if editing is going on right now, let it flow into this text object
463
0
        OutlinerView* pOutlinerView = mpView->GetTextEditOutlinerView();
464
0
        if( pOutlinerView )
465
0
        {
466
0
            SdrObject* pObj = mpView->GetTextEditObject();
467
0
            if( pObj &&
468
0
                pObj->GetObjInventor()   == SdrInventor::Default &&
469
0
                pObj->GetObjIdentifier() == SdrObjKind::TitleText &&
470
0
                aOutliner.GetParagraphCount() > 1 )
471
0
            {
472
                // in title objects, only one paragraph is allowed
473
0
                while ( aOutliner.GetParagraphCount() > 1 )
474
0
                {
475
0
                    Paragraph* pPara = aOutliner.GetParagraph( 0 );
476
0
                    sal_Int32 nLen = aOutliner.GetText( pPara ).getLength();
477
0
                    aOutliner.QuickInsertLineBreak(ESelection(0, nLen, 1, 0));
478
0
                }
479
0
            }
480
0
        }
481
482
0
        std::optional<OutlinerParaObject> pOPO = aOutliner.CreateParaObject();
483
484
0
        if (pOutlinerView)
485
0
        {
486
0
            pOutlinerView->InsertText(*pOPO);
487
0
        }
488
0
        else
489
0
        {
490
0
            rtl::Reference<SdrRectObj> pTO = new SdrRectObj(
491
0
                mpView->getSdrModelFromSdrView(), ::tools::Rectangle(), SdrObjKind::Text);
492
0
            pTO->SetOutlinerParaObject(std::move(pOPO));
493
494
0
            const bool bUndo = mpView->IsUndoEnabled();
495
0
            if( bUndo )
496
0
                mpView->BegUndo(SdResId(STR_UNDO_INSERT_TEXTFRAME));
497
0
            pPage->InsertObject(pTO.get());
498
499
            /* can be bigger as the maximal allowed size:
500
               limit object size if necessary */
501
0
            Size aSize(aOutliner.CalcTextSize());
502
0
            Size aMaxSize = mrDoc.GetMaxObjSize();
503
0
            aSize.setHeight( std::min(aSize.Height(), aMaxSize.Height()) );
504
0
            aSize.setWidth( std::min(aSize.Width(), aMaxSize.Width()) );
505
0
            aSize = mpWindow->LogicToPixel(aSize);
506
507
            // put it at the center of the window
508
0
            Size aTemp(mpWindow->GetOutputSizePixel());
509
0
            Point aPos(aTemp.Width() / 2, aTemp.Height() / 2);
510
0
            aPos.AdjustX( -(aSize.Width() / 2) );
511
0
            aPos.AdjustY( -(aSize.Height() / 2) );
512
0
            aSize = mpWindow->PixelToLogic(aSize);
513
0
            aPos = mpWindow->PixelToLogic(aPos);
514
0
            pTO->SetLogicRect(::tools::Rectangle(aPos, aSize));
515
516
0
            if (pDlg->IsLink())
517
0
            {
518
0
                pTO->SetTextLink(aFile, aFilterName );
519
0
            }
520
521
0
            if( bUndo )
522
0
            {
523
0
                mpView->AddUndo(mrDoc.GetSdrUndoFactory().CreateUndoInsertObject(*pTO));
524
0
                mpView->EndUndo();
525
0
            }
526
0
        }
527
0
    }
528
0
}
529
530
void FuInsertFile::InsTextOrRTFinOlMode(SfxMedium* pMedium)
531
0
{
532
    // selected file format: text, RTF or HTML (default is text)
533
0
    EETextFormat nFormat = EETextFormat::Text;
534
535
0
    if( aFilterName.indexOf( "Rich") != -1 )
536
0
        nFormat = EETextFormat::Rtf;
537
0
    else if( aFilterName.indexOf( "HTML" ) != -1 )
538
0
        nFormat = EETextFormat::Html;
539
540
0
    ::Outliner&    rDocliner = static_cast<OutlineView*>(mpView)->GetOutliner();
541
542
0
    std::vector<Paragraph*> aSelList;
543
0
    rDocliner.GetView(0)->CreateSelectionList(aSelList);
544
545
0
    Paragraph* pPara = aSelList.empty() ? nullptr : *(aSelList.begin());
546
547
    // what should we insert?
548
0
    while (pPara && !Outliner::HasParaFlag(pPara, ParaFlag::ISPAGE))
549
0
        pPara = rDocliner.GetParent(pPara);
550
551
0
    sal_Int32 nTargetPos = rDocliner.GetAbsPos(pPara) + 1;
552
553
    // apply layout of predecessor page
554
0
    sal_uInt16 nPage = 0;
555
0
    pPara = rDocliner.GetParagraph( rDocliner.GetAbsPos( pPara ) - 1 );
556
0
    while (pPara)
557
0
    {
558
0
        sal_Int32 nPos = rDocliner.GetAbsPos( pPara );
559
0
        if ( Outliner::HasParaFlag( pPara, ParaFlag::ISPAGE ) )
560
0
            nPage++;
561
0
        pPara = rDocliner.GetParagraph( nPos - 1 );
562
0
    }
563
0
    SdPage* pPage = mrDoc.GetSdPage(nPage, PageKind::Standard);
564
0
    aLayoutName = pPage->GetLayoutName();
565
0
    sal_Int32 nIndex = aLayoutName.indexOf(SD_LT_SEPARATOR);
566
0
    if( nIndex != -1 )
567
0
        aLayoutName = aLayoutName.copy(0, nIndex);
568
569
    /* create our own outline since:
570
       - it is possible that the document outliner is actually used in the
571
         structuring mode
572
       - the draw outliner of the drawing engine has to draw something in
573
         between
574
       - the global outliner could be used in SdPage::CreatePresObj */
575
0
    ::Outliner aOutliner( &mrDoc.GetItemPool(), OutlinerMode::OutlineObject );
576
0
    aOutliner.SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(mrDoc.GetStyleSheetPool()));
577
578
    // set reference device
579
0
    aOutliner.SetRefDevice(SdModule::get()->GetVirtualRefDevice());
580
0
    aOutliner.SetPaperSize(Size(0x7fffffff, 0x7fffffff));
581
582
0
    SvStream* pStream = pMedium->GetInStream();
583
0
    assert(pStream && "No InStream!");
584
0
    pStream->Seek( 0 );
585
586
0
    ErrCode nErr = aOutliner.Read(*pStream, pMedium->GetBaseURL(), nFormat, mpDocSh->GetHeaderAttributes());
587
588
0
    if (nErr || !aOutliner.GetEditEngine().HasText())
589
0
    {
590
0
        std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(mpWindow->GetFrameWeld(),
591
0
                                                       VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR)));
592
0
        xErrorBox->run();
593
0
    }
594
0
    else
595
0
    {
596
0
        sal_Int32 nParaCount = aOutliner.GetParagraphCount();
597
598
        // for progress bar: number of level-0-paragraphs
599
0
        sal_uInt16 nNewPages = 0;
600
0
        pPara = aOutliner.GetParagraph( 0 );
601
0
        while (pPara)
602
0
        {
603
0
            sal_Int32 nPos = aOutliner.GetAbsPos( pPara );
604
0
            if( Outliner::HasParaFlag( pPara, ParaFlag::ISPAGE ) )
605
0
                nNewPages++;
606
0
            pPara = aOutliner.GetParagraph( ++nPos );
607
0
        }
608
609
0
        mpDocSh->SetWaitCursor( false );
610
611
0
        std::optional<SfxProgress> pProgress( std::in_place, mpDocSh, SdResId(STR_CREATE_PAGES), nNewPages);
612
0
        pProgress->SetState( 0, 100 );
613
614
0
        nNewPages = 0;
615
616
0
        ViewShellId nViewShellId = mrViewShell.GetViewShellBase().GetViewShellId();
617
0
        rDocliner.GetUndoManager().EnterListAction(
618
0
                                    SdResId(STR_UNDO_INSERT_FILE), OUString(), 0, nViewShellId );
619
620
0
        sal_Int32 nSourcePos = 0;
621
0
        SfxStyleSheet* pStyleSheet = pPage->GetStyleSheetForPresObj( PresObjKind::Outline );
622
0
        Paragraph* pSourcePara = aOutliner.GetParagraph( 0 );
623
0
        while (pSourcePara)
624
0
        {
625
0
            sal_Int32 nPos = aOutliner.GetAbsPos( pSourcePara );
626
0
            sal_Int16 nDepth = aOutliner.GetDepth( nPos );
627
628
            // only take the last paragraph if it is filled
629
0
            if (nSourcePos < nParaCount - 1 ||
630
0
                !aOutliner.GetText(pSourcePara).isEmpty())
631
0
            {
632
0
                rDocliner.Insert( aOutliner.GetText(pSourcePara), nTargetPos, nDepth );
633
0
                OUString aStyleSheetName( pStyleSheet->GetName() );
634
0
                aStyleSheetName = aStyleSheetName.subView( 0, aStyleSheetName.getLength()-1 ) +
635
0
                    OUString::number( nDepth <= 0 ? 1 : nDepth+1 );
636
0
                SfxStyleSheetBasePool* pStylePool = mrDoc.GetStyleSheetPool();
637
0
                SfxStyleSheet* pOutlStyle = static_cast<SfxStyleSheet*>( pStylePool->Find( aStyleSheetName, pStyleSheet->GetFamily() ) );
638
0
                rDocliner.SetStyleSheet( nTargetPos, pOutlStyle );
639
0
            }
640
641
0
            if( Outliner::HasParaFlag( pSourcePara, ParaFlag::ISPAGE ) )
642
0
            {
643
0
                nNewPages++;
644
0
                pProgress->SetState( nNewPages );
645
0
            }
646
647
0
            pSourcePara = aOutliner.GetParagraph( ++nPos );
648
0
            nTargetPos++;
649
0
            nSourcePos++;
650
0
        }
651
652
0
        rDocliner.GetUndoManager().LeaveListAction();
653
654
0
        pProgress.reset();
655
656
0
        mpDocSh->SetWaitCursor( true );
657
0
    }
658
0
}
659
660
bool FuInsertFile::InsSDDinOlMode(SfxMedium* pMedium)
661
0
{
662
0
    OutlineView* pOlView = static_cast<OutlineView*>(mpView);
663
664
    // transfer Outliner content to SdDrawDocument
665
0
    pOlView->PrepareClose();
666
667
    // read in like in the character mode
668
0
    if (InsSDDinDrMode(pMedium))
669
0
    {
670
0
        ::Outliner& rOutliner = pOlView->GetViewByWindow(mpWindow)->GetOutliner();
671
672
        // cut notification links temporarily
673
0
        Link<Outliner::ParagraphHdlParam,void> aOldParagraphInsertedHdl = rOutliner.GetParaInsertedHdl();
674
0
        rOutliner.SetParaInsertedHdl( Link<Outliner::ParagraphHdlParam,void>());
675
0
        Link<Outliner::ParagraphHdlParam,void> aOldParagraphRemovingHdl = rOutliner.GetParaRemovingHdl();
676
0
        rOutliner.SetParaRemovingHdl( Link<Outliner::ParagraphHdlParam,void>());
677
0
        Link<Outliner::DepthChangeHdlParam,void> aOldDepthChangedHdl = rOutliner.GetDepthChangedHdl();
678
0
        rOutliner.SetDepthChangedHdl( Link<::Outliner::DepthChangeHdlParam,void>());
679
0
        Link<::Outliner*,void> aOldBeginMovingHdl = rOutliner.GetBeginMovingHdl();
680
0
        rOutliner.SetBeginMovingHdl( Link<::Outliner*,void>());
681
0
        Link<::Outliner*,void> aOldEndMovingHdl = rOutliner.GetEndMovingHdl();
682
0
        rOutliner.SetEndMovingHdl( Link<::Outliner*,void>());
683
684
0
        Link<EditStatus&,void> aOldStatusEventHdl = rOutliner.GetStatusEventHdl();
685
0
        rOutliner.SetStatusEventHdl(Link<EditStatus&,void>());
686
687
0
        rOutliner.Clear();
688
0
        pOlView->FillOutliner();
689
690
        // set links again
691
0
        rOutliner.SetParaInsertedHdl(aOldParagraphInsertedHdl);
692
0
        rOutliner.SetParaRemovingHdl(aOldParagraphRemovingHdl);
693
0
        rOutliner.SetDepthChangedHdl(aOldDepthChangedHdl);
694
0
        rOutliner.SetBeginMovingHdl(aOldBeginMovingHdl);
695
0
        rOutliner.SetEndMovingHdl(aOldEndMovingHdl);
696
0
        rOutliner.SetStatusEventHdl(aOldStatusEventHdl);
697
698
0
        return true;
699
0
    }
700
0
    else
701
0
        return false;
702
0
}
703
704
void FuInsertFile::GetSupportedFilterVector( ::std::vector< OUString >& rFilterVector )
705
0
{
706
0
    SfxFilterMatcher&   rMatcher = SfxGetpApp()->GetFilterMatcher();
707
0
    std::shared_ptr<const SfxFilter> pSearchFilter;
708
709
0
    rFilterVector.clear();
710
711
0
    if( ( pSearchFilter = rMatcher.GetFilter4Mime( u"text/plain"_ustr )) != nullptr )
712
0
        rFilterVector.push_back( pSearchFilter->GetMimeType() );
713
714
0
    if( ( pSearchFilter = rMatcher.GetFilter4Mime( u"application/rtf"_ustr ) ) != nullptr )
715
0
        rFilterVector.push_back( pSearchFilter->GetMimeType() );
716
717
0
    if( ( pSearchFilter = rMatcher.GetFilter4Mime( u"text/html"_ustr ) ) != nullptr )
718
0
        rFilterVector.push_back( pSearchFilter->GetMimeType() );
719
0
}
720
721
} // end of namespace sd
722
723
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */