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>
21 #include <config_folders.h>
23 #include <tools/inetmsg.hxx>
24 #include <tools/diagnose_ex.h>
25 #include <svl/eitem.hxx>
26 #include <svl/stritem.hxx>
27 #include <svl/intitem.hxx>
28 #include <svtools/svparser.hxx>
29 #include <cppuhelper/exc_hlp.hxx>
30 #include <sal/log.hxx>
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/UpdateDocMode.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/XEmbedPersist.hpp>
40 #include <com/sun/star/embed/XEmbeddedObject.hpp>
41 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
42 #include <com/sun/star/script/provider/XScript.hpp>
43 #include <com/sun/star/script/provider/XScriptProvider.hpp>
44 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
45 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
46 #include <com/sun/star/uri/UriReferenceFactory.hpp>
47 #include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>
48 #include <com/sun/star/util/XModifiable.hpp>
50 #include <toolkit/helper/vclunohelper.hxx>
52 #include <com/sun/star/uno/Reference.h>
53 #include <com/sun/star/uno/Any.h>
54 #include <com/sun/star/ucb/XContent.hpp>
55 #include <com/sun/star/task/ErrorCodeRequest.hpp>
56 #include <unotools/securityoptions.hxx>
58 #include <comphelper/processfactory.hxx>
59 #include <comphelper/string.hxx>
61 #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
62 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
63 #include <com/sun/star/task/InteractionClassification.hpp>
64 #include <com/sun/star/frame/XModel.hpp>
66 #include <basic/sbuno.hxx>
67 #include <basic/sbstar.hxx>
68 #include <basic/basmgr.hxx>
69 #include <basic/sberrors.hxx>
70 #include <vcl/weld.hxx>
71 #include <basic/sbx.hxx>
72 #include <svtools/sfxecode.hxx>
73 #include <svtools/ehdl.hxx>
75 #include <unotools/pathoptions.hxx>
76 #include <unotools/ucbhelper.hxx>
77 #include <tools/inetmime.hxx>
78 #include <tools/urlobj.hxx>
79 #include <svl/inettype.hxx>
80 #include <svl/sharecontrolfile.hxx>
81 #include <osl/file.hxx>
82 #include <rtl/bootstrap.hxx>
83 #include <vcl/svapp.hxx>
84 #include <framework/interaction.hxx>
85 #include <framework/documentundoguard.hxx>
86 #include <comphelper/interaction.hxx>
87 #include <comphelper/storagehelper.hxx>
88 #include <comphelper/documentconstants.hxx>
90 #include <sfx2/signaturestate.hxx>
91 #include <sfx2/app.hxx>
92 #include <appdata.hxx>
93 #include <sfx2/request.hxx>
94 #include <sfx2/bindings.hxx>
95 #include <sfx2/sfxresid.hxx>
96 #include <sfx2/docfile.hxx>
97 #include <sfx2/docfilt.hxx>
98 #include <sfx2/objsh.hxx>
99 #include <objshimp.hxx>
100 #include <sfx2/event.hxx>
101 #include <sfx2/dispatch.hxx>
102 #include <sfx2/viewfrm.hxx>
103 #include <sfx2/viewsh.hxx>
104 #include <sfx2/ctrlitem.hxx>
105 #include <sfx2/sfxuno.hxx>
106 #include <arrdecl.hxx>
107 #include <sfx2/module.hxx>
108 #include <sfx2/docfac.hxx>
109 #include <helper.hxx>
110 #include <sfx2/sfxsids.hrc>
111 #include <sfx2/strings.hrc>
112 #include <workwin.hxx>
113 #include <sfx2/sfxdlg.hxx>
114 #include <appbaslib.hxx>
115 #include <openflag.hxx>
116 #include "objstor.hxx"
117 #include <appopen.hxx>
121 using namespace ::com::sun::star
;
122 using namespace ::com::sun::star::uno
;
123 using namespace ::com::sun::star::ucb
;
124 using namespace ::com::sun::star::document
;
125 using namespace ::com::sun::star::frame
;
126 using namespace ::com::sun::star::script
;
127 using namespace ::com::sun::star::script::provider
;
128 using namespace ::com::sun::star::container
;
130 // class SfxHeaderAttributes_Impl ----------------------------------------
132 class SfxHeaderAttributes_Impl
: public SvKeyValueIterator
135 SfxObjectShell
* pDoc
;
136 SvKeyValueIteratorRef xIter
;
140 explicit SfxHeaderAttributes_Impl( SfxObjectShell
* pSh
) :
141 SvKeyValueIterator(), pDoc( pSh
),
142 xIter( pSh
->GetMedium()->GetHeaderAttributes_Impl() ),
145 virtual bool GetFirst( SvKeyValue
& rKV
) override
{ return xIter
->GetFirst( rKV
); }
146 virtual bool GetNext( SvKeyValue
& rKV
) override
{ return xIter
->GetNext( rKV
); }
147 virtual void Append( const SvKeyValue
& rKV
) override
;
149 void ClearForSourceView() { xIter
= new SvKeyValueIterator
; bAlert
= false; }
150 void SetAttributes();
151 void SetAttribute( const SvKeyValue
& rKV
);
155 sal_uInt16
const aTitleMap_Impl
[3][2] =
158 /* SFX_TITLE_CAPTION */ { SFX_TITLE_FILENAME
, SFX_TITLE_TITLE
},
159 /* SFX_TITLE_PICKLIST */ { 32, SFX_TITLE_FULLNAME
},
160 /* SFX_TITLE_HISTORY */ { 32, SFX_TITLE_FULLNAME
}
164 bool SfxObjectShell::IsAbortingImport() const
166 return pImpl
->bIsAbortingImport
;
170 uno::Reference
<document::XDocumentProperties
>
171 SfxObjectShell::getDocProperties()
173 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
174 GetModel(), uno::UNO_QUERY_THROW
);
175 uno::Reference
<document::XDocumentProperties
> xDocProps(
176 xDPS
->getDocumentProperties());
177 DBG_ASSERT(xDocProps
.is(),
178 "SfxObjectShell: model has no DocumentProperties");
183 void SfxObjectShell::DoFlushDocInfo()
188 // Note: the only thing that calls this is the modification event handler
189 // that is installed at the XDocumentProperties
190 void SfxObjectShell::FlushDocInfo()
196 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
197 DoFlushDocInfo(); // call template method
198 const OUString
url(xDocProps
->getAutoloadURL());
199 sal_Int32
delay(xDocProps
->getAutoloadSecs());
200 SetAutoLoad( INetURLObject(url
), delay
* 1000,
201 (delay
> 0) || !url
.isEmpty() );
204 void SfxObjectShell::SetError(ErrCode lErr
)
206 if (pImpl
->lErr
==ERRCODE_NONE
)
212 ErrCode
SfxObjectShell::GetError() const
214 return GetErrorCode().IgnoreWarning();
217 ErrCode
SfxObjectShell::GetErrorCode() const
219 ErrCode lError
=pImpl
->lErr
;
220 if(!lError
&& GetMedium())
221 lError
=GetMedium()->GetErrorCode();
225 void SfxObjectShell::ResetError()
227 pImpl
->lErr
=ERRCODE_NONE
;
228 SfxMedium
* pMed
= GetMedium();
233 void SfxObjectShell::EnableSetModified( bool bEnable
)
235 SAL_INFO_IF( bEnable
== pImpl
->m_bEnableSetModified
, "sfx", "SFX_PERSIST: EnableSetModified 2x called with the same value" );
236 pImpl
->m_bEnableSetModified
= bEnable
;
240 bool SfxObjectShell::IsEnableSetModified() const
242 return pImpl
->m_bEnableSetModified
&& !IsReadOnly();
246 bool SfxObjectShell::IsModified()
248 if ( pImpl
->m_bIsModified
)
251 if ( !pImpl
->m_xDocStorage
.is() || IsReadOnly() )
253 // if the document still has no storage and is not set to be modified explicitly it is not modified
254 // a readonly document is also not modified
259 if (pImpl
->mpObjectContainer
)
261 uno::Sequence
< OUString
> aNames
= GetEmbeddedObjectContainer().GetObjectNames();
262 for ( const auto& rName
: aNames
)
264 uno::Reference
< embed::XEmbeddedObject
> xObj
= GetEmbeddedObjectContainer().GetEmbeddedObject( rName
);
265 OSL_ENSURE( xObj
.is(), "An empty entry in the embedded objects list!" );
270 sal_Int32 nState
= xObj
->getCurrentState();
271 if ( nState
!= embed::EmbedStates::LOADED
)
273 uno::Reference
< util::XModifiable
> xModifiable( xObj
->getComponent(), uno::UNO_QUERY
);
274 if ( xModifiable
.is() && xModifiable
->isModified() )
278 catch( uno::Exception
& )
288 void SfxObjectShell::SetModified( bool bModifiedP
)
290 SAL_INFO_IF( !bModifiedP
&& !IsEnableSetModified(), "sfx",
291 "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False" );
293 if( !IsEnableSetModified() )
296 if( pImpl
->m_bIsModified
!= bModifiedP
)
298 pImpl
->m_bIsModified
= bModifiedP
;
304 void SfxObjectShell::ModifyChanged()
306 if ( pImpl
->bClosing
)
307 // SetModified dispose of the models!
311 SfxViewFrame
* pViewFrame
= SfxViewFrame::Current();
313 pViewFrame
->GetBindings().Invalidate( SID_SAVEDOCS
);
315 Invalidate( SID_SIGNATURE
);
316 Invalidate( SID_MACRO_SIGNATURE
);
317 Broadcast( SfxHint( SfxHintId::TitleChanged
) ); // xmlsec05, signed state might change in title...
319 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::ModifyChanged
, GlobalEventConfig::GetEventName(GlobalEventId::MODIFYCHANGED
), this ) );
323 bool SfxObjectShell::IsReadOnlyUI() const
327 Returns sal_True if the document for the UI is treated as r/o. This is
328 regardless of the actual r/o, which can be checked with <IsReadOnly()>.
332 return pImpl
->bReadOnlyUI
;
336 bool SfxObjectShell::IsReadOnlyMedium() const
340 Returns sal_True when the medium is r/o, for instance when opened as r/o.
346 return pMedium
->IsReadOnly();
349 bool SfxObjectShell::IsOriginallyReadOnlyMedium() const
351 return pMedium
== nullptr || pMedium
->IsOriginallyReadOnly();
354 bool SfxObjectShell::IsOriginallyLoadedReadOnlyMedium() const
356 return pMedium
!= nullptr && pMedium
->IsOriginallyLoadedReadOnly();
360 void SfxObjectShell::SetReadOnlyUI( bool bReadOnly
)
364 Turns the document in an r/o and r/w state respectively without reloading
365 it and without changing the open mode of the medium.
369 if ( bReadOnly
!= pImpl
->bReadOnlyUI
)
371 pImpl
->bReadOnlyUI
= bReadOnly
;
372 Broadcast( SfxHint(SfxHintId::ModeChanged
) );
377 void SfxObjectShell::SetReadOnly()
379 // Let the document be completely readonly, means that the
380 // medium open mode is adjusted accordingly, and the write lock
381 // on the file is removed.
383 if ( !pMedium
|| IsReadOnlyMedium() )
386 bool bWasROUI
= IsReadOnly();
388 pMedium
->UnlockFile( false );
390 // the storage-based mediums are already based on the temporary file
391 // so UnlockFile has already closed the locking stream
392 if ( !pMedium
->HasStorage_Impl() && IsLoadingFinished() )
393 pMedium
->CloseInStream();
395 pMedium
->SetOpenMode( SFX_STREAM_READONLY
, true );
396 pMedium
->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY
, true ) );
399 Broadcast( SfxHint(SfxHintId::ModeChanged
) );
403 bool SfxObjectShell::IsReadOnly() const
405 return pImpl
->bReadOnlyUI
|| pMedium
== nullptr;
409 bool SfxObjectShell::IsInModalMode() const
411 return pImpl
->bModalMode
|| pImpl
->bRunningMacro
;
414 bool SfxObjectShell::AcceptStateUpdate() const
416 return !IsInModalMode();
420 void SfxObjectShell::SetMacroMode_Impl( bool bModal
)
422 if ( !pImpl
->bRunningMacro
!= !bModal
)
424 pImpl
->bRunningMacro
= bModal
;
425 Broadcast( SfxHint( SfxHintId::ModeChanged
) );
430 void SfxObjectShell::SetModalMode_Impl( bool bModal
)
432 // Broadcast only if modified, or otherwise it will possibly go into
434 if ( pImpl
->bModalMode
== bModal
)
438 sal_uInt16
&rDocModalCount
= SfxGetpApp()->Get_Impl()->nDocModalMode
;
445 pImpl
->bModalMode
= bModal
;
446 Broadcast( SfxHint( SfxHintId::ModeChanged
) );
449 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
451 bool SfxObjectShell::SwitchToShared( bool bShared
, bool bSave
)
455 if ( bShared
!= IsDocShared() )
457 OUString aOrigURL
= GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
459 if ( aOrigURL
.isEmpty() && bSave
)
461 // this is a new document, let it be stored before switching to the shared mode;
462 // the storing should be done without shared flag, since it is possible that the
463 // target location does not allow to create sharing control file;
464 // the shared flag will be set later after creation of sharing control file
465 SfxViewFrame
* pViewFrame
= SfxViewFrame::GetFirst( this );
469 // TODO/LATER: currently the application guards against the reentrance problem
470 const SfxPoolItem
* pItem
= pViewFrame
->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC
: SID_SAVEASDOC
);
471 const SfxBoolItem
* pResult
= dynamic_cast<const SfxBoolItem
*>( pItem
);
472 bResult
= ( pResult
&& pResult
->GetValue() );
474 aOrigURL
= GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
478 bool bOldValue
= HasSharedXMLFlagSet();
479 SetSharedXMLFlag( bShared
);
481 bool bRemoveEntryOnError
= false;
482 if ( bResult
&& bShared
)
486 ::svt::ShareControlFile
aControlFile( aOrigURL
);
487 aControlFile
.InsertOwnEntry();
488 bRemoveEntryOnError
= true;
490 catch( uno::Exception
& )
496 if ( bResult
&& bSave
)
498 SfxViewFrame
* pViewFrame
= SfxViewFrame::GetFirst( this );
502 // TODO/LATER: currently the application guards against the reentrance problem
503 SetModified(); // the modified flag has to be set to let the document be stored with the shared flag
504 const SfxPoolItem
* pItem
= pViewFrame
->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC
: SID_SAVEASDOC
);
505 const SfxBoolItem
* pResult
= dynamic_cast<const SfxBoolItem
*>( pItem
);
506 bResult
= ( pResult
&& pResult
->GetValue() );
512 // TODO/LATER: Is it possible that the following calls fail?
515 pImpl
->m_aSharedFileURL
= aOrigURL
;
516 GetMedium()->SwitchDocumentToTempFile();
520 const OUString aTempFileURL
= pMedium
->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
521 GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
522 pImpl
->m_aSharedFileURL
.clear();
524 // now remove the temporary file the document was based on
525 ::utl::UCBContentHelper::Kill( aTempFileURL
);
529 // aOrigURL can not be used since it contains an old value
530 ::svt::ShareControlFile
aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
531 aControlFile
.RemoveFile();
533 catch( uno::Exception
& )
540 // the saving has failed!
541 if ( bRemoveEntryOnError
)
545 ::svt::ShareControlFile
aControlFile( aOrigURL
);
546 aControlFile
.RemoveEntry();
548 catch( uno::Exception
& )
552 SetSharedXMLFlag( bOldValue
);
556 bResult
= false; // the second switch to the same mode
565 void SfxObjectShell::FreeSharedFile( const OUString
& aTempFileURL
)
567 SetSharedXMLFlag( false );
569 if ( !IsDocShared() || aTempFileURL
.isEmpty()
570 || ::utl::UCBContentHelper::EqualURLs( aTempFileURL
, GetSharedFileURL() ) )
573 if ( pImpl
->m_bAllowShareControlFileClean
)
577 ::svt::ShareControlFile
aControlFile( GetSharedFileURL() );
578 aControlFile
.RemoveEntry();
580 catch( uno::Exception
& )
585 // the cleaning is forbidden only once
586 pImpl
->m_bAllowShareControlFileClean
= true;
588 // now remove the temporary file the document is based currently on
589 ::utl::UCBContentHelper::Kill( aTempFileURL
);
591 pImpl
->m_aSharedFileURL
.clear();
595 void SfxObjectShell::DoNotCleanShareControlFile()
597 pImpl
->m_bAllowShareControlFileClean
= false;
601 void SfxObjectShell::SetSharedXMLFlag( bool bFlag
) const
603 pImpl
->m_bSharedXMLFlag
= bFlag
;
607 bool SfxObjectShell::HasSharedXMLFlagSet() const
609 return pImpl
->m_bSharedXMLFlag
;
614 bool SfxObjectShell::IsDocShared() const
616 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
617 return ( !pImpl
->m_aSharedFileURL
.isEmpty() );
624 OUString
SfxObjectShell::GetSharedFileURL() const
626 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
627 return pImpl
->m_aSharedFileURL
;
633 Size
SfxObjectShell::GetFirstPageSize()
635 return GetVisArea(ASPECT_THUMBNAIL
).GetSize();
639 IndexBitSet
& SfxObjectShell::GetNoSet_Impl()
641 return pImpl
->aBitSet
;
645 // changes the title of the document
647 void SfxObjectShell::SetTitle
649 const OUString
& rTitle
// the new Document Title
654 With this method, the title of the document can be set.
655 This corresponds initially to the full file name. A setting of the
656 title does not affect the file name, but it will be shown in the
657 Caption-Bars of the MDI-window.
663 if ( ( ( HasName() && pImpl
->aTitle
== rTitle
)
664 || ( !HasName() && GetTitle() == rTitle
) )
668 SfxApplication
*pSfxApp
= SfxGetpApp();
670 // If possible release the unnamed number.
671 if ( pImpl
->bIsNamedVisible
&& USHRT_MAX
!= pImpl
->nVisualDocumentNumber
)
673 pSfxApp
->ReleaseIndex(pImpl
->nVisualDocumentNumber
);
674 pImpl
->bIsNamedVisible
= false;
678 pImpl
->aTitle
= rTitle
;
683 SfxShell::SetName( GetTitle(SFX_TITLE_APINAME
) );
684 Broadcast( SfxHint(SfxHintId::TitleChanged
) );
690 OUString
SfxObjectShell::GetTitle( sal_uInt16 nMaxLength
) const
694 Returns the title or logical file name of the document, depending on the
697 If the file name with path is used, the Name shortened by replacing one or
698 more directory names with "...", URLs are currently always returned
703 SfxMedium
*pMed
= GetMedium();
708 if ( SFX_TITLE_DETECT
== nMaxLength
&& pImpl
->aTitle
.isEmpty() )
710 static bool bRecur
= false;
712 return "-not available-";
719 const SfxStringItem
* pNameItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_DOCINFO_TITLE
, false);
721 aTitle
= pNameItem
->GetValue();
724 if ( aTitle
.isEmpty() )
725 aTitle
= GetTitle( SFX_TITLE_FILENAME
);
731 if (SFX_TITLE_APINAME
== nMaxLength
)
734 // Picklist/Caption is mapped
735 if ( pMed
&& ( nMaxLength
== SFX_TITLE_CAPTION
|| nMaxLength
== SFX_TITLE_PICKLIST
) )
737 // If a specific title was given at open:
738 // important for URLs: use INetProtocol::File for which the set title is not
739 // considered. (See below, analysis of aTitleMap_Impl)
740 const SfxStringItem
* pNameItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMed
->GetItemSet(), SID_DOCINFO_TITLE
, false);
742 return pNameItem
->GetValue();
746 DBG_ASSERT( !HasName() || pMed
, "HasName() but no Medium?!?" );
747 if ( !HasName() || !pMed
)
749 // Title already set?
750 if ( !pImpl
->aTitle
.isEmpty() )
751 return pImpl
->aTitle
;
753 // must it be numbered?
754 const OUString
aNoName(SfxResId(STR_NONAME
));
755 if (pImpl
->bIsNamedVisible
)
758 return aNoName
+ " " + OUString::number(pImpl
->nVisualDocumentNumber
);
761 // Document called "Untitled" for the time being
766 const INetURLObject
aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
767 if ( nMaxLength
> SFX_TITLE_CAPTION
&& nMaxLength
<= SFX_TITLE_HISTORY
)
770 if (aURL
.GetProtocol() == INetProtocol::File
)
774 nMaxLength
= aTitleMap_Impl
[nMaxLength
-SFX_TITLE_CAPTION
][nRemote
];
778 if ( aURL
.GetProtocol() == INetProtocol::File
)
780 if ( nMaxLength
== SFX_TITLE_FULLNAME
)
781 return aURL
.HasMark() ? INetURLObject( aURL
.GetURLNoMark() ).PathToFileName() : aURL
.PathToFileName();
782 if ( nMaxLength
== SFX_TITLE_FILENAME
)
783 return aURL
.getName(INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
);
784 if ( pImpl
->aTitle
.isEmpty() )
785 pImpl
->aTitle
= aURL
.getBase( INetURLObject::LAST_SEGMENT
,
786 true, INetURLObject::DecodeMechanism::WithCharset
);
790 if ( nMaxLength
>= SFX_TITLE_MAXLEN
)
792 const OUString
aComplete( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
793 if( aComplete
.getLength() > nMaxLength
)
794 return "..." + aComplete
.copy( aComplete
.getLength() - nMaxLength
+ 3, nMaxLength
- 3 );
797 if ( nMaxLength
== SFX_TITLE_FILENAME
)
799 const OUString aName
= INetURLObject::decode( aURL
.GetBase(), INetURLObject::DecodeMechanism::WithCharset
);
800 return aName
.isEmpty() ? aURL
.GetURLNoPass() : aName
;
802 if ( nMaxLength
== SFX_TITLE_FULLNAME
)
803 return aURL
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
);
805 // Generate Title from file name if possible
806 if ( pImpl
->aTitle
.isEmpty() )
807 pImpl
->aTitle
= aURL
.GetBase();
809 // workaround for the case when the name can not be retrieved from URL by INetURLObject
810 if ( pImpl
->aTitle
.isEmpty() )
811 pImpl
->aTitle
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::WithCharset
);
815 return pImpl
->aTitle
;
819 void SfxObjectShell::InvalidateName()
823 Returns the title of the new document, DocInfo-Title or
824 File name. Is required for loading from template or SaveAs.
828 pImpl
->aTitle
.clear();
829 SetName( GetTitle( SFX_TITLE_APINAME
) );
831 Broadcast( SfxHint(SfxHintId::TitleChanged
) );
835 void SfxObjectShell::SetNamedVisibility_Impl()
837 if ( !pImpl
->bIsNamedVisible
)
839 pImpl
->bIsNamedVisible
= true;
840 if ( !HasName() && USHRT_MAX
== pImpl
->nVisualDocumentNumber
&& pImpl
->aTitle
.isEmpty() )
842 pImpl
->nVisualDocumentNumber
= SfxGetpApp()->GetFreeIndex();
843 Broadcast( SfxHint(SfxHintId::TitleChanged
) );
847 SetName( GetTitle(SFX_TITLE_APINAME
) );
850 void SfxObjectShell::SetNoName()
853 GetModel()->attachResource( OUString(), GetModel()->getArgs() );
857 SfxProgress
* SfxObjectShell::GetProgress() const
859 return pImpl
->pProgress
;
863 void SfxObjectShell::SetProgress_Impl
865 SfxProgress
*pProgress
/* to started <SfxProgress> or 0,
866 if the progress is to be reset */
871 Internal method to set or reset the Progress modes for
876 DBG_ASSERT( ( !pImpl
->pProgress
&& pProgress
) ||
877 ( pImpl
->pProgress
&& !pProgress
),
878 "Progress activation/deactivation mismatch" );
879 pImpl
->pProgress
= pProgress
;
883 void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame
const * pFrame
)
885 SfxApplication
* pSfxApp
= SfxGetpApp();
886 if ( pSfxApp
->IsDowning() || IsLoading() || !pFrame
|| pFrame
->GetFrame().IsClosing_Impl() )
889 const SfxBoolItem
* pHiddenItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_HIDDEN
, false);
890 if ( !pHiddenItem
|| !pHiddenItem
->GetValue() )
892 SfxEventHintId nId
= pImpl
->nEventId
;
893 pImpl
->nEventId
= SfxEventHintId::NONE
;
894 if ( nId
== SfxEventHintId::OpenDoc
)
895 pSfxApp
->NotifyEvent(SfxViewEventHint( nId
, GlobalEventConfig::GetEventName(GlobalEventId::OPENDOC
), this, pFrame
->GetFrame().GetController() ), false);
896 else if (nId
== SfxEventHintId::CreateDoc
)
897 pSfxApp
->NotifyEvent(SfxViewEventHint( nId
, GlobalEventConfig::GetEventName(GlobalEventId::CREATEDOC
), this, pFrame
->GetFrame().GetController() ), false);
902 void SfxObjectShell::SetActivateEvent_Impl(SfxEventHintId nId
)
904 pImpl
->nEventId
= nId
;
907 bool SfxObjectShell::IsAutoLoadLocked() const
909 /* Returns whether an Autoload is allowed to be executed. Before the
910 surrounding FrameSet of the AutoLoad is also taken into account as well.
914 return !IsReadOnly();
918 void SfxObjectShell::BreakMacroSign_Impl( bool bBreakMacroSign
)
920 pImpl
->m_bMacroSignBroken
= bBreakMacroSign
;
924 void SfxObjectShell::CheckSecurityOnLoading_Impl()
926 uno::Reference
< task::XInteractionHandler
> xInteraction
;
928 xInteraction
= GetMedium()->GetInteractionHandler();
930 // check if there is a broken signature...
931 CheckForBrokenDocSignatures_Impl();
933 CheckEncryption_Impl( xInteraction
);
935 // check macro security
936 pImpl
->aMacroMode
.checkMacrosOnLoading( xInteraction
);
940 void SfxObjectShell::CheckEncryption_Impl( const uno::Reference
< task::XInteractionHandler
>& xHandler
)
943 bool bIsEncrypted
= false;
944 bool bHasNonEncrypted
= false;
948 uno::Reference
< beans::XPropertySet
> xPropSet( GetStorage(), uno::UNO_QUERY_THROW
);
949 xPropSet
->getPropertyValue("Version") >>= aVersion
;
950 xPropSet
->getPropertyValue("HasEncryptedEntries") >>= bIsEncrypted
;
951 xPropSet
->getPropertyValue("HasNonEncryptedEntries") >>= bHasNonEncrypted
;
953 catch( uno::Exception
& )
957 if ( aVersion
.compareTo( ODFVER_012_TEXT
) < 0 )
960 // this is ODF1.2 or later
961 if ( !(bIsEncrypted
&& bHasNonEncrypted
) )
964 if ( !pImpl
->m_bIncomplEncrWarnShown
)
966 // this is an encrypted document with nonencrypted streams inside, show the warning
967 css::task::ErrorCodeRequest aErrorCode
;
968 aErrorCode
.ErrCode
= sal_uInt32(ERRCODE_SFX_INCOMPLETE_ENCRYPTION
);
970 SfxMedium::CallApproveHandler( xHandler
, uno::makeAny( aErrorCode
), false );
971 pImpl
->m_bIncomplEncrWarnShown
= true;
974 // broken signatures imply no macro execution at all
975 pImpl
->aMacroMode
.disallowMacroExecution();
979 void SfxObjectShell::CheckForBrokenDocSignatures_Impl()
981 SignatureState nSignatureState
= GetDocumentSignatureState();
982 bool bSignatureBroken
= ( nSignatureState
== SignatureState::BROKEN
);
983 if ( !bSignatureBroken
)
986 // broken signatures imply no macro execution at all
987 pImpl
->aMacroMode
.disallowMacroExecution();
991 void SfxObjectShell::SetAutoLoad(
992 const INetURLObject
& rUrl
, sal_uInt32 nTime
, bool bReload
)
994 pImpl
->pReloadTimer
.reset();
997 pImpl
->pReloadTimer
.reset(new AutoReloadTimer_Impl(
998 rUrl
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
),
1000 pImpl
->pReloadTimer
->Start();
1004 void SfxObjectShell::SetLoading(SfxLoadedFlags nFlags
)
1006 pImpl
->nLoadedFlags
= nFlags
;
1009 bool SfxObjectShell::IsLoadingFinished() const
1011 return ( pImpl
->nLoadedFlags
== SfxLoadedFlags::ALL
);
1014 void SfxObjectShell::InitOwnModel_Impl()
1016 if ( pImpl
->bModelInitialized
)
1019 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_DOC_SALVAGE
, false);
1022 pImpl
->aTempName
= pMedium
->GetPhysicalName();
1023 pMedium
->GetItemSet()->ClearItem( SID_DOC_SALVAGE
);
1024 pMedium
->GetItemSet()->ClearItem( SID_FILE_NAME
);
1025 pMedium
->GetItemSet()->Put( SfxStringItem( SID_FILE_NAME
, pMedium
->GetOrigURL() ) );
1029 pMedium
->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL
);
1030 pMedium
->GetItemSet()->ClearItem( SID_DOCUMENT
);
1033 pMedium
->GetItemSet()->ClearItem( SID_REFERER
);
1034 uno::Reference
< frame::XModel
> xModel
= GetModel();
1037 SfxItemSet
*pSet
= GetMedium()->GetItemSet();
1038 if ( !GetMedium()->IsReadOnly() )
1039 pSet
->ClearItem( SID_INPUTSTREAM
);
1040 uno::Sequence
< beans::PropertyValue
> aArgs
;
1041 TransformItems( SID_OPENDOC
, *pSet
, aArgs
);
1042 xModel
->attachResource( GetMedium()->GetOrigURL(), aArgs
);
1043 impl_addToModelCollection(xModel
);
1046 pImpl
->bModelInitialized
= true;
1049 void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags
)
1051 std::shared_ptr
<const SfxFilter
> pFlt
= pMedium
->GetFilter();
1054 SetFormatSpecificCompatibilityOptions( pFlt
->GetTypeName() );
1057 bool bSetModifiedTRUE
= false;
1058 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_DOC_SALVAGE
, false);
1059 if( ( nFlags
& SfxLoadedFlags::MAINDOCUMENT
) && !(pImpl
->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
)
1060 && !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::MAINDOCUMENT
))
1062 pImpl
->nFlagsInProgress
|= SfxLoadedFlags::MAINDOCUMENT
;
1063 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())->SetAttributes();
1065 if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().hasElements() ) && !IsModifyPasswordEntered() )
1070 bSetModifiedTRUE
= true;
1072 if ( !IsEnableSetModified() )
1073 EnableSetModified();
1075 if( !bSetModifiedTRUE
&& IsEnableSetModified() )
1076 SetModified( false );
1078 CheckSecurityOnLoading_Impl();
1080 bHasName
= true; // the document is loaded, so the name should already available
1081 GetTitle( SFX_TITLE_DETECT
);
1082 InitOwnModel_Impl();
1083 pImpl
->nFlagsInProgress
&= ~SfxLoadedFlags::MAINDOCUMENT
;
1086 if( ( nFlags
& SfxLoadedFlags::IMAGES
) && !(pImpl
->nLoadedFlags
& SfxLoadedFlags::IMAGES
)
1087 && !(pImpl
->nFlagsInProgress
& SfxLoadedFlags::IMAGES
))
1089 pImpl
->nFlagsInProgress
|= SfxLoadedFlags::IMAGES
;
1090 uno::Reference
<document::XDocumentProperties
> xDocProps(
1091 getDocProperties());
1092 const OUString
url(xDocProps
->getAutoloadURL());
1093 sal_Int32
delay(xDocProps
->getAutoloadSecs());
1094 SetAutoLoad( INetURLObject(url
), delay
* 1000,
1095 (delay
> 0) || !url
.isEmpty() );
1096 if( !bSetModifiedTRUE
&& IsEnableSetModified() )
1097 SetModified( false );
1098 Invalidate( SID_SAVEASDOC
);
1099 pImpl
->nFlagsInProgress
&= ~SfxLoadedFlags::IMAGES
;
1102 pImpl
->nLoadedFlags
|= nFlags
;
1104 if ( pImpl
->nFlagsInProgress
!= SfxLoadedFlags::NONE
)
1107 // in case of reentrance calls the first called FinishedLoading() call on the stack
1108 // should do the notification, in result the notification is done when all the FinishedLoading() calls are finished
1110 if ( bSetModifiedTRUE
)
1113 SetModified( false );
1115 if ( (pImpl
->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
) && (pImpl
->nLoadedFlags
& SfxLoadedFlags::IMAGES
) )
1117 const SfxBoolItem
* pTemplateItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_TEMPLATE
, false);
1118 bool bTemplate
= pTemplateItem
&& pTemplateItem
->GetValue();
1120 // closing the streams on loading should be under control of SFX!
1121 DBG_ASSERT( pMedium
->IsOpen(), "Don't close the medium when loading documents!" );
1125 TemplateDisconnectionAfterLoad();
1129 // if a readonly medium has storage then it's stream is already based on temporary file
1130 if( !(pMedium
->GetOpenMode() & StreamMode::WRITE
) && !pMedium
->HasStorage_Impl() )
1131 // don't lock file opened read only
1132 pMedium
->CloseInStream();
1136 SetInitialized_Impl( false );
1138 // Title is not available until loading has finished
1139 Broadcast( SfxHint( SfxHintId::TitleChanged
) );
1140 if ( pImpl
->nEventId
!= SfxEventHintId::NONE
)
1141 PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
1144 void SfxObjectShell::TemplateDisconnectionAfterLoad()
1146 // document is created from a template
1147 //TODO/LATER: should the templates always be XML docs!
1149 SfxMedium
* pTmpMedium
= pMedium
;
1153 const OUString
aName( pTmpMedium
->GetName() );
1154 const SfxStringItem
* pTemplNamItem
= SfxItemSet::GetItem
<SfxStringItem
>(pTmpMedium
->GetItemSet(), SID_TEMPLATE_NAME
, false);
1155 OUString aTemplateName
;
1156 if ( pTemplNamItem
)
1157 aTemplateName
= pTemplNamItem
->GetValue();
1160 // !TODO/LATER: what's this?!
1161 // Interactive ( DClick, Contextmenu ) no long name is included
1162 aTemplateName
= getDocProperties()->getTitle();
1163 if ( aTemplateName
.isEmpty() )
1165 INetURLObject
aURL( aName
);
1166 aURL
.CutExtension();
1167 aTemplateName
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
);
1171 // set medium to noname
1172 pTmpMedium
->SetName( OUString(), true );
1173 pTmpMedium
->Init_Impl();
1179 if( IsPackageStorageFormat_Impl( *pTmpMedium
) )
1181 // untitled document must be based on temporary storage
1182 // the medium should not dispose the storage in this case
1183 uno::Reference
< embed::XStorage
> xTmpStor
= ::comphelper::OStorageHelper::GetTemporaryStorage();
1184 GetStorage()->copyToStorage( xTmpStor
);
1186 // the medium should disconnect from the original location
1187 // the storage should not be disposed since the document is still
1188 // based on it, but in DoSaveCompleted it will be disposed
1189 pTmpMedium
->CanDisposeStorage_Impl( false );
1190 pTmpMedium
->Close();
1192 // setting the new storage the medium will be based on
1193 pTmpMedium
->SetStorage_Impl( xTmpStor
);
1196 bool ok
= DoSaveCompleted( pTmpMedium
);
1197 assert(pMedium
!= nullptr);
1200 const SfxStringItem
* pSalvageItem
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_DOC_SALVAGE
, false);
1201 bool bSalvage
= pSalvageItem
!= nullptr;
1205 // some further initializations for templates
1206 SetTemplate_Impl( aName
, aTemplateName
, this );
1209 // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
1210 pTmpMedium
->CanDisposeStorage_Impl( false );
1214 SetError(ERRCODE_IO_GENERAL
);
1219 // some further initializations for templates
1220 SetTemplate_Impl( aName
, aTemplateName
, this );
1221 pTmpMedium
->CreateTempFile();
1224 // templates are never readonly
1225 pTmpMedium
->GetItemSet()->ClearItem( SID_DOC_READONLY
);
1226 pTmpMedium
->SetOpenMode( SFX_STREAM_READWRITE
, true );
1228 // notifications about possible changes in readonly state and document info
1229 Broadcast( SfxHint(SfxHintId::ModeChanged
) );
1231 // created untitled document can't be modified
1232 SetModified( false );
1236 bool SfxObjectShell::IsLoading() const
1239 Has FinishedLoading been called?
1242 return !( pImpl
->nLoadedFlags
& SfxLoadedFlags::MAINDOCUMENT
);
1246 void SfxObjectShell::CancelTransfers()
1249 Here can Transfers get canceled, which were not registered
1250 by RegisterTransfer.
1253 if( ( pImpl
->nLoadedFlags
& SfxLoadedFlags::ALL
) != SfxLoadedFlags::ALL
)
1255 pImpl
->bIsAbortingImport
= true;
1262 AutoReloadTimer_Impl::AutoReloadTimer_Impl(
1263 const OUString
& rURL
, sal_uInt32 nTime
, SfxObjectShell
* pSh
)
1264 : aUrl( rURL
), pObjSh( pSh
)
1266 SetTimeout( nTime
);
1270 void AutoReloadTimer_Impl::Invoke()
1272 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( pObjSh
);
1276 // Not possible/meaningful at the moment?
1277 if ( !pObjSh
->CanReload_Impl() || pObjSh
->IsAutoLoadLocked() || Application::IsUICaptured() )
1284 SfxAllItemSet
aSet( SfxGetpApp()->GetPool() );
1285 aSet
.Put( SfxBoolItem( SID_AUTOLOAD
, true ) );
1286 if ( !aUrl
.isEmpty() )
1287 aSet
.Put( SfxStringItem( SID_FILE_NAME
, aUrl
) );
1288 if (pObjSh
->HasName()) {
1290 SfxStringItem(SID_REFERER
, pObjSh
->GetMedium()->GetName()));
1292 SfxRequest
aReq( SID_RELOAD
, SfxCallMode::SLOT
, aSet
);
1293 // this will delete this
1294 pObjSh
->Get_Impl()->pReloadTimer
.reset();
1295 pFrame
->ExecReload_Impl( aReq
);
1299 // this will delete this
1300 pObjSh
->Get_Impl()->pReloadTimer
.reset();
1303 SfxModule
* SfxObjectShell::GetModule() const
1305 return GetFactory().GetModule();
1308 ErrCode
SfxObjectShell::CallBasic( const OUString
& rMacro
,
1309 const OUString
& rBasic
, SbxArray
* pArgs
,
1312 SfxApplication
* pApp
= SfxGetpApp();
1313 if( pApp
->GetName() != rBasic
)
1315 if ( !AdjustMacroMode() )
1316 return ERRCODE_IO_ACCESSDENIED
;
1319 BasicManager
*pMgr
= GetBasicManager();
1320 if( pApp
->GetName() == rBasic
)
1321 pMgr
= SfxApplication::GetBasicManager();
1322 ErrCode nRet
= SfxApplication::CallBasic( rMacro
, pMgr
, pArgs
, pRet
);
1328 bool lcl_isScriptAccessAllowed_nothrow( const Reference
< XInterface
>& _rxScriptContext
)
1332 Reference
< XEmbeddedScripts
> xScripts( _rxScriptContext
, UNO_QUERY
);
1333 if ( !xScripts
.is() )
1335 Reference
< XScriptInvocationContext
> xContext( _rxScriptContext
, UNO_QUERY_THROW
);
1336 xScripts
.set( xContext
->getScriptContainer(), UNO_SET_THROW
);
1339 return xScripts
->getAllowMacroExecution();
1341 catch( const Exception
& )
1343 DBG_UNHANDLED_EXCEPTION("sfx.doc");
1349 // don't allow LibreLogo to be used with our mouseover/etc dom-alike events
1350 bool SfxObjectShell::UnTrustedScript(const OUString
& rScriptURL
)
1352 if (!rScriptURL
.startsWith("vnd.sun.star.script:"))
1355 // ensure URL Escape Codes are decoded
1356 css::uno::Reference
<css::uri::XUriReference
> uri(
1357 css::uri::UriReferenceFactory::create(comphelper::getProcessComponentContext())->parse(rScriptURL
));
1358 css::uno::Reference
<css::uri::XVndSunStarScriptUrl
> sfUri(uri
, css::uno::UNO_QUERY
);
1363 // pyuno encodes path separator as |
1364 OUString sScript
= sfUri
->getName().replace('|', '/');
1366 // check if any path portion matches LibreLogo and ban it if it does
1367 sal_Int32 nIndex
= 0;
1370 OUString aToken
= sScript
.getToken(0, '/', nIndex
);
1371 if (aToken
.startsWithIgnoreAsciiCase("LibreLogo"))
1376 while (nIndex
>= 0);
1381 ErrCode
SfxObjectShell::CallXScript( const Reference
< XInterface
>& _rxScriptContext
, const OUString
& _rScriptURL
,
1382 const Sequence
< Any
>& aParams
, Any
& aRet
, Sequence
< sal_Int16
>& aOutParamIndex
, Sequence
< Any
>& aOutParam
, bool bRaiseError
, const css::uno::Any
* pCaller
)
1384 SAL_INFO("sfx", "in CallXScript" );
1385 ErrCode nErr
= ERRCODE_NONE
;
1387 bool bCaughtException
= false;
1391 if ( !lcl_isScriptAccessAllowed_nothrow( _rxScriptContext
) )
1392 return ERRCODE_IO_ACCESSDENIED
;
1394 if ( UnTrustedScript(_rScriptURL
) )
1395 return ERRCODE_IO_ACCESSDENIED
;
1397 // obtain/create a script provider
1398 Reference
< provider::XScriptProvider
> xScriptProvider
;
1399 Reference
< provider::XScriptProviderSupplier
> xSPS( _rxScriptContext
, UNO_QUERY
);
1401 xScriptProvider
.set( xSPS
->getScriptProvider() );
1403 if ( !xScriptProvider
.is() )
1405 Reference
< provider::XScriptProviderFactory
> xScriptProviderFactory
=
1406 provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
1407 xScriptProvider
.set( xScriptProviderFactory
->createScriptProvider( makeAny( _rxScriptContext
) ), UNO_SET_THROW
);
1410 // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
1411 ::framework::DocumentUndoGuard
aUndoGuard( _rxScriptContext
.get() );
1413 // obtain the script, and execute it
1414 Reference
< provider::XScript
> xScript( xScriptProvider
->getScript( _rScriptURL
), UNO_SET_THROW
);
1415 if ( pCaller
&& pCaller
->hasValue() )
1417 Reference
< beans::XPropertySet
> xProps( xScript
, uno::UNO_QUERY
);
1420 Sequence
< uno::Any
> aArgs( 1 );
1421 aArgs
[ 0 ] = *pCaller
;
1422 xProps
->setPropertyValue("Caller", uno::makeAny( aArgs
) );
1425 aRet
= xScript
->invoke( aParams
, aOutParamIndex
, aOutParam
);
1427 catch ( const uno::Exception
& )
1429 aException
= ::cppu::getCaughtException();
1430 bCaughtException
= true;
1431 nErr
= ERRCODE_BASIC_INTERNAL_ERROR
;
1434 if ( bCaughtException
&& bRaiseError
)
1436 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
1437 ScopedVclPtr
<VclAbstractDialog
> pScriptErrDlg( pFact
->CreateScriptErrorDialog( aException
) );
1438 if ( pScriptErrDlg
.get() )
1439 pScriptErrDlg
->Execute();
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 INetURLObject( pDoc
->GetMedium()->GetName() ).GetNewAbsURL( aURL
.copy( 4 ), &aObj
);
1482 xDocProps
->setAutoloadURL(
1483 aObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
1487 xDocProps
->setAutoloadSecs( nTime
);
1489 catch (lang::IllegalArgumentException
&)
1494 else if( rKV
.GetKey().equalsIgnoreAsciiCase( "expires" ) )
1496 DateTime
aDateTime( DateTime::EMPTY
);
1497 if( INetMIMEMessage::ParseDateField( rKV
.GetValue(), aDateTime
) )
1499 aDateTime
.ConvertToLocalTime();
1500 pDoc
->GetMedium()->SetExpired_Impl( aDateTime
);
1504 pDoc
->GetMedium()->SetExpired_Impl( Date( 1, 1, 1970 ) );
1509 void SfxHeaderAttributes_Impl::Append( const SvKeyValue
& rKV
)
1511 xIter
->Append( rKV
);
1512 if( bAlert
) SetAttribute( rKV
);
1515 SvKeyValueIterator
* SfxObjectShell::GetHeaderAttributes()
1517 if( !pImpl
->xHeaderAttributes
.is() )
1519 DBG_ASSERT( pMedium
, "No Medium" );
1520 pImpl
->xHeaderAttributes
= new SfxHeaderAttributes_Impl( this );
1522 return static_cast<SvKeyValueIterator
*>( pImpl
->xHeaderAttributes
.get() );
1525 void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
1527 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())
1528 ->ClearForSourceView();
1532 void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
1534 static_cast<SfxHeaderAttributes_Impl
*>(GetHeaderAttributes())
1538 bool SfxObjectShell::IsPreview() const
1543 bool bPreview
= false;
1544 const SfxStringItem
* pFlags
= SfxItemSet::GetItem
<SfxStringItem
>(pMedium
->GetItemSet(), SID_OPTIONS
, false);
1547 // Distributed values among individual items
1548 const OUString aFileFlags
= pFlags
->GetValue().toAsciiUpperCase();
1549 if ( -1 != aFileFlags
.indexOf( 'B' ) )
1555 const SfxBoolItem
* pItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_PREVIEW
, false);
1557 bPreview
= pItem
->GetValue();
1563 void SfxObjectShell::SetWaitCursor( bool bSet
) const
1565 for( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this ); pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, this ) )
1568 pFrame
->GetFrame().GetWindow().EnterWait();
1570 pFrame
->GetFrame().GetWindow().LeaveWait();
1574 OUString
SfxObjectShell::GetAPIName() const
1576 INetURLObject
aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
1577 OUString
aName( aURL
.GetBase() );
1578 if( aName
.isEmpty() )
1579 aName
= aURL
.GetURLNoPass();
1580 if ( aName
.isEmpty() )
1581 aName
= GetTitle( SFX_TITLE_DETECT
);
1585 void SfxObjectShell::Invalidate( sal_uInt16 nId
)
1587 for( SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this ); pFrame
; pFrame
= SfxViewFrame::GetNext( *pFrame
, this ) )
1588 Invalidate_Impl( pFrame
->GetBindings(), nId
);
1591 bool SfxObjectShell::AdjustMacroMode()
1593 uno::Reference
< task::XInteractionHandler
> xInteraction
;
1595 xInteraction
= pMedium
->GetInteractionHandler();
1597 CheckForBrokenDocSignatures_Impl();
1599 CheckEncryption_Impl( xInteraction
);
1601 return pImpl
->aMacroMode
.adjustMacroMode( xInteraction
);
1604 vcl::Window
* SfxObjectShell::GetDialogParent( SfxMedium
const * pLoadingMedium
)
1606 VclPtr
<vcl::Window
> pWindow
;
1607 SfxItemSet
* pSet
= pLoadingMedium
? pLoadingMedium
->GetItemSet() : GetMedium()->GetItemSet();
1608 const SfxUnoFrameItem
* pUnoItem
= SfxItemSet::GetItem
<SfxUnoFrameItem
>(pSet
, SID_FILLFRAME
, false);
1611 const uno::Reference
< frame::XFrame
>& xFrame( pUnoItem
->GetFrame() );
1612 pWindow
= VCLUnoHelper::GetWindow( xFrame
->getContainerWindow() );
1617 SfxFrame
* pFrame
= nullptr;
1618 const SfxFrameItem
* pFrameItem
= SfxItemSet::GetItem
<SfxFrameItem
>(pSet
, SID_DOCFRAME
, false);
1619 if( pFrameItem
&& pFrameItem
->GetFrame() )
1620 // get target frame from ItemSet
1621 pFrame
= pFrameItem
->GetFrame();
1624 // try the current frame
1625 SfxViewFrame
* pView
= SfxViewFrame::Current();
1626 if ( !pView
|| pView
->GetObjectShell() != this )
1627 // get any visible frame
1628 pView
= SfxViewFrame::GetFirst(this);
1630 pFrame
= &pView
->GetFrame();
1634 // get topmost window
1635 pWindow
= VCLUnoHelper::GetWindow( pFrame
->GetFrameInterface()->getContainerWindow() );
1640 // this frame may be invisible, show it if it is allowed
1641 const SfxBoolItem
* pHiddenItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pSet
, SID_HIDDEN
, false);
1642 if ( !pHiddenItem
|| !pHiddenItem
->GetValue() )
1652 void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode
)
1654 eCreateMode
= nMode
;
1657 bool SfxObjectShell::IsInPlaceActive()
1659 if ( eCreateMode
!= SfxObjectCreateMode::EMBEDDED
)
1662 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
1663 return pFrame
&& pFrame
->GetFrame().IsInPlace();
1666 bool SfxObjectShell::IsUIActive()
1668 if ( eCreateMode
!= SfxObjectCreateMode::EMBEDDED
)
1671 SfxViewFrame
* pFrame
= SfxViewFrame::GetFirst( this );
1672 return pFrame
&& pFrame
->GetFrame().IsInPlace() && pFrame
->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
1675 bool SfxObjectShell::UseInteractionToHandleError(
1676 const uno::Reference
< task::XInteractionHandler
>& xHandler
,
1679 bool bResult
= false;
1681 if ( xHandler
.is() )
1685 uno::Any aInteraction
;
1686 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > lContinuations(2);
1687 ::comphelper::OInteractionAbort
* pAbort
= new ::comphelper::OInteractionAbort();
1688 ::comphelper::OInteractionApprove
* pApprove
= new ::comphelper::OInteractionApprove();
1689 lContinuations
[0].set( static_cast< task::XInteractionContinuation
* >( pAbort
), uno::UNO_QUERY
);
1690 lContinuations
[1].set( static_cast< task::XInteractionContinuation
* >( pApprove
), uno::UNO_QUERY
);
1692 task::ErrorCodeRequest aErrorCode
;
1693 aErrorCode
.ErrCode
= sal_uInt32(nError
);
1694 aInteraction
<<= aErrorCode
;
1695 xHandler
->handle(::framework::InteractionRequest::CreateRequest (aInteraction
,lContinuations
));
1696 bResult
= pAbort
->wasSelected();
1698 catch( uno::Exception
& )
1705 sal_Int16
SfxObjectShell_Impl::getCurrentMacroExecMode() const
1707 sal_Int16
nImposedExecMode( MacroExecMode::NEVER_EXECUTE
);
1709 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1710 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1713 const SfxUInt16Item
* pMacroModeItem
= SfxItemSet::GetItem
<SfxUInt16Item
>(pMedium
->GetItemSet(), SID_MACROEXECMODE
, false);
1714 if ( pMacroModeItem
)
1715 nImposedExecMode
= pMacroModeItem
->GetValue();
1717 return nImposedExecMode
;
1720 void SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode
)
1722 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1723 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1726 pMedium
->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE
, nMacroMode
) );
1730 OUString
SfxObjectShell_Impl::getDocumentLocation() const
1734 const SfxMedium
* pMedium( rDocShell
.GetMedium() );
1735 OSL_PRECOND( pMedium
, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
1738 sLocation
= pMedium
->GetName();
1739 if ( sLocation
.isEmpty() )
1741 // for documents made from a template: get the name of the template
1742 sLocation
= rDocShell
.getDocProperties()->getTemplateURL();
1748 bool SfxObjectShell_Impl::documentStorageHasMacros() const
1750 return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage
);
1753 bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const
1755 return rDocShell
.GetMacroCallsSeenWhileLoading();
1758 Reference
< XEmbeddedScripts
> SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
1760 return Reference
< XEmbeddedScripts
>( rDocShell
.GetModel(), UNO_QUERY
);
1763 SignatureState
SfxObjectShell_Impl::getScriptingSignatureState()
1765 SignatureState
nSignatureState( rDocShell
.GetScriptingSignatureState() );
1767 if ( nSignatureState
!= SignatureState::NOSIGNATURES
&& m_bMacroSignBroken
)
1769 // if there is a macro signature it must be handled as broken
1770 nSignatureState
= SignatureState::BROKEN
;
1773 return nSignatureState
;
1776 bool SfxObjectShell_Impl::hasTrustedScriptingSignature( bool bAllowUIToAddAuthor
)
1778 bool bResult
= false;
1785 uno::Reference
< beans::XPropertySet
> xPropSet( rDocShell
.GetStorage(), uno::UNO_QUERY_THROW
);
1786 xPropSet
->getPropertyValue("Version") >>= aVersion
;
1788 catch( uno::Exception
& )
1792 uno::Reference
< security::XDocumentDigitalSignatures
> xSigner( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion
) );
1794 if ( nScriptingSignatureState
== SignatureState::UNKNOWN
1795 || nScriptingSignatureState
== SignatureState::OK
1796 || nScriptingSignatureState
== SignatureState::NOTVALIDATED
)
1798 uno::Sequence
< security::DocumentSignatureInformation
> aInfo
= rDocShell
.GetDocumentSignatureInformation( true, xSigner
);
1800 if ( aInfo
.hasElements() )
1802 if ( nScriptingSignatureState
== SignatureState::UNKNOWN
)
1803 nScriptingSignatureState
= SfxObjectShell::ImplCheckSignaturesInformation( aInfo
);
1805 if ( nScriptingSignatureState
== SignatureState::OK
1806 || nScriptingSignatureState
== SignatureState::NOTVALIDATED
)
1808 bResult
= std::any_of(aInfo
.begin(), aInfo
.end(),
1809 [&xSigner
](const security::DocumentSignatureInformation
& rInfo
) {
1810 return xSigner
->isAuthorTrusted( rInfo
.Signer
); });
1812 if ( !bResult
&& bAllowUIToAddAuthor
)
1814 uno::Reference
< task::XInteractionHandler
> xInteraction
;
1815 if ( rDocShell
.GetMedium() )
1816 xInteraction
= rDocShell
.GetMedium()->GetInteractionHandler();
1818 if ( xInteraction
.is() )
1820 task::DocumentMacroConfirmationRequest aRequest
;
1821 aRequest
.DocumentURL
= getDocumentLocation();
1822 aRequest
.DocumentStorage
= rDocShell
.GetMedium()->GetZipStorageToSign_Impl();
1823 aRequest
.DocumentSignatureInformation
= aInfo
;
1824 aRequest
.DocumentVersion
= aVersion
;
1825 aRequest
.Classification
= task::InteractionClassification_QUERY
;
1826 bResult
= SfxMedium::CallApproveHandler( xInteraction
, uno::makeAny( aRequest
), true );
1833 catch( uno::Exception
& )
1839 bool SfxObjectShell::IsContinueImportOnFilterExceptions(const OUString
& aErrMessage
)
1841 if (mbContinueImportOnFilterExceptions
== undefined
)
1843 if (Application::GetDialogCancelMode() == DialogCancelMode::Off
)
1845 // Ask the user to try to continue or abort loading
1846 OUString aMessage
= SfxResId(STR_QMSG_ERROR_OPENING_FILE
);
1847 if (!aErrMessage
.isEmpty())
1848 aMessage
+= SfxResId(STR_QMSG_ERROR_OPENING_FILE_DETAILS
) + aErrMessage
;
1849 aMessage
+= SfxResId(STR_QMSG_ERROR_OPENING_FILE_CONTINUE
);
1850 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
1851 VclMessageType::Question
, VclButtonsType::YesNo
, aMessage
));
1852 mbContinueImportOnFilterExceptions
= (xBox
->run() == RET_YES
) ? yes
: no
;
1855 mbContinueImportOnFilterExceptions
= no
;
1857 return mbContinueImportOnFilterExceptions
== yes
;
1860 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */