1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include <tools/inetmsg.hxx>
23 #include <comphelper/diagnose_ex.hxx>
24 #include <svl/eitem.hxx>
25 #include <svl/stritem.hxx>
26 #include <svl/intitem.hxx>
27 #include <svtools/svparser.hxx>
28 #include <cppuhelper/exc_hlp.hxx>
29 #include <sal/log.hxx>
30 #include <o3tl/string_view.hxx>
32 #include <com/sun/star/awt/XTopWindow.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/container/XChild.hpp>
35 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
36 #include <com/sun/star/document/XDocumentProperties.hpp>
37 #include <com/sun/star/document/MacroExecMode.hpp>
38 #include <com/sun/star/document/XScriptInvocationContext.hpp>
39 #include <com/sun/star/embed/EmbedStates.hpp>
40 #include <com/sun/star/embed/XEmbeddedObject.hpp>
41 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
42 #include <com/sun/star/script/provider/XScript.hpp>
43 #include <com/sun/star/script/provider/XScriptProvider.hpp>
44 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
45 #include <com/sun/star/uri/UriReferenceFactory.hpp>
46 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
47 #include <com/sun/star/util/XModifiable.hpp>
49 #include <com/sun/star/uno/Reference.h>
50 #include <com/sun/star/uno/Any.h>
51 #include <com/sun/star/task/ErrorCodeRequest2.hpp>
53 #include <comphelper/lok.hxx>
54 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
55 #include <comphelper/processfactory.hxx>
56 #include <comphelper/string.hxx>
58 #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
59 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
60 #include <com/sun/star/task/InteractionClassification.hpp>
61 #include <com/sun/star/task/XInteractionHandler.hpp>
62 #include <com/sun/star/frame/XModel.hpp>
64 #include <basic/basmgr.hxx>
65 #include <basic/sberrors.hxx>
67 #include <vcl/weld.hxx>
68 #include <basic/sbx.hxx>
69 #include <svtools/sfxecode.hxx>
71 #include <unotools/mediadescriptor.hxx>
72 #include <unotools/ucbhelper.hxx>
73 #include <tools/urlobj.hxx>
74 #include <svl/sharecontrolfile.hxx>
75 #include <rtl/uri.hxx>
76 #include <vcl/svapp.hxx>
77 #include <framework/interaction.hxx>
78 #include <framework/documentundoguard.hxx>
79 #include <comphelper/interaction.hxx>
80 #include <comphelper/storagehelper.hxx>
81 #include <comphelper/documentconstants.hxx>
82 #include <comphelper/namedvaluecollection.hxx>
83 #include <ucbhelper/simpleinteractionrequest.hxx>
84 #include <officecfg/Office/Common.hxx>
86 #include <sfx2/brokenpackageint.hxx>
87 #include <sfx2/signaturestate.hxx>
88 #include <sfx2/app.hxx>
89 #include <appdata.hxx>
90 #include <sfx2/request.hxx>
91 #include <sfx2/bindings.hxx>
92 #include <sfx2/sfxresid.hxx>
93 #include <sfx2/docfile.hxx>
94 #include <sfx2/objsh.hxx>
95 #include <objshimp.hxx>
96 #include <sfx2/event.hxx>
97 #include <sfx2/viewfrm.hxx>
98 #include <sfx2/sfxuno.hxx>
99 #include <sfx2/module.hxx>
100 #include <sfx2/docfac.hxx>
101 #include <sfx2/sfxsids.hrc>
102 #include <sfx2/strings.hrc>
103 #include <workwin.hxx>
104 #include <sfx2/sfxdlg.hxx>
105 #include <sfx2/infobar.hxx>
106 #include <sfx2/lokhelper.hxx>
107 #include <sfx2/sfxbasemodel.hxx>
108 #include <openflag.hxx>
109 #include "objstor.hxx"
110 #include <appopen.hxx>
111 #include <sfx2/viewsh.hxx>
115 using namespace ::com::sun::star
;
116 using namespace ::com::sun::star::uno
;
117 using namespace ::com::sun::star::ucb
;
118 using namespace ::com::sun::star::document
;
119 using namespace ::com::sun::star::frame
;
120 using namespace ::com::sun::star::script
;
121 using namespace ::com::sun::star::script::provider
;
122 using namespace ::com::sun::star::container
;
124 // class SfxHeaderAttributes_Impl ----------------------------------------
128 class SfxHeaderAttributes_Impl
: public SvKeyValueIterator
131 SfxObjectShell
* pDoc
;
132 SvKeyValueIteratorRef xIter
;
136 explicit SfxHeaderAttributes_Impl( SfxObjectShell
* pSh
) :
138 xIter( pSh
->GetMedium()->GetHeaderAttributes_Impl() ),
141 virtual bool GetFirst( SvKeyValue
& rKV
) override
{ return xIter
->GetFirst( rKV
); }
142 virtual bool GetNext( SvKeyValue
& rKV
) override
{ return xIter
->GetNext( rKV
); }
143 virtual void Append( const SvKeyValue
& rKV
) override
;
145 void ClearForSourceView() { xIter
= new SvKeyValueIterator
; bAlert
= false; }
146 void SetAttributes();
147 void SetAttribute( const SvKeyValue
& rKV
);
152 sal_uInt16
const aTitleMap_Impl
[3][2] =
155 /* SFX_TITLE_CAPTION */ { SFX_TITLE_FILENAME
, SFX_TITLE_TITLE
},
156 /* SFX_TITLE_PICKLIST */ { 32, SFX_TITLE_FULLNAME
},
157 /* SFX_TITLE_HISTORY */ { 32, SFX_TITLE_FULLNAME
}
161 bool SfxObjectShell::IsAbortingImport() const
163 return pImpl
->bIsAbortingImport
;
167 uno::Reference
<document::XDocumentProperties
>
168 SfxObjectShell::getDocProperties() const
170 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
171 GetModel(), uno::UNO_QUERY_THROW
);
172 uno::Reference
<document::XDocumentProperties
> xDocProps(
173 xDPS
->getDocumentProperties());
174 DBG_ASSERT(xDocProps
.is(),
175 "SfxObjectShell: model has no DocumentProperties");
180 void SfxObjectShell::DoFlushDocInfo()
185 // Note: the only thing that calls this is the modification event handler
186 // that is installed at the XDocumentProperties
187 void SfxObjectShell::FlushDocInfo()
193 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
194 DoFlushDocInfo(); // call template method
195 const OUString
url(xDocProps
->getAutoloadURL());
196 sal_Int32
delay(xDocProps
->getAutoloadSecs());
197 SetAutoLoad( INetURLObject(url
), delay
* 1000,
198 (delay
> 0) || !url
.isEmpty() );
201 void SfxObjectShell::AppendInfoBarWhenReady(const OUString
& sId
, const OUString
& sPrimaryMessage
,
202 const OUString
& sSecondaryMessage
,
203 InfobarType aInfobarType
, bool bShowCloseButton
)
205 InfobarData aInfobarData
;
206 aInfobarData
.msId
= sId
;
207 aInfobarData
.msPrimaryMessage
= sPrimaryMessage
;
208 aInfobarData
.msSecondaryMessage
= sSecondaryMessage
;
209 aInfobarData
.maInfobarType
= aInfobarType
;
210 aInfobarData
.mbShowCloseButton
= bShowCloseButton
;
211 Get_Impl()->m_aPendingInfobars
.emplace_back(aInfobarData
);
214 std::vector
<InfobarData
>& SfxObjectShell::getPendingInfobars()
216 return Get_Impl()->m_aPendingInfobars
;
219 void SfxObjectShell::SetError(const ErrCodeMsg
& lErr
)
221 if (pImpl
->lErr
==ERRCODE_NONE
)
227 ErrCodeMsg
SfxObjectShell::GetErrorIgnoreWarning() const
229 return GetErrorCode().IgnoreWarning();
232 ErrCodeMsg
SfxObjectShell::GetErrorCode() const
234 ErrCodeMsg lError
=pImpl
->lErr
;
235 if(!lError
&& GetMedium())
236 lError
=GetMedium()->GetErrorCode();
240 void SfxObjectShell::ResetError()
242 pImpl
->lErr
=ERRCODE_NONE
;
243 SfxMedium
* pMed
= GetMedium();
248 void SfxObjectShell::EnableSetModified( bool bEnable
)
250 SAL_INFO_IF( bEnable
== pImpl
->m_bEnableSetModified
, "sfx", "SFX_PERSIST: EnableSetModified 2x called with the same value" );
251 pImpl
->m_bEnableSetModified
= bEnable
;
255 bool SfxObjectShell::IsEnableSetModified() const
257 // tdf#146547 read-only does not prevent modified, instead try to prevent
258 // setting "internal" documents that may be displayed in some dialog but
259 // which the user didn't load or activate to modified.
260 return pImpl
->m_bEnableSetModified
&& !IsPreview()
261 && eCreateMode
!= SfxObjectCreateMode::ORGANIZER
262 && eCreateMode
!= SfxObjectCreateMode::INTERNAL
;
266 bool SfxObjectShell::IsModified() const
268 if ( pImpl
->m_bIsModified
)
271 if ( !pImpl
->m_xDocStorage
.is() || IsReadOnly() )
273 // if the document still has no storage and is not set to be modified explicitly it is not modified
274 // a readonly document is also not modified
279 if (pImpl
->mxObjectContainer
)
281 const uno::Sequence
< OUString
> aNames
= GetEmbeddedObjectContainer().GetObjectNames();
282 for ( const auto& rName
: aNames
)
284 uno::Reference
< embed::XEmbeddedObject
> xObj
= GetEmbeddedObjectContainer().GetEmbeddedObject( rName
);
285 OSL_ENSURE( xObj
.is(), "An empty entry in the embedded objects list!" );
290 sal_Int32 nState
= xObj
->getCurrentState();
291 if ( nState
!= embed::EmbedStates::LOADED
)
293 uno::Reference
< util::XModifiable
> xModifiable( xObj
->getComponent(), uno::UNO_QUERY
);
294 if ( xModifiable
.is() && xModifiable
->isModified() )
298 catch( uno::Exception
& )
308 void SfxObjectShell::SetModified( bool bModifiedP
)
310 SAL_INFO_IF( !bModifiedP
&& !IsEnableSetModified(), "sfx",
311 "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False" );
313 if( !IsEnableSetModified() )
316 if( pImpl
->m_bIsModified
!= bModifiedP
)
318 pImpl
->m_bIsModified
= bModifiedP
;
324 void SfxObjectShell::ModifyChanged()
326 if ( pImpl
->bClosing
)
327 // SetModified dispose of the models!
330 SfxViewFrame
* pViewFrame
= SfxViewFrame::Current();
332 pViewFrame
->GetBindings().Invalidate( SID_SAVEDOCS
);
334 Invalidate( SID_SIGNATURE
);
335 Invalidate( SID_MACRO_SIGNATURE
);
336 Broadcast( SfxHint( SfxHintId::TitleChanged
) ); // xmlsec05, signed state might change in title...
338 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::ModifyChanged
, GlobalEventConfig::GetEventName(GlobalEventId::MODIFYCHANGED
), this ) );
340 // Don't wait to get this important state via binding notification timeout.
341 if ( comphelper::LibreOfficeKit::isActive() )
343 OString aStatus
= ".uno:ModifiedStatus="_ostr
;
344 aStatus
+= IsModified() ? "true" : "false";
345 SfxLokHelper::notifyAllViews(LOK_CALLBACK_STATE_CHANGED
, aStatus
);
350 bool SfxObjectShell::IsReadOnlyUI() const
354 Returns sal_True if the document for the UI is treated as r/o. This is
355 regardless of the actual r/o, which can be checked with <IsReadOnly()>.
359 return pImpl
->bReadOnlyUI
|| SfxViewShell::IsCurrentLokViewReadOnly();
363 bool SfxObjectShell::IsReadOnlyMedium() const
367 Returns sal_True when the medium is r/o, for instance when opened as r/o.
373 return pMedium
->IsReadOnly();
376 bool SfxObjectShell::IsOriginallyReadOnlyMedium() const
378 return pMedium
== nullptr || pMedium
->IsOriginallyReadOnly();
381 bool SfxObjectShell::IsOriginallyLoadedReadOnlyMedium() const
383 return pMedium
!= nullptr && pMedium
->IsOriginallyLoadedReadOnly();
387 void SfxObjectShell::SetReadOnlyUI( bool bReadOnly
)
391 Turns the document in a r/o and r/w state respectively without reloading
392 it and without changing the open mode of the medium.
396 if ( bReadOnly
!= pImpl
->bReadOnlyUI
)
398 pImpl
->bReadOnlyUI
= bReadOnly
;
399 Broadcast( SfxHint(SfxHintId::ModeChanged
) );
404 void SfxObjectShell::SetReadOnly()
406 // Let the document be completely readonly, means that the
407 // medium open mode is adjusted accordingly, and the write lock
408 // on the file is removed.
410 if ( !pMedium
|| IsReadOnlyMedium() )
413 bool bWasROUI
= IsReadOnly();
415 pMedium
->UnlockFile( false );
417 // the storage-based mediums are already based on the temporary file
418 // so UnlockFile has already closed the locking stream
419 if ( !pMedium
->HasStorage_Impl() && IsLoadingFinished() )
420 pMedium
->CloseInStream();
422 pMedium
->SetOpenMode( SFX_STREAM_READONLY
, true );
423 pMedium
->GetItemSet().Put( SfxBoolItem( SID_DOC_READONLY
, true ) );
426 Broadcast( SfxHint(SfxHintId::ModeChanged
) );
430 bool SfxObjectShell::IsReadOnly() const
432 return pImpl
->bReadOnlyUI
|| pMedium
== nullptr;
436 bool SfxObjectShell::IsInModalMode() const
438 return pImpl
->bModalMode
|| pImpl
->bRunningMacro
;
441 bool SfxObjectShell::AcceptStateUpdate() const
443 return !IsInModalMode();
447 void SfxObjectShell::SetMacroMode_Impl( bool bModal
)
449 if ( !pImpl
->bRunningMacro
!= !bModal
)
451 pImpl
->bRunningMacro
= bModal
;
452 Broadcast( SfxHint( SfxHintId::ModeChanged
) );
457 void SfxObjectShell::SetModalMode_Impl( bool bModal
)
459 // Broadcast only if modified, or otherwise it will possibly go into
461 if ( pImpl
->bModalMode
== bModal
)
465 sal_uInt16
&rDocModalCount
= SfxGetpApp()->Get_Impl()->nDocModalMode
;
472 pImpl
->bModalMode
= bModal
;
473 Broadcast( SfxHint( SfxHintId::ModeChanged
) );
476 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
478 bool SfxObjectShell::SwitchToShared( bool bShared
, bool bSave
)
482 if ( bShared
!= IsDocShared() )
484 OUString aOrigURL
= GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
486 if ( aOrigURL
.isEmpty() && bSave
)
488 // this is a new document, let it be stored before switching to the shared mode;
489 // the storing should be done without shared flag, since it is possible that the
490 // target location does not allow to create sharing control file;
491 // the shared flag will be set later after creation of sharing control file
492 SfxViewFrame
* pViewFrame
= SfxViewFrame::GetFirst( this );
496 // TODO/LATER: currently the application guards against the reentrance problem
497 const SfxPoolItemHolder
aItem(pViewFrame
->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC
: SID_SAVEASDOC
));
498 const SfxBoolItem
* pResult(dynamic_cast<const SfxBoolItem
*>(aItem
.getItem()));
499 bResult
= ( pResult
&& pResult
->GetValue() );
501 aOrigURL
= GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
505 bool bOldValue
= HasSharedXMLFlagSet();
506 SetSharedXMLFlag( bShared
);
508 bool bRemoveEntryOnError
= false;
509 if ( bResult
&& bShared
)
513 ::svt::ShareControlFile
aControlFile( aOrigURL
);
514 aControlFile
.InsertOwnEntry();
515 bRemoveEntryOnError
= true;
517 catch( uno::Exception
& )
523 if ( bResult
&& bSave
)
525 SfxViewFrame
* pViewFrame
= SfxViewFrame::GetFirst( this );
529 // TODO/LATER: currently the application guards against the reentrance problem
530 SetModified(); // the modified flag has to be set to let the document be stored with the shared flag
533 // Do *not* use dispatch mechanism in this place - we don't want others (extensions etc.) to intercept this.
534 pImpl
->pBaseModel
->store();
546 // TODO/LATER: Is it possible that the following calls fail?
549 pImpl
->m_aSharedFileURL
= aOrigURL
;
550 GetMedium()->SwitchDocumentToTempFile();
554 const OUString aTempFileURL
= pMedium
->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
555 GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
556 pImpl
->m_aSharedFileURL
.clear();
558 // now remove the temporary file the document was based on
559 ::utl::UCBContentHelper::Kill( aTempFileURL
);
563 // aOrigURL can not be used since it contains an old value
564 ::svt::ShareControlFile
aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
565 aControlFile
.RemoveFile();
567 catch( uno::Exception
& )
574 // the saving has failed!
575 if ( bRemoveEntryOnError
)
579 ::svt::ShareControlFile
aControlFile( aOrigURL
);
580 aControlFile
.RemoveEntry();
582 catch( uno::Exception
& )
586 SetSharedXMLFlag( bOldValue
);
590 bResult
= false; // the second switch to the same mode
599 void SfxObjectShell::FreeSharedFile( const OUString
& aTempFileURL
)
601 SetSharedXMLFlag( false );
603 if ( !IsDocShared() || aTempFileURL
.isEmpty()
604 || ::utl::UCBContentHelper::EqualURLs( aTempFileURL
, GetSharedFileURL() ) )
607 if ( pImpl
->m_bAllowShareControlFileClean
)
611 ::svt::ShareControlFile
aControlFile( GetSharedFileURL() );
612 aControlFile
.RemoveEntry();
614 catch( uno::Exception
& )
619 // the cleaning is forbidden only once
620 pImpl
->m_bAllowShareControlFileClean
= true;
622 // now remove the temporary file the document is based currently on
623 ::utl::UCBContentHelper::Kill( aTempFileURL
);
625 pImpl
->m_aSharedFileURL
.clear();
629 void SfxObjectShell::DoNotCleanShareControlFile()
631 pImpl
->m_bAllowShareControlFileClean
= false;
635 void SfxObjectShell::SetSharedXMLFlag( bool bFlag
) const
637 pImpl
->m_bSharedXMLFlag
= bFlag
;
641 bool SfxObjectShell::HasSharedXMLFlagSet() const
643 return pImpl
->m_bSharedXMLFlag
;
648 bool SfxObjectShell::IsDocShared() const
650 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
651 return ( !pImpl
->m_aSharedFileURL
.isEmpty() );
658 OUString
SfxObjectShell::GetSharedFileURL() const
660 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
661 return pImpl
->m_aSharedFileURL
;
667 Size
SfxObjectShell::GetFirstPageSize() const
669 return GetVisArea(ASPECT_THUMBNAIL
).GetSize();
673 IndexBitSet
& SfxObjectShell::GetNoSet_Impl()
675 return pImpl
->aBitSet
;
679 // changes the title of the document
681 void SfxObjectShell::SetTitle
683 const OUString
& rTitle
// the new Document Title
688 With this method, the title of the document can be set.
689 This corresponds initially to the full file name. A setting of the
690 title does not affect the file name, but it will be shown in the
691 Caption-Bars of the MDI-window.
697 if ( ( ( HasName() && pImpl
->aTitle
== rTitle
)
698 || ( !HasName() && GetTitle() == rTitle
) )
702 SfxApplication
*pSfxApp
= SfxGetpApp();
704 // If possible release the unnamed number.
705 if ( pImpl
->bIsNamedVisible
&& USHRT_MAX
!= pImpl
->nVisualDocumentNumber
)
707 pSfxApp
->ReleaseIndex(pImpl
->nVisualDocumentNumber
);
708 pImpl
->bIsNamedVisible
= false;
712 pImpl
->aTitle
= rTitle
;
717 SfxShell::SetName( GetTitle(SFX_TITLE_APINAME
) );
718 Broadcast( SfxHint(SfxHintId::TitleChanged
) );
724 OUString
SfxObjectShell::GetTitle( sal_uInt16 nMaxLength
) const
728 Returns the title or logical file name of the document, depending on the
731 If the file name with path is used, the Name shortened by replacing one or
732 more directory names with "...", URLs are currently always returned
737 SfxMedium
*pMed
= GetMedium();
742 if ( SFX_TITLE_DETECT
== nMaxLength
&& pImpl
->aTitle
.isEmpty() )
744 static bool bRecur
= false;
746 return "-not available-";
753 const SfxStringItem
* pNameItem
= pMed
->GetItemSet().GetItem(SID_DOCINFO_TITLE
, false);
755 aTitle
= pNameItem
->GetValue();
758 if ( aTitle
.isEmpty() )
759 aTitle
= GetTitle( SFX_TITLE_FILENAME
);
765 if (SFX_TITLE_APINAME
== nMaxLength
)
768 // Picklist/Caption is mapped
769 if ( pMed
&& ( nMaxLength
== SFX_TITLE_CAPTION
|| nMaxLength
== SFX_TITLE_PICKLIST
) )
771 // If a specific title was given at open:
772 // important for URLs: use INetProtocol::File for which the set title is not
773 // considered. (See below, analysis of aTitleMap_Impl)
774 const SfxStringItem
* pNameItem
= pMed
->GetItemSet().GetItem(SID_DOCINFO_TITLE
, false);
776 return pNameItem
->GetValue();
780 DBG_ASSERT( !HasName() || pMed
, "HasName() but no Medium?!?" );
781 if ( !HasName() || !pMed
)
783 // Title already set?
784 if ( !pImpl
->aTitle
.isEmpty() )
785 return pImpl
->aTitle
;
787 // must it be numbered?
788 const OUString
aNoName(SfxResId(STR_NONAME
));
789 if (pImpl
->bIsNamedVisible
)
792 return aNoName
+ " " + OUString::number(pImpl
->nVisualDocumentNumber
);
795 // Document called "Untitled" for the time being
800 const INetURLObject
aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
801 if ( nMaxLength
> SFX_TITLE_CAPTION
&& nMaxLength
<= SFX_TITLE_HISTORY
)
804 if (aURL
.GetProtocol() == INetProtocol::File
)
808 nMaxLength
= aTitleMap_Impl
[nMaxLength
-SFX_TITLE_CAPTION
][nRemote
];
812 if ( aURL
.GetProtocol() == INetProtocol::File
)
814 if ( nMaxLength
== SFX_TITLE_FULLNAME
)
815 return aURL
.HasMark() ? INetURLObject( aURL
.GetURLNoMark() ).PathToFileName() : aURL
.PathToFileName();
816 if ( nMaxLength
== SFX_TITLE_FILENAME
)
817 return aURL
.getName(INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
);
818 if ( pImpl
->aTitle
.isEmpty() )
819 pImpl
->aTitle
= aURL
.getBase( INetURLObject::LAST_SEGMENT
,
820 true, INetURLObject::DecodeMechanism::WithCharset
);
824 if ( nMaxLength
>= SFX_TITLE_MAXLEN
)
826 const OUString
aComplete( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
827 if( aComplete
.getLength() > nMaxLength
)
828 return OUString::Concat("...") + aComplete
.subView( aComplete
.getLength() - nMaxLength
+ 3, nMaxLength
- 3 );
831 if ( nMaxLength
== SFX_TITLE_FILENAME
)
833 const OUString aName
= INetURLObject::decode( aURL
.GetBase(), INetURLObject::DecodeMechanism::WithCharset
);
834 return aName
.isEmpty() ? aURL
.GetURLNoPass() : aName
;
836 if ( nMaxLength
== SFX_TITLE_FULLNAME
)
837 return aURL
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
);
839 // Generate Title from file name if possible
840 if ( pImpl
->aTitle
.isEmpty() )
841 pImpl
->aTitle
= aURL
.GetBase();
843 // workaround for the case when the name can not be retrieved from URL by INetURLObject
844 if ( pImpl
->aTitle
.isEmpty() )
845 pImpl
->aTitle
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::WithCharset
);
849 return pImpl
->aTitle
;
853 void SfxObjectShell::InvalidateName()
857 Returns the title of the new document, DocInfo-Title or
858 File name. Is required for loading from template or SaveAs.
862 pImpl
->aTitle
.clear();
863 SetName( GetTitle( SFX_TITLE_APINAME
) );
865 Broadcast( SfxHint(SfxHintId::TitleChanged
) );
869 void SfxObjectShell::SetNamedVisibility_Impl()
871 if ( !pImpl
->bIsNamedVisible
)
873 pImpl
->bIsNamedVisible
= true;
874 if ( !HasName() && USHRT_MAX
== pImpl
->nVisualDocumentNumber
&& pImpl
->aTitle
.isEmpty() )
876 pImpl
->nVisualDocumentNumber
= SfxGetpApp()->GetFreeIndex();
877 Broadcast( SfxHint(SfxHintId::TitleChanged
) );
881 SetName( GetTitle(SFX_TITLE_APINAME
) );
884 void SfxObjectShell::SetNoName()
887 GetModel()->attachResource( OUString(), GetModel()->getArgs() );
891 SfxProgress
* SfxObjectShell::GetProgress() const
893 return pImpl
->pProgress
;
897 void SfxObjectShell::SetProgress_Impl
899 SfxProgress
*pProgress
/* to started <SfxProgress> or 0,
900 if the progress is to be reset */
905 Internal method to set or reset the Progress modes for
910 DBG_ASSERT( ( !pImpl
->pProgress
&& pProgress
) ||
911 ( pImpl
->pProgress
&& !pProgress
),
912 "Progress activation/deactivation mismatch" );
913 pImpl
->pProgress
= pProgress
;
917 void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame
const * pFrame
)
919 SfxApplication
* pSfxApp
= SfxGetpApp();
920 if ( pSfxApp
->IsDowning() || IsLoading() || !pFrame
|| pFrame
->GetFrame().IsClosing_Impl() )
923 const SfxBoolItem
* pHiddenItem
= pMedium
->GetItemSet().GetItem(SID_HIDDEN
, false);
924 if ( !pHiddenItem
|| !pHiddenItem
->GetValue() )
926 SfxEventHintId nId
= pImpl
->nEventId
;
927 pImpl
->nEventId
= SfxEventHintId::NONE
;
928 if ( nId
== SfxEventHintId::OpenDoc
)
929 pSfxApp
->NotifyEvent(SfxViewEventHint( nId
, GlobalEventConfig::GetEventName(GlobalEventId::OPENDOC
), this, pFrame
->GetFrame().GetController() ), false);
930 else if (nId
== SfxEventHintId::CreateDoc
)
931 pSfxApp
->NotifyEvent(SfxViewEventHint( nId
, GlobalEventConfig::GetEventName(GlobalEventId::CREATEDOC
), this, pFrame
->GetFrame().GetController() ), false);
936 void SfxObjectShell::SetActivateEvent_Impl(SfxEventHintId nId
)
938 pImpl
->nEventId
= nId
;
941 bool SfxObjectShell::IsAutoLoadLocked() const
943 /* Returns whether an Autoload is allowed to be executed. Before the
944 surrounding FrameSet of the AutoLoad is also taken into account as well.
948 return !IsReadOnly();
952 void SfxObjectShell::BreakMacroSign_Impl( bool bBreakMacroSign
)
954 pImpl
->m_bMacroSignBroken
= bBreakMacroSign
;
958 void SfxObjectShell::CheckSecurityOnLoading_Impl()
960 // make sure LO evaluates the macro signatures, so it can be preserved
961 GetScriptingSignatureState();
963 uno::Reference
< task::XInteractionHandler
> xInteraction
;
965 xInteraction
= GetMedium()->GetInteractionHandler();
967 // check if there is a broken signature...
968 CheckForBrokenDocSignatures_Impl();
970 CheckEncryption_Impl( xInteraction
);
972 // check macro security
973 const bool bHasValidContentSignature
= HasValidSignatures();
974 const bool bHasMacros
= pImpl
->aMacroMode
.hasMacros();
975 pImpl
->aMacroMode
.checkMacrosOnLoading( xInteraction
, bHasValidContentSignature
, bHasMacros
);
976 pImpl
->m_bHadCheckedMacrosOnLoad
= bHasMacros
;
979 bool SfxObjectShell::GetHadCheckedMacrosOnLoad() const
981 return pImpl
->m_bHadCheckedMacrosOnLoad
;
984 bool SfxObjectShell::AllowedLinkProtocolFromDocument(const OUString
& rUrl
, SfxObjectShell
* pObjShell
, weld::Window
* pDialogParent
)
986 if (!INetURLObject(rUrl
).IsExoticProtocol())
988 // Default to ignoring exotic protocols
992 // If the document had macros when loaded then follow the allowed macro-mode
993 if (pObjShell
->GetHadCheckedMacrosOnLoad())
994 bAllow
= pObjShell
->AdjustMacroMode();
995 else // otherwise ask the user, defaulting to cancel
997 //Reuse URITools::onOpenURI warning string
998 std::unique_ptr
<weld::MessageDialog
> xQueryBox(Application::CreateMessageDialog(pDialogParent
,
999 VclMessageType::Warning
, VclButtonsType::YesNo
,
1000 SfxResId(STR_DANGEROUS_TO_OPEN
)));
1001 xQueryBox
->set_primary_text(xQueryBox
->get_primary_text().replaceFirst("$(ARG1)",
1002 INetURLObject::decode(rUrl
, INetURLObject::DecodeMechanism::Unambiguous
)));
1003 xQueryBox
->set_default_response(RET_NO
);
1004 bAllow
= xQueryBox
->run() == RET_YES
;
1007 SAL_WARN_IF(!bAllow
, "sfx.appl", "SfxObjectShell::AllowedLinkProtocolFromDocument ignoring: " << rUrl
);
1011 void SfxObjectShell::CheckEncryption_Impl( const uno::Reference
< task::XInteractionHandler
>& xHandler
)
1014 bool bIsEncrypted
= false;
1015 bool bHasNonEncrypted
= false;
1019 uno::Reference
< beans::XPropertySet
> xPropSet( GetStorage(), uno::UNO_QUERY_THROW
);
1020 xPropSet
->getPropertyValue("Version") >>= aVersion
;
1021 xPropSet
->getPropertyValue("HasEncryptedEntries") >>= bIsEncrypted
;
1022 xPropSet
->getPropertyValue("HasNonEncryptedEntries") >>= bHasNonEncrypted
;
1024 catch( uno::Exception
& )
1028 if ( aVersion
.compareTo( ODFVER_012_TEXT
) < 0 )
1031 // this is ODF1.2 or later
1032 if ( !(bIsEncrypted
&& bHasNonEncrypted
) )
1035 if ( !pImpl
->m_bIncomplEncrWarnShown
)
1037 // this is an encrypted document with nonencrypted streams inside, show the warning
1038 css::task::ErrorCodeRequest aErrorCode
;
1039 aErrorCode
.ErrCode
= sal_uInt32(ERRCODE_SFX_INCOMPLETE_ENCRYPTION
);
1041 SfxMedium::CallApproveHandler( xHandler
, uno::Any( aErrorCode
), false );
1042 pImpl
->m_bIncomplEncrWarnShown
= true;
1045 // broken signatures imply no macro execution at all
1046 pImpl
->aMacroMode
.disallowMacroExecution();
1050 void SfxObjectShell::CheckForBrokenDocSignatures_Impl()
1052 SignatureState nSignatureState
= GetDocumentSignatureState();
1053 bool bSignatureBroken
= ( nSignatureState
== SignatureState::BROKEN
);
1054 if ( !bSignatureBroken
)
1057 // broken signatures imply no macro execution at all
1058 pImpl
->aMacroMode
.disallowMacroExecution();
1062 void SfxObjectShell::SetAutoLoad(
1063 const INetURLObject
& rUrl
, sal_uInt32 nTime
, bool bReload
)
1065 pImpl
->pReloadTimer
.reset();
1068 pImpl
->pReloadTimer
.reset(new AutoReloadTimer_Impl(
1069 rUrl
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
),
1071 pImpl
->pReloadTimer
->Start();
1075 void SfxObjectShell::SetLoading(SfxLoadedFlags nFlags
)
1077 pImpl
->nLoadedFlags
= nFlags
;
1080 bool SfxObjectShell::IsLoadingFinished() const
1082 return ( pImpl
->nLoadedFlags
== SfxLoadedFlags::ALL
);
1085 void SfxObjectShell::InitOwnModel_Impl()
1087 if ( pImpl
->bModelInitialized
)
1090 const SfxStringItem
* pSalvageItem
= pMedium
->GetItemSet().GetItem(SID_DOC_SALVAGE
, false);
1093 pImpl
->aTempName
= pMedium
->GetPhysicalName();
1094 pMedium
->GetItemSet().ClearItem( SID_DOC_SALVAGE
);
1095 pMedium
->GetItemSet().ClearItem( SID_FILE_NAME
);
1096 pMedium
->GetItemSet().Put( SfxStringItem( SID_FILE_NAME
, pMedium
->GetOrigURL() ) );
1100 pMedium
->GetItemSet().ClearItem( SID_PROGRESS_STATUSBAR_CONTROL
);
1101 pMedium
->GetItemSet().ClearItem( SID_DOCUMENT
);
1104 pMedium
->GetItemSet().ClearItem( SID_REFERER
);
1105 uno::Reference
< frame::XModel
> xModel
= GetModel();
1108 SfxItemSet
& rSet
= GetMedium()->GetItemSet();
1109 if ( !GetMedium()->IsReadOnly() )
1110 rSet
.ClearItem( SID_INPUTSTREAM
);
1111 uno::Sequence
< beans::PropertyValue
> aArgs
;
1112 TransformItems( SID_OPENDOC
, rSet
, aArgs
);
1113 xModel
->attachResource( GetMedium()->GetOrigURL(), aArgs
);
1114 impl_addToModelCollection(xModel
);
1117 pImpl
->bModelInitialized
= true;
1120 void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags
)
1122 bool bSetModifiedTRUE
= false;
1123 const SfxStringItem
* pSalvageItem
= pMedium
->GetItemSet().GetItem(SID_DOC_SALVAGE
, false);
1124 if( ( nFlags
& SfxLoadedFlags::MAINDOCUMENT
) && !(pImpl
->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
)
1125 && !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::MAINDOCUMENT
))
1127 pImpl
->nFlagsInProgress
|= SfxLoadedFlags::MAINDOCUMENT
;
1128 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())->SetAttributes();
1130 if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().hasElements() ) && !IsModifyPasswordEntered() )
1135 bSetModifiedTRUE
= true;
1137 if ( !IsEnableSetModified() )
1138 EnableSetModified();
1140 if( !bSetModifiedTRUE
&& IsEnableSetModified() )
1141 SetModified( false );
1143 CheckSecurityOnLoading_Impl();
1145 bHasName
= true; // the document is loaded, so the name should already available
1146 GetTitle( SFX_TITLE_DETECT
);
1147 InitOwnModel_Impl();
1149 if (IsLoadReadonly())
1151 OUString aFilterName
;
1152 if (const SfxStringItem
* pFilterNameItem
=
1153 pMedium
->GetItemSet().GetItem(SID_FILTER_NAME
, false))
1154 aFilterName
= pFilterNameItem
->GetValue();
1157 if (const SfxStringItem
* pFileNameItem
=
1158 pMedium
->GetItemSet().GetItem(SID_FILE_NAME
, false))
1160 const INetURLObject
aURL(pFileNameItem
->GetValue());
1161 aFileName
= aURL
.getBase(INetURLObject::LAST_SEGMENT
, true,
1162 INetURLObject::DecodeMechanism::WithCharset
);
1165 bool bSilent
= false;
1166 if (const SfxBoolItem
* pSilentNameItem
=
1167 pMedium
->GetItemSet().GetItem(SID_SILENT
, false))
1168 bSilent
= pSilentNameItem
->GetValue();
1170 if (!bSilent
&& aFilterName
.indexOf("Excel") != -1)
1172 Reference
<task::XInteractionHandler
> xHandler(pMedium
->GetInteractionHandler());
1175 beans::NamedValue aLoadReadOnlyRequest
;
1176 aLoadReadOnlyRequest
.Name
= "LoadReadOnlyRequest";
1177 aLoadReadOnlyRequest
.Value
<<= aFileName
;
1179 Any
aRequest(aLoadReadOnlyRequest
);
1180 rtl::Reference
<ucbhelper::SimpleInteractionRequest
> xRequest
1181 = new ucbhelper::SimpleInteractionRequest(aRequest
,
1182 ContinuationFlags::Approve
|
1183 ContinuationFlags::Disapprove
);
1185 xHandler
->handle(xRequest
);
1187 if (xRequest
->getResponse() == ContinuationFlags::Disapprove
)
1189 SetSecurityOptOpenReadOnly(false);
1190 pMedium
->GetItemSet().Put(SfxBoolItem(SID_DOC_READONLY
, false));
1196 pImpl
->nFlagsInProgress
&= ~SfxLoadedFlags::MAINDOCUMENT
;
1199 if( ( nFlags
& SfxLoadedFlags::IMAGES
) && !(pImpl
->nLoadedFlags
& SfxLoadedFlags::IMAGES
)
1200 && !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::IMAGES
))
1202 pImpl
->nFlagsInProgress
|= SfxLoadedFlags::IMAGES
;
1203 uno::Reference
<document::XDocumentProperties
> xDocProps(
1204 getDocProperties());
1205 const OUString
url(xDocProps
->getAutoloadURL());
1206 sal_Int32
delay(xDocProps
->getAutoloadSecs());
1207 SetAutoLoad( INetURLObject(url
), delay
* 1000,
1208 (delay
> 0) || !url
.isEmpty() );
1209 if( !bSetModifiedTRUE
&& IsEnableSetModified() )
1210 SetModified( false );
1211 Invalidate( SID_SAVEASDOC
);
1212 pImpl
->nFlagsInProgress
&= ~SfxLoadedFlags::IMAGES
;
1215 pImpl
->nLoadedFlags
|= nFlags
;
1217 if ( pImpl
->nFlagsInProgress
!= SfxLoadedFlags::NONE
)
1220 // in case of reentrance calls the first called FinishedLoading() call on the stack
1221 // should do the notification, in result the notification is done when all the FinishedLoading() calls are finished
1223 if ( bSetModifiedTRUE
)
1226 SetModified( false );
1228 if ( (pImpl
->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
) && (pImpl
->nLoadedFlags
& SfxLoadedFlags::IMAGES
) )
1230 const SfxBoolItem
* pTemplateItem
= pMedium
->GetItemSet().GetItem(SID_TEMPLATE
, false);
1231 bool bTemplate
= pTemplateItem
&& pTemplateItem
->GetValue();
1233 // closing the streams on loading should be under control of SFX!
1234 DBG_ASSERT( pMedium
->IsOpen(), "Don't close the medium when loading documents!" );
1238 TemplateDisconnectionAfterLoad();
1242 // if a readonly medium has storage then it's stream is already based on temporary file
1243 if( !(pMedium
->GetOpenMode() & StreamMode::WRITE
) && !pMedium
->HasStorage_Impl() )
1244 // don't lock file opened read only
1245 pMedium
->CloseInStream();
1249 SetInitialized_Impl( false );
1251 // Title is not available until loading has finished
1252 Broadcast( SfxHint( SfxHintId::TitleChanged
) );
1253 if ( pImpl
->nEventId
!= SfxEventHintId::NONE
)
1254 PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
1257 void SfxObjectShell::TemplateDisconnectionAfterLoad()
1259 // document is created from a template
1260 //TODO/LATER: should the templates always be XML docs!
1262 SfxMedium
* pTmpMedium
= pMedium
;
1266 const OUString
aName( pTmpMedium
->GetName() );
1267 const SfxStringItem
* pTemplNamItem
= pTmpMedium
->GetItemSet().GetItem(SID_TEMPLATE_NAME
, false);
1268 OUString aTemplateName
;
1269 if ( pTemplNamItem
)
1270 aTemplateName
= pTemplNamItem
->GetValue();
1273 // !TODO/LATER: what's this?!
1274 // Interactive ( DClick, Contextmenu ) no long name is included
1275 aTemplateName
= getDocProperties()->getTitle();
1276 if ( aTemplateName
.isEmpty() )
1278 INetURLObject
aURL( aName
);
1279 aURL
.CutExtension();
1280 aTemplateName
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
);
1284 // set medium to noname
1285 pTmpMedium
->SetName( OUString(), true );
1286 pTmpMedium
->Init_Impl();
1292 if( IsPackageStorageFormat_Impl( *pTmpMedium
) )
1294 // untitled document must be based on temporary storage
1295 // the medium should not dispose the storage in this case
1296 uno::Reference
< embed::XStorage
> xTmpStor
= ::comphelper::OStorageHelper::GetTemporaryStorage();
1297 GetStorage()->copyToStorage( xTmpStor
);
1299 // the medium should disconnect from the original location
1300 // the storage should not be disposed since the document is still
1301 // based on it, but in DoSaveCompleted it will be disposed
1302 pTmpMedium
->CanDisposeStorage_Impl( false );
1303 pTmpMedium
->Close();
1305 // setting the new storage the medium will be based on
1306 pTmpMedium
->SetStorage_Impl( xTmpStor
);
1309 bool ok
= DoSaveCompleted( pTmpMedium
);
1310 assert(pMedium
!= nullptr);
1313 const SfxStringItem
* pSalvageItem
= pMedium
->GetItemSet().GetItem(SID_DOC_SALVAGE
, false);
1314 bool bSalvage
= pSalvageItem
!= nullptr;
1318 // some further initializations for templates
1319 SetTemplate_Impl( aName
, aTemplateName
, this );
1322 // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
1323 pTmpMedium
->CanDisposeStorage_Impl( false );
1327 SetError(ERRCODE_IO_GENERAL
);
1332 // some further initializations for templates
1333 SetTemplate_Impl( aName
, aTemplateName
, this );
1334 pTmpMedium
->CreateTempFile();
1337 // templates are never readonly
1338 pTmpMedium
->GetItemSet().ClearItem( SID_DOC_READONLY
);
1339 pTmpMedium
->SetOpenMode( SFX_STREAM_READWRITE
, true );
1341 // notifications about possible changes in readonly state and document info
1342 Broadcast( SfxHint(SfxHintId::ModeChanged
) );
1344 // created untitled document can't be modified
1345 SetModified( false );
1349 bool SfxObjectShell::IsLoading() const
1352 Has FinishedLoading been called?
1355 return !( pImpl
->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
);
1359 void SfxObjectShell::CancelTransfers()
1362 Here can Transfers get canceled, which were not registered
1363 by RegisterTransfer.
1366 if( ( pImpl
->nLoadedFlags
& SfxLoadedFlags::ALL
) != SfxLoadedFlags::ALL
)
1368 pImpl
->bIsAbortingImport
= true;
1375 AutoReloadTimer_Impl::AutoReloadTimer_Impl(
1376 OUString _aURL
, sal_uInt32 nTime
, SfxObjectShell
* pSh
)
1377 : Timer("sfx2 AutoReloadTimer_Impl"), aUrl(std::move( _aURL
)), pObjSh( pSh
)
1379 SetTimeout( nTime
);
1383 void AutoReloadTimer_Impl::Invoke()
1385 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( pObjSh
);
1389 // Not possible/meaningful at the moment?
1390 if ( !pObjSh
->CanReload_Impl() || pObjSh
->IsAutoLoadLocked() || Application::IsUICaptured() )
1397 SfxAllItemSet
aSet( SfxGetpApp()->GetPool() );
1398 aSet
.Put( SfxBoolItem( SID_AUTOLOAD
, true ) );
1399 if ( !aUrl
.isEmpty() )
1400 aSet
.Put( SfxStringItem( SID_FILE_NAME
, aUrl
) );
1401 if (pObjSh
->HasName()) {
1403 SfxStringItem(SID_REFERER
, pObjSh
->GetMedium()->GetName()));
1405 SfxRequest
aReq( SID_RELOAD
, SfxCallMode::SLOT
, aSet
);
1406 // this will delete this
1407 pObjSh
->Get_Impl()->pReloadTimer
.reset();
1408 pFrame
->ExecReload_Impl( aReq
);
1412 // this will delete this
1413 pObjSh
->Get_Impl()->pReloadTimer
.reset();
1416 SfxModule
* SfxObjectShell::GetModule() const
1418 return GetFactory().GetModule();
1421 ErrCode
SfxObjectShell::CallBasic( std::u16string_view rMacro
,
1422 std::u16string_view rBasic
, SbxArray
* pArgs
,
1425 SfxApplication
* pApp
= SfxGetpApp();
1426 if( pApp
->GetName() != rBasic
)
1428 if ( !AdjustMacroMode() )
1429 return ERRCODE_IO_ACCESSDENIED
;
1432 BasicManager
*pMgr
= GetBasicManager();
1433 if( pApp
->GetName() == rBasic
)
1434 pMgr
= SfxApplication::GetBasicManager();
1435 ErrCode nRet
= SfxApplication::CallBasic( OUString(rMacro
), pMgr
, pArgs
, pRet
);
1439 bool SfxObjectShell::isScriptAccessAllowed( const Reference
< XInterface
>& _rxScriptContext
)
1443 Reference
< XEmbeddedScripts
> xScripts( _rxScriptContext
, UNO_QUERY
);
1444 if ( !xScripts
.is() )
1446 Reference
< XScriptInvocationContext
> xContext( _rxScriptContext
, UNO_QUERY_THROW
);
1447 xScripts
.set( xContext
->getScriptContainer(), UNO_SET_THROW
);
1450 return xScripts
->getAllowMacroExecution();
1452 catch( const Exception
& )
1454 DBG_UNHANDLED_EXCEPTION("sfx.doc");
1459 // don't allow LibreLogo to be used with our mouseover/etc dom-alike events
1460 bool SfxObjectShell::UnTrustedScript(const OUString
& rScriptURL
)
1462 if (!rScriptURL
.startsWith("vnd.sun.star.script:"))
1465 // ensure URL Escape Codes are decoded
1466 css::uno::Reference
<css::uri::XUriReference
> uri(
1467 css::uri::UriReferenceFactory::create(comphelper::getProcessComponentContext())->parse(rScriptURL
));
1468 css::uno::Reference
<css::uri::XVndSunStarScriptUrl
> sfUri(uri
, css::uno::UNO_QUERY
);
1473 // pyuno encodes path separator as |
1474 OUString sScript
= sfUri
->getName().replace('|', '/');
1476 // check if any path portion matches LibreLogo and ban it if it does
1477 sal_Int32 nIndex
= 0;
1480 OUString aToken
= sScript
.getToken(0, '/', nIndex
);
1481 if (aToken
.startsWithIgnoreAsciiCase("LibreLogo") || aToken
.indexOf('~') != -1)
1486 while (nIndex
>= 0);
1491 ErrCode
SfxObjectShell::CallXScript( const Reference
< XInterface
>& _rxScriptContext
, const OUString
& _rScriptURL
,
1492 const Sequence
< Any
>& aParams
, Any
& aRet
, Sequence
< sal_Int16
>& aOutParamIndex
, Sequence
< Any
>& aOutParam
, bool bRaiseError
, const css::uno::Any
* pCaller
)
1494 SAL_INFO("sfx", "in CallXScript" );
1495 ErrCode nErr
= ERRCODE_NONE
;
1497 bool bCaughtException
= false;
1501 if (!isScriptAccessAllowed(_rxScriptContext
))
1502 return ERRCODE_IO_ACCESSDENIED
;
1504 if ( UnTrustedScript(_rScriptURL
) )
1505 return ERRCODE_IO_ACCESSDENIED
;
1507 // obtain/create a script provider
1508 Reference
< provider::XScriptProvider
> xScriptProvider
;
1509 Reference
< provider::XScriptProviderSupplier
> xSPS( _rxScriptContext
, UNO_QUERY
);
1511 xScriptProvider
.set( xSPS
->getScriptProvider() );
1513 if ( !xScriptProvider
.is() )
1515 Reference
< provider::XScriptProviderFactory
> xScriptProviderFactory
=
1516 provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
1517 xScriptProvider
.set( xScriptProviderFactory
->createScriptProvider( Any( _rxScriptContext
) ), UNO_SET_THROW
);
1520 // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
1521 ::framework::DocumentUndoGuard
aUndoGuard( _rxScriptContext
);
1523 // obtain the script, and execute it
1524 Reference
< provider::XScript
> xScript( xScriptProvider
->getScript( _rScriptURL
), UNO_SET_THROW
);
1525 if ( pCaller
&& pCaller
->hasValue() )
1527 Reference
< beans::XPropertySet
> xProps( xScript
, uno::UNO_QUERY
);
1530 Sequence
< uno::Any
> aArgs
{ *pCaller
};
1531 xProps
->setPropertyValue("Caller", uno::Any( aArgs
) );
1534 aRet
= xScript
->invoke( aParams
, aOutParamIndex
, aOutParam
);
1536 catch ( const uno::Exception
& )
1538 aException
= ::cppu::getCaughtException();
1539 bCaughtException
= true;
1540 nErr
= ERRCODE_BASIC_INTERNAL_ERROR
;
1543 if ( bCaughtException
&& bRaiseError
)
1545 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
1546 pFact
->ShowAsyncScriptErrorDialog( nullptr, aException
);
1549 SAL_INFO("sfx", "leaving CallXScript" );
1553 // perhaps rename to CallScript once we get rid of the existing CallScript
1554 // and Call, CallBasic, CallStarBasic methods
1555 ErrCode
SfxObjectShell::CallXScript( const OUString
& rScriptURL
,
1556 const css::uno::Sequence
< css::uno::Any
>& aParams
,
1557 css::uno::Any
& aRet
,
1558 css::uno::Sequence
< sal_Int16
>& aOutParamIndex
,
1559 css::uno::Sequence
< css::uno::Any
>& aOutParam
,
1561 const css::uno::Any
* pCaller
)
1563 return CallXScript( GetModel(), rScriptURL
, aParams
, aRet
, aOutParamIndex
, aOutParam
, bRaiseError
, pCaller
);
1566 void SfxHeaderAttributes_Impl::SetAttributes()
1570 for( bool bCont
= xIter
->GetFirst( aPair
); bCont
;
1571 bCont
= xIter
->GetNext( aPair
) )
1572 SetAttribute( aPair
);
1575 void SfxHeaderAttributes_Impl::SetAttribute( const SvKeyValue
& rKV
)
1577 const OUString
& aValue
= rKV
.GetValue();
1578 if( rKV
.GetKey().equalsIgnoreAsciiCase("refresh") && !rKV
.GetValue().isEmpty() )
1580 sal_Int32 nIdx
{ 0 };
1581 const sal_Int32 nTime
{ o3tl::toInt32(o3tl::getToken(aValue
, 0, ';', nIdx
)) };
1582 const OUString aURL
{ comphelper::string::strip(o3tl::getToken(aValue
, 0, ';', nIdx
), ' ') };
1583 uno::Reference
<document::XDocumentProperties
> xDocProps(
1584 pDoc
->getDocProperties());
1585 if( aURL
.startsWithIgnoreAsciiCase( "url=" ) )
1588 xDocProps
->setAutoloadURL(
1589 rtl::Uri::convertRelToAbs(pDoc
->GetMedium()->GetName(), aURL
.copy( 4 )) );
1590 } catch (rtl::MalformedUriException
&) {
1591 TOOLS_WARN_EXCEPTION("sfx", "");
1596 xDocProps
->setAutoloadSecs( nTime
);
1598 catch (lang::IllegalArgumentException
&)
1603 else if( rKV
.GetKey().equalsIgnoreAsciiCase( "expires" ) )
1605 DateTime
aDateTime( DateTime::EMPTY
);
1606 if( INetMIMEMessage::ParseDateField( rKV
.GetValue(), aDateTime
) )
1608 aDateTime
.ConvertToLocalTime();
1609 pDoc
->GetMedium()->SetExpired_Impl( aDateTime
);
1613 pDoc
->GetMedium()->SetExpired_Impl( Date( 1, 1, 1970 ) );
1618 void SfxHeaderAttributes_Impl::Append( const SvKeyValue
& rKV
)
1620 xIter
->Append( rKV
);
1621 if( bAlert
) SetAttribute( rKV
);
1624 SvKeyValueIterator
* SfxObjectShell::GetHeaderAttributes()
1626 if( !pImpl
->xHeaderAttributes
.is() )
1628 DBG_ASSERT( pMedium
, "No Medium" );
1629 pImpl
->xHeaderAttributes
= new SfxHeaderAttributes_Impl( this );
1631 return pImpl
->xHeaderAttributes
.get();
1634 void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
1636 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())
1637 ->ClearForSourceView();
1641 void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
1643 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())
1647 bool SfxObjectShell::IsPreview() const
1652 bool bPreview
= false;
1653 const SfxStringItem
* pFlags
= pMedium
->GetItemSet().GetItem(SID_OPTIONS
, false);
1656 // Distributed values among individual items
1657 const OUString aFileFlags
= pFlags
->GetValue().toAsciiUpperCase();
1658 if ( -1 != aFileFlags
.indexOf( 'B' ) )
1664 const SfxBoolItem
* pItem
= pMedium
->GetItemSet().GetItem(SID_PREVIEW
, false);
1666 bPreview
= pItem
->GetValue();
1672 void SfxObjectShell::SetWaitCursor( bool bSet
) const
1674 for( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this ); pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, this ) )
1677 pFrame
->GetFrame().GetWindow().EnterWait();
1679 pFrame
->GetFrame().GetWindow().LeaveWait();
1683 OUString
SfxObjectShell::GetAPIName() const
1685 INetURLObject
aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
1686 OUString
aName( aURL
.GetBase() );
1687 if( aName
.isEmpty() )
1688 aName
= aURL
.GetURLNoPass();
1689 if ( aName
.isEmpty() )
1690 aName
= GetTitle( SFX_TITLE_DETECT
);
1694 void SfxObjectShell::Invalidate( sal_uInt16 nId
)
1696 for( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this ); pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, this ) )
1697 Invalidate_Impl( pFrame
->GetBindings(), nId
);
1700 bool SfxObjectShell::AdjustMacroMode()
1702 uno::Reference
< task::XInteractionHandler
> xInteraction
;
1704 xInteraction
= pMedium
->GetInteractionHandler();
1706 CheckForBrokenDocSignatures_Impl();
1708 CheckEncryption_Impl( xInteraction
);
1710 return pImpl
->aMacroMode
.adjustMacroMode( xInteraction
);
1713 css::uno::Reference
<css::awt::XWindow
> SfxObjectShell::GetDialogParent( SfxMedium
const * pLoadingMedium
)
1715 css::uno::Reference
<css::awt::XWindow
> xWindow
;
1716 SfxItemSet
& rSet
= pLoadingMedium
? pLoadingMedium
->GetItemSet() : GetMedium()->GetItemSet();
1717 const SfxUnoFrameItem
* pUnoItem
= rSet
.GetItem(SID_FILLFRAME
, false);
1720 const uno::Reference
< frame::XFrame
>& xFrame( pUnoItem
->GetFrame() );
1721 xWindow
= xFrame
->getContainerWindow();
1726 SfxFrame
* pFrame
= nullptr;
1727 const SfxFrameItem
* pFrameItem
= rSet
.GetItem
<SfxFrameItem
>(SID_DOCFRAME
, false);
1728 if( pFrameItem
&& pFrameItem
->GetFrame() )
1729 // get target frame from ItemSet
1730 pFrame
= pFrameItem
->GetFrame();
1733 // try the current frame
1734 SfxViewFrame
* pView
= SfxViewFrame::Current();
1735 if ( !pView
|| pView
->GetObjectShell() != this )
1736 // get any visible frame
1737 pView
= SfxViewFrame::GetFirst(this);
1739 pFrame
= &pView
->GetFrame();
1744 // get topmost window
1745 xWindow
= pFrame
->GetFrameInterface()->getContainerWindow();
1751 // this frame may be invisible, show it if it is allowed
1752 const SfxBoolItem
* pHiddenItem
= rSet
.GetItem(SID_HIDDEN
, false);
1753 if ( !pHiddenItem
|| !pHiddenItem
->GetValue() )
1755 xWindow
->setVisible(true);
1756 css::uno::Reference
<css::awt::XTopWindow
> xTopWindow(xWindow
, uno::UNO_QUERY
);
1757 SAL_WARN_IF(!xTopWindow
, "sfx.appl", "XTopWindow not available from XWindow");
1759 xTopWindow
->toFront();
1766 void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode
)
1768 eCreateMode
= nMode
;
1771 bool SfxObjectShell::IsInPlaceActive() const
1773 if ( eCreateMode
!= SfxObjectCreateMode::EMBEDDED
)
1776 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
1777 return pFrame
&& pFrame
->GetFrame().IsInPlace();
1780 bool SfxObjectShell::IsUIActive() const
1782 if ( eCreateMode
!= SfxObjectCreateMode::EMBEDDED
)
1785 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
1786 return pFrame
&& pFrame
->GetFrame().IsInPlace() && pFrame
->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
1789 bool SfxObjectShell::UseInteractionToHandleError(
1790 const uno::Reference
< task::XInteractionHandler
>& xHandler
,
1791 const ErrCodeMsg
& nError
)
1793 bool bResult
= false;
1795 if ( xHandler
.is() )
1799 uno::Any aInteraction
;
1800 rtl::Reference
<::comphelper::OInteractionAbort
> pAbort
= new ::comphelper::OInteractionAbort();
1801 rtl::Reference
<::comphelper::OInteractionApprove
> pApprove
= new ::comphelper::OInteractionApprove();
1802 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > lContinuations
{
1806 task::ErrorCodeRequest2
aErrorCode(OUString(), uno::Reference
<XInterface
>(),
1807 sal_Int32(sal_uInt32(nError
.GetCode())), nError
.GetArg1(), nError
.GetArg2(),
1808 static_cast<sal_Int16
>(nError
.GetDialogMask()));
1809 aInteraction
<<= aErrorCode
;
1810 xHandler
->handle(::framework::InteractionRequest::CreateRequest (aInteraction
,lContinuations
));
1811 bResult
= pAbort
->wasSelected();
1813 catch( uno::Exception
& )
1820 sal_Int16
SfxObjectShell_Impl::getCurrentMacroExecMode() const
1822 sal_Int16
nImposedExecMode( MacroExecMode::NEVER_EXECUTE
);
1824 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1825 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1828 const SfxUInt16Item
* pMacroModeItem
= pMedium
->GetItemSet().GetItem(SID_MACROEXECMODE
, false);
1829 if ( pMacroModeItem
)
1830 nImposedExecMode
= pMacroModeItem
->GetValue();
1832 return nImposedExecMode
;
1835 void SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode
)
1837 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1838 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1841 pMedium
->GetItemSet().Put( SfxUInt16Item( SID_MACROEXECMODE
, nMacroMode
) );
1845 OUString
SfxObjectShell_Impl::getDocumentLocation() const
1849 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1850 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
1853 sLocation
= pMedium
->GetName();
1854 if ( sLocation
.isEmpty() )
1856 // for documents made from a template: get the name of the template
1857 sLocation
= rDocShell
.getDocProperties()->getTemplateURL();
1860 // tdf#128006 take document base url as location
1861 if (sLocation
.isEmpty())
1862 sLocation
= rDocShell
.getDocumentBaseURL();
1868 bool SfxObjectShell_Impl::documentStorageHasMacros() const
1870 return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage
);
1873 bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const
1875 return rDocShell
.GetMacroCallsSeenWhileLoading();
1878 Reference
< XEmbeddedScripts
> SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
1880 return Reference
< XEmbeddedScripts
>( rDocShell
.GetModel(), UNO_QUERY
);
1883 SignatureState
SfxObjectShell_Impl::getScriptingSignatureState()
1885 SignatureState
nSignatureState( rDocShell
.GetScriptingSignatureState() );
1887 if ( nSignatureState
!= SignatureState::NOSIGNATURES
&& m_bMacroSignBroken
)
1889 // if there is a macro signature it must be handled as broken
1890 nSignatureState
= SignatureState::BROKEN
;
1893 return nSignatureState
;
1896 bool SfxObjectShell_Impl::hasTrustedScriptingSignature(
1897 const css::uno::Reference
<css::task::XInteractionHandler
>& _rxInteraction
)
1899 bool bResult
= false;
1903 if ( nScriptingSignatureState
== SignatureState::UNKNOWN
1904 || nScriptingSignatureState
== SignatureState::OK
1905 || nScriptingSignatureState
== SignatureState::NOTVALIDATED
)
1910 uno::Reference
< beans::XPropertySet
> xPropSet( rDocShell
.GetStorage(), uno::UNO_QUERY_THROW
);
1911 xPropSet
->getPropertyValue("Version") >>= aVersion
;
1913 catch( uno::Exception
& )
1917 uno::Reference
< security::XDocumentDigitalSignatures
> xSigner( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion
) );
1919 const uno::Sequence
< security::DocumentSignatureInformation
> aInfo
= rDocShell
.GetDocumentSignatureInformation( true, xSigner
);
1921 if ( aInfo
.hasElements() )
1923 if ( nScriptingSignatureState
== SignatureState::UNKNOWN
)
1924 nScriptingSignatureState
= DocumentSignatures::getSignatureState(aInfo
);
1926 if ( nScriptingSignatureState
== SignatureState::OK
1927 || nScriptingSignatureState
== SignatureState::NOTVALIDATED
)
1929 bResult
= std::any_of(aInfo
.begin(), aInfo
.end(),
1930 [&xSigner
](const security::DocumentSignatureInformation
& rInfo
) {
1931 return xSigner
->isAuthorTrusted( rInfo
.Signer
); });
1933 if (!bResult
&& _rxInteraction
)
1935 task::DocumentMacroConfirmationRequest aRequest
;
1936 aRequest
.DocumentURL
= getDocumentLocation();
1937 aRequest
.DocumentStorage
= rDocShell
.GetMedium()->GetScriptingStorageToSign_Impl();
1938 aRequest
.DocumentSignatureInformation
= aInfo
;
1939 aRequest
.DocumentVersion
= aVersion
;
1940 aRequest
.Classification
= task::InteractionClassification_QUERY
;
1941 bResult
= SfxMedium::CallApproveHandler( _rxInteraction
, uno::Any( aRequest
), true );
1947 catch( uno::Exception
& )
1953 bool SfxObjectShell::IsContinueImportOnFilterExceptions()
1955 if (mbContinueImportOnFilterExceptions
== undefined
)
1959 mbContinueImportOnFilterExceptions
= no
;
1963 if (utl::MediaDescriptor
desc(pMedium
->GetArgs());
1964 !desc
.getUnpackedValueOrDefault("RepairAllowed", true))
1966 mbContinueImportOnFilterExceptions
= no
;
1970 if (const SfxBoolItem
* pRepairItem
1971 = pMedium
->GetItemSet().GetItem(SID_REPAIRPACKAGE
, false);
1972 pRepairItem
&& pRepairItem
->GetValue())
1974 mbContinueImportOnFilterExceptions
= yes
;
1978 auto xInteractionHandler
= pMedium
->GetInteractionHandler();
1979 if (!xInteractionHandler
)
1981 mbContinueImportOnFilterExceptions
= no
;
1985 const OUString
aDocName(pMedium
->GetURLObject().getName(
1986 INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
));
1987 RequestPackageReparation
aRequest(aDocName
);
1988 xInteractionHandler
->handle(aRequest
.GetRequest());
1989 if (aRequest
.isApproved())
1991 mbContinueImportOnFilterExceptions
= yes
;
1992 // lok: we want to overwrite file in jail, so don't use template flag
1993 bool bIsLOK
= comphelper::LibreOfficeKit::isActive();
1995 pMedium
->GetItemSet().Put(SfxBoolItem(SID_REPAIRPACKAGE
, true));
1996 pMedium
->GetItemSet().Put(SfxBoolItem(SID_TEMPLATE
, !bIsLOK
));
1997 pMedium
->GetItemSet().Put(SfxStringItem(SID_DOCINFO_TITLE
, aDocName
));
2000 mbContinueImportOnFilterExceptions
= no
;
2002 return mbContinueImportOnFilterExceptions
== yes
;
2005 bool SfxObjectShell::isEditDocLocked() const
2007 Reference
<XModel3
> xModel
= GetModel();
2010 if (!officecfg::Office::Common::Misc::AllowEditReadonlyDocs::get())
2012 return comphelper::NamedValueCollection::getOrDefault(xModel
->getArgs2( { "LockEditDoc" } ), u
"LockEditDoc", false);
2015 bool SfxObjectShell::isContentExtractionLocked() const
2017 Reference
<XModel3
> xModel
= GetModel();
2020 return comphelper::NamedValueCollection::getOrDefault(xModel
->getArgs2( { "LockContentExtraction" } ), u
"LockContentExtraction", false);
2023 bool SfxObjectShell::isExportLocked() const
2025 Reference
<XModel3
> xModel
= GetModel();
2028 return comphelper::NamedValueCollection::getOrDefault(xModel
->getArgs2( { "LockExport" } ), u
"LockExport", false);
2031 bool SfxObjectShell::isPrintLocked() const
2033 Reference
<XModel3
> xModel
= GetModel();
2036 return comphelper::NamedValueCollection::getOrDefault(xModel
->getArgs2( { "LockPrint" } ), u
"LockPrint", false);
2039 bool SfxObjectShell::isSaveLocked() const
2041 Reference
<XModel3
> xModel
= GetModel();
2044 return comphelper::NamedValueCollection::getOrDefault(xModel
->getArgs2( { "LockSave" } ), u
"LockSave", false);
2047 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */