Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/app/docsh.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 <config_features.h>
21
22
#include <officecfg/Office/Calc.hxx>
23
#include <officecfg/Office/Common.hxx>
24
#include <officecfg/Office/Impress.hxx>
25
#include <officecfg/Office/Writer.hxx>
26
#include <vcl/weld/MessageDialog.hxx>
27
#include <vcl/svapp.hxx>
28
#include <vcl/syswin.hxx>
29
#include <vcl/jobset.hxx>
30
#include <svl/numformat.hxx>
31
#include <svl/whiter.hxx>
32
#include <svl/eitem.hxx>
33
#include <svl/stritem.hxx>
34
#include <svl/PasswordHelper.hxx>
35
#include <tools/urlobj.hxx>
36
#include <unotools/moduleoptions.hxx>
37
#include <sfx2/bindings.hxx>
38
#include <sfx2/docfile.hxx>
39
#include <sfx2/docfilt.hxx>
40
#include <sfx2/notebookbar/SfxNotebookBar.hxx>
41
#include <sfx2/printer.hxx>
42
#include <sfx2/linkmgr.hxx>
43
#include <editeng/flstitem.hxx>
44
#include <comphelper/lok.hxx>
45
#include <comphelper/classids.hxx>
46
#include <comphelper/sequenceashashmap.hxx>
47
#include <basic/sbmod.hxx>
48
#include <osl/diagnose.h>
49
#include <node.hxx>
50
#include <swwait.hxx>
51
#include <printdata.hxx>
52
#include <view.hxx>
53
#include <edtwin.hxx>
54
#include <PostItMgr.hxx>
55
#include <wrtsh.hxx>
56
#include <docsh.hxx>
57
#include <viewopt.hxx>
58
#include <wdocsh.hxx>
59
#include <swmodule.hxx>
60
#include <globdoc.hxx>
61
#include <usrpref.hxx>
62
#include <shellio.hxx>
63
#include <docstyle.hxx>
64
#include <doc.hxx>
65
#include <docfunc.hxx>
66
#include <IDocumentUndoRedo.hxx>
67
#include <IDocumentSettingAccess.hxx>
68
#include <IDocumentLinksAdministration.hxx>
69
#include <IDocumentDeviceAccess.hxx>
70
#include <IDocumentDrawModelAccess.hxx>
71
#include <IDocumentRedlineAccess.hxx>
72
#include <IDocumentStatistics.hxx>
73
#include <IDocumentState.hxx>
74
#include <pview.hxx>
75
#include <srcview.hxx>
76
#include <ndindex.hxx>
77
#include <ndole.hxx>
78
#include <txtftn.hxx>
79
#include <ftnidx.hxx>
80
#include <fldbas.hxx>
81
#include <docary.hxx>
82
#include <swerror.h>
83
#include <cmdid.h>
84
#include <strings.hrc>
85
86
#include <sfx2/viewfrm.hxx>
87
#include <sfx2/objface.hxx>
88
89
#define ShellClass_SwDocShell
90
#include <sfx2/msg.hxx>
91
#include <swslots.hxx>
92
#include <com/sun/star/document/UpdateDocMode.hpp>
93
94
#include <com/sun/star/script/XLibraryContainer.hpp>
95
#include <com/sun/star/document/XDocumentProperties.hpp>
96
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
97
#include <com/sun/star/sdb/DatabaseContext.hpp>
98
#include <com/sun/star/sdb/XDocumentDataSource.hpp>
99
#include <com/sun/star/uri/UriReferenceFactory.hpp>
100
#include <com/sun/star/uri/VndSunStarPkgUrlReferenceFactory.hpp>
101
#include <com/sun/star/frame/XStorable.hpp>
102
#include <ooo/vba/XSinkCaller.hpp>
103
104
#include <unotextrange.hxx>
105
106
#include <dbmgr.hxx>
107
#include <iodetect.hxx>
108
109
#include <comphelper/processfactory.hxx>
110
#include <svx/fillbitmaplink.hxx>
111
#include <unotxdoc.hxx>
112
113
using namespace ::com::sun::star;
114
using namespace ::com::sun::star::uno;
115
using namespace ::com::sun::star::script;
116
using namespace ::com::sun::star::container;
117
118
SFX_IMPL_SUPERCLASS_INTERFACE(SwDocShell, SfxObjectShell)
119
120
void SwDocShell::InitInterface_Impl()
121
9
{
122
9
}
123
124
125
SFX_IMPL_OBJECTFACTORY(SwDocShell, SvGlobalName(SO3_SW_CLASSID), u"swriter"_ustr  )
126
127
bool SwDocShell::InsertGeneratedStream(SfxMedium & rMedium,
128
        uno::Reference<text::XTextRange> const& xInsertPosition)
129
0
{
130
0
    SwUnoInternalPaM aPam(*GetDoc()); // must have doc since called from SwView
131
0
    if (!::sw::XTextRangeToSwPaM(aPam, xInsertPosition))
132
0
        return false;
133
    // similar to SwView::InsertMedium
134
0
    SwReaderPtr pReader;
135
0
    Reader *const pRead = StartConvertFrom(rMedium, pReader, nullptr, &aPam);
136
0
    if (!pRead)
137
0
        return false;
138
0
    ErrCodeMsg const nError = pReader->Read(*pRead);
139
0
    return ERRCODE_NONE == nError;
140
0
}
141
142
// Prepare loading
143
Reader* SwDocShell::StartConvertFrom(SfxMedium& rMedium, SwReaderPtr& rpRdr,
144
                                    SwCursorShell const *pCursorShell,
145
                                    SwPaM* pPaM )
146
0
{
147
0
    bool bAPICall = false;
148
0
    if( const SfxBoolItem* pApiItem = rMedium.GetItemSet().GetItemIfSet( FN_API_CALL ) )
149
0
        bAPICall = pApiItem->GetValue();
150
151
0
    std::shared_ptr<const SfxFilter> pFlt = rMedium.GetFilter();
152
0
    if( !pFlt )
153
0
    {
154
0
        if(!bAPICall)
155
0
        {
156
0
            std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
157
0
                                                          VclMessageType::Info, VclButtonsType::Ok,
158
0
                                                          SwResId(STR_CANTOPEN)));
159
0
            xInfoBox->run();
160
0
        }
161
0
        return nullptr;
162
0
    }
163
0
    OUString aFileName( rMedium.GetName() );
164
0
    Reader* pRead = SwReaderWriter::GetReader( pFlt->GetUserData() );
165
0
    if( !pRead )
166
0
        return nullptr;
167
168
0
    if( rMedium.IsStorage()
169
0
        ? SwReaderType::Storage & pRead->GetReaderType()
170
0
        : SwReaderType::Stream & pRead->GetReaderType() )
171
0
    {
172
0
        if (pPaM)
173
0
            rpRdr.reset(new SwReader( rMedium, aFileName, *pPaM ));
174
0
        else if (pCursorShell)
175
0
            rpRdr.reset(new SwReader( rMedium, aFileName, *pCursorShell->GetCursor() ));
176
0
        else
177
0
            rpRdr.reset(new SwReader( rMedium, aFileName, m_xDoc.get() ));
178
0
    }
179
0
    else
180
0
        return nullptr;
181
182
    // #i30171# set the UpdateDocMode at the SwDocShell
183
0
    const SfxUInt16Item* pUpdateDocItem = rMedium.GetItemSet().GetItem(SID_UPDATEDOCMODE, false);
184
0
    m_nUpdateDocMode = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE;
185
186
0
    if (!pFlt->GetDefaultTemplate().isEmpty())
187
0
        pRead->SetTemplateName( pFlt->GetDefaultTemplate() );
188
189
0
    if( pRead == ReadAscii && nullptr != rMedium.GetInStream() &&
190
0
        pFlt->GetUserData() == FILTER_TEXT_DLG )
191
0
    {
192
0
        SwAsciiOptions aOpt;
193
0
        if( const SfxStringItem* pItem = rMedium.GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS ) )
194
0
            aOpt.ReadUserData( pItem->GetValue() );
195
196
0
        pRead->GetReaderOpt().SetASCIIOpts( aOpt );
197
0
    }
198
199
0
    return pRead;
200
0
}
201
202
// Loading
203
bool SwDocShell::ConvertFrom( SfxMedium& rMedium )
204
0
{
205
0
    SwReaderPtr pRdr;
206
0
    Reader* pRead = StartConvertFrom(rMedium, pRdr);
207
0
    if (!pRead)
208
0
      return false; // #129881# return if no reader is found
209
0
    rtl::Reference<SotStorage> pStg=pRead->getSotStorageRef(); // #i45333# save sot storage ref in case of recursive calls
210
211
    // Reading a foreign format starts from the same state as reading our own one, so link updates
212
    // are off until the load settles them.
213
0
    getEmbeddedObjectContainer().setUserAllowsLinkUpdate(false);
214
215
0
    m_xDoc->setDocAccTitle(OUString());
216
0
    if (const auto pFrame1 = SfxViewFrame::GetFirst(this))
217
0
    {
218
0
        if (auto pSysWin = pFrame1->GetWindow().GetSystemWindow())
219
0
        {
220
0
            pSysWin->SetAccessibleName(OUString());
221
0
        }
222
0
    }
223
0
    SwWait aWait( *this, true );
224
225
0
    SwModule* mod = SwModule::get();
226
        // Suppress SfxProgress, when we are Embedded
227
0
    mod->SetEmbeddedLoadSave(SfxObjectCreateMode::EMBEDDED == GetCreateMode());
228
229
0
    pRdr->GetDoc().getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, dynamic_cast< const SwWebDocShell *>( this ) !=  nullptr);
230
231
    // Restore the pool default if reading a saved document.
232
0
    m_xDoc->RemoveAllFormatLanguageDependencies();
233
234
0
    ErrCodeMsg nErr = pRdr->Read( *pRead );
235
236
    // Maybe put away one old Doc
237
0
    if (m_xDoc.get() != &pRdr->GetDoc())
238
0
    {
239
0
        RemoveLink();
240
0
        m_xDoc = &pRdr->GetDoc();
241
242
0
        AddLink();
243
244
0
        if (!m_xBasePool.is())
245
0
            m_xBasePool = new SwDocStyleSheetPool( *m_xDoc, SfxObjectCreateMode::ORGANIZER == GetCreateMode() );
246
0
    }
247
248
0
    UpdateFontList();
249
0
    InitDrawModelAndDocShell(this, m_xDoc ? m_xDoc->getIDocumentDrawModelAccess().GetDrawModel() : nullptr);
250
251
0
    pRdr.reset();
252
253
0
    mod->SetEmbeddedLoadSave(false);
254
255
0
    SetError(nErr);
256
0
    bool bOk = !nErr.IsError();
257
258
0
    if (bOk && !m_xDoc->IsInLoadAsynchron())
259
0
    {
260
0
        LoadingFinished();
261
0
    }
262
263
0
    pRead->setSotStorageRef(pStg); // #i45333# save sot storage ref in case of recursive calls
264
265
0
    return bOk;
266
0
}
267
268
// Saving the Default-Format, Stg present
269
bool SwDocShell::Save()
270
0
{
271
    //#i3370# remove quick help to prevent saving of autocorrection suggestions
272
0
    if (m_pView)
273
0
        m_pView->GetEditWin().StopQuickHelp();
274
0
    SwWait aWait( *this, true );
275
276
0
    CalcLayoutForOLEObjects();  // format for OLE objects
277
    // #i62875#
278
    // reset compatibility flag <DoNotCaptureDrawObjsOnPage>, if possible
279
0
    if (m_pWrtShell && m_xDoc &&
280
0
        m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
281
0
        docfunc::AllDrawObjsOnPage(*m_xDoc))
282
0
    {
283
0
        m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
284
0
    }
285
286
0
    ErrCodeMsg nErr = ERR_SWG_WRITE_ERROR;
287
0
    ErrCode nVBWarning = ERRCODE_NONE;
288
0
    if( SfxObjectShell::Save() )
289
0
    {
290
0
        SwModule* mod = SwModule::get();
291
0
        switch( GetCreateMode() )
292
0
        {
293
0
        case SfxObjectCreateMode::INTERNAL:
294
0
            nErr = ERRCODE_NONE;
295
0
            break;
296
297
0
        case SfxObjectCreateMode::ORGANIZER:
298
0
            {
299
0
                WriterRef xWrt;
300
0
                ::GetXMLWriter(std::u16string_view(), GetMedium()->GetBaseURL(true), xWrt);
301
0
                xWrt->SetOrganizerMode( true );
302
0
                SwWriter aWrt( *GetMedium(), *m_xDoc );
303
0
                nErr = aWrt.Write( xWrt );
304
0
                xWrt->SetOrganizerMode( false );
305
0
            }
306
0
            break;
307
308
0
        case SfxObjectCreateMode::EMBEDDED:
309
            // Suppress SfxProgress, if we are Embedded
310
0
            mod->SetEmbeddedLoadSave(true);
311
0
            [[fallthrough]];
312
313
0
        case SfxObjectCreateMode::STANDARD:
314
0
        default:
315
0
            {
316
0
                if (m_xDoc->ContainsMSVBasic())
317
0
                {
318
0
                    if (officecfg::Office::Writer::Filter::Import::VBA::Save::get())
319
0
                        nVBWarning = GetSaveWarningOfMSVBAStorage( static_cast<SfxObjectShell&>(*this) );
320
0
                    m_xDoc->SetContainsMSVBasic( false );
321
0
                }
322
323
                // End TableBox Edit!
324
0
                if (m_pWrtShell)
325
0
                    m_pWrtShell->EndAllTableBoxEdit();
326
327
0
                WriterRef xWrt;
328
0
                ::GetXMLWriter(std::u16string_view(), GetMedium()->GetBaseURL(true), xWrt);
329
330
0
                bool bLockedView(false);
331
0
                if (m_pWrtShell)
332
0
                {
333
0
                    bLockedView = m_pWrtShell->IsViewLocked();
334
0
                    m_pWrtShell->LockView( true );    //lock visible section
335
0
                }
336
337
0
                SwWriter aWrt( *GetMedium(), *m_xDoc );
338
0
                nErr = aWrt.Write( xWrt );
339
340
0
                if (m_pWrtShell)
341
0
                    m_pWrtShell->LockView( bLockedView );
342
0
            }
343
0
            break;
344
0
        }
345
0
        mod->SetEmbeddedLoadSave(false);
346
0
    }
347
0
    SetError(nErr ? nErr : nVBWarning);
348
349
0
    SfxViewFrame *const pFrame =
350
0
        m_pWrtShell ? &m_pWrtShell->GetView().GetViewFrame() : nullptr;
351
0
    if( pFrame )
352
0
    {
353
0
        pFrame->GetBindings().SetState(SfxBoolItem(SID_DOC_MODIFIED, false));
354
0
    }
355
0
    return !nErr.IsError();
356
0
}
357
358
SwDocShell::LockAllViewsGuard_Impl::LockAllViewsGuard_Impl(SwViewShell* pViewShell)
359
70.4k
{
360
70.4k
    if (!pViewShell)
361
0
        return;
362
70.4k
    for (SwViewShell& rShell : pViewShell->GetRingContainer())
363
70.4k
    {
364
70.4k
        if (!rShell.IsViewLocked())
365
70.4k
        {
366
70.4k
            m_aViewWasUnLocked.push_back(&rShell);
367
70.4k
            rShell.LockView(true);
368
70.4k
        }
369
70.4k
    }
370
70.4k
}
371
372
SwDocShell::LockAllViewsGuard_Impl::~LockAllViewsGuard_Impl()
373
70.4k
{
374
70.4k
    for (SwViewShell* pShell : m_aViewWasUnLocked)
375
70.4k
        pShell->LockView(false);
376
70.4k
}
377
378
std::unique_ptr<SfxObjectShell::LockAllViewsGuard> SwDocShell::LockAllViews()
379
70.4k
{
380
70.4k
    return std::make_unique<LockAllViewsGuard_Impl>(GetEditShell());
381
70.4k
}
382
383
// Save using the Defaultformat
384
bool SwDocShell::SaveAs( SfxMedium& rMedium )
385
0
{
386
0
    SwWait aWait( *this, true );
387
    //#i3370# remove quick help to prevent saving of autocorrection suggestions
388
0
    if (m_pView)
389
0
        m_pView->GetEditWin().StopQuickHelp();
390
391
    //#i91811# mod if we have an active margin window, write back the text
392
0
    if (m_pView &&
393
0
        m_pView->GetPostItMgr() &&
394
0
        m_pView->GetPostItMgr()->HasActiveSidebarWin())
395
0
    {
396
0
        m_pView->GetPostItMgr()->UpdateDataOnActiveSidebarWin();
397
0
    }
398
399
0
    if (m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) &&
400
0
        !m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS))
401
0
        RemoveOLEObjects();
402
403
0
    if (GetMedium())
404
0
    {
405
        // Task 75666 - is the Document imported by our Microsoft-Filters?
406
0
        std::shared_ptr<const SfxFilter> pOldFilter = GetMedium()->GetFilter();
407
0
        if( pOldFilter &&
408
0
            ( pOldFilter->GetUserData() == FILTER_WW8 ||
409
0
              pOldFilter->GetUserData() == "CWW6" ||
410
0
              pOldFilter->GetUserData() == "WW6" ) )
411
0
        {
412
            // when saving it in our own fileformat, then remove the template
413
            // name from the docinfo.
414
0
            uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
415
0
                GetModel(), uno::UNO_QUERY_THROW);
416
0
            uno::Reference<document::XDocumentProperties> xDocProps
417
0
                = xDPS->getDocumentProperties();
418
0
            xDocProps->setTemplateName(OUString());
419
0
            xDocProps->setTemplateURL(OUString());
420
0
            xDocProps->setTemplateDate(::util::DateTime());
421
0
        }
422
0
    }
423
424
0
    CalcLayoutForOLEObjects();  // format for OLE objects
425
426
0
    const bool bURLChanged = GetMedium() && GetMedium()->GetURLObject() != rMedium.GetURLObject();
427
0
    const SwDBManager* const pMgr = m_xDoc->GetDBManager();
428
0
    const bool bHasEmbedded = pMgr && !pMgr->getEmbeddedName().isEmpty();
429
0
    bool bSaveDS = bHasEmbedded && bURLChanged;
430
0
    if (bSaveDS)
431
0
    {
432
        // Don't save data source in case a temporary is being saved for preview in MM wizard
433
0
        if (const SfxBoolItem* pNoEmbDS
434
0
            = rMedium.GetItemSet().GetItem(SID_NO_EMBEDDED_DS, false))
435
0
            bSaveDS = !pNoEmbDS->GetValue();
436
0
    }
437
0
    if (bSaveDS)
438
0
    {
439
        // We have an embedded data source definition, need to re-store it,
440
        // otherwise relative references will break when the new file is in a
441
        // different directory.
442
443
0
        OUString aURL(GetMedium()->GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::NONE));
444
0
        if (aURL.isEmpty())
445
0
        {
446
            // No old URL - is this a new document created from a template with embedded DS?
447
            // Try to get the template URL to reconstruct the embedded data source URL
448
0
            aURL = GetMedium()->GetArgs().getUnpackedValueOrDefault(u"URL"_ustr, aURL);
449
0
        }
450
451
0
        if (!aURL.isEmpty())
452
0
        {
453
0
            const auto& xContext(comphelper::getProcessComponentContext());
454
0
            auto xUri = css::uri::UriReferenceFactory::create(xContext)->parse(aURL);
455
0
            assert(xUri.is());
456
0
            xUri = css::uri::VndSunStarPkgUrlReferenceFactory::create(xContext)
457
0
                       ->createVndSunStarPkgUrlReference(xUri);
458
0
            assert(xUri.is());
459
0
            aURL = xUri->getUriReference() + "/"
460
0
                   + INetURLObject::encode(pMgr->getEmbeddedName(), INetURLObject::PART_FPATH,
461
0
                                           INetURLObject::EncodeMechanism::All);
462
463
0
            bool bCopyTo = GetCreateMode() == SfxObjectCreateMode::EMBEDDED;
464
0
            if (!bCopyTo)
465
0
            {
466
0
                if (const SfxBoolItem* pSaveToItem
467
0
                    = rMedium.GetItemSet().GetItem(SID_SAVETO, false))
468
0
                    bCopyTo = pSaveToItem->GetValue();
469
0
            }
470
471
0
            auto xDatabaseContext = sdb::DatabaseContext::create(xContext);
472
0
            uno::Reference<sdb::XDocumentDataSource> xDataSource(xDatabaseContext->getByName(aURL),
473
0
                                                                 uno::UNO_QUERY);
474
0
            if (xDataSource)
475
0
            {
476
0
                uno::Reference<frame::XStorable> xStorable(xDataSource->getDatabaseDocument(),
477
0
                                                           uno::UNO_QUERY);
478
0
                SwDBManager::StoreEmbeddedDataSource(xStorable, rMedium.GetOutputStorage(),
479
0
                                                     pMgr->getEmbeddedName(), rMedium.GetName(),
480
0
                                                     bCopyTo);
481
0
            }
482
0
        }
483
0
    }
484
485
    // #i62875#
486
    // reset compatibility flag <DoNotCaptureDrawObjsOnPage>, if possible
487
0
    if (m_pWrtShell &&
488
0
        m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
489
0
        docfunc::AllDrawObjsOnPage(*m_xDoc))
490
0
    {
491
0
        m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
492
0
    }
493
494
0
    ErrCodeMsg nErr = ERR_SWG_WRITE_ERROR;
495
0
    ErrCode nVBWarning = ERRCODE_NONE;
496
0
    uno::Reference < embed::XStorage > xStor = rMedium.GetOutputStorage();
497
0
    if( SfxObjectShell::SaveAs( rMedium ) )
498
0
    {
499
0
        if( GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT) && dynamic_cast< const SwGlobalDocShell *>( this ) ==  nullptr )
500
0
        {
501
            // The document is closed explicitly, but using SfxObjectShellLock is still more correct here
502
0
            SfxObjectShellLock xDocSh =
503
0
                new SwGlobalDocShell( SfxObjectCreateMode::INTERNAL );
504
            // the global document can not be a template
505
0
            xDocSh->SetupStorage( xStor, SotStorage::GetVersion( xStor ), false );
506
0
            xDocSh->DoClose();
507
0
        }
508
509
0
        if (m_xDoc->ContainsMSVBasic())
510
0
        {
511
0
            if (officecfg::Office::Writer::Filter::Import::VBA::Save::get())
512
0
                nVBWarning = GetSaveWarningOfMSVBAStorage( static_cast<SfxObjectShell&>(*this) );
513
0
            m_xDoc->SetContainsMSVBasic( false );
514
0
        }
515
516
0
        if (m_pWrtShell)
517
0
        {
518
            // End TableBox Edit!
519
0
            m_pWrtShell->EndAllTableBoxEdit();
520
521
            // Remove invalid signatures.
522
0
            m_pWrtShell->ValidateAllParagraphSignatures(false);
523
524
0
            m_pWrtShell->ClassifyDocPerHighestParagraphClass();
525
0
        }
526
527
        // Remember and preserve Modified-Flag without calling the Link
528
        // (for OLE; after Statement from MM)
529
0
        const bool bIsModified = m_xDoc->getIDocumentState().IsModified();
530
0
        m_xDoc->GetIDocumentUndoRedo().LockUndoNoModifiedPosition();
531
0
        Link<bool,void> aOldOLELnk( m_xDoc->GetOle2Link() );
532
0
        m_xDoc->SetOle2Link( Link<bool,void>() );
533
534
0
        SwModule* mod = SwModule::get();
535
            // Suppress SfxProgress when we are Embedded
536
0
        mod->SetEmbeddedLoadSave(SfxObjectCreateMode::EMBEDDED == GetCreateMode());
537
538
0
        WriterRef xWrt;
539
0
        ::GetXMLWriter(std::u16string_view(), rMedium.GetBaseURL(true), xWrt);
540
541
0
        bool bLockedView(false);
542
0
        if (m_pWrtShell)
543
0
        {
544
0
            bLockedView = m_pWrtShell->IsViewLocked();
545
0
            m_pWrtShell->LockView( true );    //lock visible section
546
0
        }
547
548
0
        SwWriter aWrt( rMedium, *m_xDoc );
549
0
        nErr = aWrt.Write( xWrt );
550
551
0
        if (m_pWrtShell)
552
0
            m_pWrtShell->LockView( bLockedView );
553
554
0
        if( bIsModified )
555
0
        {
556
0
            m_xDoc->getIDocumentState().SetModified();
557
0
            m_xDoc->GetIDocumentUndoRedo().UnLockUndoNoModifiedPosition();
558
0
        }
559
0
        m_xDoc->SetOle2Link( aOldOLELnk );
560
561
0
        mod->SetEmbeddedLoadSave(false);
562
563
        // Increase RSID
564
0
        m_xDoc->setRsid( m_xDoc->getRsid() );
565
566
0
        m_xDoc->cleanupUnoCursorTable();
567
0
    }
568
0
    SetError(nErr ? nErr : nVBWarning);
569
570
0
    return !nErr.IsError();
571
0
}
572
573
// Save all Formats
574
static SwSrcView* lcl_GetSourceView( SwDocShell const * pSh )
575
0
{
576
    // are we in SourceView?
577
0
    SfxViewFrame* pVFrame = SfxViewFrame::GetFirst( pSh );
578
0
    SfxViewShell* pViewShell = pVFrame ? pVFrame->GetViewShell() : nullptr;
579
0
    return dynamic_cast<SwSrcView*>( pViewShell );
580
0
}
581
582
bool SwDocShell::ConvertTo( SfxMedium& rMedium )
583
0
{
584
0
    std::shared_ptr<const SfxFilter> pFlt = rMedium.GetFilter();
585
0
    if( !pFlt )
586
0
        return false;
587
588
0
    WriterRef xWriter;
589
0
    SwReaderWriter::GetWriter( pFlt->GetUserData(), rMedium.GetBaseURL( true ), xWriter );
590
0
    if( !xWriter.is() )
591
0
    {   // Filter not available
592
0
        std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr,
593
0
                                                      VclMessageType::Info, VclButtonsType::Ok,
594
0
                                                      SwResId(STR_DLLNOTFOUND)));
595
0
        xInfoBox->run();
596
0
        return false;
597
0
    }
598
599
    //#i3370# remove quick help to prevent saving of autocorrection suggestions
600
0
    if (m_pView)
601
0
        m_pView->GetEditWin().StopQuickHelp();
602
603
    //#i91811# mod if we have an active margin window, write back the text
604
0
    if (m_pView &&
605
0
        m_pView->GetPostItMgr() &&
606
0
        m_pView->GetPostItMgr()->HasActiveSidebarWin())
607
0
    {
608
0
        m_pView->GetPostItMgr()->UpdateDataOnActiveSidebarWin();
609
0
    }
610
611
0
    ErrCode nVBWarning = ERRCODE_NONE;
612
613
0
    if (m_xDoc->ContainsMSVBasic())
614
0
    {
615
0
        bool bSave = pFlt->GetUserData() == "CWW8"
616
0
                     && officecfg::Office::Writer::Filter::Import::VBA::Save::get();
617
618
0
        if ( bSave )
619
0
        {
620
0
            rtl::Reference<SotStorage> xStg = new SotStorage(rMedium.GetOutStream(), false);
621
0
            OSL_ENSURE( !xStg->GetError(), "No storage available for storing VBA macros!" );
622
0
            if ( !xStg->GetError() )
623
0
            {
624
0
                nVBWarning = SaveOrDelMSVBAStorage( static_cast<SfxObjectShell&>(*this), *xStg, bSave, u"Macros"_ustr );
625
0
                xStg->Commit();
626
0
                m_xDoc->SetContainsMSVBasic( true );
627
0
            }
628
0
        }
629
0
    }
630
631
    // End TableBox Edit!
632
0
    if (m_pWrtShell)
633
0
        m_pWrtShell->EndAllTableBoxEdit();
634
635
0
    if( pFlt->GetUserData() == "HTML" )
636
0
    {
637
#if HAVE_FEATURE_SCRIPTING
638
        if( !officecfg::Office::Common::Filter::HTML::Export::Basic::get()
639
            && officecfg::Office::Common::Filter::HTML::Export::Warning::get()
640
            && HasBasic() )
641
        {
642
            uno::Reference< XLibraryContainer > xLibCont = GetBasicContainer();
643
            uno::Reference< XNameAccess > xLib;
644
            const Sequence<OUString> aNames = xLibCont->getElementNames();
645
            for(const OUString& rName : aNames)
646
            {
647
                Any aLib = xLibCont->getByName(rName);
648
                aLib >>= xLib;
649
                if(xLib.is())
650
                {
651
                    Sequence<OUString> aModNames = xLib->getElementNames();
652
                    if(aModNames.hasElements())
653
                    {
654
                        SetError(WARN_SWG_HTML_NO_MACROS);
655
                        break;
656
                    }
657
                }
658
            }
659
        }
660
#endif
661
0
    }
662
663
    // #i76360# Update document statistics
664
0
    if ( !rMedium.IsSkipImages() )
665
0
        m_xDoc->getIDocumentStatistics().UpdateDocStat( false, true );
666
667
0
    CalcLayoutForOLEObjects();  // format for OLE objects
668
    // #i62875#
669
    // reset compatibility flag <DoNotCaptureDrawObjsOnPage>, if possible
670
0
    if (m_pWrtShell &&
671
0
        m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
672
0
        docfunc::AllDrawObjsOnPage(*m_xDoc))
673
0
    {
674
0
        m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, false);
675
0
    }
676
677
0
    if( xWriter->IsStgWriter() &&
678
0
        ( pFlt->GetUserData() == FILTER_XML ||
679
0
          pFlt->GetUserData() == FILTER_XMLV ||
680
0
          pFlt->GetUserData() == FILTER_XMLVW ) )
681
0
    {
682
        // determine the own Type
683
0
        sal_uInt8 nMyType = 0;
684
0
        if( dynamic_cast< const SwWebDocShell *>( this ) !=  nullptr )
685
0
            nMyType = 1;
686
0
        else if( dynamic_cast< const SwGlobalDocShell *>( this ) !=  nullptr )
687
0
            nMyType = 2;
688
689
        // determine the desired Type
690
0
        sal_uInt8 nSaveType = 0;
691
0
        SotClipboardFormatId nSaveClipId = pFlt->GetFormat();
692
0
        if( SotClipboardFormatId::STARWRITERWEB_8 == nSaveClipId ||
693
0
            SotClipboardFormatId::STARWRITERWEB_60 == nSaveClipId ||
694
0
            SotClipboardFormatId::STARWRITERWEB_50 == nSaveClipId ||
695
0
            SotClipboardFormatId::STARWRITERWEB_40 == nSaveClipId )
696
0
            nSaveType = 1;
697
0
        else if( SotClipboardFormatId::STARWRITERGLOB_8 == nSaveClipId ||
698
0
                 SotClipboardFormatId::STARWRITERGLOB_8_TEMPLATE == nSaveClipId ||
699
0
                 SotClipboardFormatId::STARWRITERGLOB_60 == nSaveClipId ||
700
0
                 SotClipboardFormatId::STARWRITERGLOB_50 == nSaveClipId ||
701
0
                 SotClipboardFormatId::STARWRITERGLOB_40 == nSaveClipId )
702
0
            nSaveType = 2;
703
704
        // Change Flags of the Document accordingly
705
0
        bool bIsHTMLModeSave = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE);
706
0
        bool bIsGlobalDocSave = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT);
707
0
        bool bIsGlblDocSaveLinksSave = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS);
708
0
        if( nMyType != nSaveType )
709
0
        {
710
0
            GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, 1 == nSaveType);
711
0
            GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT, 2 == nSaveType);
712
0
            if( 2 != nSaveType )
713
0
                GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS, false);
714
0
        }
715
716
        // if the target format is storage based, then the output storage must be already created
717
0
        if ( rMedium.IsStorage() )
718
0
        {
719
            // set MediaType on target storage
720
            // (MediaType will be queried during SaveAs)
721
0
            try
722
0
            {
723
                // TODO/MBA: testing
724
0
                uno::Reference < beans::XPropertySet > xSet( rMedium.GetStorage(), uno::UNO_QUERY );
725
0
                if ( xSet.is() )
726
0
                    xSet->setPropertyValue(u"MediaType"_ustr, uno::Any( SotExchange::GetFormatMimeType( nSaveClipId ) ) );
727
0
            }
728
0
            catch (const uno::Exception&)
729
0
            {
730
0
            }
731
0
        }
732
733
        // Now normally save the Document
734
0
        bool bRet = SaveAs( rMedium );
735
736
0
        if( nMyType != nSaveType )
737
0
        {
738
0
            GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, bIsHTMLModeSave );
739
0
            GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT, bIsGlobalDocSave);
740
0
            GetDoc()->getIDocumentSettingAccess().set(DocumentSettingId::GLOBAL_DOCUMENT_SAVE_LINKS, bIsGlblDocSaveLinksSave);
741
0
        }
742
743
0
        return bRet;
744
0
    }
745
746
0
    if( pFlt->GetUserData() == FILTER_TEXT_DLG &&
747
0
        (m_pWrtShell || !::lcl_GetSourceView(this)))
748
0
    {
749
0
        SwAsciiOptions aOpt;
750
0
        OUString sItemOpt;
751
0
        if( const SfxStringItem* pItem = rMedium.GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS ) )
752
0
            sItemOpt = pItem->GetValue();
753
0
        if(!sItemOpt.isEmpty())
754
0
            aOpt.ReadUserData( sItemOpt );
755
756
0
        xWriter->SetAsciiOptions( aOpt );
757
0
    }
758
759
0
    SwModule* mod = SwModule::get();
760
        // Suppress SfxProgress when we are Embedded
761
0
    mod->SetEmbeddedLoadSave(SfxObjectCreateMode::EMBEDDED == GetCreateMode());
762
763
    // Span Context in order to suppress the Selection's View
764
0
    ErrCodeMsg nErrno;
765
0
    const OUString aFileName( rMedium.GetName() );
766
767
0
    bool bSelection = false;
768
0
    if (m_pWrtShell)
769
0
    {
770
0
        const SfxBoolItem* pSelectionItem = rMedium.GetItemSet().GetItemIfSet(SID_SELECTION);
771
0
        bSelection = pSelectionItem && pSelectionItem->GetValue();
772
0
    }
773
774
    // No View, so the whole Document! (unless SID_SELECTION explicitly set)
775
0
    if (m_pWrtShell && (!Application::IsHeadlessModeEnabled() || bSelection))
776
0
    {
777
778
0
        SwWait aWait( *this, true );
779
        // #i106906#
780
0
        const bool bFormerLockView = m_pWrtShell->IsViewLocked();
781
0
        m_pWrtShell->LockView( true );
782
0
        m_pWrtShell->StartAllAction();
783
0
        m_pWrtShell->Push();
784
0
        SwWriter aWrt( rMedium, *m_pWrtShell, !bSelection );
785
0
        nErrno = aWrt.Write( xWriter, &aFileName );
786
        //JP 16.05.97: In case the SFX revokes the View while saving
787
0
        if (m_pWrtShell)
788
0
        {
789
0
            m_pWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent);
790
0
            m_pWrtShell->EndAllAction();
791
            // #i106906#
792
0
            m_pWrtShell->LockView( bFormerLockView );
793
0
        }
794
0
    }
795
0
    else
796
0
    {
797
        // are we in SourceView?
798
0
        SwSrcView* pSrcView = ::lcl_GetSourceView( this );
799
0
        if( pSrcView )
800
0
        {
801
0
            pSrcView->SaveContentTo(rMedium);
802
0
            nErrno = ERRCODE_NONE;
803
0
        }
804
0
        else
805
0
        {
806
0
            SwWriter aWrt( rMedium, *m_xDoc );
807
0
            nErrno = aWrt.Write( xWriter, &aFileName );
808
0
        }
809
0
    }
810
811
0
    mod->SetEmbeddedLoadSave(false);
812
0
    SetError(nErrno ? nErrno : nVBWarning);
813
0
    if( !rMedium.IsStorage() )
814
0
        rMedium.CloseOutStream();
815
816
0
    return ! nErrno.IsError();
817
0
}
818
819
// Hands off
820
// do not yet activate, must deliver TRUE
821
bool SwDocShell::SaveCompleted( const uno::Reference < embed::XStorage >& xStor  )
822
0
{
823
0
    bool bRet = SfxObjectShell::SaveCompleted( xStor );
824
0
    if( bRet )
825
0
    {
826
        // Do not decide until here, whether Saving was successful or not
827
0
        if( IsModified() )
828
0
            m_xDoc->getIDocumentState().SetModified();
829
0
        else
830
0
            m_xDoc->getIDocumentState().ResetModified();
831
0
    }
832
833
0
    if (m_pOLEChildList)
834
0
    {
835
0
        bool bResetModified = IsEnableSetModified();
836
0
        if( bResetModified )
837
0
            EnableSetModified( false );
838
839
0
        uno::Sequence < OUString > aNames = m_pOLEChildList->GetObjectNames();
840
0
        for( sal_Int32 n = aNames.getLength(); n; n-- )
841
0
        {
842
0
            if (!m_pOLEChildList->MoveEmbeddedObject(aNames[n-1], GetEmbeddedObjectContainer()))
843
0
            {
844
0
                OSL_FAIL("Copying of objects didn't work!" );
845
0
            }
846
0
        }
847
848
0
        m_pOLEChildList.reset();
849
0
        if( bResetModified )
850
0
            EnableSetModified();
851
0
    }
852
0
    return bRet;
853
0
}
854
855
// Draw()-Override for OLE2 (Sfx)
856
void SwDocShell::Draw( OutputDevice* pDev, const JobSetup& rSetup,
857
                               sal_uInt16 nAspect, bool bOutputForScreen )
858
0
{
859
    //fix #25341# Draw should not affect the Modified
860
0
    bool bResetModified = IsEnableSetModified();
861
0
    if ( bResetModified )
862
0
        EnableSetModified( false );
863
864
    // When there is a JobSetup connected to the Document, we copy it to
865
    // reconnect it after PrtOle2. We don't use an empty JobSetup because
866
    // that would only lead to questionable results after expensive
867
    // reformatting (Preview!)
868
0
    std::unique_ptr<JobSetup> pOrig;
869
0
    if ( !rSetup.GetPrinterName().isEmpty() && ASPECT_THUMBNAIL != nAspect )
870
0
    {
871
0
        const JobSetup* pCurrentJobSetup = m_xDoc->getIDocumentDeviceAccess().getJobsetup();
872
0
        if( pCurrentJobSetup )         // then we copy that
873
0
            pOrig.reset(new JobSetup( *pCurrentJobSetup ));
874
0
        m_xDoc->getIDocumentDeviceAccess().setJobsetup( rSetup );
875
0
    }
876
877
0
    tools::Rectangle aRect( nAspect == ASPECT_THUMBNAIL ?
878
0
            GetVisArea( nAspect ) : GetVisArea( ASPECT_CONTENT ) );
879
880
0
    pDev->Push();
881
0
    pDev->SetFillColor();
882
0
    pDev->SetLineColor();
883
0
    pDev->SetBackground();
884
0
    const bool bWeb = dynamic_cast< const SwWebDocShell *>( this ) !=  nullptr;
885
0
    SwPrintData aOpts;
886
0
    SwViewShell::PrtOle2(m_xDoc.get(), SwModule::get()->GetUsrPref(bWeb), aOpts, *pDev, aRect, bOutputForScreen);
887
0
    pDev->Pop();
888
889
0
    if( pOrig )
890
0
    {
891
0
        m_xDoc->getIDocumentDeviceAccess().setJobsetup( *pOrig );
892
0
    }
893
0
    if ( bResetModified )
894
0
        EnableSetModified();
895
0
}
896
897
rtl::Reference<SwXTextDocument> SwDocShell::GetBaseModel() const
898
386k
{
899
386k
    const auto xModel = SfxObjectShell::GetBaseModel();
900
386k
    assert(!xModel || dynamic_cast<SwXTextDocument*>(xModel.get()));
901
386k
    return static_cast<SwXTextDocument*>(xModel.get());
902
386k
}
903
904
void SwDocShell::SetVisArea( const tools::Rectangle &rRect )
905
5.95k
{
906
5.95k
    tools::Rectangle aRect( rRect );
907
5.95k
    if (m_pView)
908
0
    {
909
0
        Size aSz( m_pView->GetDocSz() );
910
0
        aSz.AdjustWidth(DOCUMENTBORDER ); aSz.AdjustHeight(DOCUMENTBORDER );
911
0
        tools::Long nMoveX = 0, nMoveY = 0;
912
0
        if ( aRect.Right() > aSz.Width() )
913
0
            nMoveX = aSz.Width() - aRect.Right();
914
0
        if ( aRect.Bottom() > aSz.Height() )
915
0
            nMoveY = aSz.Height() - aRect.Bottom();
916
0
        aRect.Move( nMoveX, nMoveY );
917
0
        nMoveX = aRect.Left() < 0 ? -aRect.Left() : 0;
918
0
        nMoveY = aRect.Top()  < 0 ? -aRect.Top()  : 0;
919
0
        aRect.Move( nMoveX, nMoveY );
920
921
        // Calls SfxInPlaceObject::SetVisArea()!
922
0
        m_pView->SetVisArea( aRect );
923
0
    }
924
5.95k
    else
925
5.95k
        SfxObjectShell::SetVisArea( aRect );
926
5.95k
}
927
928
tools::Rectangle SwDocShell::GetVisArea( sal_uInt16 nAspect ) const
929
5.95k
{
930
5.95k
    if ( nAspect == ASPECT_THUMBNAIL )
931
0
    {
932
        // Preview: set VisArea to the first page.
933
0
        SwNodeIndex aIdx( m_xDoc->GetNodes().GetEndOfExtras(), 1 );
934
0
        SwContentNode* pNd = SwNodes::GoNext(&aIdx);
935
936
0
        const SwRect aPageRect = pNd->FindPageFrameRect();
937
0
        if (aPageRect.IsEmpty())
938
0
            return tools::Rectangle();
939
0
        tools::Rectangle aRect(aPageRect.SVRect());
940
941
        // tdf#81219 sanitize - nobody is interested in a thumbnail where's
942
        // nothing visible
943
0
        if (aRect.GetHeight() > 2*aRect.GetWidth())
944
0
            aRect.SetSize(Size(aRect.GetWidth(), 2*aRect.GetWidth()));
945
0
        else if (aRect.GetWidth() > 2*aRect.GetHeight())
946
0
            aRect.SetSize(Size(2*aRect.GetHeight(), aRect.GetHeight()));
947
948
0
        return aRect;
949
0
    }
950
5.95k
    return SfxObjectShell::GetVisArea( nAspect );
951
5.95k
}
952
953
Printer *SwDocShell::GetDocumentPrinter()
954
0
{
955
0
    return m_xDoc->getIDocumentDeviceAccess().getPrinter( false );
956
0
}
957
958
OutputDevice* SwDocShell::GetDocumentRefDev()
959
0
{
960
0
    return m_xDoc->getIDocumentDeviceAccess().getReferenceDevice( false );
961
0
}
962
963
void SwDocShell::OnDocumentPrinterChanged( Printer * pNewPrinter )
964
0
{
965
0
    if ( pNewPrinter )
966
0
        GetDoc()->getIDocumentDeviceAccess().setJobsetup( pNewPrinter->GetJobSetup() );
967
0
    else
968
0
        GetDoc()->getIDocumentDeviceAccess().setPrinter( nullptr, true, true );
969
0
}
970
971
// #i20883# Digital Signatures and Encryption
972
HiddenInformation SwDocShell::GetHiddenInformationState( HiddenInformation nStates )
973
0
{
974
    // get global state like HiddenInformation::DOCUMENTVERSIONS
975
0
    HiddenInformation nState = SfxObjectShell::GetHiddenInformationState( nStates );
976
977
0
    if ( nStates & HiddenInformation::RECORDEDCHANGES )
978
0
    {
979
0
        if ( !GetDoc()->getIDocumentRedlineAccess().GetRedlineTable().empty() )
980
0
            nState |= HiddenInformation::RECORDEDCHANGES;
981
0
    }
982
0
    if ( nStates & HiddenInformation::NOTES )
983
0
    {
984
0
        OSL_ENSURE( GetWrtShell(), "No SwWrtShell, no information" );
985
0
        if(GetWrtShell() && GetWrtShell()->GetFieldType(SwFieldIds::Postit, OUString())->HasHiddenInformationNotes())
986
0
                nState |= HiddenInformation::NOTES;
987
0
    }
988
989
0
    return nState;
990
0
}
991
992
void SwDocShell::GetState(SfxItemSet& rSet)
993
8.61k
{
994
8.61k
    SfxWhichIter aIter(rSet);
995
8.61k
    sal_uInt16  nWhich  = aIter.FirstWhich();
996
997
17.2k
    while (nWhich)
998
8.61k
    {
999
8.61k
        switch (nWhich)
1000
8.61k
        {
1001
0
        case SID_PRINTPREVIEW:
1002
0
        {
1003
0
            bool bDisable = IsInPlaceActive();
1004
            // Disable "multiple layout"
1005
0
            if ( !bDisable )
1006
0
            {
1007
0
                SfxViewFrame *pTmpFrame = SfxViewFrame::GetFirst(this);
1008
0
                while (pTmpFrame)     // Look for Preview
1009
0
                {
1010
0
                    if ( auto pSwView = dynamic_cast<SwView*>( pTmpFrame->GetViewShell() ) )
1011
0
                        if (pSwView->GetWrtShell().GetViewOptions()->getBrowseMode())
1012
0
                        {
1013
0
                            bDisable = true;
1014
0
                            break;
1015
0
                        }
1016
0
                    pTmpFrame = SfxViewFrame::GetNext(*pTmpFrame, this);
1017
0
                }
1018
0
            }
1019
            // End of disabled "multiple layout"
1020
0
            if ( bDisable )
1021
0
                rSet.DisableItem( SID_PRINTPREVIEW );
1022
0
            else
1023
0
            {
1024
0
                SfxBoolItem aBool( SID_PRINTPREVIEW, false );
1025
0
                if( dynamic_cast<SwPagePreview*>( SfxViewShell::Current())  )
1026
0
                    aBool.SetValue( true );
1027
0
                rSet.Put( aBool );
1028
0
            }
1029
0
        }
1030
0
        break;
1031
0
        case SID_AUTO_CORRECT_DLG:
1032
0
            if ( comphelper::LibreOfficeKit::isActive() )
1033
0
                rSet.DisableItem( SID_AUTO_CORRECT_DLG );
1034
0
        break;
1035
0
        case SID_SOURCEVIEW:
1036
0
        {
1037
0
            SfxViewShell* pCurrView = GetView() ? static_cast<SfxViewShell*>(GetView())
1038
0
                                        : SfxViewShell::Current();
1039
0
            bool bSourceView = dynamic_cast<SwSrcView*>( pCurrView ) !=  nullptr;
1040
0
            rSet.Put(SfxBoolItem(SID_SOURCEVIEW, bSourceView));
1041
0
        }
1042
0
        break;
1043
0
        case SID_HTML_MODE:
1044
0
            rSet.Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(this)));
1045
0
        break;
1046
1047
0
        case FN_ABSTRACT_STARIMPRESS:
1048
0
        case FN_OUTLINE_TO_IMPRESS:
1049
0
            if (!SvtModuleOptions().IsImpressInstalled() || GetObjectShell()->isExportLocked())
1050
0
                rSet.DisableItem(nWhich);
1051
0
            [[fallthrough]];
1052
0
        case FN_ABSTRACT_NEWDOC:
1053
0
        case FN_OUTLINE_TO_CLIPBOARD:
1054
0
            {
1055
0
                if ( GetDoc()->GetNodes().GetOutLineNds().empty() )
1056
0
                    rSet.DisableItem( nWhich );
1057
0
            }
1058
0
            break;
1059
0
        case SID_BROWSER_MODE:
1060
0
        case FN_PRINT_LAYOUT:
1061
0
            {
1062
0
                bool bState = GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE);
1063
0
                if(FN_PRINT_LAYOUT == nWhich)
1064
0
                    bState = !bState;
1065
0
                rSet.Put( SfxBoolItem( nWhich, bState));
1066
0
            }
1067
0
            break;
1068
1069
0
        case FN_NEW_GLOBAL_DOC:
1070
0
            if (dynamic_cast<const SwGlobalDocShell*>(this) != nullptr
1071
0
                || GetObjectShell()->isExportLocked())
1072
0
                rSet.DisableItem( nWhich );
1073
0
            break;
1074
1075
0
        case FN_NEW_HTML_DOC:
1076
0
            if (dynamic_cast<const SwWebDocShell*>(this) != nullptr
1077
0
                || GetObjectShell()->isExportLocked())
1078
0
                rSet.DisableItem( nWhich );
1079
0
            break;
1080
1081
0
        case FN_OPEN_FILE:
1082
0
            if( dynamic_cast< const SwWebDocShell *>( this ) !=  nullptr )
1083
0
                rSet.DisableItem( nWhich );
1084
0
            break;
1085
1086
0
        case SID_ATTR_YEAR2000:
1087
0
            {
1088
0
                const SvNumberFormatter* pFormatr = m_xDoc->GetNumberFormatter(false);
1089
0
                rSet.Put( SfxUInt16Item( nWhich,
1090
0
                        static_cast< sal_uInt16 >(
1091
0
                        pFormatr ? pFormatr->GetYear2000()
1092
0
                              : officecfg::Office::Common::DateFormat::TwoDigitYear::get())) );
1093
0
            }
1094
0
            break;
1095
0
        case SID_ATTR_CHAR_FONTLIST:
1096
0
        {
1097
0
            rSet.Put( SvxFontListItem(m_pFontList.get(), SID_ATTR_CHAR_FONTLIST) );
1098
0
        }
1099
0
        break;
1100
0
        case SID_MAIL_PREPAREEXPORT:
1101
0
        {
1102
            //check if linked content or possibly hidden content is available
1103
            //m_xDoc->UpdateFields( NULL, false );
1104
0
            sfx2::LinkManager& rLnkMgr = m_xDoc->getIDocumentLinksAdministration().GetLinkManager();
1105
0
            const ::sfx2::SvBaseLinks& rLnks = rLnkMgr.GetLinks();
1106
0
            bool bRet = false;
1107
0
            if( !rLnks.empty() )
1108
0
                bRet = true;
1109
0
            else
1110
0
            {
1111
                //sections with hidden flag, hidden character attribute, hidden paragraph/text or conditional text fields
1112
0
                bRet = m_xDoc->HasInvisibleContent();
1113
0
            }
1114
0
            rSet.Put( SfxBoolItem( nWhich, bRet ) );
1115
0
        }
1116
0
        break;
1117
8.61k
        case SID_NOTEBOOKBAR:
1118
8.61k
        {
1119
8.61k
            bool bVisible = false;
1120
8.61k
            if (SfxViewShell* pViewShell = GetView() ? GetView() : SfxViewShell::Current())
1121
8.61k
            {
1122
8.61k
                bVisible = sfx2::SfxNotebookBar::StateMethod(pViewShell->GetViewFrame().GetBindings(),
1123
8.61k
                                                             u"modules/swriter/ui/");
1124
8.61k
            }
1125
8.61k
            rSet.Put( SfxBoolItem( SID_NOTEBOOKBAR, bVisible ) );
1126
8.61k
        }
1127
8.61k
        break;
1128
0
        case FN_REDLINE_ACCEPT_ALL:
1129
0
        case FN_REDLINE_REJECT_ALL:
1130
0
        case FN_REDLINE_REINSTATE_ALL:
1131
0
        {
1132
0
            if (GetDoc()->getIDocumentRedlineAccess().GetRedlineTable().empty() ||
1133
0
                HasChangeRecordProtection()) // tdf#128229 Disable Accept / Reject all if redlines are password protected
1134
0
                rSet.DisableItem(nWhich);
1135
0
        }
1136
0
        break;
1137
0
        case SID_TEMPLATE_LOAD:
1138
            // In the launched template dialog the subsequent "Load" button depends
1139
            // on m_pWrtShell existing
1140
0
            if (!m_pWrtShell)
1141
0
                rSet.DisableItem(nWhich);
1142
0
        break;
1143
1144
0
        default: OSL_ENSURE(false,"You cannot get here!");
1145
1146
8.61k
        }
1147
8.61k
        nWhich = aIter.NextWhich();
1148
8.61k
    }
1149
8.61k
}
1150
1151
// OLE-Hdls
1152
IMPL_LINK( SwDocShell, Ole2ModifiedHdl, bool, bNewStatus, void )
1153
37.0M
{
1154
37.0M
    if (m_pWrtShell)
1155
10.3k
    {
1156
10.3k
        SwOLENode* pOLENode = nullptr;
1157
10.3k
        if (!m_pWrtShell->IsTableMode())
1158
10.3k
        {
1159
10.3k
            pOLENode = m_pWrtShell->GetCursor()->GetPointNode().GetOLENode();
1160
10.3k
        }
1161
10.3k
        if (pOLENode)
1162
0
        {
1163
0
            if (pOLENode->GetOLEObj().IsProtected())
1164
0
            {
1165
0
                return;
1166
0
            }
1167
0
        }
1168
10.3k
    }
1169
1170
37.0M
    if( IsEnableSetModified() )
1171
1.06M
        SetModified( bNewStatus );
1172
37.0M
}
1173
1174
// return Pool here, because virtual
1175
SfxStyleSheetBasePool*  SwDocShell::GetStyleSheetPool()
1176
499k
{
1177
499k
    return m_xBasePool.get();
1178
499k
}
1179
1180
sfx2::StyleManager* SwDocShell::GetStyleManager()
1181
0
{
1182
0
    return m_pStyleManager.get();
1183
0
}
1184
1185
void SwDocShell::SetView(SwView* pVw)
1186
25.8k
{
1187
25.8k
    SetViewShell_Impl(pVw);
1188
25.8k
    m_pView = pVw;
1189
25.8k
    if (m_pView)
1190
17.2k
    {
1191
17.2k
        m_pWrtShell = &m_pView->GetWrtShell();
1192
1193
        // Set view-specific redline author.
1194
17.2k
        const OUString& rRedlineAuthor = m_pView->GetRedlineAuthor();
1195
17.2k
        if (!rRedlineAuthor.isEmpty())
1196
0
            SwModule::get()->SetRedlineAuthor(m_pView->GetRedlineAuthor());
1197
17.2k
    }
1198
8.61k
    else
1199
8.61k
        m_pWrtShell = nullptr;
1200
25.8k
}
1201
1202
// #i59688#
1203
// linked graphics are now loaded on demand.
1204
// Thus, loading of linked graphics no longer needed and necessary for
1205
// the load of document being finished.
1206
void SwDocShell::LoadingFinished()
1207
0
{
1208
    // #i38810#
1209
    // Original fix fails after integration of cws xmlsec11:
1210
    // interface <SfxObjectShell::EnableSetModified(..)> no longer works, because
1211
    // <SfxObjectShell::FinishedLoading(..)> doesn't care about its status and
1212
    // enables the document modification again.
1213
    // Thus, manual modify the document, if it's modified and its links are updated
1214
    // before <FinishedLoading(..)> is called.
1215
0
    const bool bHasDocToStayModified( m_xDoc->getIDocumentState().IsModified() && m_xDoc->getIDocumentLinksAdministration().LinksUpdated() );
1216
1217
#if ENABLE_YRS
1218
#if 0
1219
    // this doesn't even filter as advertised!
1220
    auto const args{GetBaseModel()->getArgs2({u"YrsConnect"_ustr})};
1221
#endif
1222
    // when loading, it is only available from SfxMedium, not SfxBaseModel
1223
    if (css::uno::Any any = GetMedium()->GetArgs().getValue(u"YrsConnect"_ustr); any.hasValue())
1224
        m_xDoc->getIDocumentState().YrsInitConnector(any);
1225
#endif
1226
1227
0
    FinishedLoading();
1228
0
    SfxViewFrame* pVFrame = SfxViewFrame::GetFirst(this);
1229
0
    if(pVFrame)
1230
0
    {
1231
0
        SfxViewShell* pShell = pVFrame->GetViewShell();
1232
0
        if(auto pSrcView = dynamic_cast<SwSrcView*>( pShell) )
1233
0
            pSrcView->Load(this);
1234
0
    }
1235
1236
    // #i38810#
1237
0
    if ( bHasDocToStayModified && !m_xDoc->getIDocumentState().IsModified() )
1238
0
    {
1239
0
        m_xDoc->getIDocumentState().SetModified();
1240
0
    }
1241
0
}
1242
1243
// a Transfer is cancelled (is called from SFX)
1244
void SwDocShell::CancelTransfers()
1245
8.61k
{
1246
    // Cancel all links from LinkManager
1247
8.61k
    m_xDoc->getIDocumentLinksAdministration().GetLinkManager().CancelTransfers();
1248
8.61k
    SfxObjectShell::CancelTransfers();
1249
8.61k
}
1250
1251
SwEditShell * SwDocShell::GetEditShell()
1252
70.4k
{
1253
70.4k
    return m_pWrtShell;
1254
70.4k
}
1255
1256
SwFEShell* SwDocShell::GetFEShell()
1257
0
{
1258
0
    return m_pWrtShell;
1259
0
}
1260
1261
void SwDocShell::RemoveOLEObjects()
1262
0
{
1263
0
    SwIterator<SwContentNode,SwFormatColl> aIter( *m_xDoc->GetDfltGrfFormatColl() );
1264
0
    for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
1265
0
    {
1266
0
        SwOLENode* pOLENd = pNd->GetOLENode();
1267
0
        if( pOLENd && ( pOLENd->IsOLEObjectDeleted() ||
1268
0
                        pOLENd->IsInGlobalDocSection() ) )
1269
0
        {
1270
0
            if (!m_pOLEChildList)
1271
0
                m_pOLEChildList.reset( new comphelper::EmbeddedObjectContainer );
1272
1273
0
            OUString aObjName = pOLENd->GetOLEObj().GetCurrentPersistName();
1274
0
            GetEmbeddedObjectContainer().MoveEmbeddedObject( aObjName, *m_pOLEChildList );
1275
0
        }
1276
0
    }
1277
0
}
1278
1279
// When a document is loaded, SwDoc::PrtOLENotify is called to update
1280
// the sizes of math objects. However, for objects that do not have a
1281
// SwFrame at this time, only a flag is set (bIsOLESizeInvalid) and the
1282
// size change takes place later, while calculating the layout in the
1283
// idle handler. If this document is saved now, it is saved with invalid
1284
// sizes. For this reason, the layout has to be calculated before a document is
1285
// saved, but of course only if there are OLE objects with bOLESizeInvalid set.
1286
void SwDocShell::CalcLayoutForOLEObjects()
1287
0
{
1288
0
    if (!m_pWrtShell)
1289
0
        return;
1290
1291
0
    if (m_pView && m_pView->GetIPClient())
1292
0
    {
1293
        // We have an active OLE edit: allow link updates, so an up to date replacement graphic can
1294
        // be created.
1295
0
        comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer();
1296
0
        rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
1297
0
    }
1298
1299
0
    SwIterator<SwContentNode,SwFormatColl> aIter( *m_xDoc->GetDfltGrfFormatColl() );
1300
0
    for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
1301
0
    {
1302
0
        SwOLENode* pOLENd = pNd->GetOLENode();
1303
0
        if( pOLENd && pOLENd->IsOLESizeInvalid() )
1304
0
        {
1305
0
            m_pWrtShell->CalcLayout();
1306
0
            break;
1307
0
        }
1308
0
    }
1309
0
}
1310
1311
// #i42634# Overwrites SfxObjectShell::UpdateLinks
1312
// This new function is necessary to trigger update of links in docs
1313
// read by the binary filter:
1314
void SwDocShell::UpdateLinks()
1315
0
{
1316
0
    GetDoc()->getIDocumentLinksAdministration().UpdateLinks();
1317
    // #i50703# Update footnote numbers
1318
0
    SwTextFootnote::SetUniqueSeqRefNo( *GetDoc() );
1319
0
    SwNodeIndex aTmp( GetDoc()->GetNodes() );
1320
0
    GetDoc()->GetFootnoteIdxs().UpdateFootnote( aTmp.GetNode() );
1321
0
}
1322
1323
void SwDocShell::PerformLinkUpdate()
1324
0
{
1325
0
    sfx2::LinkManager& rLinkMgr
1326
0
        = GetDoc()->getIDocumentLinksAdministration().GetLinkManager();
1327
0
    registerDeferredFormImageLinks(GetDeferredFormControlImages(), rLinkMgr);
1328
0
    ClearDeferredFormControlImages();
1329
0
    rLinkMgr.UpdateAllLinks(false,
1330
0
                            GetMedium() ? GetMedium()->GetName() : OUString());
1331
0
}
1332
1333
uno::Reference< frame::XController >
1334
                                SwDocShell::GetController()
1335
0
{
1336
0
    css::uno::Reference< css::frame::XController > aRet;
1337
    // #i82346# No view in page preview
1338
0
    if ( GetView() )
1339
0
        aRet = GetView()->GetController();
1340
0
    return aRet;
1341
0
}
1342
1343
constexpr OUString s_EventNames[] =
1344
{
1345
    u"OnPageCountChange"_ustr,
1346
    u"OnMailMerge"_ustr,
1347
    u"OnMailMergeFinished"_ustr,
1348
    u"OnFieldMerge"_ustr,
1349
    u"OnFieldMergeFinished"_ustr,
1350
    u"OnLayoutFinished"_ustr
1351
};
1352
sal_Int32 const s_nEvents(std::size(s_EventNames));
1353
1354
Sequence< OUString >    SwDocShell::GetEventNames()
1355
92
{
1356
92
    Sequence< OUString > aRet = SfxObjectShell::GetEventNames();
1357
92
    sal_Int32 nLen = aRet.getLength();
1358
92
    aRet.realloc(nLen + 6);
1359
92
    OUString* pNames = aRet.getArray();
1360
92
    pNames[nLen++] = GetEventName(0);
1361
92
    pNames[nLen++] = GetEventName(1);
1362
92
    pNames[nLen++] = GetEventName(2);
1363
92
    pNames[nLen++] = GetEventName(3);
1364
92
    pNames[nLen++] = GetEventName(4);
1365
92
    pNames[nLen]   = GetEventName(5);
1366
1367
92
    return aRet;
1368
92
}
1369
1370
const OUString & SwDocShell::GetEventName( sal_Int32 nIndex )
1371
552
{
1372
552
    if (nIndex < s_nEvents)
1373
552
    {
1374
552
        return s_EventNames[nIndex];
1375
552
    }
1376
0
    return EMPTY_OUSTRING;
1377
552
}
1378
1379
const ::sfx2::IXmlIdRegistry* SwDocShell::GetXmlIdRegistry() const
1380
0
{
1381
0
    return m_xDoc ? &m_xDoc->GetXmlIdRegistry() : nullptr;
1382
0
}
1383
1384
bool SwDocShell::IsChangeRecording(SfxViewShell* pViewShell, bool bRecordAllViews) const
1385
1.37M
{
1386
1.37M
    SwWrtShell* pWrtShell = nullptr;
1387
1.37M
    auto pView = dynamic_cast<SwView*>(pViewShell);
1388
1.37M
    if (pView)
1389
0
    {
1390
0
        pWrtShell = pView->GetWrtShellPtr();
1391
0
    }
1392
1.37M
    if (!pWrtShell)
1393
1.37M
    {
1394
1.37M
        pWrtShell = m_pWrtShell;
1395
1.37M
    }
1396
1397
1.37M
    if (!pWrtShell)
1398
1.37M
        return false;
1399
1400
0
    auto bOn = bool(pWrtShell->GetRedlineFlags() & RedlineFlags::On);
1401
0
    if (bOn)
1402
0
    {
1403
0
        if (bRecordAllViews)
1404
0
        {
1405
0
            for (SwViewShell& rSh : pWrtShell->GetRingContainer())
1406
0
            {
1407
0
                if (!rSh.GetViewOptions()->IsRedlineRecordingOn())
1408
0
                {
1409
0
                    return false;
1410
0
                }
1411
0
            }
1412
0
        }
1413
1414
0
        return true;
1415
0
    }
1416
1417
0
    return false;
1418
0
}
1419
1420
bool SwDocShell::HasChangeRecordProtection() const
1421
0
{
1422
0
    if (!m_pWrtShell)
1423
0
        return false;
1424
0
    return m_pWrtShell->getIDocumentRedlineAccess().GetRedlinePassword().hasElements();
1425
0
}
1426
1427
void SwDocShell::SetChangeRecording( bool bActivate, bool bLockAllViews, SfxRedlineRecordingMode eRedlineRecordingMode)
1428
0
{
1429
0
    RedlineFlags nOn = bActivate ? RedlineFlags::On : RedlineFlags::NONE;
1430
0
    RedlineFlags nMode = m_pWrtShell->GetRedlineFlags();
1431
0
    if (bLockAllViews)
1432
0
    {
1433
        // tdf#107870: prevent jumping to cursor
1434
0
        auto aViewGuard(LockAllViews());
1435
0
        m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn, eRedlineRecordingMode );
1436
0
    }
1437
0
    else
1438
0
    {
1439
0
        m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn, eRedlineRecordingMode );
1440
0
    }
1441
0
}
1442
1443
void SwDocShell::SetProtectionPassword( const OUString &rNewPassword )
1444
0
{
1445
0
    const SfxAllItemSet aSet( GetPool() );
1446
1447
0
    IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
1448
0
    Sequence< sal_Int8 > aPasswd = rIDRA.GetRedlinePassword();
1449
0
    const SfxBoolItem* pRedlineProtectItem = aSet.GetItemIfSet(FN_REDLINE_PROTECT, false);
1450
0
    if (pRedlineProtectItem
1451
0
        && pRedlineProtectItem->GetValue() == aPasswd.hasElements())
1452
0
        return;
1453
1454
0
    if (!rNewPassword.isEmpty())
1455
0
    {
1456
        // when password protection is applied change tracking must always be active
1457
0
        SetChangeRecording( true );
1458
1459
0
        Sequence< sal_Int8 > aNewPasswd;
1460
0
        SvPasswordHelper::GetHashPassword( aNewPasswd, rNewPassword );
1461
0
        rIDRA.SetRedlinePassword( aNewPasswd );
1462
0
    }
1463
0
    else
1464
0
    {
1465
0
        rIDRA.SetRedlinePassword( Sequence< sal_Int8 >() );
1466
0
    }
1467
0
}
1468
1469
bool SwDocShell::GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > &rPasswordHash )
1470
0
{
1471
0
    bool bRes = false;
1472
1473
0
    const SfxAllItemSet aSet( GetPool() );
1474
1475
0
    IDocumentRedlineAccess& rIDRA = m_pWrtShell->getIDocumentRedlineAccess();
1476
0
    const Sequence< sal_Int8 >& aPasswdHash( rIDRA.GetRedlinePassword() );
1477
0
    const SfxBoolItem* pRedlineProtectItem = aSet.GetItemIfSet(FN_REDLINE_PROTECT, false);
1478
0
    if (pRedlineProtectItem
1479
0
        && pRedlineProtectItem->GetValue() == aPasswdHash.hasElements())
1480
0
        return false;
1481
0
    rPasswordHash = aPasswdHash;
1482
0
    bRes = true;
1483
1484
0
    return bRes;
1485
0
}
1486
1487
void SwDocShell::RegisterAutomationDocumentEventsCaller(css::uno::Reference< ooo::vba::XSinkCaller > const& xCaller)
1488
0
{
1489
0
    mxAutomationDocumentEventsCaller = xCaller;
1490
0
}
1491
1492
void SwDocShell::CallAutomationDocumentEventSinks(const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments)
1493
87.8k
{
1494
87.8k
    if (mxAutomationDocumentEventsCaller.is())
1495
0
        mxAutomationDocumentEventsCaller->CallSinks(Method, Arguments);
1496
87.8k
}
1497
1498
void SwDocShell::RegisterAutomationDocumentObject(css::uno::Reference< ooo::vba::word::XDocument > const& xDocument)
1499
0
{
1500
0
    mxAutomationDocumentObject = xDocument;
1501
0
}
1502
1503
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */