Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/doc/objmisc.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 <tools/debug.hxx>
23
#include <tools/inetmsg.hxx>
24
#include <comphelper/diagnose_ex.hxx>
25
#include <svl/eitem.hxx>
26
#include <svl/stritem.hxx>
27
#include <svl/intitem.hxx>
28
#include <svtools/svparser.hxx>
29
#include <cppuhelper/exc_hlp.hxx>
30
#include <sal/log.hxx>
31
#include <o3tl/string_view.hxx>
32
33
#include <com/sun/star/awt/XTopWindow.hpp>
34
#include <com/sun/star/beans/XPropertySet.hpp>
35
#include <com/sun/star/container/XChild.hpp>
36
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
37
#include <com/sun/star/document/XDocumentProperties.hpp>
38
#include <com/sun/star/document/MacroExecMode.hpp>
39
#include <com/sun/star/document/XScriptInvocationContext.hpp>
40
#include <com/sun/star/embed/EmbedStates.hpp>
41
#include <com/sun/star/embed/XEmbeddedObject.hpp>
42
#include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
43
#include <com/sun/star/script/provider/XScript.hpp>
44
#include <com/sun/star/script/provider/XScriptProvider.hpp>
45
#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
46
#include <com/sun/star/uri/UriReferenceFactory.hpp>
47
#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
48
#include <com/sun/star/util/XModifiable.hpp>
49
50
#include <com/sun/star/uno/Reference.h>
51
#include <com/sun/star/uno/Any.h>
52
#include <com/sun/star/task/ErrorCodeRequest2.hpp>
53
54
#include <comphelper/lok.hxx>
55
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
56
#include <comphelper/processfactory.hxx>
57
#include <comphelper/sequenceashashmap.hxx>
58
#include <comphelper/string.hxx>
59
60
#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
61
#include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
62
#include <com/sun/star/task/InteractionClassification.hpp>
63
#include <com/sun/star/task/XInteractionHandler.hpp>
64
#include <com/sun/star/frame/XModel.hpp>
65
66
#include <basic/basmgr.hxx>
67
#include <basic/sberrors.hxx>
68
#include <utility>
69
#include <vcl/weld/MessageDialog.hxx>
70
#include <vcl/weld/weld.hxx>
71
#include <basic/sbx.hxx>
72
#include <svtools/sfxecode.hxx>
73
74
#include <unotools/ucbhelper.hxx>
75
#include <tools/urlobj.hxx>
76
#include <svl/sharecontrolfile.hxx>
77
#include <rtl/uri.hxx>
78
#include <vcl/svapp.hxx>
79
#include <framework/interaction.hxx>
80
#include <framework/documentundoguard.hxx>
81
#include <comphelper/interaction.hxx>
82
#include <comphelper/storagehelper.hxx>
83
#include <comphelper/documentconstants.hxx>
84
#include <comphelper/namedvaluecollection.hxx>
85
#include <ucbhelper/simpleinteractionrequest.hxx>
86
#include <officecfg/Office/Common.hxx>
87
88
#include <sfx2/brokenpackageint.hxx>
89
#include <sfx2/signaturestate.hxx>
90
#include <sfx2/app.hxx>
91
#include <appdata.hxx>
92
#include <sfx2/request.hxx>
93
#include <sfx2/bindings.hxx>
94
#include <sfx2/sfxresid.hxx>
95
#include <sfx2/docfile.hxx>
96
#include <sfx2/objsh.hxx>
97
#include <objshimp.hxx>
98
#include <sfx2/event.hxx>
99
#include <sfx2/viewfrm.hxx>
100
#include <sfx2/sfxuno.hxx>
101
#include <sfx2/module.hxx>
102
#include <sfx2/docfac.hxx>
103
#include <sfx2/sfxsids.hrc>
104
#include <sfx2/strings.hrc>
105
#include <workwin.hxx>
106
#include <sfx2/sfxdlg.hxx>
107
#include <sfx2/infobar.hxx>
108
#include <sfx2/lokhelper.hxx>
109
#include <sfx2/sfxbasemodel.hxx>
110
#include <openflag.hxx>
111
#include "objstor.hxx"
112
#include <appopen.hxx>
113
#include <sfx2/viewsh.hxx>
114
115
#include <memory>
116
117
using namespace ::com::sun::star;
118
using namespace ::com::sun::star::uno;
119
using namespace ::com::sun::star::ucb;
120
using namespace ::com::sun::star::document;
121
using namespace ::com::sun::star::frame;
122
using namespace ::com::sun::star::script;
123
using namespace ::com::sun::star::script::provider;
124
125
// class SfxHeaderAttributes_Impl ----------------------------------------
126
127
namespace {
128
129
class SfxHeaderAttributes_Impl : public SvKeyValueIterator
130
{
131
private:
132
    SfxObjectShell* pDoc;
133
    SvKeyValueIteratorRef xIter;
134
    bool bAlert;
135
136
public:
137
    explicit SfxHeaderAttributes_Impl( SfxObjectShell* pSh ) :
138
14.4k
         pDoc( pSh ),
139
14.4k
        xIter( pSh->GetMedium()->GetHeaderAttributes_Impl() ),
140
14.4k
        bAlert( false ) {}
141
142
21.3k
    virtual bool GetFirst( SvKeyValue& rKV ) override { return xIter->GetFirst( rKV ); }
143
1.95k
    virtual bool GetNext( SvKeyValue& rKV ) override { return xIter->GetNext( rKV ); }
144
    virtual void Append( const SvKeyValue& rKV ) override;
145
146
0
    void ClearForSourceView() { xIter = new SvKeyValueIterator; bAlert = false; }
147
    void SetAttributes();
148
    void SetAttribute( const SvKeyValue& rKV );
149
};
150
151
}
152
153
sal_uInt16 const aTitleMap_Impl[3][2] =
154
{
155
                                //  local               remote
156
    /*  SFX_TITLE_CAPTION   */  {   SFX_TITLE_FILENAME, SFX_TITLE_TITLE },
157
    /*  SFX_TITLE_PICKLIST  */  {   32,                 SFX_TITLE_FULLNAME },
158
    /*  SFX_TITLE_HISTORY   */  {   32,                 SFX_TITLE_FULLNAME }
159
};
160
161
162
bool SfxObjectShell::IsAbortingImport() const
163
2.96M
{
164
2.96M
    return pImpl->bIsAbortingImport;
165
2.96M
}
166
167
168
uno::Reference<document::XDocumentProperties>
169
SfxObjectShell::getDocProperties() const
170
108k
{
171
108k
    uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
172
108k
        GetModel(), uno::UNO_QUERY_THROW);
173
108k
    uno::Reference<document::XDocumentProperties> xDocProps(
174
108k
        xDPS->getDocumentProperties());
175
108k
    DBG_ASSERT(xDocProps.is(),
176
108k
        "SfxObjectShell: model has no DocumentProperties");
177
108k
    return xDocProps;
178
108k
}
179
180
181
void SfxObjectShell::DoFlushDocInfo()
182
17.3k
{
183
17.3k
}
184
185
186
// Note: the only thing that calls this is the modification event handler
187
// that is installed at the XDocumentProperties
188
void SfxObjectShell::FlushDocInfo()
189
120k
{
190
120k
    if ( IsLoading() )
191
53.2k
        return;
192
193
67.4k
    SetModified();
194
67.4k
    uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
195
67.4k
    DoFlushDocInfo(); // call template method
196
67.4k
    const OUString url(xDocProps->getAutoloadURL());
197
67.4k
    sal_Int32 delay(xDocProps->getAutoloadSecs());
198
67.4k
    SetAutoLoad( INetURLObject(url), delay * 1000,
199
67.4k
                 (delay > 0) || !url.isEmpty() );
200
67.4k
}
201
202
void SfxObjectShell::AppendInfoBarWhenReady(const OUString& sId, const OUString& sPrimaryMessage,
203
                                          const OUString& sSecondaryMessage,
204
                                          InfobarType aInfobarType, bool bShowCloseButton)
205
0
{
206
0
    InfobarData aInfobarData;
207
0
    aInfobarData.msId = sId;
208
0
    aInfobarData.msPrimaryMessage = sPrimaryMessage;
209
0
    aInfobarData.msSecondaryMessage = sSecondaryMessage;
210
0
    aInfobarData.maInfobarType = aInfobarType;
211
0
    aInfobarData.mbShowCloseButton = bShowCloseButton;
212
0
    Get_Impl()->m_aPendingInfobars.emplace_back(aInfobarData);
213
0
}
214
215
std::vector<InfobarData>& SfxObjectShell::getPendingInfobars()
216
0
{
217
0
    return Get_Impl()->m_aPendingInfobars;
218
0
}
219
220
void SfxObjectShell::SetError(const ErrCodeMsg& lErr)
221
37
{
222
37
    if (pImpl->lErr == ERRCODE_NONE || (pImpl->lErr.IsWarning() && lErr.IsError()))
223
37
    {
224
37
        pImpl->lErr=lErr;
225
37
    }
226
37
}
227
228
ErrCodeMsg SfxObjectShell::GetErrorIgnoreWarning() const
229
8.19k
{
230
8.19k
    return GetErrorCode().IgnoreWarning();
231
8.19k
}
232
233
ErrCodeMsg SfxObjectShell::GetErrorCode() const
234
16.2k
{
235
16.2k
    ErrCodeMsg lError=pImpl->lErr;
236
16.2k
    if(!lError && GetMedium())
237
16.2k
        lError=GetMedium()->GetErrorCode();
238
16.2k
    return lError;
239
16.2k
}
240
241
void SfxObjectShell::ResetError()
242
8.19k
{
243
8.19k
    pImpl->lErr=ERRCODE_NONE;
244
8.19k
    SfxMedium * pMed = GetMedium();
245
8.19k
    if( pMed )
246
8.19k
        pMed->ResetError();
247
8.19k
}
248
249
void SfxObjectShell::EnableSetModified( bool bEnable )
250
209k
{
251
209k
    SAL_INFO_IF( bEnable == pImpl->m_bEnableSetModified, "sfx", "SFX_PERSIST: EnableSetModified 2x called with the same value" );
252
209k
    pImpl->m_bEnableSetModified = bEnable;
253
209k
}
254
255
256
bool SfxObjectShell::IsEnableSetModified() const
257
83.2M
{
258
    // tdf#146547 read-only does not prevent modified, instead try to prevent
259
    // setting "internal" documents that may be displayed in some dialog but
260
    // which the user didn't load or activate to modified.
261
83.2M
    return pImpl->m_bEnableSetModified && !IsPreview()
262
83.1M
        && eCreateMode != SfxObjectCreateMode::ORGANIZER
263
83.1M
        && eCreateMode != SfxObjectCreateMode::INTERNAL
264
        // tdf#157931 form documents only in design mode
265
39.3M
        && ((pImpl->pBaseModel
266
39.3M
                && !pImpl->pBaseModel->impl_isDisposed()
267
38.4M
                && pImpl->pBaseModel->IsInitialized()
268
38.2M
                && pImpl->pBaseModel->getIdentifier() != "com.sun.star.sdb.FormDesign")
269
1.02M
            || !IsReadOnly());
270
83.2M
}
271
272
273
bool SfxObjectShell::IsModified() const
274
9.62M
{
275
9.62M
    if ( pImpl->m_bIsModified )
276
9.43M
        return true;
277
278
187k
    if ( !pImpl->m_xDocStorage.is() || IsReadOnly() )
279
32.1k
    {
280
        // if the document still has no storage and is not set to be modified explicitly it is not modified
281
        // a readonly document is also not modified
282
283
32.1k
        return false;
284
32.1k
    }
285
286
155k
    if (pImpl->mxObjectContainer)
287
0
    {
288
0
        const uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
289
0
        for ( const auto& rName : aNames )
290
0
        {
291
0
            uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( rName );
292
0
            OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!" );
293
0
            if ( xObj.is() )
294
0
            {
295
0
                try
296
0
                {
297
0
                    sal_Int32 nState = xObj->getCurrentState();
298
0
                    if ( nState != embed::EmbedStates::LOADED )
299
0
                    {
300
0
                        uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
301
0
                        if ( xModifiable.is() && xModifiable->isModified() )
302
0
                            return true;
303
0
                    }
304
0
                }
305
0
                catch( uno::Exception& )
306
0
                {}
307
0
            }
308
0
        }
309
0
    }
310
311
155k
    return false;
312
155k
}
313
314
315
void SfxObjectShell::SetModified( bool bModifiedP )
316
9.69M
{
317
9.69M
    SAL_INFO_IF( !bModifiedP && !IsEnableSetModified(), "sfx",
318
9.69M
        "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False" );
319
320
9.69M
    if( !IsEnableSetModified() )
321
13.7k
        return;
322
323
9.68M
    if( pImpl->m_bIsModified != bModifiedP )
324
217k
    {
325
217k
        pImpl->m_bIsModified = bModifiedP;
326
217k
        ModifyChanged();
327
217k
    }
328
9.68M
}
329
330
331
void SfxObjectShell::ModifyChanged()
332
217k
{
333
217k
    if ( pImpl->bClosing )
334
        // SetModified dispose of the models!
335
13.1k
        return;
336
337
204k
    SfxViewFrame* pViewFrame = SfxViewFrame::Current();
338
204k
    if ( pViewFrame )
339
0
        pViewFrame->GetBindings().Invalidate( SID_SAVEDOCS );
340
341
204k
    Invalidate( SID_SIGNATURE );
342
204k
    Invalidate( SID_MACRO_SIGNATURE );
343
204k
    Broadcast( SfxHint( SfxHintId::TitleChanged ) );    // xmlsec05, signed state might change in title...
344
345
204k
    SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::ModifyChanged, GlobalEventConfig::GetEventName(GlobalEventId::MODIFYCHANGED), this ) );
346
347
    // Don't wait to get this important state via binding notification timeout.
348
204k
    if ( comphelper::LibreOfficeKit::isActive() )
349
0
    {
350
0
        OString aStatus = ".uno:ModifiedStatus="_ostr;
351
0
        aStatus += IsModified() ? "true" : "false";
352
0
        SfxLokHelper::notifyAllViews(LOK_CALLBACK_STATE_CHANGED, aStatus);
353
0
    }
354
204k
}
355
356
357
bool SfxObjectShell::IsReadOnlyUI() const
358
359
/*  [Description]
360
361
    Returns sal_True if the document for the UI is treated as r/o. This is
362
    regardless of the actual r/o, which can be checked with <IsReadOnly()>.
363
*/
364
365
277k
{
366
277k
    return pImpl->bReadOnlyUI || SfxViewShell::IsCurrentLokViewReadOnly();
367
277k
}
368
369
370
bool SfxObjectShell::IsReadOnlyMedium() const
371
372
/*  [Description]
373
374
    Returns sal_True when the medium is r/o, for instance when opened as r/o.
375
*/
376
377
0
{
378
0
    if ( !pMedium )
379
0
        return true;
380
0
    return pMedium->IsReadOnly();
381
0
}
382
383
bool SfxObjectShell::IsOriginallyReadOnlyMedium() const
384
0
{
385
0
    return pMedium == nullptr || pMedium->IsOriginallyReadOnly();
386
0
}
387
388
bool SfxObjectShell::IsOriginallyLoadedReadOnlyMedium() const
389
0
{
390
0
    return pMedium != nullptr && pMedium->IsOriginallyLoadedReadOnly();
391
0
}
392
393
394
void SfxObjectShell::SetReadOnlyUI( bool bReadOnly )
395
396
/*  [Description]
397
398
    Turns the document in a r/o and r/w state respectively without reloading
399
    it and without changing the open mode of the medium.
400
*/
401
402
10.7k
{
403
10.7k
    if ( bReadOnly != pImpl->bReadOnlyUI )
404
10.7k
    {
405
10.7k
        pImpl->bReadOnlyUI = bReadOnly;
406
10.7k
        Broadcast( SfxHint(SfxHintId::ModeChanged) );
407
10.7k
    }
408
10.7k
}
409
410
411
void SfxObjectShell::SetReadOnly()
412
0
{
413
    // Let the document be completely readonly, means that the
414
    // medium open mode is adjusted accordingly, and the write lock
415
    // on the file is removed.
416
417
0
    if ( !pMedium || IsReadOnlyMedium() )
418
0
        return;
419
420
0
    bool bWasROUI = IsReadOnly();
421
422
0
    pMedium->UnlockFile( false );
423
424
    // the storage-based mediums are already based on the temporary file
425
    // so UnlockFile has already closed the locking stream
426
0
    if ( !pMedium->HasStorage_Impl() && IsLoadingFinished() )
427
0
        pMedium->CloseInStream();
428
429
0
    pMedium->SetOpenMode( SFX_STREAM_READONLY, true );
430
0
    pMedium->GetItemSet().Put( SfxBoolItem( SID_DOC_READONLY, true ) );
431
432
0
    if ( !bWasROUI )
433
0
        Broadcast( SfxHint(SfxHintId::ModeChanged) );
434
0
}
435
436
437
bool SfxObjectShell::IsReadOnly() const
438
1.47M
{
439
1.47M
    return pImpl->bReadOnlyUI || pMedium == nullptr || pMedium->HasRestrictedFonts();
440
1.47M
}
441
442
443
bool SfxObjectShell::IsInModalMode() const
444
0
{
445
0
    return pImpl->bModalMode || pImpl->bRunningMacro;
446
0
}
447
448
bool SfxObjectShell::AcceptStateUpdate() const
449
0
{
450
0
    return !IsInModalMode();
451
0
}
452
453
454
void SfxObjectShell::SetMacroMode_Impl( bool bModal )
455
0
{
456
0
    if ( !pImpl->bRunningMacro != !bModal )
457
0
    {
458
0
        pImpl->bRunningMacro = bModal;
459
0
        Broadcast( SfxHint( SfxHintId::ModeChanged ) );
460
0
    }
461
0
}
462
463
464
void SfxObjectShell::SetModalMode_Impl( bool bModal )
465
0
{
466
    // Broadcast only if modified, or otherwise it will possibly go into
467
    // an endless loop
468
0
    if ( pImpl->bModalMode == bModal )
469
0
        return;
470
471
    // Central count
472
0
    sal_uInt16 &rDocModalCount = SfxGetpApp()->Get_Impl()->nDocModalMode;
473
0
    if ( bModal )
474
0
        ++rDocModalCount;
475
0
    else
476
0
        --rDocModalCount;
477
478
    // Switch
479
0
    pImpl->bModalMode = bModal;
480
0
    Broadcast( SfxHint( SfxHintId::ModeChanged ) );
481
0
}
482
483
#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
484
485
bool SfxObjectShell::SwitchToShared( bool bShared, bool bSave )
486
{
487
    bool bResult = true;
488
489
    if ( bShared != IsDocShared() )
490
    {
491
        OUString aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
492
493
        if ( aOrigURL.isEmpty() && bSave )
494
        {
495
            // this is a new document, let it be stored before switching to the shared mode;
496
            // the storing should be done without shared flag, since it is possible that the
497
            // target location does not allow to create sharing control file;
498
            // the shared flag will be set later after creation of sharing control file
499
            SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
500
501
            if ( pViewFrame )
502
            {
503
                // TODO/LATER: currently the application guards against the reentrance problem
504
                const SfxPoolItemHolder aItem(pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC ));
505
                const SfxBoolItem* pResult(dynamic_cast<const SfxBoolItem*>(aItem.getItem()));
506
                bResult = ( pResult && pResult->GetValue() );
507
                if ( bResult )
508
                    aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
509
            }
510
        }
511
512
        bool bOldValue = HasSharedXMLFlagSet();
513
        SetSharedXMLFlag( bShared );
514
515
        bool bRemoveEntryOnError = false;
516
        if ( bResult && bShared )
517
        {
518
            try
519
            {
520
                ::svt::ShareControlFile aControlFile( aOrigURL );
521
                aControlFile.InsertOwnEntry();
522
                bRemoveEntryOnError = true;
523
            }
524
            catch( uno::Exception& )
525
            {
526
                bResult = false;
527
            }
528
        }
529
530
        if ( bResult && bSave )
531
        {
532
            SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
533
534
            if ( pViewFrame )
535
            {
536
                // TODO/LATER: currently the application guards against the reentrance problem
537
                SetModified(); // the modified flag has to be set to let the document be stored with the shared flag
538
                try
539
                {
540
                    // Do *not* use dispatch mechanism in this place - we don't want others (extensions etc.) to intercept this.
541
                    pImpl->pBaseModel->store();
542
                    bResult = true;
543
                }
544
                catch (...)
545
                {
546
                    bResult = false;
547
                }
548
            }
549
        }
550
551
        if ( bResult )
552
        {
553
            // TODO/LATER: Is it possible that the following calls fail?
554
            if ( bShared )
555
            {
556
                pImpl->m_aSharedFileURL = aOrigURL;
557
                GetMedium()->SwitchDocumentToTempFile();
558
            }
559
            else
560
            {
561
                const OUString aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
562
                GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
563
                pImpl->m_aSharedFileURL.clear();
564
565
                // now remove the temporary file the document was based on
566
                ::utl::UCBContentHelper::Kill( aTempFileURL );
567
568
                try
569
                {
570
                    // aOrigURL can not be used since it contains an old value
571
                    ::svt::ShareControlFile aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
572
                    aControlFile.RemoveFile();
573
                }
574
                catch( uno::Exception& )
575
                {
576
                }
577
            }
578
        }
579
        else
580
        {
581
            // the saving has failed!
582
            if ( bRemoveEntryOnError )
583
            {
584
                try
585
                {
586
                    ::svt::ShareControlFile aControlFile( aOrigURL );
587
                    aControlFile.RemoveEntry();
588
                }
589
                catch( uno::Exception& )
590
                {}
591
            }
592
593
            SetSharedXMLFlag( bOldValue );
594
        }
595
    }
596
    else
597
        bResult = false; // the second switch to the same mode
598
599
    if ( bResult )
600
        SetTitle( u""_ustr );
601
602
    return bResult;
603
}
604
605
606
void SfxObjectShell::FreeSharedFile( const OUString& aTempFileURL )
607
{
608
    SetSharedXMLFlag( false );
609
610
    if ( !IsDocShared() || aTempFileURL.isEmpty()
611
      || ::utl::UCBContentHelper::EqualURLs( aTempFileURL, GetSharedFileURL() ) )
612
        return;
613
614
    if ( pImpl->m_bAllowShareControlFileClean )
615
    {
616
        try
617
        {
618
            ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
619
            aControlFile.RemoveEntry();
620
        }
621
        catch( uno::Exception& )
622
        {
623
        }
624
    }
625
626
    // the cleaning is forbidden only once
627
    pImpl->m_bAllowShareControlFileClean = true;
628
629
    // now remove the temporary file the document is based currently on
630
    ::utl::UCBContentHelper::Kill( aTempFileURL );
631
632
    pImpl->m_aSharedFileURL.clear();
633
}
634
635
636
void SfxObjectShell::DoNotCleanShareControlFile()
637
{
638
    pImpl->m_bAllowShareControlFileClean = false;
639
}
640
641
642
void SfxObjectShell::SetSharedXMLFlag( bool bFlag ) const
643
{
644
    pImpl->m_bSharedXMLFlag = bFlag;
645
}
646
647
648
bool SfxObjectShell::HasSharedXMLFlagSet() const
649
{
650
    return pImpl->m_bSharedXMLFlag;
651
}
652
653
#endif
654
655
bool SfxObjectShell::IsDocShared() const
656
134k
{
657
#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
658
    return ( !pImpl->m_aSharedFileURL.isEmpty() );
659
#else
660
134k
    return false;
661
134k
#endif
662
134k
}
663
664
665
OUString SfxObjectShell::GetSharedFileURL() const
666
0
{
667
#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
668
    return pImpl->m_aSharedFileURL;
669
#else
670
0
    return OUString();
671
0
#endif
672
0
}
673
674
Size SfxObjectShell::GetFirstPageSize() const
675
0
{
676
0
    return GetVisArea(ASPECT_THUMBNAIL).GetSize();
677
0
}
678
679
680
IndexBitSet& SfxObjectShell::GetNoSet_Impl()
681
8.16k
{
682
8.16k
    return pImpl->aBitSet;
683
8.16k
}
684
685
686
// changes the title of the document
687
688
void SfxObjectShell::SetTitle
689
(
690
    const OUString& rTitle                // the new Document Title
691
)
692
693
/*  [Description]
694
695
    With this method, the title of the document can be set.
696
    This corresponds initially to the full file name. A setting of the
697
    title does not affect the file name, but it will be shown in the
698
    Caption-Bars of the MDI-window.
699
*/
700
701
122k
{
702
703
    // Nothing to do?
704
122k
    if ( ( ( HasName() && pImpl->aTitle == rTitle )
705
122k
        || ( !HasName() && GetTitle() == rTitle ) )
706
116k
      && !IsDocShared() )
707
116k
        return;
708
709
6.22k
    SfxApplication *pSfxApp = SfxGetpApp();
710
711
    // If possible release the unnamed number.
712
6.22k
    if ( pImpl->bIsNamedVisible && USHRT_MAX != pImpl->nVisualDocumentNumber )
713
0
    {
714
0
        pSfxApp->ReleaseIndex(pImpl->nVisualDocumentNumber);
715
0
        pImpl->bIsNamedVisible = false;
716
0
    }
717
718
    // Set Title
719
6.22k
    pImpl->aTitle = rTitle;
720
721
    // Notification
722
6.22k
    if ( GetMedium() )
723
6.22k
    {
724
6.22k
        SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) );
725
6.22k
        Broadcast( SfxHint(SfxHintId::TitleChanged) );
726
6.22k
    }
727
6.22k
}
728
729
730
731
OUString SfxObjectShell::GetTitle( sal_uInt16  nMaxLength ) const
732
733
/*  [Description]
734
735
    Returns the title or logical file name of the document, depending on the
736
    'nMaxLength'.
737
738
    If the file name with path is used, the Name shortened by replacing one or
739
    more directory names with "...", URLs are currently always returned
740
    in complete form.
741
*/
742
743
829k
{
744
829k
    SfxMedium *pMed = GetMedium();
745
829k
    if ( IsLoading() )
746
129k
        return OUString();
747
748
    // Create Title?
749
699k
    if ( SFX_TITLE_DETECT == nMaxLength && pImpl->aTitle.isEmpty() )
750
195k
    {
751
195k
        static bool bRecur = false;
752
195k
        if ( bRecur )
753
0
            return u"-not available-"_ustr;
754
195k
        bRecur = true;
755
756
195k
        OUString aTitle;
757
758
195k
        if ( pMed )
759
195k
        {
760
195k
            const SfxStringItem* pNameItem = pMed->GetItemSet().GetItem(SID_DOCINFO_TITLE, false);
761
195k
            if ( pNameItem )
762
0
                aTitle = pNameItem->GetValue();
763
195k
        }
764
765
195k
        if ( aTitle.isEmpty() )
766
195k
            aTitle = GetTitle( SFX_TITLE_FILENAME );
767
768
195k
        bRecur = false;
769
195k
        return aTitle;
770
195k
    }
771
772
504k
    if (SFX_TITLE_APINAME == nMaxLength )
773
10.3k
        return GetAPIName();
774
775
    // Picklist/Caption is mapped
776
493k
    if ( pMed && ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) )
777
0
    {
778
        // If a specific title was given at open:
779
        // important for URLs: use INetProtocol::File for which the set title is not
780
        // considered. (See below, analysis of aTitleMap_Impl)
781
0
        const SfxStringItem* pNameItem = pMed->GetItemSet().GetItem(SID_DOCINFO_TITLE, false);
782
0
        if ( pNameItem )
783
0
            return pNameItem->GetValue();
784
0
    }
785
786
    // Still unnamed?
787
493k
    DBG_ASSERT( !HasName() || pMed, "HasName() but no Medium?!?" );
788
493k
    if ( !HasName() || !pMed )
789
493k
    {
790
        // Title already set?
791
493k
        if ( !pImpl->aTitle.isEmpty() )
792
18.8k
            return pImpl->aTitle;
793
794
        // must it be numbered?
795
474k
        const OUString aNoName(SfxResId(STR_NONAME));
796
474k
        if (pImpl->bIsNamedVisible)
797
36.7k
        {
798
            // Append number
799
36.7k
            return aNoName + " " + OUString::number(pImpl->nVisualDocumentNumber);
800
36.7k
        }
801
802
        // Document called "Untitled" for the time being
803
438k
        return aNoName;
804
474k
    }
805
493k
    assert(pMed);
806
807
0
    const INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
808
0
    if ( nMaxLength > SFX_TITLE_CAPTION && nMaxLength <= SFX_TITLE_HISTORY )
809
0
    {
810
0
        sal_uInt16 nRemote;
811
0
        if (aURL.GetProtocol() == INetProtocol::File)
812
0
            nRemote = 0;
813
0
        else
814
0
            nRemote = 1;
815
0
        nMaxLength = aTitleMap_Impl[nMaxLength-SFX_TITLE_CAPTION][nRemote];
816
0
    }
817
818
    // Local file?
819
0
    if ( aURL.GetProtocol() == INetProtocol::File )
820
0
    {
821
0
        if ( nMaxLength == SFX_TITLE_FULLNAME )
822
0
            return aURL.HasMark() ? INetURLObject( aURL.GetURLNoMark() ).PathToFileName() : aURL.PathToFileName();
823
0
        if ( nMaxLength == SFX_TITLE_FILENAME )
824
0
            return aURL.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset);
825
0
        if ( pImpl->aTitle.isEmpty() )
826
0
            pImpl->aTitle = aURL.getBase( INetURLObject::LAST_SEGMENT,
827
0
                                         true, INetURLObject::DecodeMechanism::WithCharset );
828
0
    }
829
0
    else
830
0
    {
831
0
        if ( nMaxLength >= SFX_TITLE_MAXLEN )
832
0
        {
833
0
            const OUString aComplete( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
834
0
            if( aComplete.getLength() > nMaxLength )
835
0
                return OUString::Concat("...") + aComplete.subView( aComplete.getLength() - nMaxLength + 3, nMaxLength - 3 );
836
0
            return aComplete;
837
0
        }
838
0
        if ( nMaxLength == SFX_TITLE_FILENAME )
839
0
        {
840
0
            const OUString aName = INetURLObject::decode( aURL.GetBase(), INetURLObject::DecodeMechanism::WithCharset );
841
0
            return aName.isEmpty() ? aURL.GetURLNoPass() : aName;
842
0
        }
843
0
        if ( nMaxLength == SFX_TITLE_FULLNAME )
844
0
            return aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
845
846
        // Generate Title from file name if possible
847
0
        if ( pImpl->aTitle.isEmpty() )
848
0
            pImpl->aTitle = aURL.GetBase();
849
850
        // workaround for the case when the name can not be retrieved from URL by INetURLObject
851
0
        if ( pImpl->aTitle.isEmpty() )
852
0
            pImpl->aTitle = aURL.GetMainURL( INetURLObject::DecodeMechanism::WithCharset );
853
0
    }
854
855
    // Complete Title
856
0
    return pImpl->aTitle;
857
0
}
858
859
860
void SfxObjectShell::InvalidateName()
861
862
/*  [Description]
863
864
    Returns the title of the new document, DocInfo-Title or
865
    File name. Is required for loading from template or SaveAs.
866
*/
867
868
0
{
869
0
    pImpl->aTitle.clear();
870
871
0
    OUString sOldName = GetName();
872
0
    OUString sNewName = GetTitle(SFX_TITLE_APINAME);
873
0
    if (sOldName != sNewName)
874
0
    {
875
0
        SetName(sNewName);
876
0
        Broadcast(SfxHint(SfxHintId::TitleChanged));
877
0
    }
878
0
}
879
880
881
void SfxObjectShell::SetNamedVisibility_Impl()
882
4.08k
{
883
4.08k
    if ( !pImpl->bIsNamedVisible )
884
4.08k
    {
885
4.08k
        pImpl->bIsNamedVisible = true;
886
4.08k
        if ( !HasName() && USHRT_MAX == pImpl->nVisualDocumentNumber && pImpl->aTitle.isEmpty() )
887
4.08k
        {
888
4.08k
            pImpl->nVisualDocumentNumber = SfxGetpApp()->GetFreeIndex();
889
4.08k
            Broadcast( SfxHint(SfxHintId::TitleChanged) );
890
4.08k
        }
891
4.08k
    }
892
893
4.08k
    SetName( GetTitle(SFX_TITLE_APINAME) );
894
4.08k
}
895
896
void SfxObjectShell::SetNoName()
897
0
{
898
0
    bHasName = false;
899
0
    GetModel()->attachResource( OUString(), GetModel()->getArgs() );
900
0
}
901
902
903
SfxProgress* SfxObjectShell::GetProgress() const
904
321k
{
905
321k
    return pImpl->pProgress;
906
321k
}
907
908
909
void SfxObjectShell::SetProgress_Impl
910
(
911
    SfxProgress *pProgress      /* to started <SfxProgress> or 0,
912
                                   if the progress is to be reset */
913
)
914
915
/*  [Description]
916
917
    Internal method to set or reset the Progress modes for
918
    SfxObjectShell.
919
*/
920
921
94.1k
{
922
94.1k
    DBG_ASSERT( ( !pImpl->pProgress && pProgress ) ||
923
94.1k
                ( pImpl->pProgress && !pProgress ),
924
94.1k
                "Progress activation/deactivation mismatch" );
925
94.1k
    pImpl->pProgress = pProgress;
926
94.1k
}
927
928
929
void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame const * pFrame )
930
4.08k
{
931
4.08k
    SfxApplication* pSfxApp = SfxGetpApp();
932
4.08k
    if ( pSfxApp->IsDowning() || IsLoading() || !pFrame || pFrame->GetFrame().IsClosing_Impl() )
933
0
        return;
934
935
4.08k
    const SfxBoolItem* pHiddenItem = pMedium ? pMedium->GetItemSet().GetItem(SID_HIDDEN, false) : nullptr;
936
4.08k
    if ( !pHiddenItem || !pHiddenItem->GetValue() )
937
4.08k
    {
938
4.08k
        SfxEventHintId nId = pImpl->nEventId;
939
4.08k
        pImpl->nEventId = SfxEventHintId::NONE;
940
4.08k
        if ( nId == SfxEventHintId::OpenDoc )
941
0
            pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(GlobalEventId::OPENDOC), this, pFrame->GetFrame().GetController() ), false);
942
4.08k
        else if (nId == SfxEventHintId::CreateDoc )
943
0
            pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(GlobalEventId::CREATEDOC), this, pFrame->GetFrame().GetController() ), false);
944
4.08k
    }
945
4.08k
}
946
947
948
void SfxObjectShell::SetActivateEvent_Impl(SfxEventHintId nId )
949
0
{
950
0
    pImpl->nEventId = nId;
951
0
}
952
953
bool SfxObjectShell::IsAutoLoadLocked() const
954
955
/* Returns whether an Autoload is allowed to be executed. Before the
956
   surrounding FrameSet of the AutoLoad is also taken into account as well.
957
*/
958
959
0
{
960
0
    return !IsReadOnly();
961
0
}
962
963
964
void SfxObjectShell::BreakMacroSign_Impl( bool bBreakMacroSign )
965
6.59k
{
966
6.59k
    pImpl->m_bMacroSignBroken = bBreakMacroSign;
967
6.59k
}
968
969
970
void SfxObjectShell::CheckSecurityOnLoading_Impl()
971
4.08k
{
972
4.08k
    if (GetErrorCode() == ERRCODE_IO_BROKENPACKAGE)
973
0
    {   // safety first: don't run any macros from broken package.
974
0
        pImpl->aMacroMode.disallowMacroExecution();
975
0
        return; // do not get signature status - needs to be done after RepairPackage
976
0
    }
977
978
    // make sure LO evaluates the macro signatures, so it can be preserved
979
4.08k
    GetScriptingSignatureState();
980
981
4.08k
    uno::Reference< task::XInteractionHandler > xInteraction;
982
4.08k
    if ( GetMedium() )
983
4.08k
        xInteraction = GetMedium()->GetInteractionHandler();
984
985
    // check if there is a broken signature...
986
4.08k
    CheckForBrokenDocSignatures_Impl();
987
988
4.08k
    CheckEncryption_Impl( xInteraction );
989
990
    // check macro security
991
4.08k
    const bool bHasValidContentSignature = HasValidSignatures();
992
4.08k
    const bool bHasMacros = pImpl->aMacroMode.hasMacros();
993
4.08k
    pImpl->aMacroMode.checkMacrosOnLoading( xInteraction, bHasValidContentSignature, bHasMacros );
994
4.08k
    pImpl->m_bHadCheckedMacrosOnLoad = bHasMacros;
995
4.08k
}
996
997
bool SfxObjectShell::GetHadCheckedMacrosOnLoad() const
998
0
{
999
0
    return pImpl->m_bHadCheckedMacrosOnLoad;
1000
0
}
1001
1002
bool SfxObjectShell::AllowedLinkProtocolFromDocument(const OUString& rUrl, SfxObjectShell* pObjShell, weld::Window* pDialogParent)
1003
0
{
1004
0
    if (!INetURLObject(rUrl).IsExoticProtocol())
1005
0
        return true;
1006
    // Default to ignoring exotic protocols
1007
0
    bool bAllow = false;
1008
0
    if (pObjShell)
1009
0
    {
1010
        // If the document had macros when loaded then follow the allowed macro-mode
1011
0
        if (pObjShell->GetHadCheckedMacrosOnLoad())
1012
0
            bAllow = pObjShell->AdjustMacroMode();
1013
0
        else // otherwise ask the user, defaulting to cancel
1014
0
        {
1015
            //Reuse URITools::onOpenURI warning string
1016
0
            std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pDialogParent,
1017
0
                                                           VclMessageType::Warning, VclButtonsType::YesNo,
1018
0
                                                           SfxResId(STR_DANGEROUS_TO_OPEN)));
1019
0
            xQueryBox->set_primary_text(xQueryBox->get_primary_text().replaceFirst("$(ARG1)",
1020
0
                INetURLObject::decode(rUrl, INetURLObject::DecodeMechanism::Unambiguous)));
1021
0
            xQueryBox->set_default_response(RET_NO);
1022
0
            bAllow = xQueryBox->run() == RET_YES;
1023
0
        }
1024
0
    }
1025
0
    SAL_WARN_IF(!bAllow, "sfx.appl", "SfxObjectShell::AllowedLinkProtocolFromDocument ignoring: " << rUrl);
1026
0
    return bAllow;
1027
0
}
1028
1029
void SfxObjectShell::CheckEncryption_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
1030
4.08k
{
1031
4.08k
    OUString aVersion;
1032
4.08k
    bool bIsEncrypted = false;
1033
4.08k
    bool bHasNonEncrypted = false;
1034
1035
4.08k
    try
1036
4.08k
    {
1037
4.08k
        uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1038
4.08k
        xPropSet->getPropertyValue(u"Version"_ustr) >>= aVersion;
1039
4.08k
        xPropSet->getPropertyValue(u"HasEncryptedEntries"_ustr) >>= bIsEncrypted;
1040
4.08k
        xPropSet->getPropertyValue(u"HasNonEncryptedEntries"_ustr) >>= bHasNonEncrypted;
1041
4.08k
    }
1042
4.08k
    catch( uno::Exception& )
1043
4.08k
    {
1044
0
    }
1045
1046
4.08k
    if ( aVersion.compareTo( ODFVER_012_TEXT ) < 0 )
1047
0
        return;
1048
1049
    // this is ODF1.2 or later
1050
4.08k
    if ( !(bIsEncrypted && bHasNonEncrypted) )
1051
4.08k
        return;
1052
1053
0
    if ( !pImpl->m_bIncomplEncrWarnShown )
1054
0
    {
1055
        // this is an encrypted document with nonencrypted streams inside, show the warning
1056
0
        css::task::ErrorCodeRequest aErrorCode;
1057
0
        aErrorCode.ErrCode = sal_uInt32(ERRCODE_SFX_INCOMPLETE_ENCRYPTION);
1058
1059
0
        SfxMedium::CallApproveHandler( xHandler, uno::Any( aErrorCode ), false );
1060
0
        pImpl->m_bIncomplEncrWarnShown = true;
1061
0
    }
1062
1063
    // broken signatures imply no macro execution at all
1064
0
    pImpl->aMacroMode.disallowMacroExecution();
1065
0
}
1066
1067
1068
void SfxObjectShell::CheckForBrokenDocSignatures_Impl()
1069
4.08k
{
1070
4.08k
    SignatureState nSignatureState = GetDocumentSignatureState();
1071
4.08k
    bool bSignatureBroken = ( nSignatureState == SignatureState::BROKEN );
1072
4.08k
    if ( !bSignatureBroken )
1073
4.08k
        return;
1074
1075
    // broken signatures imply no macro execution at all
1076
0
    pImpl->aMacroMode.disallowMacroExecution();
1077
0
}
1078
1079
1080
void SfxObjectShell::SetAutoLoad(
1081
    const INetURLObject& rUrl, sal_uInt32 nTime, bool bReload )
1082
67.4k
{
1083
67.4k
    pImpl->pReloadTimer.reset();
1084
67.4k
    if ( bReload )
1085
0
    {
1086
0
        pImpl->pReloadTimer.reset(new AutoReloadTimer_Impl(
1087
0
                                rUrl.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ),
1088
0
                                nTime, this ));
1089
0
        pImpl->pReloadTimer->Start();
1090
0
    }
1091
67.4k
}
1092
1093
void SfxObjectShell::SetLoading(SfxLoadedFlags nFlags)
1094
240k
{
1095
240k
    pImpl->nLoadedFlags = nFlags;
1096
240k
}
1097
1098
bool SfxObjectShell::IsLoadingFinished() const
1099
4.08k
{
1100
4.08k
    return ( pImpl->nLoadedFlags == SfxLoadedFlags::ALL );
1101
4.08k
}
1102
1103
void SfxObjectShell::InitOwnModel_Impl()
1104
0
{
1105
0
    if ( pImpl->bModelInitialized )
1106
0
        return;
1107
1108
0
    const SfxStringItem* pSalvageItem = pMedium->GetItemSet().GetItem(SID_DOC_SALVAGE, false);
1109
0
    if ( pSalvageItem )
1110
0
    {
1111
0
        pImpl->aTempName = pMedium->GetPhysicalName();
1112
0
        pMedium->GetItemSet().ClearItem( SID_DOC_SALVAGE );
1113
0
        pMedium->GetItemSet().ClearItem( SID_FILE_NAME );
1114
0
        pMedium->GetItemSet().Put( SfxStringItem( SID_FILE_NAME, pMedium->GetOrigURL() ) );
1115
0
    }
1116
0
    else
1117
0
    {
1118
0
        pMedium->GetItemSet().ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
1119
0
        pMedium->GetItemSet().ClearItem( SID_DOCUMENT );
1120
0
    }
1121
1122
0
    pMedium->GetItemSet().ClearItem( SID_REFERER );
1123
0
    uno::Reference< frame::XModel >  xModel = GetModel();
1124
0
    if ( xModel.is() )
1125
0
    {
1126
0
        SfxItemSet& rSet = GetMedium()->GetItemSet();
1127
0
        if ( !GetMedium()->IsReadOnly() )
1128
0
            rSet.ClearItem( SID_INPUTSTREAM );
1129
0
        comphelper::SequenceAsHashMap aArgs = TransformItems(SID_OPENDOC, rSet);
1130
0
        xModel->attachResource(GetMedium()->GetOrigURL(), aArgs.getAsConstPropertyValueList());
1131
0
        impl_addToModelCollection(xModel);
1132
0
    }
1133
1134
0
    pImpl->bModelInitialized = true;
1135
0
}
1136
1137
void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags )
1138
0
{
1139
0
    bool bSetModifiedTRUE = false;
1140
0
    const SfxStringItem* pSalvageItem = pMedium->GetItemSet().GetItem(SID_DOC_SALVAGE, false);
1141
0
    if( ( nFlags & SfxLoadedFlags::MAINDOCUMENT ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT )
1142
0
        && !(pImpl->nFlagsInProgress & SfxLoadedFlags::MAINDOCUMENT ))
1143
0
    {
1144
0
        pImpl->nFlagsInProgress |= SfxLoadedFlags::MAINDOCUMENT;
1145
0
        static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())->SetAttributes();
1146
1147
0
        pMedium->activateEmbeddedFonts();
1148
1149
0
        if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().hasElements() ) && !IsModifyPasswordEntered() )
1150
0
            SetReadOnly();
1151
1152
        // Salvage
1153
0
        if ( pSalvageItem )
1154
0
            bSetModifiedTRUE = true;
1155
1156
0
        if ( !IsEnableSetModified() )
1157
0
            EnableSetModified();
1158
1159
0
        if( !bSetModifiedTRUE && IsEnableSetModified() )
1160
0
            SetModified( false );
1161
1162
0
        CheckSecurityOnLoading_Impl();
1163
1164
0
        bHasName = true; // the document is loaded, so the name should already available
1165
0
        GetTitle( SFX_TITLE_DETECT );
1166
0
        InitOwnModel_Impl();
1167
1168
0
        if (IsLoadReadonly())
1169
0
        {
1170
0
            OUString aFilterName;
1171
0
            if (const SfxStringItem* pFilterNameItem =
1172
0
                pMedium->GetItemSet().GetItem(SID_FILTER_NAME, false))
1173
0
                aFilterName = pFilterNameItem->GetValue();
1174
1175
0
            OUString aFileName;
1176
0
            if (const SfxStringItem* pFileNameItem =
1177
0
                pMedium->GetItemSet().GetItem(SID_FILE_NAME, false))
1178
0
            {
1179
0
                const INetURLObject aURL(pFileNameItem->GetValue());
1180
0
                aFileName = aURL.getBase(INetURLObject::LAST_SEGMENT, true,
1181
0
                                         INetURLObject::DecodeMechanism::WithCharset);
1182
0
            }
1183
1184
0
            bool bSilent = false;
1185
0
            if (const SfxBoolItem* pSilentNameItem =
1186
0
                pMedium->GetItemSet().GetItem(SID_SILENT, false))
1187
0
                bSilent = pSilentNameItem->GetValue();
1188
1189
0
            if (!bSilent && aFilterName.indexOf("Excel") != -1)
1190
0
            {
1191
0
                Reference<task::XInteractionHandler> xHandler(pMedium->GetInteractionHandler());
1192
0
                if (xHandler.is())
1193
0
                {
1194
0
                    beans::NamedValue aLoadReadOnlyRequest;
1195
0
                    aLoadReadOnlyRequest.Name = "LoadReadOnlyRequest";
1196
0
                    aLoadReadOnlyRequest.Value <<= aFileName;
1197
1198
0
                    Any aRequest(aLoadReadOnlyRequest);
1199
0
                    rtl::Reference<ucbhelper::SimpleInteractionRequest> xRequest
1200
0
                        = new ucbhelper::SimpleInteractionRequest(aRequest,
1201
0
                                                                  ContinuationFlags::Approve |
1202
0
                                                                  ContinuationFlags::Disapprove);
1203
1204
0
                    xHandler->handle(xRequest);
1205
1206
0
                    if (xRequest->getResponse() == ContinuationFlags::Disapprove)
1207
0
                    {
1208
0
                        SetSecurityOptOpenReadOnly(false);
1209
0
                        pMedium->GetItemSet().Put(SfxBoolItem(SID_DOC_READONLY, false));
1210
0
                    }
1211
0
                }
1212
0
            }
1213
0
        }
1214
1215
0
        pImpl->nFlagsInProgress &= ~SfxLoadedFlags::MAINDOCUMENT;
1216
0
    }
1217
1218
0
    if( ( nFlags & SfxLoadedFlags::IMAGES ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::IMAGES )
1219
0
        && !(pImpl->nFlagsInProgress & SfxLoadedFlags::IMAGES ))
1220
0
    {
1221
0
        pImpl->nFlagsInProgress |= SfxLoadedFlags::IMAGES;
1222
0
        uno::Reference<document::XDocumentProperties> xDocProps(
1223
0
            getDocProperties());
1224
0
        const OUString url(xDocProps->getAutoloadURL());
1225
0
        sal_Int32 delay(xDocProps->getAutoloadSecs());
1226
0
        SetAutoLoad( INetURLObject(url), delay * 1000,
1227
0
                     (delay > 0) || !url.isEmpty() );
1228
0
        if( !bSetModifiedTRUE && IsEnableSetModified() )
1229
0
            SetModified( false );
1230
0
        Invalidate( SID_SAVEASDOC );
1231
0
        pImpl->nFlagsInProgress &= ~SfxLoadedFlags::IMAGES;
1232
0
    }
1233
1234
0
    pImpl->nLoadedFlags |= nFlags;
1235
1236
0
    if ( pImpl->nFlagsInProgress != SfxLoadedFlags::NONE )
1237
0
        return;
1238
1239
    // in case of reentrance calls the first called FinishedLoading() call on the stack
1240
    // should do the notification, in result the notification is done when all the FinishedLoading() calls are finished
1241
1242
0
    if ( bSetModifiedTRUE )
1243
0
        SetModified();
1244
0
    else
1245
0
        SetModified( false );
1246
1247
0
    if ( (pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) && (pImpl->nLoadedFlags & SfxLoadedFlags::IMAGES ) )
1248
0
    {
1249
0
        const SfxBoolItem* pTemplateItem = pMedium->GetItemSet().GetItem(SID_TEMPLATE, false);
1250
0
        bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
1251
1252
        // closing the streams on loading should be under control of SFX!
1253
0
        DBG_ASSERT( pMedium->IsOpen(), "Don't close the medium when loading documents!" );
1254
1255
0
        if ( bTemplate )
1256
0
        {
1257
0
            TemplateDisconnectionAfterLoad();
1258
0
        }
1259
0
        else
1260
0
        {
1261
            // if a readonly medium has storage then it's stream is already based on temporary file
1262
0
            if( !(pMedium->GetOpenMode() & StreamMode::WRITE) && !pMedium->HasStorage_Impl() )
1263
                // don't lock file opened read only
1264
0
                pMedium->CloseInStream();
1265
0
        }
1266
0
    }
1267
1268
0
    SetInitialized_Impl( false );
1269
1270
    // Title is not available until loading has finished
1271
0
    Broadcast( SfxHint( SfxHintId::TitleChanged ) );
1272
0
    if ( pImpl->nEventId != SfxEventHintId::NONE )
1273
0
        PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
1274
0
}
1275
1276
void SfxObjectShell::TemplateDisconnectionAfterLoad()
1277
0
{
1278
    // document is created from a template
1279
    //TODO/LATER: should the templates always be XML docs!
1280
1281
0
    SfxMedium* pTmpMedium = pMedium;
1282
0
    if ( !pTmpMedium )
1283
0
        return;
1284
1285
0
    const OUString aName( pTmpMedium->GetName() );
1286
0
    const SfxStringItem* pTemplNamItem = pTmpMedium->GetItemSet().GetItem(SID_TEMPLATE_NAME, false);
1287
0
    OUString aTemplateName;
1288
0
    if ( pTemplNamItem )
1289
0
        aTemplateName = pTemplNamItem->GetValue();
1290
0
    else
1291
0
    {
1292
        // !TODO/LATER: what's this?!
1293
        // Interactive ( DClick, Contextmenu ) no long name is included
1294
0
        aTemplateName = getDocProperties()->getTitle();
1295
0
        if ( aTemplateName.isEmpty() )
1296
0
        {
1297
0
            INetURLObject aURL( aName );
1298
0
            aURL.CutExtension();
1299
0
            aTemplateName = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset );
1300
0
        }
1301
0
    }
1302
1303
    // tdf#165348: release the lock on the original file before clearing the URL, otherwise
1304
    // UnlockFile (called later from Close) won't know which lock file to remove.
1305
0
    pTmpMedium->UnlockFile(false);
1306
1307
    // set medium to noname
1308
0
    pTmpMedium->SetName( OUString(), true );
1309
0
    pTmpMedium->Init_Impl();
1310
1311
    // drop resource
1312
0
    SetNoName();
1313
0
    InvalidateName();
1314
1315
0
    if( IsPackageStorageFormat_Impl( *pTmpMedium ) )
1316
0
    {
1317
        // untitled document must be based on temporary storage
1318
        // the medium should not dispose the storage in this case
1319
0
        uno::Reference < embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
1320
0
        GetStorage()->copyToStorage( xTmpStor );
1321
1322
        // the medium should disconnect from the original location
1323
        // the storage should not be disposed since the document is still
1324
        // based on it, but in DoSaveCompleted it will be disposed
1325
0
        pTmpMedium->CanDisposeStorage_Impl( false );
1326
0
        pTmpMedium->Close();
1327
1328
        // setting the new storage the medium will be based on
1329
0
        pTmpMedium->SetStorage_Impl( xTmpStor );
1330
1331
0
        pMedium = nullptr;
1332
0
        bool ok = DoSaveCompleted( pTmpMedium );
1333
0
        assert(pMedium != nullptr);
1334
0
        if( ok )
1335
0
        {
1336
0
            const SfxStringItem* pSalvageItem = pMedium->GetItemSet().GetItem(SID_DOC_SALVAGE, false);
1337
0
            bool bSalvage = pSalvageItem != nullptr;
1338
1339
0
            if ( !bSalvage )
1340
0
            {
1341
                // some further initializations for templates
1342
0
                SetTemplate_Impl( aName, aTemplateName, this );
1343
0
            }
1344
1345
            // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
1346
0
            pTmpMedium->CanDisposeStorage_Impl( false );
1347
0
        }
1348
0
        else
1349
0
        {
1350
0
            SetError(ERRCODE_IO_GENERAL);
1351
0
        }
1352
0
    }
1353
0
    else
1354
0
    {
1355
        // some further initializations for templates
1356
0
        SetTemplate_Impl( aName, aTemplateName, this );
1357
0
        pTmpMedium->CreateTempFile();
1358
0
    }
1359
1360
    // templates are never readonly
1361
0
    pTmpMedium->GetItemSet().ClearItem( SID_DOC_READONLY );
1362
0
    pTmpMedium->SetOpenMode( SFX_STREAM_READWRITE, true );
1363
1364
    // notifications about possible changes in readonly state and document info
1365
0
    Broadcast( SfxHint(SfxHintId::ModeChanged) );
1366
1367
    // created untitled document can't be modified
1368
0
    SetModified( false );
1369
0
}
1370
1371
1372
bool SfxObjectShell::IsLoading() const
1373
/*  [Description]
1374
1375
    Has FinishedLoading been called?
1376
*/
1377
13.9M
{
1378
13.9M
    return !( pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT );
1379
13.9M
}
1380
1381
1382
void SfxObjectShell::CancelTransfers()
1383
/*  [Description]
1384
1385
    Here can Transfers get canceled, which were not registered
1386
    by RegisterTransfer.
1387
*/
1388
4.08k
{
1389
4.08k
    if( ( pImpl->nLoadedFlags & SfxLoadedFlags::ALL ) != SfxLoadedFlags::ALL )
1390
0
    {
1391
0
        pImpl->bIsAbortingImport = true;
1392
0
        if( IsLoading() )
1393
0
            FinishedLoading();
1394
0
    }
1395
4.08k
}
1396
1397
1398
AutoReloadTimer_Impl::AutoReloadTimer_Impl(
1399
    OUString _aURL, sal_uInt32 nTime, SfxObjectShell* pSh )
1400
0
    : Timer("sfx2 AutoReloadTimer_Impl"), aUrl(std::move( _aURL )), pObjSh( pSh )
1401
0
{
1402
0
    SetTimeout( nTime );
1403
0
}
1404
1405
1406
void AutoReloadTimer_Impl::Invoke()
1407
0
{
1408
0
    SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjSh );
1409
1410
0
    if ( pFrame )
1411
0
    {
1412
        // Not possible/meaningful at the moment?
1413
0
        if ( !pObjSh->CanReload_Impl() || pObjSh->IsAutoLoadLocked() || Application::IsUICaptured() )
1414
0
        {
1415
            // Allow a retry
1416
0
            Start();
1417
0
            return;
1418
0
        }
1419
1420
0
        SfxAllItemSet aSet( SfxGetpApp()->GetPool() );
1421
0
        aSet.Put( SfxBoolItem( SID_AUTOLOAD, true ) );
1422
0
        if ( !aUrl.isEmpty() )
1423
0
            aSet.Put(  SfxStringItem( SID_FILE_NAME, aUrl ) );
1424
0
        if (pObjSh->HasName()) {
1425
0
            aSet.Put(
1426
0
                SfxStringItem(SID_REFERER, pObjSh->GetMedium()->GetName()));
1427
0
        }
1428
0
        SfxRequest aReq( SID_RELOAD, SfxCallMode::SLOT, aSet );
1429
        // this will delete this
1430
0
        pObjSh->Get_Impl()->pReloadTimer.reset();
1431
0
        pFrame->ExecReload_Impl( aReq );
1432
0
        return;
1433
0
    }
1434
1435
    // this will delete this
1436
0
    pObjSh->Get_Impl()->pReloadTimer.reset();
1437
0
}
1438
1439
SfxModule* SfxObjectShell::GetModule() const
1440
146k
{
1441
146k
    return GetFactory().GetModule();
1442
146k
}
1443
1444
ErrCode SfxObjectShell::CallBasic( std::u16string_view rMacro,
1445
    std::u16string_view rBasic, SbxArray* pArgs,
1446
    SbxValue* pRet )
1447
0
{
1448
0
    SfxApplication* pApp = SfxGetpApp();
1449
0
    if( pApp->GetName() != rBasic )
1450
0
    {
1451
0
        if ( !AdjustMacroMode() )
1452
0
            return ERRCODE_IO_ACCESSDENIED;
1453
0
    }
1454
1455
0
    BasicManager *pMgr = GetBasicManager();
1456
0
    if( pApp->GetName() == rBasic )
1457
0
        pMgr = SfxApplication::GetBasicManager();
1458
0
    ErrCode nRet = SfxApplication::CallBasic( OUString(rMacro), pMgr, pArgs, pRet );
1459
0
    return nRet;
1460
0
}
1461
1462
bool SfxObjectShell::isScriptAccessAllowed( const Reference< XInterface >& _rxScriptContext )
1463
0
{
1464
0
    try
1465
0
    {
1466
0
        Reference< XEmbeddedScripts > xScripts( _rxScriptContext, UNO_QUERY );
1467
0
        if ( !xScripts.is() )
1468
0
        {
1469
0
            Reference< XScriptInvocationContext > xContext( _rxScriptContext, UNO_QUERY_THROW );
1470
0
            xScripts.set( xContext->getScriptContainer(), UNO_SET_THROW );
1471
0
        }
1472
1473
0
        return xScripts->getAllowMacroExecution();
1474
0
    }
1475
0
    catch( const Exception& )
1476
0
    {
1477
0
        DBG_UNHANDLED_EXCEPTION("sfx.doc");
1478
0
    }
1479
0
    return false;
1480
0
}
1481
1482
// don't allow LibreLogo to be used with our mouseover/etc dom-alike events
1483
bool SfxObjectShell::UnTrustedScript(const OUString& rScriptURL)
1484
0
{
1485
0
    if (!rScriptURL.startsWith("vnd.sun.star.script:"))
1486
0
        return false;
1487
1488
    // ensure URL Escape Codes are decoded
1489
0
    css::uno::Reference<css::uri::XUriReference> uri(
1490
0
        css::uri::UriReferenceFactory::create(comphelper::getProcessComponentContext())->parse(rScriptURL));
1491
0
    css::uno::Reference<css::uri::XVndSunStarScriptUrl> sfUri(uri, css::uno::UNO_QUERY);
1492
1493
0
    if (!sfUri.is())
1494
0
        return false;
1495
1496
    // pyuno encodes path separator as |
1497
0
    OUString sScript = sfUri->getName().replace('|', '/');
1498
1499
    // check if any path portion matches LibreLogo and ban it if it does
1500
0
    sal_Int32 nIndex = 0;
1501
0
    do
1502
0
    {
1503
0
        OUString aToken = sScript.getToken(0, '/', nIndex);
1504
0
        if (aToken.startsWithIgnoreAsciiCase("LibreLogo") || aToken.indexOf('~') != -1)
1505
0
        {
1506
0
            return true;
1507
0
        }
1508
0
    }
1509
0
    while (nIndex >= 0);
1510
1511
0
    return false;
1512
0
}
1513
1514
ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptContext, const OUString& _rScriptURL,
1515
    const Sequence< Any >& aParams, Any& aRet, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam, bool bRaiseError, const css::uno::Any* pCaller )
1516
0
{
1517
0
    SAL_INFO("sfx", "in CallXScript" );
1518
0
    ErrCode nErr = ERRCODE_NONE;
1519
1520
0
    bool bCaughtException = false;
1521
0
    Any aException;
1522
0
    try
1523
0
    {
1524
0
        if (!isScriptAccessAllowed(_rxScriptContext))
1525
0
            return ERRCODE_IO_ACCESSDENIED;
1526
1527
0
        if ( UnTrustedScript(_rScriptURL) )
1528
0
            return ERRCODE_IO_ACCESSDENIED;
1529
1530
        // obtain/create a script provider
1531
0
        Reference< provider::XScriptProvider > xScriptProvider;
1532
0
        Reference< provider::XScriptProviderSupplier > xSPS( _rxScriptContext, UNO_QUERY );
1533
0
        if ( xSPS.is() )
1534
0
            xScriptProvider.set( xSPS->getScriptProvider() );
1535
1536
0
        if ( !xScriptProvider.is() )
1537
0
        {
1538
0
            Reference< provider::XScriptProviderFactory > xScriptProviderFactory =
1539
0
                provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
1540
0
            xScriptProvider.set( xScriptProviderFactory->createScriptProvider( Any( _rxScriptContext ) ), UNO_SET_THROW );
1541
0
        }
1542
1543
        // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
1544
0
        ::framework::DocumentUndoGuard aUndoGuard( _rxScriptContext );
1545
1546
        // obtain the script, and execute it
1547
0
        Reference< provider::XScript > xScript( xScriptProvider->getScript( _rScriptURL ), UNO_SET_THROW );
1548
0
        if ( pCaller && pCaller->hasValue() )
1549
0
        {
1550
0
            Reference< beans::XPropertySet > xProps( xScript, uno::UNO_QUERY );
1551
0
            if ( xProps.is() )
1552
0
            {
1553
0
                Sequence< uno::Any > aArgs{ *pCaller };
1554
0
                xProps->setPropertyValue(u"Caller"_ustr, uno::Any( aArgs ) );
1555
0
            }
1556
0
        }
1557
0
        aRet = xScript->invoke( aParams, aOutParamIndex, aOutParam );
1558
0
    }
1559
0
    catch ( const uno::Exception& )
1560
0
    {
1561
0
        aException = ::cppu::getCaughtException();
1562
0
        bCaughtException = true;
1563
0
        nErr = ERRCODE_BASIC_INTERNAL_ERROR;
1564
0
    }
1565
1566
0
    if ( bCaughtException && bRaiseError )
1567
0
    {
1568
0
        SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1569
0
        pFact->ShowAsyncScriptErrorDialog( nullptr, aException );
1570
0
    }
1571
1572
0
    SAL_INFO("sfx", "leaving CallXScript" );
1573
0
    return nErr;
1574
0
}
1575
1576
// perhaps rename to CallScript once we get rid of the existing CallScript
1577
// and Call, CallBasic, CallStarBasic methods
1578
ErrCode SfxObjectShell::CallXScript( const OUString& rScriptURL,
1579
        const css::uno::Sequence< css::uno::Any >& aParams,
1580
        css::uno::Any& aRet,
1581
        css::uno::Sequence< sal_Int16 >& aOutParamIndex,
1582
        css::uno::Sequence< css::uno::Any >& aOutParam,
1583
        bool bRaiseError,
1584
        const css::uno::Any* pCaller )
1585
0
{
1586
0
    return CallXScript( GetModel(), rScriptURL, aParams, aRet, aOutParamIndex, aOutParam, bRaiseError, pCaller );
1587
0
}
1588
1589
void SfxHeaderAttributes_Impl::SetAttributes()
1590
0
{
1591
0
    bAlert = true;
1592
0
    SvKeyValue aPair;
1593
0
    for( bool bCont = xIter->GetFirst( aPair ); bCont;
1594
0
         bCont = xIter->GetNext( aPair ) )
1595
0
        SetAttribute( aPair );
1596
0
}
1597
1598
void SfxHeaderAttributes_Impl::SetAttribute( const SvKeyValue& rKV )
1599
0
{
1600
0
    const OUString& aValue = rKV.GetValue();
1601
0
    if( rKV.GetKey().equalsIgnoreAsciiCase("refresh") && !rKV.GetValue().isEmpty() )
1602
0
    {
1603
0
        sal_Int32 nIdx{ 0 };
1604
0
        const sal_Int32 nTime{ o3tl::toInt32(o3tl::getToken(aValue, 0, ';', nIdx )) };
1605
0
        const OUString aURL{ comphelper::string::strip(o3tl::getToken(aValue, 0, ';', nIdx ), ' ') };
1606
0
        uno::Reference<document::XDocumentProperties> xDocProps(
1607
0
            pDoc->getDocProperties());
1608
0
        if( aURL.startsWithIgnoreAsciiCase( "url=" ) )
1609
0
        {
1610
0
            try {
1611
0
                xDocProps->setAutoloadURL(
1612
0
                    rtl::Uri::convertRelToAbs(pDoc->GetMedium()->GetName(), aURL.copy( 4 )) );
1613
0
            } catch (rtl::MalformedUriException &) {
1614
0
                TOOLS_WARN_EXCEPTION("sfx", "");
1615
0
            }
1616
0
        }
1617
0
        try
1618
0
        {
1619
0
            xDocProps->setAutoloadSecs( nTime );
1620
0
        }
1621
0
        catch (lang::IllegalArgumentException &)
1622
0
        {
1623
            // ignore
1624
0
        }
1625
0
    }
1626
0
    else if( rKV.GetKey().equalsIgnoreAsciiCase( "expires" ) )
1627
0
    {
1628
0
        DateTime aDateTime( DateTime::EMPTY );
1629
0
        if( INetMIMEMessage::ParseDateField( rKV.GetValue(), aDateTime ) )
1630
0
        {
1631
0
            aDateTime.ConvertToLocalTime();
1632
0
            pDoc->GetMedium()->SetExpired_Impl( aDateTime );
1633
0
        }
1634
0
        else
1635
0
        {
1636
0
            pDoc->GetMedium()->SetExpired_Impl( DateTime(Date( 1, 1, 1970 )) );
1637
0
        }
1638
0
    }
1639
0
}
1640
1641
void SfxHeaderAttributes_Impl::Append( const SvKeyValue& rKV )
1642
5.13k
{
1643
5.13k
    xIter->Append( rKV );
1644
5.13k
    if( bAlert ) SetAttribute( rKV );
1645
5.13k
}
1646
1647
SvKeyValueIterator* SfxObjectShell::GetHeaderAttributes()
1648
160k
{
1649
160k
    if( !pImpl->xHeaderAttributes.is() )
1650
14.4k
    {
1651
14.4k
        DBG_ASSERT( pMedium, "No Medium" );
1652
14.4k
        pImpl->xHeaderAttributes = new SfxHeaderAttributes_Impl( this );
1653
14.4k
    }
1654
160k
    return pImpl->xHeaderAttributes.get();
1655
160k
}
1656
1657
void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
1658
0
{
1659
0
    static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())
1660
0
        ->ClearForSourceView();
1661
0
}
1662
1663
1664
void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
1665
0
{
1666
0
    static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())
1667
0
        ->SetAttributes();
1668
0
}
1669
1670
bool SfxObjectShell::IsPreview() const
1671
83.5M
{
1672
83.5M
    if ( !pMedium )
1673
246k
        return false;
1674
1675
83.2M
    bool bPreview = false;
1676
83.2M
    const SfxStringItem* pFlags = pMedium->GetItemSet().GetItem(SID_OPTIONS, false);
1677
83.2M
    if ( pFlags )
1678
0
    {
1679
        // Distributed values among individual items
1680
0
        const OUString aFileFlags = pFlags->GetValue().toAsciiUpperCase();
1681
0
        if ( -1 != aFileFlags.indexOf( 'B' ) )
1682
0
            bPreview = true;
1683
0
    }
1684
1685
83.2M
    if ( !bPreview )
1686
83.2M
    {
1687
83.2M
        const SfxBoolItem* pItem = pMedium->GetItemSet().GetItem(SID_PREVIEW, false);
1688
83.2M
        if ( pItem )
1689
0
            bPreview = pItem->GetValue();
1690
83.2M
    }
1691
1692
83.2M
    return bPreview;
1693
83.5M
}
1694
1695
void SfxObjectShell::SetWaitCursor( bool bSet ) const
1696
52.3k
{
1697
52.3k
    for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
1698
0
    {
1699
0
        if ( bSet )
1700
0
            pFrame->GetFrame().GetWindow().EnterWait();
1701
0
        else
1702
0
            pFrame->GetFrame().GetWindow().LeaveWait();
1703
0
    }
1704
52.3k
}
1705
1706
OUString SfxObjectShell::GetAPIName() const
1707
10.3k
{
1708
10.3k
    INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
1709
10.3k
    OUString aName( aURL.GetBase() );
1710
10.3k
    if( aName.isEmpty() )
1711
10.3k
        aName = aURL.GetURLNoPass();
1712
10.3k
    if ( aName.isEmpty() )
1713
10.3k
        aName = GetTitle( SFX_TITLE_DETECT );
1714
10.3k
    return aName;
1715
10.3k
}
1716
1717
void SfxObjectShell::Invalidate( sal_uInt16 nId )
1718
409k
{
1719
409k
    for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
1720
0
        Invalidate_Impl( pFrame->GetBindings(), nId );
1721
409k
}
1722
1723
bool SfxObjectShell::AdjustMacroMode()
1724
0
{
1725
0
    uno::Reference< task::XInteractionHandler > xInteraction;
1726
0
    if ( pMedium )
1727
0
        xInteraction = pMedium->GetInteractionHandler();
1728
1729
0
    CheckForBrokenDocSignatures_Impl();
1730
1731
0
    CheckEncryption_Impl( xInteraction );
1732
1733
0
    return pImpl->aMacroMode.adjustMacroMode( xInteraction );
1734
0
}
1735
1736
css::uno::Reference<css::awt::XWindow> SfxObjectShell::GetDialogParent( SfxMedium const * pLoadingMedium )
1737
0
{
1738
0
    css::uno::Reference<css::awt::XWindow> xWindow;
1739
0
    SfxItemSet& rSet = pLoadingMedium ? pLoadingMedium->GetItemSet() : GetMedium()->GetItemSet();
1740
0
    const SfxUnoFrameItem* pUnoItem = rSet.GetItem(SID_FILLFRAME, false);
1741
0
    if ( pUnoItem )
1742
0
    {
1743
0
        const uno::Reference < frame::XFrame >& xFrame( pUnoItem->GetFrame() );
1744
0
        xWindow = xFrame->getContainerWindow();
1745
0
    }
1746
1747
0
    if (!xWindow)
1748
0
    {
1749
0
        SfxFrame* pFrame = nullptr;
1750
0
        const SfxFrameItem* pFrameItem = rSet.GetItem<SfxFrameItem>(SID_DOCFRAME, false);
1751
0
        if( pFrameItem && pFrameItem->GetFrame() )
1752
            // get target frame from ItemSet
1753
0
            pFrame = pFrameItem->GetFrame();
1754
0
        else
1755
0
        {
1756
            // try the current frame
1757
0
            SfxViewFrame* pView = SfxViewFrame::Current();
1758
0
            if ( !pView || pView->GetObjectShell() != this )
1759
                // get any visible frame
1760
0
                pView = SfxViewFrame::GetFirst(this);
1761
0
            if ( pView )
1762
0
                pFrame = &pView->GetFrame();
1763
0
        }
1764
1765
0
        if ( pFrame )
1766
0
        {
1767
            // get topmost window
1768
0
            xWindow = pFrame->GetFrameInterface()->getContainerWindow();
1769
0
        }
1770
0
    }
1771
1772
0
    if (xWindow)
1773
0
    {
1774
        // this frame may be invisible, show it if it is allowed
1775
0
        const SfxBoolItem* pHiddenItem = rSet.GetItem(SID_HIDDEN, false);
1776
0
        if ( !pHiddenItem || !pHiddenItem->GetValue() )
1777
0
        {
1778
0
            xWindow->setVisible(true);
1779
0
            css::uno::Reference<css::awt::XTopWindow> xTopWindow(xWindow, uno::UNO_QUERY);
1780
0
            SAL_WARN_IF(!xTopWindow, "sfx.appl", "XTopWindow not available from XWindow");
1781
0
            if (xTopWindow)
1782
0
                xTopWindow->toFront();
1783
0
        }
1784
0
    }
1785
1786
0
    return xWindow;
1787
0
}
1788
1789
void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode )
1790
0
{
1791
0
    eCreateMode = nMode;
1792
0
}
1793
1794
bool SfxObjectShell::IsInPlaceActive() const
1795
48.5k
{
1796
48.5k
    if ( eCreateMode != SfxObjectCreateMode::EMBEDDED )
1797
20.4k
        return false;
1798
1799
28.1k
    SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
1800
28.1k
    return pFrame && pFrame->GetFrame().IsInPlace();
1801
48.5k
}
1802
1803
bool SfxObjectShell::IsUIActive() const
1804
0
{
1805
0
    if ( eCreateMode != SfxObjectCreateMode::EMBEDDED )
1806
0
        return false;
1807
1808
0
    SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
1809
0
    return pFrame && pFrame->GetFrame().IsInPlace() && pFrame->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
1810
0
}
1811
1812
bool SfxObjectShell::UseInteractionToHandleError(
1813
                    const uno::Reference< task::XInteractionHandler >& xHandler,
1814
                    const ErrCodeMsg& nError )
1815
0
{
1816
0
    bool bResult = false;
1817
1818
0
    if ( xHandler.is() )
1819
0
    {
1820
0
        try
1821
0
        {
1822
0
            uno::Any aInteraction;
1823
0
            rtl::Reference<::comphelper::OInteractionAbort> pAbort = new ::comphelper::OInteractionAbort();
1824
0
            rtl::Reference<::comphelper::OInteractionApprove> pApprove = new ::comphelper::OInteractionApprove();
1825
0
            uno::Sequence< uno::Reference< task::XInteractionContinuation > > lContinuations{
1826
0
                pAbort, pApprove
1827
0
            };
1828
1829
0
            task::ErrorCodeRequest2 aErrorCode(OUString(), uno::Reference<XInterface>(),
1830
0
                sal_Int32(sal_uInt32(nError.GetCode())), nError.GetArg1(), nError.GetArg2(),
1831
0
                static_cast<sal_Int16>(nError.GetDialogMask()));
1832
0
            aInteraction <<= aErrorCode;
1833
0
            xHandler->handle(::framework::InteractionRequest::CreateRequest (aInteraction,lContinuations));
1834
0
            bResult = pAbort->wasSelected();
1835
0
        }
1836
0
        catch( uno::Exception& )
1837
0
        {}
1838
0
    }
1839
1840
0
    return bResult;
1841
0
}
1842
1843
sal_Int16 SfxObjectShell_Impl::getCurrentMacroExecMode() const
1844
0
{
1845
0
    sal_Int16 nImposedExecMode( MacroExecMode::NEVER_EXECUTE );
1846
1847
0
    const SfxMedium* pMedium( rDocShell.GetMedium() );
1848
0
    OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1849
0
    if ( pMedium )
1850
0
    {
1851
0
        const SfxUInt16Item* pMacroModeItem = pMedium->GetItemSet().GetItem(SID_MACROEXECMODE, false);
1852
0
        if ( pMacroModeItem )
1853
0
            nImposedExecMode = pMacroModeItem->GetValue();
1854
0
    }
1855
0
    return nImposedExecMode;
1856
0
}
1857
1858
void SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
1859
195k
{
1860
195k
    const SfxMedium* pMedium( rDocShell.GetMedium() );
1861
195k
    OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1862
195k
    if ( pMedium )
1863
195k
    {
1864
195k
        pMedium->GetItemSet().Put( SfxUInt16Item( SID_MACROEXECMODE, nMacroMode ) );
1865
195k
    }
1866
195k
}
1867
1868
OUString SfxObjectShell_Impl::getDocumentLocation() const
1869
0
{
1870
0
    OUString sLocation;
1871
1872
0
    const SfxMedium* pMedium( rDocShell.GetMedium() );
1873
0
    OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
1874
0
    if ( pMedium )
1875
0
    {
1876
0
        sLocation = pMedium->GetName();
1877
0
        if ( sLocation.isEmpty() )
1878
0
        {
1879
            // for documents made from a template: get the name of the template
1880
0
            sLocation = rDocShell.getDocProperties()->getTemplateURL();
1881
0
        }
1882
1883
        // tdf#128006 take document base url as location
1884
0
        if (sLocation.isEmpty())
1885
0
            sLocation = rDocShell.getDocumentBaseURL();
1886
0
    }
1887
1888
0
    return sLocation;
1889
0
}
1890
1891
bool SfxObjectShell_Impl::documentStorageHasMacros() const
1892
4.08k
{
1893
4.08k
    return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage );
1894
4.08k
}
1895
1896
bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const
1897
4.08k
{
1898
4.08k
    return rDocShell.GetMacroCallsSeenWhileLoading();
1899
4.08k
}
1900
1901
Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
1902
0
{
1903
0
    return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY );
1904
0
}
1905
1906
SignatureState SfxObjectShell_Impl::getScriptingSignatureState()
1907
0
{
1908
0
    SignatureState nSignatureState( rDocShell.GetScriptingSignatureState() );
1909
1910
0
    if ( nSignatureState != SignatureState::NOSIGNATURES && m_bMacroSignBroken )
1911
0
    {
1912
        // if there is a macro signature it must be handled as broken
1913
0
        nSignatureState = SignatureState::BROKEN;
1914
0
    }
1915
1916
0
    return nSignatureState;
1917
0
}
1918
1919
bool SfxObjectShell_Impl::hasTrustedScriptingSignature(
1920
    const css::uno::Reference<css::task::XInteractionHandler>& _rxInteraction)
1921
0
{
1922
0
    bool bResult = false;
1923
1924
0
    try
1925
0
    {
1926
0
        if ( nScriptingSignatureState == SignatureState::UNKNOWN
1927
0
          || nScriptingSignatureState == SignatureState::OK
1928
0
          || nScriptingSignatureState == SignatureState::NOTVALIDATED )
1929
0
        {
1930
0
            OUString aVersion;
1931
0
            try
1932
0
            {
1933
0
                uno::Reference < beans::XPropertySet > xPropSet( rDocShell.GetStorage(), uno::UNO_QUERY_THROW );
1934
0
                xPropSet->getPropertyValue(u"Version"_ustr) >>= aVersion;
1935
0
            }
1936
0
            catch( uno::Exception& )
1937
0
            {
1938
0
            }
1939
1940
0
            uno::Reference< security::XDocumentDigitalSignatures > xSigner( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion) );
1941
1942
0
            uno::Sequence<security::DocumentSignatureInformation> aInfo = rDocShell.GetDocumentSignatureInformation( true, xSigner );
1943
1944
0
            if ( aInfo.hasElements() )
1945
0
            {
1946
0
                if ( nScriptingSignatureState == SignatureState::UNKNOWN )
1947
0
                    nScriptingSignatureState = DocumentSignatures::getSignatureState(aInfo);
1948
1949
0
                if ( nScriptingSignatureState == SignatureState::OK
1950
0
                  || nScriptingSignatureState == SignatureState::NOTVALIDATED )
1951
0
                {
1952
0
                    bResult = std::any_of(aInfo.begin(), aInfo.end(),
1953
0
                        [&xSigner](const security::DocumentSignatureInformation& rInfo) {
1954
0
                            return xSigner->isAuthorTrusted( rInfo.Signer ); });
1955
1956
0
                    if (!bResult && _rxInteraction)
1957
0
                    {
1958
0
                        task::DocumentMacroConfirmationRequest aRequest;
1959
0
                        aRequest.DocumentURL = getDocumentLocation();
1960
0
                        aRequest.DocumentStorage = rDocShell.GetMedium()->GetScriptingStorageToSign_Impl();
1961
0
                        aRequest.DocumentSignatureInformation = std::move(aInfo);
1962
0
                        aRequest.DocumentVersion = aVersion;
1963
0
                        aRequest.Classification = task::InteractionClassification_QUERY;
1964
0
                        bResult = SfxMedium::CallApproveHandler( _rxInteraction, uno::Any( aRequest ), true );
1965
0
                    }
1966
0
                }
1967
0
            }
1968
0
        }
1969
0
    }
1970
0
    catch( uno::Exception& )
1971
0
    {}
1972
1973
0
    return bResult;
1974
0
}
1975
1976
bool SfxObjectShell::IsContinueImportOnFilterExceptions()
1977
913
{
1978
913
    if (mbContinueImportOnFilterExceptions == undefined)
1979
895
    {
1980
895
        if (!pMedium)
1981
0
        {
1982
0
            mbContinueImportOnFilterExceptions = no;
1983
0
            return false;
1984
0
        }
1985
1986
895
        if (!pMedium->GetArgs().getUnpackedValueOrDefault(u"RepairAllowed"_ustr, true))
1987
0
        {
1988
0
            mbContinueImportOnFilterExceptions = no;
1989
0
            return false;
1990
0
        }
1991
1992
895
        if (pMedium->IsRepairPackage())
1993
0
        {
1994
0
            mbContinueImportOnFilterExceptions = yes;
1995
0
            return true;
1996
0
        }
1997
1998
895
        auto xInteractionHandler = pMedium->GetInteractionHandler();
1999
895
        if (!xInteractionHandler)
2000
895
        {
2001
895
            mbContinueImportOnFilterExceptions = no;
2002
895
            return false;
2003
895
        }
2004
2005
0
        const OUString aDocName(pMedium->GetURLObject().getName(
2006
0
            INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset));
2007
0
        RequestPackageReparation aRequest(aDocName);
2008
0
        xInteractionHandler->handle(aRequest.GetRequest());
2009
0
        if (aRequest.isApproved())
2010
0
        {
2011
0
            mbContinueImportOnFilterExceptions = yes;
2012
            // lok: we want to overwrite file in jail, so don't use template flag
2013
0
            bool bIsLOK = comphelper::LibreOfficeKit::isActive();
2014
            // allow repair
2015
0
            pMedium->GetItemSet().Put(SfxBoolItem(SID_REPAIRPACKAGE, true));
2016
0
            pMedium->GetItemSet().Put(SfxBoolItem(SID_TEMPLATE, !bIsLOK));
2017
0
            pMedium->GetItemSet().Put(SfxStringItem(SID_DOCINFO_TITLE, aDocName));
2018
0
        }
2019
0
        else
2020
0
            mbContinueImportOnFilterExceptions = no;
2021
0
    }
2022
18
    return mbContinueImportOnFilterExceptions == yes;
2023
913
}
2024
2025
bool SfxObjectShell::isEditDocLocked() const
2026
0
{
2027
0
    Reference<XModel3> xModel = GetModel();
2028
0
    if (!xModel.is())
2029
0
        return false;
2030
0
    if (officecfg::Office::Common::Misc::ViewerAppMode::get()
2031
0
        || !officecfg::Office::Common::Misc::AllowEditReadonlyDocs::get())
2032
0
        return true;
2033
0
    try
2034
0
    {
2035
0
        return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockEditDoc"_ustr } ), u"LockEditDoc", false);
2036
0
    }
2037
0
    catch (const uno::RuntimeException&)
2038
0
    {
2039
0
        TOOLS_WARN_EXCEPTION("sfx.appl", "unexpected RuntimeException");
2040
0
    }
2041
0
    return false;
2042
0
}
2043
2044
bool SfxObjectShell::isContentExtractionLocked() const
2045
0
{
2046
0
    Reference<XModel3> xModel = GetModel();
2047
0
    if (!xModel.is())
2048
0
        return false;
2049
0
    try
2050
0
    {
2051
0
        return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockContentExtraction"_ustr } ), u"LockContentExtraction", false);
2052
0
    }
2053
0
    catch (const uno::RuntimeException&)
2054
0
    {
2055
0
        TOOLS_WARN_EXCEPTION("sfx.appl", "unexpected RuntimeException");
2056
0
    }
2057
0
    return false;
2058
0
}
2059
2060
bool SfxObjectShell::isExportLocked() const
2061
0
{
2062
0
    Reference<XModel3> xModel = GetModel();
2063
0
    if (!xModel.is())
2064
0
        return false;
2065
0
    try
2066
0
    {
2067
0
        return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockExport"_ustr } ), u"LockExport", false);
2068
0
    }
2069
0
    catch (const uno::RuntimeException&)
2070
0
    {
2071
0
        TOOLS_WARN_EXCEPTION("sfx.appl", "unexpected RuntimeException");
2072
0
    }
2073
0
    return false;
2074
0
}
2075
2076
bool SfxObjectShell::isPrintLocked() const
2077
0
{
2078
0
    Reference<XModel3> xModel = GetModel();
2079
0
    if (!xModel.is())
2080
0
        return false;
2081
0
    return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockPrint"_ustr } ), u"LockPrint", false);
2082
0
}
2083
2084
bool SfxObjectShell::isSaveLocked() const
2085
0
{
2086
0
    Reference<XModel3> xModel = GetModel();
2087
0
    if (!xModel.is())
2088
0
        return false;
2089
0
    return comphelper::NamedValueCollection::getOrDefault(xModel->getArgs2( { u"LockSave"_ustr } ), u"LockSave", false);
2090
0
}
2091
2092
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */