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/beans/XPropertySet.hpp>
32 #include <com/sun/star/container/XChild.hpp>
33 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
34 #include <com/sun/star/document/XDocumentProperties.hpp>
35 #include <com/sun/star/document/MacroExecMode.hpp>
36 #include <com/sun/star/document/XScriptInvocationContext.hpp>
37 #include <com/sun/star/embed/EmbedStates.hpp>
38 #include <com/sun/star/embed/XEmbeddedObject.hpp>
39 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
40 #include <com/sun/star/script/provider/XScript.hpp>
41 #include <com/sun/star/script/provider/XScriptProvider.hpp>
42 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
43 #include <com/sun/star/uri/UriReferenceFactory.hpp>
44 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
45 #include <com/sun/star/util/XModifiable.hpp>
47 #include <toolkit/helper/vclunohelper.hxx>
49 #include <com/sun/star/uno/Reference.h>
50 #include <com/sun/star/uno/Any.h>
51 #include <com/sun/star/task/ErrorCodeRequest.hpp>
53 #include <comphelper/processfactory.hxx>
54 #include <comphelper/string.hxx>
56 #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
57 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
58 #include <com/sun/star/task/InteractionClassification.hpp>
59 #include <com/sun/star/task/XInteractionHandler.hpp>
60 #include <com/sun/star/frame/XModel.hpp>
62 #include <basic/basmgr.hxx>
63 #include <basic/sberrors.hxx>
64 #include <vcl/weld.hxx>
65 #include <basic/sbx.hxx>
66 #include <svtools/sfxecode.hxx>
68 #include <unotools/ucbhelper.hxx>
69 #include <tools/urlobj.hxx>
70 #include <svl/sharecontrolfile.hxx>
71 #include <rtl/uri.hxx>
72 #include <vcl/svapp.hxx>
73 #include <framework/interaction.hxx>
74 #include <framework/documentundoguard.hxx>
75 #include <comphelper/interaction.hxx>
76 #include <comphelper/storagehelper.hxx>
77 #include <comphelper/documentconstants.hxx>
78 #include <comphelper/namedvaluecollection.hxx>
79 #include <officecfg/Office/Common.hxx>
81 #include <sfx2/signaturestate.hxx>
82 #include <sfx2/app.hxx>
83 #include <appdata.hxx>
84 #include <sfx2/request.hxx>
85 #include <sfx2/bindings.hxx>
86 #include <sfx2/sfxresid.hxx>
87 #include <sfx2/docfile.hxx>
88 #include <sfx2/docfilt.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
) :
129 SvKeyValueIterator(), pDoc( 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 : 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( const OUString
& rMacro
,
1314 const OUString
& 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( 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
.get() );
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( 1 );
1423 aArgs
[ 0 ] = *pCaller
;
1424 xProps
->setPropertyValue("Caller", uno::makeAny( aArgs
) );
1427 aRet
= xScript
->invoke( aParams
, aOutParamIndex
, aOutParam
);
1429 catch ( const uno::Exception
& )
1431 aException
= ::cppu::getCaughtException();
1432 bCaughtException
= true;
1433 nErr
= ERRCODE_BASIC_INTERNAL_ERROR
;
1436 if ( bCaughtException
&& bRaiseError
)
1438 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
1439 pFact
->ShowAsyncScriptErrorDialog( nullptr, aException
);
1442 SAL_INFO("sfx", "leaving CallXScript" );
1446 // perhaps rename to CallScript once we get rid of the existing CallScript
1447 // and Call, CallBasic, CallStarBasic methods
1448 ErrCode
SfxObjectShell::CallXScript( const OUString
& rScriptURL
,
1449 const css::uno::Sequence
< css::uno::Any
>& aParams
,
1450 css::uno::Any
& aRet
,
1451 css::uno::Sequence
< sal_Int16
>& aOutParamIndex
,
1452 css::uno::Sequence
< css::uno::Any
>& aOutParam
,
1454 const css::uno::Any
* pCaller
)
1456 return CallXScript( GetModel(), rScriptURL
, aParams
, aRet
, aOutParamIndex
, aOutParam
, bRaiseError
, pCaller
);
1459 void SfxHeaderAttributes_Impl::SetAttributes()
1463 for( bool bCont
= xIter
->GetFirst( aPair
); bCont
;
1464 bCont
= xIter
->GetNext( aPair
) )
1465 SetAttribute( aPair
);
1468 void SfxHeaderAttributes_Impl::SetAttribute( const SvKeyValue
& rKV
)
1470 const OUString
& aValue
= rKV
.GetValue();
1471 if( rKV
.GetKey().equalsIgnoreAsciiCase("refresh") && !rKV
.GetValue().isEmpty() )
1473 sal_Int32 nIdx
{ 0 };
1474 const sal_Int32 nTime
{ aValue
.getToken( 0, ';', nIdx
).toInt32() };
1475 const OUString aURL
{ comphelper::string::strip(aValue
.getToken( 0, ';', nIdx
), ' ') };
1476 uno::Reference
<document::XDocumentProperties
> xDocProps(
1477 pDoc
->getDocProperties());
1478 if( aURL
.startsWithIgnoreAsciiCase( "url=" ) )
1481 xDocProps
->setAutoloadURL(
1482 rtl::Uri::convertRelToAbs(pDoc
->GetMedium()->GetName(), aURL
.copy( 4 )) );
1483 } catch (rtl::MalformedUriException
&) {
1484 TOOLS_WARN_EXCEPTION("sfx", "");
1489 xDocProps
->setAutoloadSecs( nTime
);
1491 catch (lang::IllegalArgumentException
&)
1496 else if( rKV
.GetKey().equalsIgnoreAsciiCase( "expires" ) )
1498 DateTime
aDateTime( DateTime::EMPTY
);
1499 if( INetMIMEMessage::ParseDateField( rKV
.GetValue(), aDateTime
) )
1501 aDateTime
.ConvertToLocalTime();
1502 pDoc
->GetMedium()->SetExpired_Impl( aDateTime
);
1506 pDoc
->GetMedium()->SetExpired_Impl( Date( 1, 1, 1970 ) );
1511 void SfxHeaderAttributes_Impl::Append( const SvKeyValue
& rKV
)
1513 xIter
->Append( rKV
);
1514 if( bAlert
) SetAttribute( rKV
);
1517 SvKeyValueIterator
* SfxObjectShell::GetHeaderAttributes()
1519 if( !pImpl
->xHeaderAttributes
.is() )
1521 DBG_ASSERT( pMedium
, "No Medium" );
1522 pImpl
->xHeaderAttributes
= new SfxHeaderAttributes_Impl( this );
1524 return static_cast<SvKeyValueIterator
*>( pImpl
->xHeaderAttributes
.get() );
1527 void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
1529 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())
1530 ->ClearForSourceView();
1534 void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
1536 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())
1540 bool SfxObjectShell::IsPreview() const
1545 bool bPreview
= false;
1546 const SfxStringItem
* pFlags
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_OPTIONS
, false);
1549 // Distributed values among individual items
1550 const OUString aFileFlags
= pFlags
->GetValue().toAsciiUpperCase();
1551 if ( -1 != aFileFlags
.indexOf( 'B' ) )
1557 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_PREVIEW
, false);
1559 bPreview
= pItem
->GetValue();
1565 void SfxObjectShell::SetWaitCursor( bool bSet
) const
1567 for( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this ); pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, this ) )
1570 pFrame
->GetFrame().GetWindow().EnterWait();
1572 pFrame
->GetFrame().GetWindow().LeaveWait();
1576 OUString
SfxObjectShell::GetAPIName() const
1578 INetURLObject
aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
1579 OUString
aName( aURL
.GetBase() );
1580 if( aName
.isEmpty() )
1581 aName
= aURL
.GetURLNoPass();
1582 if ( aName
.isEmpty() )
1583 aName
= GetTitle( SFX_TITLE_DETECT
);
1587 void SfxObjectShell::Invalidate( sal_uInt16 nId
)
1589 for( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this ); pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, this ) )
1590 Invalidate_Impl( pFrame
->GetBindings(), nId
);
1593 bool SfxObjectShell::AdjustMacroMode()
1595 uno::Reference
< task::XInteractionHandler
> xInteraction
;
1597 xInteraction
= pMedium
->GetInteractionHandler();
1599 CheckForBrokenDocSignatures_Impl();
1601 CheckEncryption_Impl( xInteraction
);
1603 return pImpl
->aMacroMode
.adjustMacroMode( xInteraction
, true /*TODO*/ );
1606 vcl::Window
* SfxObjectShell::GetDialogParent( SfxMedium
const * pLoadingMedium
)
1608 VclPtr
<vcl::Window
> pWindow
;
1609 SfxItemSet
* pSet
= pLoadingMedium
? pLoadingMedium
->GetItemSet() : GetMedium()->GetItemSet();
1610 const SfxUnoFrameItem
* pUnoItem
= SfxItemSet::GetItem
<SfxUnoFrameItem
>(pSet
, SID_FILLFRAME
, false);
1613 const uno::Reference
< frame::XFrame
>& xFrame( pUnoItem
->GetFrame() );
1614 pWindow
= VCLUnoHelper::GetWindow( xFrame
->getContainerWindow() );
1619 SfxFrame
* pFrame
= nullptr;
1620 const SfxFrameItem
* pFrameItem
= SfxItemSet::GetItem
<SfxFrameItem
>(pSet
, SID_DOCFRAME
, false);
1621 if( pFrameItem
&& pFrameItem
->GetFrame() )
1622 // get target frame from ItemSet
1623 pFrame
= pFrameItem
->GetFrame();
1626 // try the current frame
1627 SfxViewFrame
* pView
= SfxViewFrame::Current();
1628 if ( !pView
|| pView
->GetObjectShell() != this )
1629 // get any visible frame
1630 pView
= SfxViewFrame::GetFirst(this);
1632 pFrame
= &pView
->GetFrame();
1636 // get topmost window
1637 pWindow
= VCLUnoHelper::GetWindow( pFrame
->GetFrameInterface()->getContainerWindow() );
1642 // this frame may be invisible, show it if it is allowed
1643 const SfxBoolItem
* pHiddenItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSet
, SID_HIDDEN
, false);
1644 if ( !pHiddenItem
|| !pHiddenItem
->GetValue() )
1654 void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode
)
1656 eCreateMode
= nMode
;
1659 bool SfxObjectShell::IsInPlaceActive() const
1661 if ( eCreateMode
!= SfxObjectCreateMode::EMBEDDED
)
1664 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
1665 return pFrame
&& pFrame
->GetFrame().IsInPlace();
1668 bool SfxObjectShell::IsUIActive() const
1670 if ( eCreateMode
!= SfxObjectCreateMode::EMBEDDED
)
1673 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
1674 return pFrame
&& pFrame
->GetFrame().IsInPlace() && pFrame
->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
1677 bool SfxObjectShell::UseInteractionToHandleError(
1678 const uno::Reference
< task::XInteractionHandler
>& xHandler
,
1681 bool bResult
= false;
1683 if ( xHandler
.is() )
1687 uno::Any aInteraction
;
1688 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > lContinuations(2);
1689 ::comphelper::OInteractionAbort
* pAbort
= new ::comphelper::OInteractionAbort();
1690 ::comphelper::OInteractionApprove
* pApprove
= new ::comphelper::OInteractionApprove();
1691 lContinuations
[0].set( static_cast< task::XInteractionContinuation
* >( pAbort
), uno::UNO_QUERY
);
1692 lContinuations
[1].set( static_cast< task::XInteractionContinuation
* >( pApprove
), uno::UNO_QUERY
);
1694 task::ErrorCodeRequest aErrorCode
;
1695 aErrorCode
.ErrCode
= sal_uInt32(nError
);
1696 aInteraction
<<= aErrorCode
;
1697 xHandler
->handle(::framework::InteractionRequest::CreateRequest (aInteraction
,lContinuations
));
1698 bResult
= pAbort
->wasSelected();
1700 catch( uno::Exception
& )
1707 sal_Int16
SfxObjectShell_Impl::getCurrentMacroExecMode() const
1709 sal_Int16
nImposedExecMode( MacroExecMode::NEVER_EXECUTE
);
1711 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1712 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1715 const SfxUInt16Item
* pMacroModeItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(pMedium
->GetItemSet(), SID_MACROEXECMODE
, false);
1716 if ( pMacroModeItem
)
1717 nImposedExecMode
= pMacroModeItem
->GetValue();
1719 return nImposedExecMode
;
1722 void SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode
)
1724 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1725 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1728 pMedium
->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE
, nMacroMode
) );
1732 OUString
SfxObjectShell_Impl::getDocumentLocation() const
1736 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1737 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
1740 sLocation
= pMedium
->GetName();
1741 if ( sLocation
.isEmpty() )
1743 // for documents made from a template: get the name of the template
1744 sLocation
= rDocShell
.getDocProperties()->getTemplateURL();
1747 // tdf#128006 take document base url as location
1748 if (sLocation
.isEmpty())
1749 sLocation
= rDocShell
.getDocumentBaseURL();
1755 bool SfxObjectShell_Impl::documentStorageHasMacros() const
1757 return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage
);
1760 bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const
1762 return rDocShell
.GetMacroCallsSeenWhileLoading();
1765 Reference
< XEmbeddedScripts
> SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
1767 return Reference
< XEmbeddedScripts
>( rDocShell
.GetModel(), UNO_QUERY
);
1770 SignatureState
SfxObjectShell_Impl::getScriptingSignatureState()
1772 SignatureState
nSignatureState( rDocShell
.GetScriptingSignatureState() );
1774 if ( nSignatureState
!= SignatureState::NOSIGNATURES
&& m_bMacroSignBroken
)
1776 // if there is a macro signature it must be handled as broken
1777 nSignatureState
= SignatureState::BROKEN
;
1780 return nSignatureState
;
1783 bool SfxObjectShell_Impl::hasTrustedScriptingSignature( bool bAllowUIToAddAuthor
)
1785 bool bResult
= false;
1792 uno::Reference
< beans::XPropertySet
> xPropSet( rDocShell
.GetStorage(), uno::UNO_QUERY_THROW
);
1793 xPropSet
->getPropertyValue("Version") >>= aVersion
;
1795 catch( uno::Exception
& )
1799 uno::Reference
< security::XDocumentDigitalSignatures
> xSigner( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion
) );
1801 if ( nScriptingSignatureState
== SignatureState::UNKNOWN
1802 || nScriptingSignatureState
== SignatureState::OK
1803 || nScriptingSignatureState
== SignatureState::NOTVALIDATED
)
1805 uno::Sequence
< security::DocumentSignatureInformation
> aInfo
= rDocShell
.GetDocumentSignatureInformation( true, xSigner
);
1807 if ( aInfo
.hasElements() )
1809 if ( nScriptingSignatureState
== SignatureState::UNKNOWN
)
1810 nScriptingSignatureState
= DocumentSignatures::getSignatureState(aInfo
);
1812 if ( nScriptingSignatureState
== SignatureState::OK
1813 || nScriptingSignatureState
== SignatureState::NOTVALIDATED
)
1815 bResult
= std::any_of(aInfo
.begin(), aInfo
.end(),
1816 [&xSigner
](const security::DocumentSignatureInformation
& rInfo
) {
1817 return xSigner
->isAuthorTrusted( rInfo
.Signer
); });
1819 if ( !bResult
&& bAllowUIToAddAuthor
)
1821 uno::Reference
< task::XInteractionHandler
> xInteraction
;
1822 if ( rDocShell
.GetMedium() )
1823 xInteraction
= rDocShell
.GetMedium()->GetInteractionHandler();
1825 if ( xInteraction
.is() )
1827 task::DocumentMacroConfirmationRequest aRequest
;
1828 aRequest
.DocumentURL
= getDocumentLocation();
1829 aRequest
.DocumentStorage
= rDocShell
.GetMedium()->GetZipStorageToSign_Impl();
1830 aRequest
.DocumentSignatureInformation
= aInfo
;
1831 aRequest
.DocumentVersion
= aVersion
;
1832 aRequest
.Classification
= task::InteractionClassification_QUERY
;
1833 bResult
= SfxMedium::CallApproveHandler( xInteraction
, uno::makeAny( aRequest
), true );
1840 catch( uno::Exception
& )
1846 bool SfxObjectShell::IsContinueImportOnFilterExceptions(const OUString
& aErrMessage
)
1848 if (mbContinueImportOnFilterExceptions
== undefined
)
1850 if (Application::GetDialogCancelMode() == DialogCancelMode::Off
)
1852 // Ask the user to try to continue or abort loading
1853 OUString aMessage
= SfxResId(STR_QMSG_ERROR_OPENING_FILE
);
1854 if (!aErrMessage
.isEmpty())
1855 aMessage
+= SfxResId(STR_QMSG_ERROR_OPENING_FILE_DETAILS
) + aErrMessage
;
1856 aMessage
+= SfxResId(STR_QMSG_ERROR_OPENING_FILE_CONTINUE
);
1857 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
1858 VclMessageType::Question
, VclButtonsType::YesNo
, aMessage
));
1859 mbContinueImportOnFilterExceptions
= (xBox
->run() == RET_YES
) ? yes
: no
;
1862 mbContinueImportOnFilterExceptions
= no
;
1864 return mbContinueImportOnFilterExceptions
== yes
;
1867 bool SfxObjectShell::isEditDocLocked() const
1869 Reference
<XModel
> xModel
= GetModel();
1872 if (!officecfg::Office::Common::Misc::AllowEditReadonlyDocs::get())
1874 comphelper::NamedValueCollection
aArgs(xModel
->getArgs());
1875 return aArgs
.getOrDefault("LockEditDoc", false);
1878 bool SfxObjectShell::isContentExtractionLocked() const
1880 Reference
<XModel
> xModel
= GetModel();
1883 comphelper::NamedValueCollection
aArgs(xModel
->getArgs());
1884 return aArgs
.getOrDefault("LockContentExtraction", false);
1887 bool SfxObjectShell::isExportLocked() const
1889 Reference
<XModel
> xModel
= GetModel();
1892 comphelper::NamedValueCollection
aArgs(xModel
->getArgs());
1893 return aArgs
.getOrDefault("LockExport", false);
1896 bool SfxObjectShell::isPrintLocked() const
1898 Reference
<XModel
> xModel
= GetModel();
1901 comphelper::NamedValueCollection
aArgs(xModel
->getArgs());
1902 return aArgs
.getOrDefault("LockPrint", false);
1905 bool SfxObjectShell::isSaveLocked() const
1907 Reference
<XModel
> xModel
= GetModel();
1910 comphelper::NamedValueCollection
aArgs(xModel
->getArgs());
1911 return aArgs
.getOrDefault("LockSave", false);
1914 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */