Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / sfx2 / source / doc / objmisc.cxx
blob75d8e1505987c19f816aa60779a538688ba835c4
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>
22 #include <tools/inetmsg.hxx>
23 #include <tools/diagnose_ex.h>
24 #include <svl/eitem.hxx>
25 #include <svl/stritem.hxx>
26 #include <svl/intitem.hxx>
27 #include <svtools/svparser.hxx>
28 #include <cppuhelper/exc_hlp.hxx>
29 #include <sal/log.hxx>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/container/XChild.hpp>
33 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
34 #include <com/sun/star/document/XDocumentProperties.hpp>
35 #include <com/sun/star/document/MacroExecMode.hpp>
36 #include <com/sun/star/document/XScriptInvocationContext.hpp>
37 #include <com/sun/star/embed/EmbedStates.hpp>
38 #include <com/sun/star/embed/XEmbeddedObject.hpp>
39 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
40 #include <com/sun/star/script/provider/XScript.hpp>
41 #include <com/sun/star/script/provider/XScriptProvider.hpp>
42 #include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
43 #include <com/sun/star/uri/UriReferenceFactory.hpp>
44 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
45 #include <com/sun/star/util/XModifiable.hpp>
47 #include <toolkit/helper/vclunohelper.hxx>
49 #include <com/sun/star/uno/Reference.h>
50 #include <com/sun/star/uno/Any.h>
51 #include <com/sun/star/task/ErrorCodeRequest.hpp>
53 #include <comphelper/processfactory.hxx>
54 #include <comphelper/string.hxx>
56 #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
57 #include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
58 #include <com/sun/star/task/InteractionClassification.hpp>
59 #include <com/sun/star/task/XInteractionHandler.hpp>
60 #include <com/sun/star/frame/XModel.hpp>
62 #include <basic/basmgr.hxx>
63 #include <basic/sberrors.hxx>
64 #include <vcl/weld.hxx>
65 #include <basic/sbx.hxx>
66 #include <svtools/sfxecode.hxx>
68 #include <unotools/ucbhelper.hxx>
69 #include <tools/urlobj.hxx>
70 #include <svl/sharecontrolfile.hxx>
71 #include <rtl/uri.hxx>
72 #include <vcl/svapp.hxx>
73 #include <framework/interaction.hxx>
74 #include <framework/documentundoguard.hxx>
75 #include <comphelper/interaction.hxx>
76 #include <comphelper/storagehelper.hxx>
77 #include <comphelper/documentconstants.hxx>
78 #include <comphelper/namedvaluecollection.hxx>
79 #include <officecfg/Office/Common.hxx>
81 #include <sfx2/signaturestate.hxx>
82 #include <sfx2/app.hxx>
83 #include <appdata.hxx>
84 #include <sfx2/request.hxx>
85 #include <sfx2/bindings.hxx>
86 #include <sfx2/sfxresid.hxx>
87 #include <sfx2/docfile.hxx>
88 #include <sfx2/docfilt.hxx>
89 #include <sfx2/objsh.hxx>
90 #include <objshimp.hxx>
91 #include <sfx2/event.hxx>
92 #include <sfx2/viewfrm.hxx>
93 #include <sfx2/sfxuno.hxx>
94 #include <sfx2/module.hxx>
95 #include <sfx2/docfac.hxx>
96 #include <sfx2/sfxsids.hrc>
97 #include <sfx2/strings.hrc>
98 #include <workwin.hxx>
99 #include <sfx2/sfxdlg.hxx>
100 #include <sfx2/infobar.hxx>
101 #include <openflag.hxx>
102 #include "objstor.hxx"
103 #include <appopen.hxx>
105 #include <memory>
107 using namespace ::com::sun::star;
108 using namespace ::com::sun::star::uno;
109 using namespace ::com::sun::star::ucb;
110 using namespace ::com::sun::star::document;
111 using namespace ::com::sun::star::frame;
112 using namespace ::com::sun::star::script;
113 using namespace ::com::sun::star::script::provider;
114 using namespace ::com::sun::star::container;
116 // class SfxHeaderAttributes_Impl ----------------------------------------
118 namespace {
120 class SfxHeaderAttributes_Impl : public SvKeyValueIterator
122 private:
123 SfxObjectShell* pDoc;
124 SvKeyValueIteratorRef xIter;
125 bool bAlert;
127 public:
128 explicit SfxHeaderAttributes_Impl( SfxObjectShell* pSh ) :
129 SvKeyValueIterator(), pDoc( pSh ),
130 xIter( pSh->GetMedium()->GetHeaderAttributes_Impl() ),
131 bAlert( false ) {}
133 virtual bool GetFirst( SvKeyValue& rKV ) override { return xIter->GetFirst( rKV ); }
134 virtual bool GetNext( SvKeyValue& rKV ) override { return xIter->GetNext( rKV ); }
135 virtual void Append( const SvKeyValue& rKV ) override;
137 void ClearForSourceView() { xIter = new SvKeyValueIterator; bAlert = false; }
138 void SetAttributes();
139 void SetAttribute( const SvKeyValue& rKV );
144 sal_uInt16 const aTitleMap_Impl[3][2] =
146 // local remote
147 /* SFX_TITLE_CAPTION */ { SFX_TITLE_FILENAME, SFX_TITLE_TITLE },
148 /* SFX_TITLE_PICKLIST */ { 32, SFX_TITLE_FULLNAME },
149 /* SFX_TITLE_HISTORY */ { 32, SFX_TITLE_FULLNAME }
153 bool SfxObjectShell::IsAbortingImport() const
155 return pImpl->bIsAbortingImport;
159 uno::Reference<document::XDocumentProperties>
160 SfxObjectShell::getDocProperties() const
162 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
163 GetModel(), uno::UNO_QUERY_THROW);
164 uno::Reference<document::XDocumentProperties> xDocProps(
165 xDPS->getDocumentProperties());
166 DBG_ASSERT(xDocProps.is(),
167 "SfxObjectShell: model has no DocumentProperties");
168 return xDocProps;
172 void SfxObjectShell::DoFlushDocInfo()
177 // Note: the only thing that calls this is the modification event handler
178 // that is installed at the XDocumentProperties
179 void SfxObjectShell::FlushDocInfo()
181 if ( IsLoading() )
182 return;
184 SetModified();
185 uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
186 DoFlushDocInfo(); // call template method
187 const OUString url(xDocProps->getAutoloadURL());
188 sal_Int32 delay(xDocProps->getAutoloadSecs());
189 SetAutoLoad( INetURLObject(url), delay * 1000,
190 (delay > 0) || !url.isEmpty() );
193 void SfxObjectShell::AppendInfoBarWhenReady(const OUString& sId, const OUString& sPrimaryMessage,
194 const OUString& sSecondaryMessage,
195 InfobarType aInfobarType, bool bShowCloseButton)
197 InfobarData aInfobarData;
198 aInfobarData.msId = sId;
199 aInfobarData.msPrimaryMessage = sPrimaryMessage;
200 aInfobarData.msSecondaryMessage = sSecondaryMessage;
201 aInfobarData.maInfobarType = aInfobarType;
202 aInfobarData.mbShowCloseButton = bShowCloseButton;
203 Get_Impl()->m_aPendingInfobars.emplace_back(aInfobarData);
206 std::vector<InfobarData>& SfxObjectShell::getPendingInfobars()
208 return Get_Impl()->m_aPendingInfobars;
211 void SfxObjectShell::SetError(ErrCode lErr)
213 if (pImpl->lErr==ERRCODE_NONE)
215 pImpl->lErr=lErr;
219 ErrCode SfxObjectShell::GetError() const
221 return GetErrorCode().IgnoreWarning();
224 ErrCode SfxObjectShell::GetErrorCode() const
226 ErrCode lError=pImpl->lErr;
227 if(!lError && GetMedium())
228 lError=GetMedium()->GetErrorCode();
229 return lError;
232 void SfxObjectShell::ResetError()
234 pImpl->lErr=ERRCODE_NONE;
235 SfxMedium * pMed = GetMedium();
236 if( pMed )
237 pMed->ResetError();
240 void SfxObjectShell::EnableSetModified( bool bEnable )
242 SAL_INFO_IF( bEnable == pImpl->m_bEnableSetModified, "sfx", "SFX_PERSIST: EnableSetModified 2x called with the same value" );
243 pImpl->m_bEnableSetModified = bEnable;
247 bool SfxObjectShell::IsEnableSetModified() const
249 return pImpl->m_bEnableSetModified && !IsReadOnly();
253 bool SfxObjectShell::IsModified() const
255 if ( pImpl->m_bIsModified )
256 return true;
258 if ( !pImpl->m_xDocStorage.is() || IsReadOnly() )
260 // if the document still has no storage and is not set to be modified explicitly it is not modified
261 // a readonly document is also not modified
263 return false;
266 if (pImpl->mxObjectContainer)
268 const uno::Sequence < OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
269 for ( const auto& rName : aNames )
271 uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( rName );
272 OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!" );
273 if ( xObj.is() )
277 sal_Int32 nState = xObj->getCurrentState();
278 if ( nState != embed::EmbedStates::LOADED )
280 uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
281 if ( xModifiable.is() && xModifiable->isModified() )
282 return true;
285 catch( uno::Exception& )
291 return false;
295 void SfxObjectShell::SetModified( bool bModifiedP )
297 SAL_INFO_IF( !bModifiedP && !IsEnableSetModified(), "sfx",
298 "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False" );
300 if( !IsEnableSetModified() )
301 return;
303 if( pImpl->m_bIsModified != bModifiedP )
305 pImpl->m_bIsModified = bModifiedP;
306 ModifyChanged();
311 void SfxObjectShell::ModifyChanged()
313 if ( pImpl->bClosing )
314 // SetModified dispose of the models!
315 return;
318 SfxViewFrame* pViewFrame = SfxViewFrame::Current();
319 if ( pViewFrame )
320 pViewFrame->GetBindings().Invalidate( SID_SAVEDOCS );
322 Invalidate( SID_SIGNATURE );
323 Invalidate( SID_MACRO_SIGNATURE );
324 Broadcast( SfxHint( SfxHintId::TitleChanged ) ); // xmlsec05, signed state might change in title...
326 SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::ModifyChanged, GlobalEventConfig::GetEventName(GlobalEventId::MODIFYCHANGED), this ) );
330 bool SfxObjectShell::IsReadOnlyUI() const
332 /* [Description]
334 Returns sal_True if the document for the UI is treated as r/o. This is
335 regardless of the actual r/o, which can be checked with <IsReadOnly()>.
339 return pImpl->bReadOnlyUI;
343 bool SfxObjectShell::IsReadOnlyMedium() const
345 /* [Description]
347 Returns sal_True when the medium is r/o, for instance when opened as r/o.
351 if ( !pMedium )
352 return true;
353 return pMedium->IsReadOnly();
356 bool SfxObjectShell::IsOriginallyReadOnlyMedium() const
358 return pMedium == nullptr || pMedium->IsOriginallyReadOnly();
361 bool SfxObjectShell::IsOriginallyLoadedReadOnlyMedium() const
363 return pMedium != nullptr && pMedium->IsOriginallyLoadedReadOnly();
367 void SfxObjectShell::SetReadOnlyUI( bool bReadOnly )
369 /* [Description]
371 Turns the document in a r/o and r/w state respectively without reloading
372 it and without changing the open mode of the medium.
376 if ( bReadOnly != pImpl->bReadOnlyUI )
378 pImpl->bReadOnlyUI = bReadOnly;
379 Broadcast( SfxHint(SfxHintId::ModeChanged) );
384 void SfxObjectShell::SetReadOnly()
386 // Let the document be completely readonly, means that the
387 // medium open mode is adjusted accordingly, and the write lock
388 // on the file is removed.
390 if ( !pMedium || IsReadOnlyMedium() )
391 return;
393 bool bWasROUI = IsReadOnly();
395 pMedium->UnlockFile( false );
397 // the storage-based mediums are already based on the temporary file
398 // so UnlockFile has already closed the locking stream
399 if ( !pMedium->HasStorage_Impl() && IsLoadingFinished() )
400 pMedium->CloseInStream();
402 pMedium->SetOpenMode( SFX_STREAM_READONLY, true );
403 pMedium->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
405 if ( !bWasROUI )
406 Broadcast( SfxHint(SfxHintId::ModeChanged) );
410 bool SfxObjectShell::IsReadOnly() const
412 return pImpl->bReadOnlyUI || pMedium == nullptr;
416 bool SfxObjectShell::IsInModalMode() const
418 return pImpl->bModalMode || pImpl->bRunningMacro;
421 bool SfxObjectShell::AcceptStateUpdate() const
423 return !IsInModalMode();
427 void SfxObjectShell::SetMacroMode_Impl( bool bModal )
429 if ( !pImpl->bRunningMacro != !bModal )
431 pImpl->bRunningMacro = bModal;
432 Broadcast( SfxHint( SfxHintId::ModeChanged ) );
437 void SfxObjectShell::SetModalMode_Impl( bool bModal )
439 // Broadcast only if modified, or otherwise it will possibly go into
440 // an endless loop
441 if ( pImpl->bModalMode == bModal )
442 return;
444 // Central count
445 sal_uInt16 &rDocModalCount = SfxGetpApp()->Get_Impl()->nDocModalMode;
446 if ( bModal )
447 ++rDocModalCount;
448 else
449 --rDocModalCount;
451 // Switch
452 pImpl->bModalMode = bModal;
453 Broadcast( SfxHint( SfxHintId::ModeChanged ) );
456 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
458 bool SfxObjectShell::SwitchToShared( bool bShared, bool bSave )
460 bool bResult = true;
462 if ( bShared != IsDocShared() )
464 OUString aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
466 if ( aOrigURL.isEmpty() && bSave )
468 // this is a new document, let it be stored before switching to the shared mode;
469 // the storing should be done without shared flag, since it is possible that the
470 // target location does not allow to create sharing control file;
471 // the shared flag will be set later after creation of sharing control file
472 SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
474 if ( pViewFrame )
476 // TODO/LATER: currently the application guards against the reentrance problem
477 const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC );
478 const SfxBoolItem* pResult = dynamic_cast<const SfxBoolItem*>( pItem );
479 bResult = ( pResult && pResult->GetValue() );
480 if ( bResult )
481 aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
485 bool bOldValue = HasSharedXMLFlagSet();
486 SetSharedXMLFlag( bShared );
488 bool bRemoveEntryOnError = false;
489 if ( bResult && bShared )
493 ::svt::ShareControlFile aControlFile( aOrigURL );
494 aControlFile.InsertOwnEntry();
495 bRemoveEntryOnError = true;
497 catch( uno::Exception& )
499 bResult = false;
503 if ( bResult && bSave )
505 SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
507 if ( pViewFrame )
509 // TODO/LATER: currently the application guards against the reentrance problem
510 SetModified(); // the modified flag has to be set to let the document be stored with the shared flag
511 const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC );
512 const SfxBoolItem* pResult = dynamic_cast<const SfxBoolItem*>( pItem );
513 bResult = ( pResult && pResult->GetValue() );
517 if ( bResult )
519 // TODO/LATER: Is it possible that the following calls fail?
520 if ( bShared )
522 pImpl->m_aSharedFileURL = aOrigURL;
523 GetMedium()->SwitchDocumentToTempFile();
525 else
527 const OUString aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
528 GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
529 pImpl->m_aSharedFileURL.clear();
531 // now remove the temporary file the document was based on
532 ::utl::UCBContentHelper::Kill( aTempFileURL );
536 // aOrigURL can not be used since it contains an old value
537 ::svt::ShareControlFile aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
538 aControlFile.RemoveFile();
540 catch( uno::Exception& )
545 else
547 // the saving has failed!
548 if ( bRemoveEntryOnError )
552 ::svt::ShareControlFile aControlFile( aOrigURL );
553 aControlFile.RemoveEntry();
555 catch( uno::Exception& )
559 SetSharedXMLFlag( bOldValue );
562 else
563 bResult = false; // the second switch to the same mode
565 if ( bResult )
566 SetTitle( "" );
568 return bResult;
572 void SfxObjectShell::FreeSharedFile( const OUString& aTempFileURL )
574 SetSharedXMLFlag( false );
576 if ( !IsDocShared() || aTempFileURL.isEmpty()
577 || ::utl::UCBContentHelper::EqualURLs( aTempFileURL, GetSharedFileURL() ) )
578 return;
580 if ( pImpl->m_bAllowShareControlFileClean )
584 ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
585 aControlFile.RemoveEntry();
587 catch( uno::Exception& )
592 // the cleaning is forbidden only once
593 pImpl->m_bAllowShareControlFileClean = true;
595 // now remove the temporary file the document is based currently on
596 ::utl::UCBContentHelper::Kill( aTempFileURL );
598 pImpl->m_aSharedFileURL.clear();
602 void SfxObjectShell::DoNotCleanShareControlFile()
604 pImpl->m_bAllowShareControlFileClean = false;
608 void SfxObjectShell::SetSharedXMLFlag( bool bFlag ) const
610 pImpl->m_bSharedXMLFlag = bFlag;
614 bool SfxObjectShell::HasSharedXMLFlagSet() const
616 return pImpl->m_bSharedXMLFlag;
619 #endif
621 bool SfxObjectShell::IsDocShared() const
623 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
624 return ( !pImpl->m_aSharedFileURL.isEmpty() );
625 #else
626 return false;
627 #endif
631 OUString SfxObjectShell::GetSharedFileURL() const
633 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
634 return pImpl->m_aSharedFileURL;
635 #else
636 return OUString();
637 #endif
640 Size SfxObjectShell::GetFirstPageSize() const
642 return GetVisArea(ASPECT_THUMBNAIL).GetSize();
646 IndexBitSet& SfxObjectShell::GetNoSet_Impl()
648 return pImpl->aBitSet;
652 // changes the title of the document
654 void SfxObjectShell::SetTitle
656 const OUString& rTitle // the new Document Title
659 /* [Description]
661 With this method, the title of the document can be set.
662 This corresponds initially to the full file name. A setting of the
663 title does not affect the file name, but it will be shown in the
664 Caption-Bars of the MDI-window.
669 // Nothing to do?
670 if ( ( ( HasName() && pImpl->aTitle == rTitle )
671 || ( !HasName() && GetTitle() == rTitle ) )
672 && !IsDocShared() )
673 return;
675 SfxApplication *pSfxApp = SfxGetpApp();
677 // If possible release the unnamed number.
678 if ( pImpl->bIsNamedVisible && USHRT_MAX != pImpl->nVisualDocumentNumber )
680 pSfxApp->ReleaseIndex(pImpl->nVisualDocumentNumber);
681 pImpl->bIsNamedVisible = false;
684 // Set Title
685 pImpl->aTitle = rTitle;
687 // Notification
688 if ( GetMedium() )
690 SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) );
691 Broadcast( SfxHint(SfxHintId::TitleChanged) );
697 OUString SfxObjectShell::GetTitle( sal_uInt16 nMaxLength ) const
699 /* [Description]
701 Returns the title or logical file name of the document, depending on the
702 'nMaxLength'.
704 If the file name with path is used, the Name shortened by replacing one or
705 more directory names with "...", URLs are currently always returned
706 in complete form.
710 SfxMedium *pMed = GetMedium();
711 if ( IsLoading() )
712 return OUString();
714 // Create Title?
715 if ( SFX_TITLE_DETECT == nMaxLength && pImpl->aTitle.isEmpty() )
717 static bool bRecur = false;
718 if ( bRecur )
719 return "-not available-";
720 bRecur = true;
722 OUString aTitle;
724 if ( pMed )
726 const SfxStringItem* pNameItem = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_DOCINFO_TITLE, false);
727 if ( pNameItem )
728 aTitle = pNameItem->GetValue();
731 if ( aTitle.isEmpty() )
732 aTitle = GetTitle( SFX_TITLE_FILENAME );
734 bRecur = false;
735 return aTitle;
738 if (SFX_TITLE_APINAME == nMaxLength )
739 return GetAPIName();
741 // Picklist/Caption is mapped
742 if ( pMed && ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) )
744 // If a specific title was given at open:
745 // important for URLs: use INetProtocol::File for which the set title is not
746 // considered. (See below, analysis of aTitleMap_Impl)
747 const SfxStringItem* pNameItem = SfxItemSet::GetItem<SfxStringItem>(pMed->GetItemSet(), SID_DOCINFO_TITLE, false);
748 if ( pNameItem )
749 return pNameItem->GetValue();
752 // Still unnamed?
753 DBG_ASSERT( !HasName() || pMed, "HasName() but no Medium?!?" );
754 if ( !HasName() || !pMed )
756 // Title already set?
757 if ( !pImpl->aTitle.isEmpty() )
758 return pImpl->aTitle;
760 // must it be numbered?
761 const OUString aNoName(SfxResId(STR_NONAME));
762 if (pImpl->bIsNamedVisible)
764 // Append number
765 return aNoName + " " + OUString::number(pImpl->nVisualDocumentNumber);
768 // Document called "Untitled" for the time being
769 return aNoName;
771 assert(pMed);
773 const INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
774 if ( nMaxLength > SFX_TITLE_CAPTION && nMaxLength <= SFX_TITLE_HISTORY )
776 sal_uInt16 nRemote;
777 if (aURL.GetProtocol() == INetProtocol::File)
778 nRemote = 0;
779 else
780 nRemote = 1;
781 nMaxLength = aTitleMap_Impl[nMaxLength-SFX_TITLE_CAPTION][nRemote];
784 // Local file?
785 if ( aURL.GetProtocol() == INetProtocol::File )
787 if ( nMaxLength == SFX_TITLE_FULLNAME )
788 return aURL.HasMark() ? INetURLObject( aURL.GetURLNoMark() ).PathToFileName() : aURL.PathToFileName();
789 if ( nMaxLength == SFX_TITLE_FILENAME )
790 return aURL.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset);
791 if ( pImpl->aTitle.isEmpty() )
792 pImpl->aTitle = aURL.getBase( INetURLObject::LAST_SEGMENT,
793 true, INetURLObject::DecodeMechanism::WithCharset );
795 else
797 if ( nMaxLength >= SFX_TITLE_MAXLEN )
799 const OUString aComplete( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
800 if( aComplete.getLength() > nMaxLength )
801 return OUString::Concat("...") + aComplete.subView( aComplete.getLength() - nMaxLength + 3, nMaxLength - 3 );
802 return aComplete;
804 if ( nMaxLength == SFX_TITLE_FILENAME )
806 const OUString aName = INetURLObject::decode( aURL.GetBase(), INetURLObject::DecodeMechanism::WithCharset );
807 return aName.isEmpty() ? aURL.GetURLNoPass() : aName;
809 if ( nMaxLength == SFX_TITLE_FULLNAME )
810 return aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
812 // Generate Title from file name if possible
813 if ( pImpl->aTitle.isEmpty() )
814 pImpl->aTitle = aURL.GetBase();
816 // workaround for the case when the name can not be retrieved from URL by INetURLObject
817 if ( pImpl->aTitle.isEmpty() )
818 pImpl->aTitle = aURL.GetMainURL( INetURLObject::DecodeMechanism::WithCharset );
821 // Complete Title
822 return pImpl->aTitle;
826 void SfxObjectShell::InvalidateName()
828 /* [Description]
830 Returns the title of the new document, DocInfo-Title or
831 File name. Is required for loading from template or SaveAs.
835 pImpl->aTitle.clear();
836 SetName( GetTitle( SFX_TITLE_APINAME ) );
838 Broadcast( SfxHint(SfxHintId::TitleChanged) );
842 void SfxObjectShell::SetNamedVisibility_Impl()
844 if ( !pImpl->bIsNamedVisible )
846 pImpl->bIsNamedVisible = true;
847 if ( !HasName() && USHRT_MAX == pImpl->nVisualDocumentNumber && pImpl->aTitle.isEmpty() )
849 pImpl->nVisualDocumentNumber = SfxGetpApp()->GetFreeIndex();
850 Broadcast( SfxHint(SfxHintId::TitleChanged) );
854 SetName( GetTitle(SFX_TITLE_APINAME) );
857 void SfxObjectShell::SetNoName()
859 bHasName = false;
860 GetModel()->attachResource( OUString(), GetModel()->getArgs() );
864 SfxProgress* SfxObjectShell::GetProgress() const
866 return pImpl->pProgress;
870 void SfxObjectShell::SetProgress_Impl
872 SfxProgress *pProgress /* to started <SfxProgress> or 0,
873 if the progress is to be reset */
876 /* [Description]
878 Internal method to set or reset the Progress modes for
879 SfxObjectShell.
883 DBG_ASSERT( ( !pImpl->pProgress && pProgress ) ||
884 ( pImpl->pProgress && !pProgress ),
885 "Progress activation/deactivation mismatch" );
886 pImpl->pProgress = pProgress;
890 void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame const * pFrame )
892 SfxApplication* pSfxApp = SfxGetpApp();
893 if ( pSfxApp->IsDowning() || IsLoading() || !pFrame || pFrame->GetFrame().IsClosing_Impl() )
894 return;
896 const SfxBoolItem* pHiddenItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_HIDDEN, false);
897 if ( !pHiddenItem || !pHiddenItem->GetValue() )
899 SfxEventHintId nId = pImpl->nEventId;
900 pImpl->nEventId = SfxEventHintId::NONE;
901 if ( nId == SfxEventHintId::OpenDoc )
902 pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(GlobalEventId::OPENDOC), this, pFrame->GetFrame().GetController() ), false);
903 else if (nId == SfxEventHintId::CreateDoc )
904 pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(GlobalEventId::CREATEDOC), this, pFrame->GetFrame().GetController() ), false);
909 void SfxObjectShell::SetActivateEvent_Impl(SfxEventHintId nId )
911 pImpl->nEventId = nId;
914 bool SfxObjectShell::IsAutoLoadLocked() const
916 /* Returns whether an Autoload is allowed to be executed. Before the
917 surrounding FrameSet of the AutoLoad is also taken into account as well.
921 return !IsReadOnly();
925 void SfxObjectShell::BreakMacroSign_Impl( bool bBreakMacroSign )
927 pImpl->m_bMacroSignBroken = bBreakMacroSign;
931 void SfxObjectShell::CheckSecurityOnLoading_Impl()
933 // make sure LO evaluates the macro signatures, so it can be preserved
934 GetScriptingSignatureState();
936 uno::Reference< task::XInteractionHandler > xInteraction;
937 if ( GetMedium() )
938 xInteraction = GetMedium()->GetInteractionHandler();
940 // check if there is a broken signature...
941 CheckForBrokenDocSignatures_Impl();
943 CheckEncryption_Impl( xInteraction );
945 // check macro security
946 const bool bHasValidContentSignature = HasValidSignatures();
947 pImpl->aMacroMode.checkMacrosOnLoading( xInteraction, bHasValidContentSignature );
951 void SfxObjectShell::CheckEncryption_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
953 OUString aVersion;
954 bool bIsEncrypted = false;
955 bool bHasNonEncrypted = false;
959 uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
960 xPropSet->getPropertyValue("Version") >>= aVersion;
961 xPropSet->getPropertyValue("HasEncryptedEntries") >>= bIsEncrypted;
962 xPropSet->getPropertyValue("HasNonEncryptedEntries") >>= bHasNonEncrypted;
964 catch( uno::Exception& )
968 if ( aVersion.compareTo( ODFVER_012_TEXT ) < 0 )
969 return;
971 // this is ODF1.2 or later
972 if ( !(bIsEncrypted && bHasNonEncrypted) )
973 return;
975 if ( !pImpl->m_bIncomplEncrWarnShown )
977 // this is an encrypted document with nonencrypted streams inside, show the warning
978 css::task::ErrorCodeRequest aErrorCode;
979 aErrorCode.ErrCode = sal_uInt32(ERRCODE_SFX_INCOMPLETE_ENCRYPTION);
981 SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), false );
982 pImpl->m_bIncomplEncrWarnShown = true;
985 // broken signatures imply no macro execution at all
986 pImpl->aMacroMode.disallowMacroExecution();
990 void SfxObjectShell::CheckForBrokenDocSignatures_Impl()
992 SignatureState nSignatureState = GetDocumentSignatureState();
993 bool bSignatureBroken = ( nSignatureState == SignatureState::BROKEN );
994 if ( !bSignatureBroken )
995 return;
997 // broken signatures imply no macro execution at all
998 pImpl->aMacroMode.disallowMacroExecution();
1002 void SfxObjectShell::SetAutoLoad(
1003 const INetURLObject& rUrl, sal_uInt32 nTime, bool bReload )
1005 pImpl->pReloadTimer.reset();
1006 if ( bReload )
1008 pImpl->pReloadTimer.reset(new AutoReloadTimer_Impl(
1009 rUrl.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ),
1010 nTime, this ));
1011 pImpl->pReloadTimer->Start();
1015 void SfxObjectShell::SetLoading(SfxLoadedFlags nFlags)
1017 pImpl->nLoadedFlags = nFlags;
1020 bool SfxObjectShell::IsLoadingFinished() const
1022 return ( pImpl->nLoadedFlags == SfxLoadedFlags::ALL );
1025 void SfxObjectShell::InitOwnModel_Impl()
1027 if ( pImpl->bModelInitialized )
1028 return;
1030 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE, false);
1031 if ( pSalvageItem )
1033 pImpl->aTempName = pMedium->GetPhysicalName();
1034 pMedium->GetItemSet()->ClearItem( SID_DOC_SALVAGE );
1035 pMedium->GetItemSet()->ClearItem( SID_FILE_NAME );
1036 pMedium->GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, pMedium->GetOrigURL() ) );
1038 else
1040 pMedium->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
1041 pMedium->GetItemSet()->ClearItem( SID_DOCUMENT );
1044 pMedium->GetItemSet()->ClearItem( SID_REFERER );
1045 uno::Reference< frame::XModel > xModel = GetModel();
1046 if ( xModel.is() )
1048 SfxItemSet *pSet = GetMedium()->GetItemSet();
1049 if ( !GetMedium()->IsReadOnly() )
1050 pSet->ClearItem( SID_INPUTSTREAM );
1051 uno::Sequence< beans::PropertyValue > aArgs;
1052 TransformItems( SID_OPENDOC, *pSet, aArgs );
1053 xModel->attachResource( GetMedium()->GetOrigURL(), aArgs );
1054 impl_addToModelCollection(xModel);
1057 pImpl->bModelInitialized = true;
1060 void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags )
1062 bool bSetModifiedTRUE = false;
1063 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE, false);
1064 if( ( nFlags & SfxLoadedFlags::MAINDOCUMENT ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT )
1065 && !(pImpl->nFlagsInProgress & SfxLoadedFlags::MAINDOCUMENT ))
1067 pImpl->nFlagsInProgress |= SfxLoadedFlags::MAINDOCUMENT;
1068 static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())->SetAttributes();
1070 if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().hasElements() ) && !IsModifyPasswordEntered() )
1071 SetReadOnly();
1073 // Salvage
1074 if ( pSalvageItem )
1075 bSetModifiedTRUE = true;
1077 if ( !IsEnableSetModified() )
1078 EnableSetModified();
1080 if( !bSetModifiedTRUE && IsEnableSetModified() )
1081 SetModified( false );
1083 CheckSecurityOnLoading_Impl();
1085 bHasName = true; // the document is loaded, so the name should already available
1086 GetTitle( SFX_TITLE_DETECT );
1087 InitOwnModel_Impl();
1088 pImpl->nFlagsInProgress &= ~SfxLoadedFlags::MAINDOCUMENT;
1091 if( ( nFlags & SfxLoadedFlags::IMAGES ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::IMAGES )
1092 && !(pImpl->nFlagsInProgress & SfxLoadedFlags::IMAGES ))
1094 pImpl->nFlagsInProgress |= SfxLoadedFlags::IMAGES;
1095 uno::Reference<document::XDocumentProperties> xDocProps(
1096 getDocProperties());
1097 const OUString url(xDocProps->getAutoloadURL());
1098 sal_Int32 delay(xDocProps->getAutoloadSecs());
1099 SetAutoLoad( INetURLObject(url), delay * 1000,
1100 (delay > 0) || !url.isEmpty() );
1101 if( !bSetModifiedTRUE && IsEnableSetModified() )
1102 SetModified( false );
1103 Invalidate( SID_SAVEASDOC );
1104 pImpl->nFlagsInProgress &= ~SfxLoadedFlags::IMAGES;
1107 pImpl->nLoadedFlags |= nFlags;
1109 if ( pImpl->nFlagsInProgress != SfxLoadedFlags::NONE )
1110 return;
1112 // in case of reentrance calls the first called FinishedLoading() call on the stack
1113 // should do the notification, in result the notification is done when all the FinishedLoading() calls are finished
1115 if ( bSetModifiedTRUE )
1116 SetModified();
1117 else
1118 SetModified( false );
1120 if ( (pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) && (pImpl->nLoadedFlags & SfxLoadedFlags::IMAGES ) )
1122 const SfxBoolItem* pTemplateItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_TEMPLATE, false);
1123 bool bTemplate = pTemplateItem && pTemplateItem->GetValue();
1125 // closing the streams on loading should be under control of SFX!
1126 DBG_ASSERT( pMedium->IsOpen(), "Don't close the medium when loading documents!" );
1128 if ( bTemplate )
1130 TemplateDisconnectionAfterLoad();
1132 else
1134 // if a readonly medium has storage then it's stream is already based on temporary file
1135 if( !(pMedium->GetOpenMode() & StreamMode::WRITE) && !pMedium->HasStorage_Impl() )
1136 // don't lock file opened read only
1137 pMedium->CloseInStream();
1141 SetInitialized_Impl( false );
1143 // Title is not available until loading has finished
1144 Broadcast( SfxHint( SfxHintId::TitleChanged ) );
1145 if ( pImpl->nEventId != SfxEventHintId::NONE )
1146 PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
1149 void SfxObjectShell::TemplateDisconnectionAfterLoad()
1151 // document is created from a template
1152 //TODO/LATER: should the templates always be XML docs!
1154 SfxMedium* pTmpMedium = pMedium;
1155 if ( !pTmpMedium )
1156 return;
1158 const OUString aName( pTmpMedium->GetName() );
1159 const SfxStringItem* pTemplNamItem = SfxItemSet::GetItem<SfxStringItem>(pTmpMedium->GetItemSet(), SID_TEMPLATE_NAME, false);
1160 OUString aTemplateName;
1161 if ( pTemplNamItem )
1162 aTemplateName = pTemplNamItem->GetValue();
1163 else
1165 // !TODO/LATER: what's this?!
1166 // Interactive ( DClick, Contextmenu ) no long name is included
1167 aTemplateName = getDocProperties()->getTitle();
1168 if ( aTemplateName.isEmpty() )
1170 INetURLObject aURL( aName );
1171 aURL.CutExtension();
1172 aTemplateName = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset );
1176 // set medium to noname
1177 pTmpMedium->SetName( OUString(), true );
1178 pTmpMedium->Init_Impl();
1180 // drop resource
1181 SetNoName();
1182 InvalidateName();
1184 if( IsPackageStorageFormat_Impl( *pTmpMedium ) )
1186 // untitled document must be based on temporary storage
1187 // the medium should not dispose the storage in this case
1188 uno::Reference < embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
1189 GetStorage()->copyToStorage( xTmpStor );
1191 // the medium should disconnect from the original location
1192 // the storage should not be disposed since the document is still
1193 // based on it, but in DoSaveCompleted it will be disposed
1194 pTmpMedium->CanDisposeStorage_Impl( false );
1195 pTmpMedium->Close();
1197 // setting the new storage the medium will be based on
1198 pTmpMedium->SetStorage_Impl( xTmpStor );
1200 pMedium = nullptr;
1201 bool ok = DoSaveCompleted( pTmpMedium );
1202 assert(pMedium != nullptr);
1203 if( ok )
1205 const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE, false);
1206 bool bSalvage = pSalvageItem != nullptr;
1208 if ( !bSalvage )
1210 // some further initializations for templates
1211 SetTemplate_Impl( aName, aTemplateName, this );
1214 // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
1215 pTmpMedium->CanDisposeStorage_Impl( false );
1217 else
1219 SetError(ERRCODE_IO_GENERAL);
1222 else
1224 // some further initializations for templates
1225 SetTemplate_Impl( aName, aTemplateName, this );
1226 pTmpMedium->CreateTempFile();
1229 // templates are never readonly
1230 pTmpMedium->GetItemSet()->ClearItem( SID_DOC_READONLY );
1231 pTmpMedium->SetOpenMode( SFX_STREAM_READWRITE, true );
1233 // notifications about possible changes in readonly state and document info
1234 Broadcast( SfxHint(SfxHintId::ModeChanged) );
1236 // created untitled document can't be modified
1237 SetModified( false );
1241 bool SfxObjectShell::IsLoading() const
1242 /* [Description]
1244 Has FinishedLoading been called?
1247 return !( pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT );
1251 void SfxObjectShell::CancelTransfers()
1252 /* [Description]
1254 Here can Transfers get canceled, which were not registered
1255 by RegisterTransfer.
1258 if( ( pImpl->nLoadedFlags & SfxLoadedFlags::ALL ) != SfxLoadedFlags::ALL )
1260 pImpl->bIsAbortingImport = true;
1261 if( IsLoading() )
1262 FinishedLoading();
1267 AutoReloadTimer_Impl::AutoReloadTimer_Impl(
1268 const OUString& rURL, sal_uInt32 nTime, SfxObjectShell* pSh )
1269 : aUrl( rURL ), pObjSh( pSh )
1271 SetTimeout( nTime );
1275 void AutoReloadTimer_Impl::Invoke()
1277 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjSh );
1279 if ( pFrame )
1281 // Not possible/meaningful at the moment?
1282 if ( !pObjSh->CanReload_Impl() || pObjSh->IsAutoLoadLocked() || Application::IsUICaptured() )
1284 // Allow a retry
1285 Start();
1286 return;
1289 SfxAllItemSet aSet( SfxGetpApp()->GetPool() );
1290 aSet.Put( SfxBoolItem( SID_AUTOLOAD, true ) );
1291 if ( !aUrl.isEmpty() )
1292 aSet.Put( SfxStringItem( SID_FILE_NAME, aUrl ) );
1293 if (pObjSh->HasName()) {
1294 aSet.Put(
1295 SfxStringItem(SID_REFERER, pObjSh->GetMedium()->GetName()));
1297 SfxRequest aReq( SID_RELOAD, SfxCallMode::SLOT, aSet );
1298 // this will delete this
1299 pObjSh->Get_Impl()->pReloadTimer.reset();
1300 pFrame->ExecReload_Impl( aReq );
1301 return;
1304 // this will delete this
1305 pObjSh->Get_Impl()->pReloadTimer.reset();
1308 SfxModule* SfxObjectShell::GetModule() const
1310 return GetFactory().GetModule();
1313 ErrCode SfxObjectShell::CallBasic( const OUString& rMacro,
1314 const OUString& rBasic, SbxArray* pArgs,
1315 SbxValue* pRet )
1317 SfxApplication* pApp = SfxGetpApp();
1318 if( pApp->GetName() != rBasic )
1320 if ( !AdjustMacroMode() )
1321 return ERRCODE_IO_ACCESSDENIED;
1324 BasicManager *pMgr = GetBasicManager();
1325 if( pApp->GetName() == rBasic )
1326 pMgr = SfxApplication::GetBasicManager();
1327 ErrCode nRet = SfxApplication::CallBasic( rMacro, pMgr, pArgs, pRet );
1328 return nRet;
1331 bool SfxObjectShell::isScriptAccessAllowed( const Reference< XInterface >& _rxScriptContext )
1335 Reference< XEmbeddedScripts > xScripts( _rxScriptContext, UNO_QUERY );
1336 if ( !xScripts.is() )
1338 Reference< XScriptInvocationContext > xContext( _rxScriptContext, UNO_QUERY_THROW );
1339 xScripts.set( xContext->getScriptContainer(), UNO_SET_THROW );
1342 return xScripts->getAllowMacroExecution();
1344 catch( const Exception& )
1346 DBG_UNHANDLED_EXCEPTION("sfx.doc");
1348 return false;
1351 // don't allow LibreLogo to be used with our mouseover/etc dom-alike events
1352 bool SfxObjectShell::UnTrustedScript(const OUString& rScriptURL)
1354 if (!rScriptURL.startsWith("vnd.sun.star.script:"))
1355 return false;
1357 // ensure URL Escape Codes are decoded
1358 css::uno::Reference<css::uri::XUriReference> uri(
1359 css::uri::UriReferenceFactory::create(comphelper::getProcessComponentContext())->parse(rScriptURL));
1360 css::uno::Reference<css::uri::XVndSunStarScriptUrl> sfUri(uri, css::uno::UNO_QUERY);
1362 if (!sfUri.is())
1363 return false;
1365 // pyuno encodes path separator as |
1366 OUString sScript = sfUri->getName().replace('|', '/');
1368 // check if any path portion matches LibreLogo and ban it if it does
1369 sal_Int32 nIndex = 0;
1372 OUString aToken = sScript.getToken(0, '/', nIndex);
1373 if (aToken.startsWithIgnoreAsciiCase("LibreLogo") || aToken.indexOf('~') != -1)
1375 return true;
1378 while (nIndex >= 0);
1380 return false;
1383 ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptContext, const OUString& _rScriptURL,
1384 const Sequence< Any >& aParams, Any& aRet, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam, bool bRaiseError, const css::uno::Any* pCaller )
1386 SAL_INFO("sfx", "in CallXScript" );
1387 ErrCode nErr = ERRCODE_NONE;
1389 bool bCaughtException = false;
1390 Any aException;
1393 if (!isScriptAccessAllowed(_rxScriptContext))
1394 return ERRCODE_IO_ACCESSDENIED;
1396 if ( UnTrustedScript(_rScriptURL) )
1397 return ERRCODE_IO_ACCESSDENIED;
1399 // obtain/create a script provider
1400 Reference< provider::XScriptProvider > xScriptProvider;
1401 Reference< provider::XScriptProviderSupplier > xSPS( _rxScriptContext, UNO_QUERY );
1402 if ( xSPS.is() )
1403 xScriptProvider.set( xSPS->getScriptProvider() );
1405 if ( !xScriptProvider.is() )
1407 Reference< provider::XScriptProviderFactory > xScriptProviderFactory =
1408 provider::theMasterScriptProviderFactory::get( ::comphelper::getProcessComponentContext() );
1409 xScriptProvider.set( xScriptProviderFactory->createScriptProvider( makeAny( _rxScriptContext ) ), UNO_SET_THROW );
1412 // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
1413 ::framework::DocumentUndoGuard aUndoGuard( _rxScriptContext.get() );
1415 // obtain the script, and execute it
1416 Reference< provider::XScript > xScript( xScriptProvider->getScript( _rScriptURL ), UNO_SET_THROW );
1417 if ( pCaller && pCaller->hasValue() )
1419 Reference< beans::XPropertySet > xProps( xScript, uno::UNO_QUERY );
1420 if ( xProps.is() )
1422 Sequence< uno::Any > aArgs( 1 );
1423 aArgs[ 0 ] = *pCaller;
1424 xProps->setPropertyValue("Caller", uno::makeAny( aArgs ) );
1427 aRet = xScript->invoke( aParams, aOutParamIndex, aOutParam );
1429 catch ( const uno::Exception& )
1431 aException = ::cppu::getCaughtException();
1432 bCaughtException = true;
1433 nErr = ERRCODE_BASIC_INTERNAL_ERROR;
1436 if ( bCaughtException && bRaiseError )
1438 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
1439 pFact->ShowAsyncScriptErrorDialog( nullptr, aException );
1442 SAL_INFO("sfx", "leaving CallXScript" );
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 try {
1481 xDocProps->setAutoloadURL(
1482 rtl::Uri::convertRelToAbs(pDoc->GetMedium()->GetName(), aURL.copy( 4 )) );
1483 } catch (rtl::MalformedUriException &) {
1484 TOOLS_WARN_EXCEPTION("sfx", "");
1489 xDocProps->setAutoloadSecs( nTime );
1491 catch (lang::IllegalArgumentException &)
1493 // ignore
1496 else if( rKV.GetKey().equalsIgnoreAsciiCase( "expires" ) )
1498 DateTime aDateTime( DateTime::EMPTY );
1499 if( INetMIMEMessage::ParseDateField( rKV.GetValue(), aDateTime ) )
1501 aDateTime.ConvertToLocalTime();
1502 pDoc->GetMedium()->SetExpired_Impl( aDateTime );
1504 else
1506 pDoc->GetMedium()->SetExpired_Impl( Date( 1, 1, 1970 ) );
1511 void SfxHeaderAttributes_Impl::Append( const SvKeyValue& rKV )
1513 xIter->Append( rKV );
1514 if( bAlert ) SetAttribute( rKV );
1517 SvKeyValueIterator* SfxObjectShell::GetHeaderAttributes()
1519 if( !pImpl->xHeaderAttributes.is() )
1521 DBG_ASSERT( pMedium, "No Medium" );
1522 pImpl->xHeaderAttributes = new SfxHeaderAttributes_Impl( this );
1524 return static_cast<SvKeyValueIterator*>( pImpl->xHeaderAttributes.get() );
1527 void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
1529 static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())
1530 ->ClearForSourceView();
1534 void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
1536 static_cast<SfxHeaderAttributes_Impl*>(GetHeaderAttributes())
1537 ->SetAttributes();
1540 bool SfxObjectShell::IsPreview() const
1542 if ( !pMedium )
1543 return false;
1545 bool bPreview = false;
1546 const SfxStringItem* pFlags = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_OPTIONS, false);
1547 if ( pFlags )
1549 // Distributed values among individual items
1550 const OUString aFileFlags = pFlags->GetValue().toAsciiUpperCase();
1551 if ( -1 != aFileFlags.indexOf( 'B' ) )
1552 bPreview = true;
1555 if ( !bPreview )
1557 const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(pMedium->GetItemSet(), SID_PREVIEW, false);
1558 if ( pItem )
1559 bPreview = pItem->GetValue();
1562 return bPreview;
1565 void SfxObjectShell::SetWaitCursor( bool bSet ) const
1567 for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
1569 if ( bSet )
1570 pFrame->GetFrame().GetWindow().EnterWait();
1571 else
1572 pFrame->GetFrame().GetWindow().LeaveWait();
1576 OUString SfxObjectShell::GetAPIName() const
1578 INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : GetMedium()->GetName() );
1579 OUString aName( aURL.GetBase() );
1580 if( aName.isEmpty() )
1581 aName = aURL.GetURLNoPass();
1582 if ( aName.isEmpty() )
1583 aName = GetTitle( SFX_TITLE_DETECT );
1584 return aName;
1587 void SfxObjectShell::Invalidate( sal_uInt16 nId )
1589 for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
1590 Invalidate_Impl( pFrame->GetBindings(), nId );
1593 bool SfxObjectShell::AdjustMacroMode()
1595 uno::Reference< task::XInteractionHandler > xInteraction;
1596 if ( pMedium )
1597 xInteraction = pMedium->GetInteractionHandler();
1599 CheckForBrokenDocSignatures_Impl();
1601 CheckEncryption_Impl( xInteraction );
1603 return pImpl->aMacroMode.adjustMacroMode( xInteraction, true /*TODO*/ );
1606 vcl::Window* SfxObjectShell::GetDialogParent( SfxMedium const * pLoadingMedium )
1608 VclPtr<vcl::Window> pWindow;
1609 SfxItemSet* pSet = pLoadingMedium ? pLoadingMedium->GetItemSet() : GetMedium()->GetItemSet();
1610 const SfxUnoFrameItem* pUnoItem = SfxItemSet::GetItem<SfxUnoFrameItem>(pSet, SID_FILLFRAME, false);
1611 if ( pUnoItem )
1613 const uno::Reference < frame::XFrame >& xFrame( pUnoItem->GetFrame() );
1614 pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1617 if ( !pWindow )
1619 SfxFrame* pFrame = nullptr;
1620 const SfxFrameItem* pFrameItem = SfxItemSet::GetItem<SfxFrameItem>(pSet, SID_DOCFRAME, false);
1621 if( pFrameItem && pFrameItem->GetFrame() )
1622 // get target frame from ItemSet
1623 pFrame = pFrameItem->GetFrame();
1624 else
1626 // try the current frame
1627 SfxViewFrame* pView = SfxViewFrame::Current();
1628 if ( !pView || pView->GetObjectShell() != this )
1629 // get any visible frame
1630 pView = SfxViewFrame::GetFirst(this);
1631 if ( pView )
1632 pFrame = &pView->GetFrame();
1635 if ( pFrame )
1636 // get topmost window
1637 pWindow = VCLUnoHelper::GetWindow( pFrame->GetFrameInterface()->getContainerWindow() );
1640 if ( pWindow )
1642 // this frame may be invisible, show it if it is allowed
1643 const SfxBoolItem* pHiddenItem = SfxItemSet::GetItem<SfxBoolItem>(pSet, SID_HIDDEN, false);
1644 if ( !pHiddenItem || !pHiddenItem->GetValue() )
1646 pWindow->Show();
1647 pWindow->ToTop();
1651 return pWindow;
1654 void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode )
1656 eCreateMode = nMode;
1659 bool SfxObjectShell::IsInPlaceActive() const
1661 if ( eCreateMode != SfxObjectCreateMode::EMBEDDED )
1662 return false;
1664 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
1665 return pFrame && pFrame->GetFrame().IsInPlace();
1668 bool SfxObjectShell::IsUIActive() const
1670 if ( eCreateMode != SfxObjectCreateMode::EMBEDDED )
1671 return false;
1673 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
1674 return pFrame && pFrame->GetFrame().IsInPlace() && pFrame->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
1677 bool SfxObjectShell::UseInteractionToHandleError(
1678 const uno::Reference< task::XInteractionHandler >& xHandler,
1679 ErrCode nError )
1681 bool bResult = false;
1683 if ( xHandler.is() )
1687 uno::Any aInteraction;
1688 uno::Sequence< uno::Reference< task::XInteractionContinuation > > lContinuations(2);
1689 ::comphelper::OInteractionAbort* pAbort = new ::comphelper::OInteractionAbort();
1690 ::comphelper::OInteractionApprove* pApprove = new ::comphelper::OInteractionApprove();
1691 lContinuations[0].set( static_cast< task::XInteractionContinuation* >( pAbort ), uno::UNO_QUERY );
1692 lContinuations[1].set( static_cast< task::XInteractionContinuation* >( pApprove ), uno::UNO_QUERY );
1694 task::ErrorCodeRequest aErrorCode;
1695 aErrorCode.ErrCode = sal_uInt32(nError);
1696 aInteraction <<= aErrorCode;
1697 xHandler->handle(::framework::InteractionRequest::CreateRequest (aInteraction,lContinuations));
1698 bResult = pAbort->wasSelected();
1700 catch( uno::Exception& )
1704 return bResult;
1707 sal_Int16 SfxObjectShell_Impl::getCurrentMacroExecMode() const
1709 sal_Int16 nImposedExecMode( MacroExecMode::NEVER_EXECUTE );
1711 const SfxMedium* pMedium( rDocShell.GetMedium() );
1712 OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1713 if ( pMedium )
1715 const SfxUInt16Item* pMacroModeItem = SfxItemSet::GetItem<SfxUInt16Item>(pMedium->GetItemSet(), SID_MACROEXECMODE, false);
1716 if ( pMacroModeItem )
1717 nImposedExecMode = pMacroModeItem->GetValue();
1719 return nImposedExecMode;
1722 void SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
1724 const SfxMedium* pMedium( rDocShell.GetMedium() );
1725 OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
1726 if ( pMedium )
1728 pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE, nMacroMode ) );
1732 OUString SfxObjectShell_Impl::getDocumentLocation() const
1734 OUString sLocation;
1736 const SfxMedium* pMedium( rDocShell.GetMedium() );
1737 OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
1738 if ( pMedium )
1740 sLocation = pMedium->GetName();
1741 if ( sLocation.isEmpty() )
1743 // for documents made from a template: get the name of the template
1744 sLocation = rDocShell.getDocProperties()->getTemplateURL();
1747 // tdf#128006 take document base url as location
1748 if (sLocation.isEmpty())
1749 sLocation = rDocShell.getDocumentBaseURL();
1752 return sLocation;
1755 bool SfxObjectShell_Impl::documentStorageHasMacros() const
1757 return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage );
1760 bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const
1762 return rDocShell.GetMacroCallsSeenWhileLoading();
1765 Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
1767 return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY );
1770 SignatureState SfxObjectShell_Impl::getScriptingSignatureState()
1772 SignatureState nSignatureState( rDocShell.GetScriptingSignatureState() );
1774 if ( nSignatureState != SignatureState::NOSIGNATURES && m_bMacroSignBroken )
1776 // if there is a macro signature it must be handled as broken
1777 nSignatureState = SignatureState::BROKEN;
1780 return nSignatureState;
1783 bool SfxObjectShell_Impl::hasTrustedScriptingSignature( bool bAllowUIToAddAuthor )
1785 bool bResult = false;
1789 OUString aVersion;
1792 uno::Reference < beans::XPropertySet > xPropSet( rDocShell.GetStorage(), uno::UNO_QUERY_THROW );
1793 xPropSet->getPropertyValue("Version") >>= aVersion;
1795 catch( uno::Exception& )
1799 uno::Reference< security::XDocumentDigitalSignatures > xSigner( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion) );
1801 if ( nScriptingSignatureState == SignatureState::UNKNOWN
1802 || nScriptingSignatureState == SignatureState::OK
1803 || nScriptingSignatureState == SignatureState::NOTVALIDATED )
1805 uno::Sequence< security::DocumentSignatureInformation > aInfo = rDocShell.GetDocumentSignatureInformation( true, xSigner );
1807 if ( aInfo.hasElements() )
1809 if ( nScriptingSignatureState == SignatureState::UNKNOWN )
1810 nScriptingSignatureState = DocumentSignatures::getSignatureState(aInfo);
1812 if ( nScriptingSignatureState == SignatureState::OK
1813 || nScriptingSignatureState == SignatureState::NOTVALIDATED )
1815 bResult = std::any_of(aInfo.begin(), aInfo.end(),
1816 [&xSigner](const security::DocumentSignatureInformation& rInfo) {
1817 return xSigner->isAuthorTrusted( rInfo.Signer ); });
1819 if ( !bResult && bAllowUIToAddAuthor )
1821 uno::Reference< task::XInteractionHandler > xInteraction;
1822 if ( rDocShell.GetMedium() )
1823 xInteraction = rDocShell.GetMedium()->GetInteractionHandler();
1825 if ( xInteraction.is() )
1827 task::DocumentMacroConfirmationRequest aRequest;
1828 aRequest.DocumentURL = getDocumentLocation();
1829 aRequest.DocumentStorage = rDocShell.GetMedium()->GetZipStorageToSign_Impl();
1830 aRequest.DocumentSignatureInformation = aInfo;
1831 aRequest.DocumentVersion = aVersion;
1832 aRequest.Classification = task::InteractionClassification_QUERY;
1833 bResult = SfxMedium::CallApproveHandler( xInteraction, uno::makeAny( aRequest ), true );
1840 catch( uno::Exception& )
1843 return bResult;
1846 bool SfxObjectShell::IsContinueImportOnFilterExceptions(const OUString& aErrMessage)
1848 if (mbContinueImportOnFilterExceptions == undefined)
1850 if (Application::GetDialogCancelMode() == DialogCancelMode::Off)
1852 // Ask the user to try to continue or abort loading
1853 OUString aMessage = SfxResId(STR_QMSG_ERROR_OPENING_FILE);
1854 if (!aErrMessage.isEmpty())
1855 aMessage += SfxResId(STR_QMSG_ERROR_OPENING_FILE_DETAILS) + aErrMessage;
1856 aMessage += SfxResId(STR_QMSG_ERROR_OPENING_FILE_CONTINUE);
1857 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
1858 VclMessageType::Question, VclButtonsType::YesNo, aMessage));
1859 mbContinueImportOnFilterExceptions = (xBox->run() == RET_YES) ? yes : no;
1861 else
1862 mbContinueImportOnFilterExceptions = no;
1864 return mbContinueImportOnFilterExceptions == yes;
1867 bool SfxObjectShell::isEditDocLocked() const
1869 Reference<XModel> xModel = GetModel();
1870 if (!xModel.is())
1871 return false;
1872 if (!officecfg::Office::Common::Misc::AllowEditReadonlyDocs::get())
1873 return true;
1874 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1875 return aArgs.getOrDefault("LockEditDoc", false);
1878 bool SfxObjectShell::isContentExtractionLocked() const
1880 Reference<XModel> xModel = GetModel();
1881 if (!xModel.is())
1882 return false;
1883 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1884 return aArgs.getOrDefault("LockContentExtraction", false);
1887 bool SfxObjectShell::isExportLocked() const
1889 Reference<XModel> xModel = GetModel();
1890 if (!xModel.is())
1891 return false;
1892 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1893 return aArgs.getOrDefault("LockExport", false);
1896 bool SfxObjectShell::isPrintLocked() const
1898 Reference<XModel> xModel = GetModel();
1899 if (!xModel.is())
1900 return false;
1901 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1902 return aArgs.getOrDefault("LockPrint", false);
1905 bool SfxObjectShell::isSaveLocked() const
1907 Reference<XModel> xModel = GetModel();
1908 if (!xModel.is())
1909 return false;
1910 comphelper::NamedValueCollection aArgs(xModel->getArgs());
1911 return aArgs.getOrDefault("LockSave", false);
1914 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */