warn on load when a document binds an event to a macro
[LibreOffice.git] / sfx2 / source / doc / objmisc.cxx
bloba61e1e8b42e1c49b27956c9751987c6379a4aeb4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
119 #include <memory>
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
134 private:
135 SfxObjectShell* pDoc;
136 SvKeyValueIteratorRef xIter;
137 bool bAlert;
139 public:
140 explicit SfxHeaderAttributes_Impl( SfxObjectShell* pSh ) :
141 SvKeyValueIterator(), pDoc( pSh ),
142 xIter( pSh->GetMedium()->GetHeaderAttributes_Impl() ),
143 bAlert( false ) {}
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] =
157 // local remote
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");
179 return xDocProps;
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()
192 if ( IsLoading() )
193 return;
195 SetModified();
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)
208 pImpl->lErr=lErr;
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();
222 return lError;
225 void SfxObjectShell::ResetError()
227 pImpl->lErr=ERRCODE_NONE;
228 SfxMedium * pMed = GetMedium();
229 if( pMed )
230 pMed->ResetError();
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 )
249 return true;
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
256 return false;
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!" );
266 if ( xObj.is() )
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() )
275 return true;
278 catch( uno::Exception& )
284 return false;
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() )
294 return;
296 if( pImpl->m_bIsModified != bModifiedP )
298 pImpl->m_bIsModified = bModifiedP;
299 ModifyChanged();
304 void SfxObjectShell::ModifyChanged()
306 if ( pImpl->bClosing )
307 // SetModified dispose of the models!
308 return;
311 SfxViewFrame* pViewFrame = SfxViewFrame::Current();
312 if ( pViewFrame )
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
325 /* [Description]
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
338 /* [Description]
340 Returns sal_True when the medium is r/o, for instance when opened as r/o.
344 if ( !pMedium )
345 return true;
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 )
362 /* [Description]
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() )
384 return;
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 ) );
398 if ( !bWasROUI )
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
433 // an endless loop
434 if ( pImpl->bModalMode == bModal )
435 return;
437 // Central count
438 sal_uInt16 &rDocModalCount = SfxGetpApp()->Get_Impl()->nDocModalMode;
439 if ( bModal )
440 ++rDocModalCount;
441 else
442 --rDocModalCount;
444 // Switch
445 pImpl->bModalMode = bModal;
446 Broadcast( SfxHint( SfxHintId::ModeChanged ) );
449 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
451 bool SfxObjectShell::SwitchToShared( bool bShared, bool bSave )
453 bool bResult = true;
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 );
467 if ( pViewFrame )
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() );
473 if ( bResult )
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& )
492 bResult = false;
496 if ( bResult && bSave )
498 SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
500 if ( pViewFrame )
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() );
510 if ( bResult )
512 // TODO/LATER: Is it possible that the following calls fail?
513 if ( bShared )
515 pImpl->m_aSharedFileURL = aOrigURL;
516 GetMedium()->SwitchDocumentToTempFile();
518 else
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& )
538 else
540 // the saving has failed!
541 if ( bRemoveEntryOnError )
545 ::svt::ShareControlFile aControlFile( aOrigURL );
546 aControlFile.RemoveEntry();
548 catch( uno::Exception& )
552 SetSharedXMLFlag( bOldValue );
555 else
556 bResult = false; // the second switch to the same mode
558 if ( bResult )
559 SetTitle( "" );
561 return bResult;
565 void SfxObjectShell::FreeSharedFile( const OUString& aTempFileURL )
567 SetSharedXMLFlag( false );
569 if ( !IsDocShared() || aTempFileURL.isEmpty()
570 || ::utl::UCBContentHelper::EqualURLs( aTempFileURL, GetSharedFileURL() ) )
571 return;
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;
612 #endif
614 bool SfxObjectShell::IsDocShared() const
616 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
617 return ( !pImpl->m_aSharedFileURL.isEmpty() );
618 #else
619 return false;
620 #endif
624 OUString SfxObjectShell::GetSharedFileURL() const
626 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
627 return pImpl->m_aSharedFileURL;
628 #else
629 return OUString();
630 #endif
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
652 /* [Description]
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.
662 // Nothing to do?
663 if ( ( ( HasName() && pImpl->aTitle == rTitle )
664 || ( !HasName() && GetTitle() == rTitle ) )
665 && !IsDocShared() )
666 return;
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;
677 // Set Title
678 pImpl->aTitle = rTitle;
680 // Notification
681 if ( GetMedium() )
683 SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) );
684 Broadcast( SfxHint(SfxHintId::TitleChanged) );
690 OUString SfxObjectShell::GetTitle( sal_uInt16 nMaxLength ) const
692 /* [Description]
694 Returns the title or logical file name of the document, depending on the
695 'nMaxLength'.
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
699 in complete form.
703 SfxMedium *pMed = GetMedium();
704 if ( IsLoading() )
705 return OUString();
707 // Create Title?
708 if ( SFX_TITLE_DETECT == nMaxLength && pImpl->aTitle.isEmpty() )
710 static bool bRecur = false;
711 if ( bRecur )
712 return "-not available-";
713 bRecur = true;
715 OUString aTitle;
717 if ( pMed )
719 const SfxStringItem* pNameItem = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_DOCINFO_TITLE, false);
720 if ( pNameItem )
721 aTitle = pNameItem->GetValue();
724 if ( aTitle.isEmpty() )
725 aTitle = GetTitle( SFX_TITLE_FILENAME );
727 bRecur = false;
728 return aTitle;
731 if (SFX_TITLE_APINAME == nMaxLength )
732 return GetAPIName();
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);
741 if ( pNameItem )
742 return pNameItem->GetValue();
745 // Still unnamed?
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)
757 // Append number
758 return aNoName + " " + OUString::number(pImpl->nVisualDocumentNumber);
761 // Document called "Untitled" for the time being
762 return aNoName;
764 assert(pMed);
766 const INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
767 if ( nMaxLength > SFX_TITLE_CAPTION && nMaxLength <= SFX_TITLE_HISTORY )
769 sal_uInt16 nRemote;
770 if (aURL.GetProtocol() == INetProtocol::File)
771 nRemote = 0;
772 else
773 nRemote = 1;
774 nMaxLength = aTitleMap_Impl[nMaxLength-SFX_TITLE_CAPTION][nRemote];
777 // Local file?
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 );
788 else
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 );
795 return aComplete;
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 );
814 // Complete Title
815 return pImpl->aTitle;
819 void SfxObjectShell::InvalidateName()
821 /* [Description]
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()
852 bHasName = false;
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 */
869 /* [Description]
871 Internal method to set or reset the Progress modes for
872 SfxObjectShell.
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() )
887 return;
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;
927 if ( GetMedium() )
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 )
942 OUString aVersion;
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 )
958 return;
960 // this is ODF1.2 or later
961 if ( !(bIsEncrypted && bHasNonEncrypted) )
962 return;
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 )
984 return;
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();
995 if ( bReload )
997 pImpl->pReloadTimer.reset(new AutoReloadTimer_Impl(
998 rUrl.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ),
999 nTime, this ));
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 )
1017 return;
1019 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE, false);
1020 if ( pSalvageItem )
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() ) );
1027 else
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();
1035 if ( xModel.is() )
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();
1052 if( pFlt )
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() )
1066 SetReadOnly();
1068 // Salvage
1069 if ( pSalvageItem )
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 )
1105 return;
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 )
1111 SetModified();
1112 else
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!" );
1123 if ( bTemplate )
1125 TemplateDisconnectionAfterLoad();
1127 else
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;
1150 if ( !pTmpMedium )
1151 return;
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();
1158 else
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();
1175 // drop resource
1176 SetNoName();
1177 InvalidateName();
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 );
1195 pMedium = nullptr;
1196 bool ok = DoSaveCompleted( pTmpMedium );
1197 assert(pMedium != nullptr);
1198 if( ok )
1200 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE, false);
1201 bool bSalvage = pSalvageItem != nullptr;
1203 if ( !bSalvage )
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 );
1212 else
1214 SetError(ERRCODE_IO_GENERAL);
1217 else
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
1237 /* [Description]
1239 Has FinishedLoading been called?
1242 return !( pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT );
1246 void SfxObjectShell::CancelTransfers()
1247 /* [Description]
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;
1256 if( IsLoading() )
1257 FinishedLoading();
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 );
1274 if ( pFrame )
1276 // Not possible/meaningful at the moment?
1277 if ( !pObjSh->CanReload_Impl() || pObjSh->IsAutoLoadLocked() || Application::IsUICaptured() )
1279 // Allow a retry
1280 Start();
1281 return;
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()) {
1289 aSet.Put(
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 );
1296 return;
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,
1310 SbxValue* pRet )
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 );
1323 return nRet;
1326 namespace
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");
1345 return false;
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:"))
1353 return false;
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);
1360 if (!sfUri.is())
1361 return false;
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"))
1373 return true;
1376 while (nIndex >= 0);
1378 return false;
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;
1388 Any aException;
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 );
1400 if ( xSPS.is() )
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 );
1418 if ( xProps.is() )
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" );
1443 return nErr;
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,
1453 bool bRaiseError,
1454 const css::uno::Any* pCaller )
1456 return CallXScript( GetModel(), rScriptURL, aParams, aRet, aOutParamIndex, aOutParam, bRaiseError, pCaller );
1459 void SfxHeaderAttributes_Impl::SetAttributes()
1461 bAlert = true;
1462 SvKeyValue aPair;
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=" ) )
1480 INetURLObject aObj;
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 &)
1491 // ignore
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 );
1502 else
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())
1535 ->SetAttributes();
1538 bool SfxObjectShell::IsPreview() const
1540 if ( !pMedium )
1541 return false;
1543 bool bPreview = false;
1544 const SfxStringItem* pFlags = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_OPTIONS, false);
1545 if ( pFlags )
1547 // Distributed values among individual items
1548 const OUString aFileFlags = pFlags->GetValue().toAsciiUpperCase();
1549 if ( -1 != aFileFlags.indexOf( 'B' ) )
1550 bPreview = true;
1553 if ( !bPreview )
1555 const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_PREVIEW, false);
1556 if ( pItem )
1557 bPreview = pItem->GetValue();
1560 return bPreview;
1563 void SfxObjectShell::SetWaitCursor( bool bSet ) const
1565 for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
1567 if ( bSet )
1568 pFrame->GetFrame().GetWindow().EnterWait();
1569 else
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 );
1582 return aName;
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;
1594 if ( pMedium )
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);
1609 if ( pUnoItem )
1611 const uno::Reference < frame::XFrame >& xFrame( pUnoItem->GetFrame() );
1612 pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1615 if ( !pWindow )
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();
1622 else
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);
1629 if ( pView )
1630 pFrame = &pView->GetFrame();
1633 if ( pFrame )
1634 // get topmost window
1635 pWindow = VCLUnoHelper::GetWindow( pFrame->GetFrameInterface()->getContainerWindow() );
1638 if ( pWindow )
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() )
1644 pWindow->Show();
1645 pWindow->ToTop();
1649 return pWindow;
1652 void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode )
1654 eCreateMode = nMode;
1657 bool SfxObjectShell::IsInPlaceActive()
1659 if ( eCreateMode != SfxObjectCreateMode::EMBEDDED )
1660 return false;
1662 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
1663 return pFrame && pFrame->GetFrame().IsInPlace();
1666 bool SfxObjectShell::IsUIActive()
1668 if ( eCreateMode != SfxObjectCreateMode::EMBEDDED )
1669 return false;
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,
1677 ErrCode nError )
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& )
1702 return bResult;
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!" );
1711 if ( pMedium )
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!" );
1724 if ( pMedium )
1726 pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE, nMacroMode ) );
1730 OUString SfxObjectShell_Impl::getDocumentLocation() const
1732 OUString sLocation;
1734 const SfxMedium* pMedium( rDocShell.GetMedium() );
1735 OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
1736 if ( pMedium )
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();
1745 return sLocation;
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;
1782 OUString aVersion;
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& )
1836 return bResult;
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;
1854 else
1855 mbContinueImportOnFilterExceptions = no;
1857 return mbContinueImportOnFilterExceptions == yes;
1860 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */