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 <tools/diagnose_ex.h>
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>
31 #include <com/sun/star/awt/XTopWindow.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/container/XChild.hpp>
34 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
35 #include <com/sun/star/document/XDocumentProperties.hpp>
36 #include <com/sun/star/document/MacroExecMode.hpp>
37 #include <com/sun/star/document/XScriptInvocationContext.hpp>
38 #include <com/sun/star/embed/EmbedStates.hpp>
39 #include <com/sun/star/embed/XEmbeddedObject.hpp>
40 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
41 #include <com/sun/star/script/provider/XScript.hpp>
42 #include <com/sun/star/script/provider/XScriptProvider.hpp>
43 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
44 #include <com/sun/star/uri/UriReferenceFactory.hpp>
45 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
46 #include <com/sun/star/util/XModifiable.hpp>
48 #include <toolkit/helper/vclunohelper.hxx>
50 #include <com/sun/star/uno/Reference.h>
51 #include <com/sun/star/uno/Any.h>
52 #include <com/sun/star/task/ErrorCodeRequest.hpp>
54 #include <comphelper/processfactory.hxx>
55 #include <comphelper/string.hxx>
57 #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
58 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
59 #include <com/sun/star/task/InteractionClassification.hpp>
60 #include <com/sun/star/task/XInteractionHandler.hpp>
61 #include <com/sun/star/frame/XModel.hpp>
63 #include <basic/basmgr.hxx>
64 #include <basic/sberrors.hxx>
65 #include <vcl/weld.hxx>
66 #include <basic/sbx.hxx>
67 #include <svtools/sfxecode.hxx>
69 #include <unotools/ucbhelper.hxx>
70 #include <tools/urlobj.hxx>
71 #include <svl/sharecontrolfile.hxx>
72 #include <rtl/uri.hxx>
73 #include <vcl/svapp.hxx>
74 #include <framework/interaction.hxx>
75 #include <framework/documentundoguard.hxx>
76 #include <comphelper/interaction.hxx>
77 #include <comphelper/storagehelper.hxx>
78 #include <comphelper/documentconstants.hxx>
79 #include <comphelper/namedvaluecollection.hxx>
80 #include <officecfg/Office/Common.hxx>
82 #include <sfx2/signaturestate.hxx>
83 #include <sfx2/app.hxx>
84 #include <appdata.hxx>
85 #include <sfx2/request.hxx>
86 #include <sfx2/bindings.hxx>
87 #include <sfx2/sfxresid.hxx>
88 #include <sfx2/docfile.hxx>
89 #include <sfx2/objsh.hxx>
90 #include <objshimp.hxx>
91 #include <sfx2/event.hxx>
92 #include <sfx2/viewfrm.hxx>
93 #include <sfx2/sfxuno.hxx>
94 #include <sfx2/module.hxx>
95 #include <sfx2/docfac.hxx>
96 #include <sfx2/sfxsids.hrc>
97 #include <sfx2/strings.hrc>
98 #include <workwin.hxx>
99 #include <sfx2/sfxdlg.hxx>
100 #include <sfx2/infobar.hxx>
101 #include <openflag.hxx>
102 #include "objstor.hxx"
103 #include <appopen.hxx>
107 using namespace ::com::sun::star
;
108 using namespace ::com::sun::star::uno
;
109 using namespace ::com::sun::star::ucb
;
110 using namespace ::com::sun::star::document
;
111 using namespace ::com::sun::star::frame
;
112 using namespace ::com::sun::star::script
;
113 using namespace ::com::sun::star::script::provider
;
114 using namespace ::com::sun::star::container
;
116 // class SfxHeaderAttributes_Impl ----------------------------------------
120 class SfxHeaderAttributes_Impl
: public SvKeyValueIterator
123 SfxObjectShell
* pDoc
;
124 SvKeyValueIteratorRef xIter
;
128 explicit SfxHeaderAttributes_Impl( SfxObjectShell
* pSh
) :
130 xIter( pSh
->GetMedium()->GetHeaderAttributes_Impl() ),
133 virtual bool GetFirst( SvKeyValue
& rKV
) override
{ return xIter
->GetFirst( rKV
); }
134 virtual bool GetNext( SvKeyValue
& rKV
) override
{ return xIter
->GetNext( rKV
); }
135 virtual void Append( const SvKeyValue
& rKV
) override
;
137 void ClearForSourceView() { xIter
= new SvKeyValueIterator
; bAlert
= false; }
138 void SetAttributes();
139 void SetAttribute( const SvKeyValue
& rKV
);
144 sal_uInt16
const aTitleMap_Impl
[3][2] =
147 /* SFX_TITLE_CAPTION */ { SFX_TITLE_FILENAME
, SFX_TITLE_TITLE
},
148 /* SFX_TITLE_PICKLIST */ { 32, SFX_TITLE_FULLNAME
},
149 /* SFX_TITLE_HISTORY */ { 32, SFX_TITLE_FULLNAME
}
153 bool SfxObjectShell::IsAbortingImport() const
155 return pImpl
->bIsAbortingImport
;
159 uno::Reference
<document::XDocumentProperties
>
160 SfxObjectShell::getDocProperties() const
162 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
163 GetModel(), uno::UNO_QUERY_THROW
);
164 uno::Reference
<document::XDocumentProperties
> xDocProps(
165 xDPS
->getDocumentProperties());
166 DBG_ASSERT(xDocProps
.is(),
167 "SfxObjectShell: model has no DocumentProperties");
172 void SfxObjectShell::DoFlushDocInfo()
177 // Note: the only thing that calls this is the modification event handler
178 // that is installed at the XDocumentProperties
179 void SfxObjectShell::FlushDocInfo()
185 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
186 DoFlushDocInfo(); // call template method
187 const OUString
url(xDocProps
->getAutoloadURL());
188 sal_Int32
delay(xDocProps
->getAutoloadSecs());
189 SetAutoLoad( INetURLObject(url
), delay
* 1000,
190 (delay
> 0) || !url
.isEmpty() );
193 void SfxObjectShell::AppendInfoBarWhenReady(const OUString
& sId
, const OUString
& sPrimaryMessage
,
194 const OUString
& sSecondaryMessage
,
195 InfobarType aInfobarType
, bool bShowCloseButton
)
197 InfobarData aInfobarData
;
198 aInfobarData
.msId
= sId
;
199 aInfobarData
.msPrimaryMessage
= sPrimaryMessage
;
200 aInfobarData
.msSecondaryMessage
= sSecondaryMessage
;
201 aInfobarData
.maInfobarType
= aInfobarType
;
202 aInfobarData
.mbShowCloseButton
= bShowCloseButton
;
203 Get_Impl()->m_aPendingInfobars
.emplace_back(aInfobarData
);
206 std::vector
<InfobarData
>& SfxObjectShell::getPendingInfobars()
208 return Get_Impl()->m_aPendingInfobars
;
211 void SfxObjectShell::SetError(ErrCode lErr
)
213 if (pImpl
->lErr
==ERRCODE_NONE
)
219 ErrCode
SfxObjectShell::GetError() const
221 return GetErrorCode().IgnoreWarning();
224 ErrCode
SfxObjectShell::GetErrorCode() const
226 ErrCode lError
=pImpl
->lErr
;
227 if(!lError
&& GetMedium())
228 lError
=GetMedium()->GetErrorCode();
232 void SfxObjectShell::ResetError()
234 pImpl
->lErr
=ERRCODE_NONE
;
235 SfxMedium
* pMed
= GetMedium();
240 void SfxObjectShell::EnableSetModified( bool bEnable
)
242 SAL_INFO_IF( bEnable
== pImpl
->m_bEnableSetModified
, "sfx", "SFX_PERSIST: EnableSetModified 2x called with the same value" );
243 pImpl
->m_bEnableSetModified
= bEnable
;
247 bool SfxObjectShell::IsEnableSetModified() const
249 return pImpl
->m_bEnableSetModified
&& !IsReadOnly();
253 bool SfxObjectShell::IsModified() const
255 if ( pImpl
->m_bIsModified
)
258 if ( !pImpl
->m_xDocStorage
.is() || IsReadOnly() )
260 // if the document still has no storage and is not set to be modified explicitly it is not modified
261 // a readonly document is also not modified
266 if (pImpl
->mxObjectContainer
)
268 const uno::Sequence
< OUString
> aNames
= GetEmbeddedObjectContainer().GetObjectNames();
269 for ( const auto& rName
: aNames
)
271 uno::Reference
< embed::XEmbeddedObject
> xObj
= GetEmbeddedObjectContainer().GetEmbeddedObject( rName
);
272 OSL_ENSURE( xObj
.is(), "An empty entry in the embedded objects list!" );
277 sal_Int32 nState
= xObj
->getCurrentState();
278 if ( nState
!= embed::EmbedStates::LOADED
)
280 uno::Reference
< util::XModifiable
> xModifiable( xObj
->getComponent(), uno::UNO_QUERY
);
281 if ( xModifiable
.is() && xModifiable
->isModified() )
285 catch( uno::Exception
& )
295 void SfxObjectShell::SetModified( bool bModifiedP
)
297 SAL_INFO_IF( !bModifiedP
&& !IsEnableSetModified(), "sfx",
298 "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False" );
300 if( !IsEnableSetModified() )
303 if( pImpl
->m_bIsModified
!= bModifiedP
)
305 pImpl
->m_bIsModified
= bModifiedP
;
311 void SfxObjectShell::ModifyChanged()
313 if ( pImpl
->bClosing
)
314 // SetModified dispose of the models!
318 SfxViewFrame
* pViewFrame
= SfxViewFrame::Current();
320 pViewFrame
->GetBindings().Invalidate( SID_SAVEDOCS
);
322 Invalidate( SID_SIGNATURE
);
323 Invalidate( SID_MACRO_SIGNATURE
);
324 Broadcast( SfxHint( SfxHintId::TitleChanged
) ); // xmlsec05, signed state might change in title...
326 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::ModifyChanged
, GlobalEventConfig::GetEventName(GlobalEventId::MODIFYCHANGED
), this ) );
330 bool SfxObjectShell::IsReadOnlyUI() const
334 Returns sal_True if the document for the UI is treated as r/o. This is
335 regardless of the actual r/o, which can be checked with <IsReadOnly()>.
339 return pImpl
->bReadOnlyUI
;
343 bool SfxObjectShell::IsReadOnlyMedium() const
347 Returns sal_True when the medium is r/o, for instance when opened as r/o.
353 return pMedium
->IsReadOnly();
356 bool SfxObjectShell::IsOriginallyReadOnlyMedium() const
358 return pMedium
== nullptr || pMedium
->IsOriginallyReadOnly();
361 bool SfxObjectShell::IsOriginallyLoadedReadOnlyMedium() const
363 return pMedium
!= nullptr && pMedium
->IsOriginallyLoadedReadOnly();
367 void SfxObjectShell::SetReadOnlyUI( bool bReadOnly
)
371 Turns the document in a r/o and r/w state respectively without reloading
372 it and without changing the open mode of the medium.
376 if ( bReadOnly
!= pImpl
->bReadOnlyUI
)
378 pImpl
->bReadOnlyUI
= bReadOnly
;
379 Broadcast( SfxHint(SfxHintId::ModeChanged
) );
384 void SfxObjectShell::SetReadOnly()
386 // Let the document be completely readonly, means that the
387 // medium open mode is adjusted accordingly, and the write lock
388 // on the file is removed.
390 if ( !pMedium
|| IsReadOnlyMedium() )
393 bool bWasROUI
= IsReadOnly();
395 pMedium
->UnlockFile( false );
397 // the storage-based mediums are already based on the temporary file
398 // so UnlockFile has already closed the locking stream
399 if ( !pMedium
->HasStorage_Impl() && IsLoadingFinished() )
400 pMedium
->CloseInStream();
402 pMedium
->SetOpenMode( SFX_STREAM_READONLY
, true );
403 pMedium
->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, true ) );
406 Broadcast( SfxHint(SfxHintId::ModeChanged
) );
410 bool SfxObjectShell::IsReadOnly() const
412 return pImpl
->bReadOnlyUI
|| pMedium
== nullptr;
416 bool SfxObjectShell::IsInModalMode() const
418 return pImpl
->bModalMode
|| pImpl
->bRunningMacro
;
421 bool SfxObjectShell::AcceptStateUpdate() const
423 return !IsInModalMode();
427 void SfxObjectShell::SetMacroMode_Impl( bool bModal
)
429 if ( !pImpl
->bRunningMacro
!= !bModal
)
431 pImpl
->bRunningMacro
= bModal
;
432 Broadcast( SfxHint( SfxHintId::ModeChanged
) );
437 void SfxObjectShell::SetModalMode_Impl( bool bModal
)
439 // Broadcast only if modified, or otherwise it will possibly go into
441 if ( pImpl
->bModalMode
== bModal
)
445 sal_uInt16
&rDocModalCount
= SfxGetpApp()->Get_Impl()->nDocModalMode
;
452 pImpl
->bModalMode
= bModal
;
453 Broadcast( SfxHint( SfxHintId::ModeChanged
) );
456 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
458 bool SfxObjectShell::SwitchToShared( bool bShared
, bool bSave
)
462 if ( bShared
!= IsDocShared() )
464 OUString aOrigURL
= GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
466 if ( aOrigURL
.isEmpty() && bSave
)
468 // this is a new document, let it be stored before switching to the shared mode;
469 // the storing should be done without shared flag, since it is possible that the
470 // target location does not allow to create sharing control file;
471 // the shared flag will be set later after creation of sharing control file
472 SfxViewFrame
* pViewFrame
= SfxViewFrame::GetFirst( this );
476 // TODO/LATER: currently the application guards against the reentrance problem
477 const SfxPoolItem
* pItem
= pViewFrame
->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC
: SID_SAVEASDOC
);
478 const SfxBoolItem
* pResult
= dynamic_cast<const SfxBoolItem
*>( pItem
);
479 bResult
= ( pResult
&& pResult
->GetValue() );
481 aOrigURL
= GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
485 bool bOldValue
= HasSharedXMLFlagSet();
486 SetSharedXMLFlag( bShared
);
488 bool bRemoveEntryOnError
= false;
489 if ( bResult
&& bShared
)
493 ::svt::ShareControlFile
aControlFile( aOrigURL
);
494 aControlFile
.InsertOwnEntry();
495 bRemoveEntryOnError
= true;
497 catch( uno::Exception
& )
503 if ( bResult
&& bSave
)
505 SfxViewFrame
* pViewFrame
= SfxViewFrame::GetFirst( this );
509 // TODO/LATER: currently the application guards against the reentrance problem
510 SetModified(); // the modified flag has to be set to let the document be stored with the shared flag
511 const SfxPoolItem
* pItem
= pViewFrame
->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC
: SID_SAVEASDOC
);
512 const SfxBoolItem
* pResult
= dynamic_cast<const SfxBoolItem
*>( pItem
);
513 bResult
= ( pResult
&& pResult
->GetValue() );
519 // TODO/LATER: Is it possible that the following calls fail?
522 pImpl
->m_aSharedFileURL
= aOrigURL
;
523 GetMedium()->SwitchDocumentToTempFile();
527 const OUString aTempFileURL
= pMedium
->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
528 GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
529 pImpl
->m_aSharedFileURL
.clear();
531 // now remove the temporary file the document was based on
532 ::utl::UCBContentHelper::Kill( aTempFileURL
);
536 // aOrigURL can not be used since it contains an old value
537 ::svt::ShareControlFile
aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
538 aControlFile
.RemoveFile();
540 catch( uno::Exception
& )
547 // the saving has failed!
548 if ( bRemoveEntryOnError
)
552 ::svt::ShareControlFile
aControlFile( aOrigURL
);
553 aControlFile
.RemoveEntry();
555 catch( uno::Exception
& )
559 SetSharedXMLFlag( bOldValue
);
563 bResult
= false; // the second switch to the same mode
572 void SfxObjectShell::FreeSharedFile( const OUString
& aTempFileURL
)
574 SetSharedXMLFlag( false );
576 if ( !IsDocShared() || aTempFileURL
.isEmpty()
577 || ::utl::UCBContentHelper::EqualURLs( aTempFileURL
, GetSharedFileURL() ) )
580 if ( pImpl
->m_bAllowShareControlFileClean
)
584 ::svt::ShareControlFile
aControlFile( GetSharedFileURL() );
585 aControlFile
.RemoveEntry();
587 catch( uno::Exception
& )
592 // the cleaning is forbidden only once
593 pImpl
->m_bAllowShareControlFileClean
= true;
595 // now remove the temporary file the document is based currently on
596 ::utl::UCBContentHelper::Kill( aTempFileURL
);
598 pImpl
->m_aSharedFileURL
.clear();
602 void SfxObjectShell::DoNotCleanShareControlFile()
604 pImpl
->m_bAllowShareControlFileClean
= false;
608 void SfxObjectShell::SetSharedXMLFlag( bool bFlag
) const
610 pImpl
->m_bSharedXMLFlag
= bFlag
;
614 bool SfxObjectShell::HasSharedXMLFlagSet() const
616 return pImpl
->m_bSharedXMLFlag
;
621 bool SfxObjectShell::IsDocShared() const
623 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
624 return ( !pImpl
->m_aSharedFileURL
.isEmpty() );
631 OUString
SfxObjectShell::GetSharedFileURL() const
633 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
634 return pImpl
->m_aSharedFileURL
;
640 Size
SfxObjectShell::GetFirstPageSize() const
642 return GetVisArea(ASPECT_THUMBNAIL
).GetSize();
646 IndexBitSet
& SfxObjectShell::GetNoSet_Impl()
648 return pImpl
->aBitSet
;
652 // changes the title of the document
654 void SfxObjectShell::SetTitle
656 const OUString
& rTitle
// the new Document Title
661 With this method, the title of the document can be set.
662 This corresponds initially to the full file name. A setting of the
663 title does not affect the file name, but it will be shown in the
664 Caption-Bars of the MDI-window.
670 if ( ( ( HasName() && pImpl
->aTitle
== rTitle
)
671 || ( !HasName() && GetTitle() == rTitle
) )
675 SfxApplication
*pSfxApp
= SfxGetpApp();
677 // If possible release the unnamed number.
678 if ( pImpl
->bIsNamedVisible
&& USHRT_MAX
!= pImpl
->nVisualDocumentNumber
)
680 pSfxApp
->ReleaseIndex(pImpl
->nVisualDocumentNumber
);
681 pImpl
->bIsNamedVisible
= false;
685 pImpl
->aTitle
= rTitle
;
690 SfxShell::SetName( GetTitle(SFX_TITLE_APINAME
) );
691 Broadcast( SfxHint(SfxHintId::TitleChanged
) );
697 OUString
SfxObjectShell::GetTitle( sal_uInt16 nMaxLength
) const
701 Returns the title or logical file name of the document, depending on the
704 If the file name with path is used, the Name shortened by replacing one or
705 more directory names with "...", URLs are currently always returned
710 SfxMedium
*pMed
= GetMedium();
715 if ( SFX_TITLE_DETECT
== nMaxLength
&& pImpl
->aTitle
.isEmpty() )
717 static bool bRecur
= false;
719 return "-not available-";
726 const SfxStringItem
* pNameItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_DOCINFO_TITLE
, false);
728 aTitle
= pNameItem
->GetValue();
731 if ( aTitle
.isEmpty() )
732 aTitle
= GetTitle( SFX_TITLE_FILENAME
);
738 if (SFX_TITLE_APINAME
== nMaxLength
)
741 // Picklist/Caption is mapped
742 if ( pMed
&& ( nMaxLength
== SFX_TITLE_CAPTION
|| nMaxLength
== SFX_TITLE_PICKLIST
) )
744 // If a specific title was given at open:
745 // important for URLs: use INetProtocol::File for which the set title is not
746 // considered. (See below, analysis of aTitleMap_Impl)
747 const SfxStringItem
* pNameItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_DOCINFO_TITLE
, false);
749 return pNameItem
->GetValue();
753 DBG_ASSERT( !HasName() || pMed
, "HasName() but no Medium?!?" );
754 if ( !HasName() || !pMed
)
756 // Title already set?
757 if ( !pImpl
->aTitle
.isEmpty() )
758 return pImpl
->aTitle
;
760 // must it be numbered?
761 const OUString
aNoName(SfxResId(STR_NONAME
));
762 if (pImpl
->bIsNamedVisible
)
765 return aNoName
+ " " + OUString::number(pImpl
->nVisualDocumentNumber
);
768 // Document called "Untitled" for the time being
773 const INetURLObject
aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
774 if ( nMaxLength
> SFX_TITLE_CAPTION
&& nMaxLength
<= SFX_TITLE_HISTORY
)
777 if (aURL
.GetProtocol() == INetProtocol::File
)
781 nMaxLength
= aTitleMap_Impl
[nMaxLength
-SFX_TITLE_CAPTION
][nRemote
];
785 if ( aURL
.GetProtocol() == INetProtocol::File
)
787 if ( nMaxLength
== SFX_TITLE_FULLNAME
)
788 return aURL
.HasMark() ? INetURLObject( aURL
.GetURLNoMark() ).PathToFileName() : aURL
.PathToFileName();
789 if ( nMaxLength
== SFX_TITLE_FILENAME
)
790 return aURL
.getName(INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
);
791 if ( pImpl
->aTitle
.isEmpty() )
792 pImpl
->aTitle
= aURL
.getBase( INetURLObject::LAST_SEGMENT
,
793 true, INetURLObject::DecodeMechanism::WithCharset
);
797 if ( nMaxLength
>= SFX_TITLE_MAXLEN
)
799 const OUString
aComplete( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
800 if( aComplete
.getLength() > nMaxLength
)
801 return OUString::Concat("...") + aComplete
.subView( aComplete
.getLength() - nMaxLength
+ 3, nMaxLength
- 3 );
804 if ( nMaxLength
== SFX_TITLE_FILENAME
)
806 const OUString aName
= INetURLObject::decode( aURL
.GetBase(), INetURLObject::DecodeMechanism::WithCharset
);
807 return aName
.isEmpty() ? aURL
.GetURLNoPass() : aName
;
809 if ( nMaxLength
== SFX_TITLE_FULLNAME
)
810 return aURL
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
);
812 // Generate Title from file name if possible
813 if ( pImpl
->aTitle
.isEmpty() )
814 pImpl
->aTitle
= aURL
.GetBase();
816 // workaround for the case when the name can not be retrieved from URL by INetURLObject
817 if ( pImpl
->aTitle
.isEmpty() )
818 pImpl
->aTitle
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::WithCharset
);
822 return pImpl
->aTitle
;
826 void SfxObjectShell::InvalidateName()
830 Returns the title of the new document, DocInfo-Title or
831 File name. Is required for loading from template or SaveAs.
835 pImpl
->aTitle
.clear();
836 SetName( GetTitle( SFX_TITLE_APINAME
) );
838 Broadcast( SfxHint(SfxHintId::TitleChanged
) );
842 void SfxObjectShell::SetNamedVisibility_Impl()
844 if ( !pImpl
->bIsNamedVisible
)
846 pImpl
->bIsNamedVisible
= true;
847 if ( !HasName() && USHRT_MAX
== pImpl
->nVisualDocumentNumber
&& pImpl
->aTitle
.isEmpty() )
849 pImpl
->nVisualDocumentNumber
= SfxGetpApp()->GetFreeIndex();
850 Broadcast( SfxHint(SfxHintId::TitleChanged
) );
854 SetName( GetTitle(SFX_TITLE_APINAME
) );
857 void SfxObjectShell::SetNoName()
860 GetModel()->attachResource( OUString(), GetModel()->getArgs() );
864 SfxProgress
* SfxObjectShell::GetProgress() const
866 return pImpl
->pProgress
;
870 void SfxObjectShell::SetProgress_Impl
872 SfxProgress
*pProgress
/* to started <SfxProgress> or 0,
873 if the progress is to be reset */
878 Internal method to set or reset the Progress modes for
883 DBG_ASSERT( ( !pImpl
->pProgress
&& pProgress
) ||
884 ( pImpl
->pProgress
&& !pProgress
),
885 "Progress activation/deactivation mismatch" );
886 pImpl
->pProgress
= pProgress
;
890 void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame
const * pFrame
)
892 SfxApplication
* pSfxApp
= SfxGetpApp();
893 if ( pSfxApp
->IsDowning() || IsLoading() || !pFrame
|| pFrame
->GetFrame().IsClosing_Impl() )
896 const SfxBoolItem
* pHiddenItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_HIDDEN
, false);
897 if ( !pHiddenItem
|| !pHiddenItem
->GetValue() )
899 SfxEventHintId nId
= pImpl
->nEventId
;
900 pImpl
->nEventId
= SfxEventHintId::NONE
;
901 if ( nId
== SfxEventHintId::OpenDoc
)
902 pSfxApp
->NotifyEvent(SfxViewEventHint( nId
, GlobalEventConfig::GetEventName(GlobalEventId::OPENDOC
), this, pFrame
->GetFrame().GetController() ), false);
903 else if (nId
== SfxEventHintId::CreateDoc
)
904 pSfxApp
->NotifyEvent(SfxViewEventHint( nId
, GlobalEventConfig::GetEventName(GlobalEventId::CREATEDOC
), this, pFrame
->GetFrame().GetController() ), false);
909 void SfxObjectShell::SetActivateEvent_Impl(SfxEventHintId nId
)
911 pImpl
->nEventId
= nId
;
914 bool SfxObjectShell::IsAutoLoadLocked() const
916 /* Returns whether an Autoload is allowed to be executed. Before the
917 surrounding FrameSet of the AutoLoad is also taken into account as well.
921 return !IsReadOnly();
925 void SfxObjectShell::BreakMacroSign_Impl( bool bBreakMacroSign
)
927 pImpl
->m_bMacroSignBroken
= bBreakMacroSign
;
931 void SfxObjectShell::CheckSecurityOnLoading_Impl()
933 // make sure LO evaluates the macro signatures, so it can be preserved
934 GetScriptingSignatureState();
936 uno::Reference
< task::XInteractionHandler
> xInteraction
;
938 xInteraction
= GetMedium()->GetInteractionHandler();
940 // check if there is a broken signature...
941 CheckForBrokenDocSignatures_Impl();
943 CheckEncryption_Impl( xInteraction
);
945 // check macro security
946 const bool bHasValidContentSignature
= HasValidSignatures();
947 pImpl
->aMacroMode
.checkMacrosOnLoading( xInteraction
, bHasValidContentSignature
);
951 void SfxObjectShell::CheckEncryption_Impl( const uno::Reference
< task::XInteractionHandler
>& xHandler
)
954 bool bIsEncrypted
= false;
955 bool bHasNonEncrypted
= false;
959 uno::Reference
< beans::XPropertySet
> xPropSet( GetStorage(), uno::UNO_QUERY_THROW
);
960 xPropSet
->getPropertyValue("Version") >>= aVersion
;
961 xPropSet
->getPropertyValue("HasEncryptedEntries") >>= bIsEncrypted
;
962 xPropSet
->getPropertyValue("HasNonEncryptedEntries") >>= bHasNonEncrypted
;
964 catch( uno::Exception
& )
968 if ( aVersion
.compareTo( ODFVER_012_TEXT
) < 0 )
971 // this is ODF1.2 or later
972 if ( !(bIsEncrypted
&& bHasNonEncrypted
) )
975 if ( !pImpl
->m_bIncomplEncrWarnShown
)
977 // this is an encrypted document with nonencrypted streams inside, show the warning
978 css::task::ErrorCodeRequest aErrorCode
;
979 aErrorCode
.ErrCode
= sal_uInt32(ERRCODE_SFX_INCOMPLETE_ENCRYPTION
);
981 SfxMedium::CallApproveHandler( xHandler
, uno::makeAny( aErrorCode
), false );
982 pImpl
->m_bIncomplEncrWarnShown
= true;
985 // broken signatures imply no macro execution at all
986 pImpl
->aMacroMode
.disallowMacroExecution();
990 void SfxObjectShell::CheckForBrokenDocSignatures_Impl()
992 SignatureState nSignatureState
= GetDocumentSignatureState();
993 bool bSignatureBroken
= ( nSignatureState
== SignatureState::BROKEN
);
994 if ( !bSignatureBroken
)
997 // broken signatures imply no macro execution at all
998 pImpl
->aMacroMode
.disallowMacroExecution();
1002 void SfxObjectShell::SetAutoLoad(
1003 const INetURLObject
& rUrl
, sal_uInt32 nTime
, bool bReload
)
1005 pImpl
->pReloadTimer
.reset();
1008 pImpl
->pReloadTimer
.reset(new AutoReloadTimer_Impl(
1009 rUrl
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
),
1011 pImpl
->pReloadTimer
->Start();
1015 void SfxObjectShell::SetLoading(SfxLoadedFlags nFlags
)
1017 pImpl
->nLoadedFlags
= nFlags
;
1020 bool SfxObjectShell::IsLoadingFinished() const
1022 return ( pImpl
->nLoadedFlags
== SfxLoadedFlags::ALL
);
1025 void SfxObjectShell::InitOwnModel_Impl()
1027 if ( pImpl
->bModelInitialized
)
1030 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_DOC_SALVAGE
, false);
1033 pImpl
->aTempName
= pMedium
->GetPhysicalName();
1034 pMedium
->GetItemSet()->ClearItem( SID_DOC_SALVAGE
);
1035 pMedium
->GetItemSet()->ClearItem( SID_FILE_NAME
);
1036 pMedium
->GetItemSet()->Put( SfxStringItem( SID_FILE_NAME
, pMedium
->GetOrigURL() ) );
1040 pMedium
->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL
);
1041 pMedium
->GetItemSet()->ClearItem( SID_DOCUMENT
);
1044 pMedium
->GetItemSet()->ClearItem( SID_REFERER
);
1045 uno::Reference
< frame::XModel
> xModel
= GetModel();
1048 SfxItemSet
*pSet
= GetMedium()->GetItemSet();
1049 if ( !GetMedium()->IsReadOnly() )
1050 pSet
->ClearItem( SID_INPUTSTREAM
);
1051 uno::Sequence
< beans::PropertyValue
> aArgs
;
1052 TransformItems( SID_OPENDOC
, *pSet
, aArgs
);
1053 xModel
->attachResource( GetMedium()->GetOrigURL(), aArgs
);
1054 impl_addToModelCollection(xModel
);
1057 pImpl
->bModelInitialized
= true;
1060 void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags
)
1062 bool bSetModifiedTRUE
= false;
1063 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_DOC_SALVAGE
, false);
1064 if( ( nFlags
& SfxLoadedFlags::MAINDOCUMENT
) && !(pImpl
->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
)
1065 && !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::MAINDOCUMENT
))
1067 pImpl
->nFlagsInProgress
|= SfxLoadedFlags::MAINDOCUMENT
;
1068 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())->SetAttributes();
1070 if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().hasElements() ) && !IsModifyPasswordEntered() )
1075 bSetModifiedTRUE
= true;
1077 if ( !IsEnableSetModified() )
1078 EnableSetModified();
1080 if( !bSetModifiedTRUE
&& IsEnableSetModified() )
1081 SetModified( false );
1083 CheckSecurityOnLoading_Impl();
1085 bHasName
= true; // the document is loaded, so the name should already available
1086 GetTitle( SFX_TITLE_DETECT
);
1087 InitOwnModel_Impl();
1088 pImpl
->nFlagsInProgress
&= ~SfxLoadedFlags::MAINDOCUMENT
;
1091 if( ( nFlags
& SfxLoadedFlags::IMAGES
) && !(pImpl
->nLoadedFlags
& SfxLoadedFlags::IMAGES
)
1092 && !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::IMAGES
))
1094 pImpl
->nFlagsInProgress
|= SfxLoadedFlags::IMAGES
;
1095 uno::Reference
<document::XDocumentProperties
> xDocProps(
1096 getDocProperties());
1097 const OUString
url(xDocProps
->getAutoloadURL());
1098 sal_Int32
delay(xDocProps
->getAutoloadSecs());
1099 SetAutoLoad( INetURLObject(url
), delay
* 1000,
1100 (delay
> 0) || !url
.isEmpty() );
1101 if( !bSetModifiedTRUE
&& IsEnableSetModified() )
1102 SetModified( false );
1103 Invalidate( SID_SAVEASDOC
);
1104 pImpl
->nFlagsInProgress
&= ~SfxLoadedFlags::IMAGES
;
1107 pImpl
->nLoadedFlags
|= nFlags
;
1109 if ( pImpl
->nFlagsInProgress
!= SfxLoadedFlags::NONE
)
1112 // in case of reentrance calls the first called FinishedLoading() call on the stack
1113 // should do the notification, in result the notification is done when all the FinishedLoading() calls are finished
1115 if ( bSetModifiedTRUE
)
1118 SetModified( false );
1120 if ( (pImpl
->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
) && (pImpl
->nLoadedFlags
& SfxLoadedFlags::IMAGES
) )
1122 const SfxBoolItem
* pTemplateItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_TEMPLATE
, false);
1123 bool bTemplate
= pTemplateItem
&& pTemplateItem
->GetValue();
1125 // closing the streams on loading should be under control of SFX!
1126 DBG_ASSERT( pMedium
->IsOpen(), "Don't close the medium when loading documents!" );
1130 TemplateDisconnectionAfterLoad();
1134 // if a readonly medium has storage then it's stream is already based on temporary file
1135 if( !(pMedium
->GetOpenMode() & StreamMode::WRITE
) && !pMedium
->HasStorage_Impl() )
1136 // don't lock file opened read only
1137 pMedium
->CloseInStream();
1141 SetInitialized_Impl( false );
1143 // Title is not available until loading has finished
1144 Broadcast( SfxHint( SfxHintId::TitleChanged
) );
1145 if ( pImpl
->nEventId
!= SfxEventHintId::NONE
)
1146 PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
1149 void SfxObjectShell::TemplateDisconnectionAfterLoad()
1151 // document is created from a template
1152 //TODO/LATER: should the templates always be XML docs!
1154 SfxMedium
* pTmpMedium
= pMedium
;
1158 const OUString
aName( pTmpMedium
->GetName() );
1159 const SfxStringItem
* pTemplNamItem
= SfxItemSet::GetItem
<SfxStringItem
>(pTmpMedium
->GetItemSet(), SID_TEMPLATE_NAME
, false);
1160 OUString aTemplateName
;
1161 if ( pTemplNamItem
)
1162 aTemplateName
= pTemplNamItem
->GetValue();
1165 // !TODO/LATER: what's this?!
1166 // Interactive ( DClick, Contextmenu ) no long name is included
1167 aTemplateName
= getDocProperties()->getTitle();
1168 if ( aTemplateName
.isEmpty() )
1170 INetURLObject
aURL( aName
);
1171 aURL
.CutExtension();
1172 aTemplateName
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
);
1176 // set medium to noname
1177 pTmpMedium
->SetName( OUString(), true );
1178 pTmpMedium
->Init_Impl();
1184 if( IsPackageStorageFormat_Impl( *pTmpMedium
) )
1186 // untitled document must be based on temporary storage
1187 // the medium should not dispose the storage in this case
1188 uno::Reference
< embed::XStorage
> xTmpStor
= ::comphelper::OStorageHelper::GetTemporaryStorage();
1189 GetStorage()->copyToStorage( xTmpStor
);
1191 // the medium should disconnect from the original location
1192 // the storage should not be disposed since the document is still
1193 // based on it, but in DoSaveCompleted it will be disposed
1194 pTmpMedium
->CanDisposeStorage_Impl( false );
1195 pTmpMedium
->Close();
1197 // setting the new storage the medium will be based on
1198 pTmpMedium
->SetStorage_Impl( xTmpStor
);
1201 bool ok
= DoSaveCompleted( pTmpMedium
);
1202 assert(pMedium
!= nullptr);
1205 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_DOC_SALVAGE
, false);
1206 bool bSalvage
= pSalvageItem
!= nullptr;
1210 // some further initializations for templates
1211 SetTemplate_Impl( aName
, aTemplateName
, this );
1214 // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
1215 pTmpMedium
->CanDisposeStorage_Impl( false );
1219 SetError(ERRCODE_IO_GENERAL
);
1224 // some further initializations for templates
1225 SetTemplate_Impl( aName
, aTemplateName
, this );
1226 pTmpMedium
->CreateTempFile();
1229 // templates are never readonly
1230 pTmpMedium
->GetItemSet()->ClearItem( SID_DOC_READONLY
);
1231 pTmpMedium
->SetOpenMode( SFX_STREAM_READWRITE
, true );
1233 // notifications about possible changes in readonly state and document info
1234 Broadcast( SfxHint(SfxHintId::ModeChanged
) );
1236 // created untitled document can't be modified
1237 SetModified( false );
1241 bool SfxObjectShell::IsLoading() const
1244 Has FinishedLoading been called?
1247 return !( pImpl
->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
);
1251 void SfxObjectShell::CancelTransfers()
1254 Here can Transfers get canceled, which were not registered
1255 by RegisterTransfer.
1258 if( ( pImpl
->nLoadedFlags
& SfxLoadedFlags::ALL
) != SfxLoadedFlags::ALL
)
1260 pImpl
->bIsAbortingImport
= true;
1267 AutoReloadTimer_Impl::AutoReloadTimer_Impl(
1268 const OUString
& rURL
, sal_uInt32 nTime
, SfxObjectShell
* pSh
)
1269 : Timer("sfx2 AutoReloadTimer_Impl"), aUrl( rURL
), pObjSh( pSh
)
1271 SetTimeout( nTime
);
1275 void AutoReloadTimer_Impl::Invoke()
1277 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( pObjSh
);
1281 // Not possible/meaningful at the moment?
1282 if ( !pObjSh
->CanReload_Impl() || pObjSh
->IsAutoLoadLocked() || Application::IsUICaptured() )
1289 SfxAllItemSet
aSet( SfxGetpApp()->GetPool() );
1290 aSet
.Put( SfxBoolItem( SID_AUTOLOAD
, true ) );
1291 if ( !aUrl
.isEmpty() )
1292 aSet
.Put( SfxStringItem( SID_FILE_NAME
, aUrl
) );
1293 if (pObjSh
->HasName()) {
1295 SfxStringItem(SID_REFERER
, pObjSh
->GetMedium()->GetName()));
1297 SfxRequest
aReq( SID_RELOAD
, SfxCallMode::SLOT
, aSet
);
1298 // this will delete this
1299 pObjSh
->Get_Impl()->pReloadTimer
.reset();
1300 pFrame
->ExecReload_Impl( aReq
);
1304 // this will delete this
1305 pObjSh
->Get_Impl()->pReloadTimer
.reset();
1308 SfxModule
* SfxObjectShell::GetModule() const
1310 return GetFactory().GetModule();
1313 ErrCode
SfxObjectShell::CallBasic( std::u16string_view rMacro
,
1314 std::u16string_view rBasic
, SbxArray
* pArgs
,
1317 SfxApplication
* pApp
= SfxGetpApp();
1318 if( pApp
->GetName() != rBasic
)
1320 if ( !AdjustMacroMode() )
1321 return ERRCODE_IO_ACCESSDENIED
;
1324 BasicManager
*pMgr
= GetBasicManager();
1325 if( pApp
->GetName() == rBasic
)
1326 pMgr
= SfxApplication::GetBasicManager();
1327 ErrCode nRet
= SfxApplication::CallBasic( OUString(rMacro
), pMgr
, pArgs
, pRet
);
1331 bool SfxObjectShell::isScriptAccessAllowed( const Reference
< XInterface
>& _rxScriptContext
)
1335 Reference
< XEmbeddedScripts
> xScripts( _rxScriptContext
, UNO_QUERY
);
1336 if ( !xScripts
.is() )
1338 Reference
< XScriptInvocationContext
> xContext( _rxScriptContext
, UNO_QUERY_THROW
);
1339 xScripts
.set( xContext
->getScriptContainer(), UNO_SET_THROW
);
1342 return xScripts
->getAllowMacroExecution();
1344 catch( const Exception
& )
1346 DBG_UNHANDLED_EXCEPTION("sfx.doc");
1351 // don't allow LibreLogo to be used with our mouseover/etc dom-alike events
1352 bool SfxObjectShell::UnTrustedScript(const OUString
& rScriptURL
)
1354 if (!rScriptURL
.startsWith("vnd.sun.star.script:"))
1357 // ensure URL Escape Codes are decoded
1358 css::uno::Reference
<css::uri::XUriReference
> uri(
1359 css::uri::UriReferenceFactory::create(comphelper::getProcessComponentContext())->parse(rScriptURL
));
1360 css::uno::Reference
<css::uri::XVndSunStarScriptUrl
> sfUri(uri
, css::uno::UNO_QUERY
);
1365 // pyuno encodes path separator as |
1366 OUString sScript
= sfUri
->getName().replace('|', '/');
1368 // check if any path portion matches LibreLogo and ban it if it does
1369 sal_Int32 nIndex
= 0;
1372 OUString aToken
= sScript
.getToken(0, '/', nIndex
);
1373 if (aToken
.startsWithIgnoreAsciiCase("LibreLogo") || aToken
.indexOf('~') != -1)
1378 while (nIndex
>= 0);
1383 ErrCode
SfxObjectShell::CallXScript( const Reference
< XInterface
>& _rxScriptContext
, const OUString
& _rScriptURL
,
1384 const Sequence
< Any
>& aParams
, Any
& aRet
, Sequence
< sal_Int16
>& aOutParamIndex
, Sequence
< Any
>& aOutParam
, bool bRaiseError
, const css::uno::Any
* pCaller
)
1386 SAL_INFO("sfx", "in CallXScript" );
1387 ErrCode nErr
= ERRCODE_NONE
;
1389 bool bCaughtException
= false;
1393 if (!isScriptAccessAllowed(_rxScriptContext
))
1394 return ERRCODE_IO_ACCESSDENIED
;
1396 if ( UnTrustedScript(_rScriptURL
) )
1397 return ERRCODE_IO_ACCESSDENIED
;
1399 // obtain/create a script provider
1400 Reference
< provider::XScriptProvider
> xScriptProvider
;
1401 Reference
< provider::XScriptProviderSupplier
> xSPS( _rxScriptContext
, UNO_QUERY
);
1403 xScriptProvider
.set( xSPS
->getScriptProvider() );
1405 if ( !xScriptProvider
.is() )
1407 Reference
< provider::XScriptProviderFactory
> xScriptProviderFactory
=
1408 provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
1409 xScriptProvider
.set( xScriptProviderFactory
->createScriptProvider( makeAny( _rxScriptContext
) ), UNO_SET_THROW
);
1412 // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
1413 ::framework::DocumentUndoGuard
aUndoGuard( _rxScriptContext
);
1415 // obtain the script, and execute it
1416 Reference
< provider::XScript
> xScript( xScriptProvider
->getScript( _rScriptURL
), UNO_SET_THROW
);
1417 if ( pCaller
&& pCaller
->hasValue() )
1419 Reference
< beans::XPropertySet
> xProps( xScript
, uno::UNO_QUERY
);
1422 Sequence
< uno::Any
> aArgs
{ *pCaller
};
1423 xProps
->setPropertyValue("Caller", uno::makeAny( aArgs
) );
1426 aRet
= xScript
->invoke( aParams
, aOutParamIndex
, aOutParam
);
1428 catch ( const uno::Exception
& )
1430 aException
= ::cppu::getCaughtException();
1431 bCaughtException
= true;
1432 nErr
= ERRCODE_BASIC_INTERNAL_ERROR
;
1435 if ( bCaughtException
&& bRaiseError
)
1437 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
1438 pFact
->ShowAsyncScriptErrorDialog( nullptr, aException
);
1441 SAL_INFO("sfx", "leaving CallXScript" );
1445 // perhaps rename to CallScript once we get rid of the existing CallScript
1446 // and Call, CallBasic, CallStarBasic methods
1447 ErrCode
SfxObjectShell::CallXScript( const OUString
& rScriptURL
,
1448 const css::uno::Sequence
< css::uno::Any
>& aParams
,
1449 css::uno::Any
& aRet
,
1450 css::uno::Sequence
< sal_Int16
>& aOutParamIndex
,
1451 css::uno::Sequence
< css::uno::Any
>& aOutParam
,
1453 const css::uno::Any
* pCaller
)
1455 return CallXScript( GetModel(), rScriptURL
, aParams
, aRet
, aOutParamIndex
, aOutParam
, bRaiseError
, pCaller
);
1458 void SfxHeaderAttributes_Impl::SetAttributes()
1462 for( bool bCont
= xIter
->GetFirst( aPair
); bCont
;
1463 bCont
= xIter
->GetNext( aPair
) )
1464 SetAttribute( aPair
);
1467 void SfxHeaderAttributes_Impl::SetAttribute( const SvKeyValue
& rKV
)
1469 const OUString
& aValue
= rKV
.GetValue();
1470 if( rKV
.GetKey().equalsIgnoreAsciiCase("refresh") && !rKV
.GetValue().isEmpty() )
1472 sal_Int32 nIdx
{ 0 };
1473 const sal_Int32 nTime
{ aValue
.getToken( 0, ';', nIdx
).toInt32() };
1474 const OUString aURL
{ comphelper::string::strip(aValue
.getToken( 0, ';', nIdx
), ' ') };
1475 uno::Reference
<document::XDocumentProperties
> xDocProps(
1476 pDoc
->getDocProperties());
1477 if( aURL
.startsWithIgnoreAsciiCase( "url=" ) )
1480 xDocProps
->setAutoloadURL(
1481 rtl::Uri::convertRelToAbs(pDoc
->GetMedium()->GetName(), aURL
.copy( 4 )) );
1482 } catch (rtl::MalformedUriException
&) {
1483 TOOLS_WARN_EXCEPTION("sfx", "");
1488 xDocProps
->setAutoloadSecs( nTime
);
1490 catch (lang::IllegalArgumentException
&)
1495 else if( rKV
.GetKey().equalsIgnoreAsciiCase( "expires" ) )
1497 DateTime
aDateTime( DateTime::EMPTY
);
1498 if( INetMIMEMessage::ParseDateField( rKV
.GetValue(), aDateTime
) )
1500 aDateTime
.ConvertToLocalTime();
1501 pDoc
->GetMedium()->SetExpired_Impl( aDateTime
);
1505 pDoc
->GetMedium()->SetExpired_Impl( Date( 1, 1, 1970 ) );
1510 void SfxHeaderAttributes_Impl::Append( const SvKeyValue
& rKV
)
1512 xIter
->Append( rKV
);
1513 if( bAlert
) SetAttribute( rKV
);
1516 SvKeyValueIterator
* SfxObjectShell::GetHeaderAttributes()
1518 if( !pImpl
->xHeaderAttributes
.is() )
1520 DBG_ASSERT( pMedium
, "No Medium" );
1521 pImpl
->xHeaderAttributes
= new SfxHeaderAttributes_Impl( this );
1523 return static_cast<SvKeyValueIterator
*>( pImpl
->xHeaderAttributes
.get() );
1526 void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
1528 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())
1529 ->ClearForSourceView();
1533 void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
1535 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())
1539 bool SfxObjectShell::IsPreview() const
1544 bool bPreview
= false;
1545 const SfxStringItem
* pFlags
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_OPTIONS
, false);
1548 // Distributed values among individual items
1549 const OUString aFileFlags
= pFlags
->GetValue().toAsciiUpperCase();
1550 if ( -1 != aFileFlags
.indexOf( 'B' ) )
1556 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_PREVIEW
, false);
1558 bPreview
= pItem
->GetValue();
1564 void SfxObjectShell::SetWaitCursor( bool bSet
) const
1566 for( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this ); pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, this ) )
1569 pFrame
->GetFrame().GetWindow().EnterWait();
1571 pFrame
->GetFrame().GetWindow().LeaveWait();
1575 OUString
SfxObjectShell::GetAPIName() const
1577 INetURLObject
aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
1578 OUString
aName( aURL
.GetBase() );
1579 if( aName
.isEmpty() )
1580 aName
= aURL
.GetURLNoPass();
1581 if ( aName
.isEmpty() )
1582 aName
= GetTitle( SFX_TITLE_DETECT
);
1586 void SfxObjectShell::Invalidate( sal_uInt16 nId
)
1588 for( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this ); pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, this ) )
1589 Invalidate_Impl( pFrame
->GetBindings(), nId
);
1592 bool SfxObjectShell::AdjustMacroMode()
1594 uno::Reference
< task::XInteractionHandler
> xInteraction
;
1596 xInteraction
= pMedium
->GetInteractionHandler();
1598 CheckForBrokenDocSignatures_Impl();
1600 CheckEncryption_Impl( xInteraction
);
1602 return pImpl
->aMacroMode
.adjustMacroMode( xInteraction
);
1605 css::uno::Reference
<css::awt::XWindow
> SfxObjectShell::GetDialogParent( SfxMedium
const * pLoadingMedium
)
1607 css::uno::Reference
<css::awt::XWindow
> xWindow
;
1608 SfxItemSet
* pSet
= pLoadingMedium
? pLoadingMedium
->GetItemSet() : GetMedium()->GetItemSet();
1609 const SfxUnoFrameItem
* pUnoItem
= SfxItemSet::GetItem
<SfxUnoFrameItem
>(pSet
, SID_FILLFRAME
, false);
1612 const uno::Reference
< frame::XFrame
>& xFrame( pUnoItem
->GetFrame() );
1613 xWindow
= xFrame
->getContainerWindow();
1618 SfxFrame
* pFrame
= nullptr;
1619 const SfxFrameItem
* pFrameItem
= SfxItemSet::GetItem
<SfxFrameItem
>(pSet
, SID_DOCFRAME
, false);
1620 if( pFrameItem
&& pFrameItem
->GetFrame() )
1621 // get target frame from ItemSet
1622 pFrame
= pFrameItem
->GetFrame();
1625 // try the current frame
1626 SfxViewFrame
* pView
= SfxViewFrame::Current();
1627 if ( !pView
|| pView
->GetObjectShell() != this )
1628 // get any visible frame
1629 pView
= SfxViewFrame::GetFirst(this);
1631 pFrame
= &pView
->GetFrame();
1636 // get topmost window
1637 xWindow
= pFrame
->GetFrameInterface()->getContainerWindow();
1643 // this frame may be invisible, show it if it is allowed
1644 const SfxBoolItem
* pHiddenItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSet
, SID_HIDDEN
, false);
1645 if ( !pHiddenItem
|| !pHiddenItem
->GetValue() )
1647 xWindow
->setVisible(true);
1648 css::uno::Reference
<css::awt::XTopWindow
> xTopWindow(xWindow
, uno::UNO_QUERY
);
1649 SAL_WARN_IF(!xTopWindow
, "sfx.appl", "XTopWindow not available from XWindow");
1651 xTopWindow
->toFront();
1658 void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode
)
1660 eCreateMode
= nMode
;
1663 bool SfxObjectShell::IsInPlaceActive() const
1665 if ( eCreateMode
!= SfxObjectCreateMode::EMBEDDED
)
1668 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
1669 return pFrame
&& pFrame
->GetFrame().IsInPlace();
1672 bool SfxObjectShell::IsUIActive() const
1674 if ( eCreateMode
!= SfxObjectCreateMode::EMBEDDED
)
1677 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
1678 return pFrame
&& pFrame
->GetFrame().IsInPlace() && pFrame
->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
1681 bool SfxObjectShell::UseInteractionToHandleError(
1682 const uno::Reference
< task::XInteractionHandler
>& xHandler
,
1685 bool bResult
= false;
1687 if ( xHandler
.is() )
1691 uno::Any aInteraction
;
1692 rtl::Reference
<::comphelper::OInteractionAbort
> pAbort
= new ::comphelper::OInteractionAbort();
1693 rtl::Reference
<::comphelper::OInteractionApprove
> pApprove
= new ::comphelper::OInteractionApprove();
1694 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > lContinuations
{
1698 task::ErrorCodeRequest aErrorCode
;
1699 aErrorCode
.ErrCode
= sal_uInt32(nError
);
1700 aInteraction
<<= aErrorCode
;
1701 xHandler
->handle(::framework::InteractionRequest::CreateRequest (aInteraction
,lContinuations
));
1702 bResult
= pAbort
->wasSelected();
1704 catch( uno::Exception
& )
1711 sal_Int16
SfxObjectShell_Impl::getCurrentMacroExecMode() const
1713 sal_Int16
nImposedExecMode( MacroExecMode::NEVER_EXECUTE
);
1715 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1716 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1719 const SfxUInt16Item
* pMacroModeItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(pMedium
->GetItemSet(), SID_MACROEXECMODE
, false);
1720 if ( pMacroModeItem
)
1721 nImposedExecMode
= pMacroModeItem
->GetValue();
1723 return nImposedExecMode
;
1726 void SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode
)
1728 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1729 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1732 pMedium
->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE
, nMacroMode
) );
1736 OUString
SfxObjectShell_Impl::getDocumentLocation() const
1740 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1741 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
1744 sLocation
= pMedium
->GetName();
1745 if ( sLocation
.isEmpty() )
1747 // for documents made from a template: get the name of the template
1748 sLocation
= rDocShell
.getDocProperties()->getTemplateURL();
1751 // tdf#128006 take document base url as location
1752 if (sLocation
.isEmpty())
1753 sLocation
= rDocShell
.getDocumentBaseURL();
1759 bool SfxObjectShell_Impl::documentStorageHasMacros() const
1761 return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage
);
1764 bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const
1766 return rDocShell
.GetMacroCallsSeenWhileLoading();
1769 Reference
< XEmbeddedScripts
> SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
1771 return Reference
< XEmbeddedScripts
>( rDocShell
.GetModel(), UNO_QUERY
);
1774 SignatureState
SfxObjectShell_Impl::getScriptingSignatureState()
1776 SignatureState
nSignatureState( rDocShell
.GetScriptingSignatureState() );
1778 if ( nSignatureState
!= SignatureState::NOSIGNATURES
&& m_bMacroSignBroken
)
1780 // if there is a macro signature it must be handled as broken
1781 nSignatureState
= SignatureState::BROKEN
;
1784 return nSignatureState
;
1787 bool SfxObjectShell_Impl::hasTrustedScriptingSignature( bool bAllowUIToAddAuthor
)
1789 bool bResult
= false;
1796 uno::Reference
< beans::XPropertySet
> xPropSet( rDocShell
.GetStorage(), uno::UNO_QUERY_THROW
);
1797 xPropSet
->getPropertyValue("Version") >>= aVersion
;
1799 catch( uno::Exception
& )
1803 uno::Reference
< security::XDocumentDigitalSignatures
> xSigner( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion
) );
1805 if ( nScriptingSignatureState
== SignatureState::UNKNOWN
1806 || nScriptingSignatureState
== SignatureState::OK
1807 || nScriptingSignatureState
== SignatureState::NOTVALIDATED
)
1809 const uno::Sequence
< security::DocumentSignatureInformation
> aInfo
= rDocShell
.GetDocumentSignatureInformation( true, xSigner
);
1811 if ( aInfo
.hasElements() )
1813 if ( nScriptingSignatureState
== SignatureState::UNKNOWN
)
1814 nScriptingSignatureState
= DocumentSignatures::getSignatureState(aInfo
);
1816 if ( nScriptingSignatureState
== SignatureState::OK
1817 || nScriptingSignatureState
== SignatureState::NOTVALIDATED
)
1819 bResult
= std::any_of(aInfo
.begin(), aInfo
.end(),
1820 [&xSigner
](const security::DocumentSignatureInformation
& rInfo
) {
1821 return xSigner
->isAuthorTrusted( rInfo
.Signer
); });
1823 if ( !bResult
&& bAllowUIToAddAuthor
)
1825 uno::Reference
< task::XInteractionHandler
> xInteraction
;
1826 if ( rDocShell
.GetMedium() )
1827 xInteraction
= rDocShell
.GetMedium()->GetInteractionHandler();
1829 if ( xInteraction
.is() )
1831 task::DocumentMacroConfirmationRequest aRequest
;
1832 aRequest
.DocumentURL
= getDocumentLocation();
1833 aRequest
.DocumentStorage
= rDocShell
.GetMedium()->GetZipStorageToSign_Impl();
1834 aRequest
.DocumentSignatureInformation
= aInfo
;
1835 aRequest
.DocumentVersion
= aVersion
;
1836 aRequest
.Classification
= task::InteractionClassification_QUERY
;
1837 bResult
= SfxMedium::CallApproveHandler( xInteraction
, uno::makeAny( aRequest
), true );
1844 catch( uno::Exception
& )
1850 bool SfxObjectShell::IsContinueImportOnFilterExceptions(std::u16string_view aErrMessage
)
1852 if (mbContinueImportOnFilterExceptions
== undefined
)
1854 if (Application::GetDialogCancelMode() == DialogCancelMode::Off
)
1856 // Ask the user to try to continue or abort loading
1857 OUString aMessage
= SfxResId(STR_QMSG_ERROR_OPENING_FILE
);
1858 if (!aErrMessage
.empty())
1859 aMessage
+= SfxResId(STR_QMSG_ERROR_OPENING_FILE_DETAILS
) + aErrMessage
;
1860 aMessage
+= SfxResId(STR_QMSG_ERROR_OPENING_FILE_CONTINUE
);
1861 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
1862 VclMessageType::Question
, VclButtonsType::YesNo
, aMessage
));
1863 mbContinueImportOnFilterExceptions
= (xBox
->run() == RET_YES
) ? yes
: no
;
1866 mbContinueImportOnFilterExceptions
= no
;
1868 return mbContinueImportOnFilterExceptions
== yes
;
1871 bool SfxObjectShell::isEditDocLocked() const
1873 Reference
<XModel3
> xModel
= GetModel();
1876 if (!officecfg::Office::Common::Misc::AllowEditReadonlyDocs::get())
1878 comphelper::NamedValueCollection
aArgs(xModel
->getArgs2( { "LockEditDoc" } ));
1879 return aArgs
.getOrDefault("LockEditDoc", false);
1882 bool SfxObjectShell::isContentExtractionLocked() const
1884 Reference
<XModel3
> xModel
= GetModel();
1887 comphelper::NamedValueCollection
aArgs(xModel
->getArgs2( { "LockContentExtraction" } ));
1888 return aArgs
.getOrDefault("LockContentExtraction", false);
1891 bool SfxObjectShell::isExportLocked() const
1893 Reference
<XModel3
> xModel
= GetModel();
1896 comphelper::NamedValueCollection
aArgs(xModel
->getArgs2( { "LockExport" } ));
1897 return aArgs
.getOrDefault("LockExport", false);
1900 bool SfxObjectShell::isPrintLocked() const
1902 Reference
<XModel3
> xModel
= GetModel();
1905 comphelper::NamedValueCollection
aArgs(xModel
->getArgs2( { "LockPrint" } ));
1906 return aArgs
.getOrDefault("LockPrint", false);
1909 bool SfxObjectShell::isSaveLocked() const
1911 Reference
<XModel3
> xModel
= GetModel();
1914 comphelper::NamedValueCollection
aArgs(xModel
->getArgs2( { "LockSave" } ));
1915 return aArgs
.getOrDefault("LockSave", false);
1918 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */