Coverage Report

Created: 2026-10-14 09:33

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