uno::Reference<document::XDocumentProperties>
SfxObjectShell::getDocProperties() const
{
uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
GetModel(), uno::UNO_QUERY_THROW);
uno::Reference<document::XDocumentProperties> xDocProps(
xDPS->getDocumentProperties());
DBG_ASSERT(xDocProps.is(), "SfxObjectShell: model has no DocumentProperties"); return xDocProps;
}
void SfxObjectShell::DoFlushDocInfo()
{
}
// Note: the only thing that calls this is the modification event handler // that is installed at the XDocumentProperties void SfxObjectShell::FlushDocInfo()
{ if ( IsLoading() ) return;
void SfxObjectShell::EnableSetModified( bool bEnable )
{
SAL_INFO_IF( bEnable == pImpl->m_bEnableSetModified, "sfx", "SFX_PERSIST: EnableSetModified 2x called with the same value" );
pImpl->m_bEnableSetModified = bEnable;
}
bool SfxObjectShell::IsEnableSetModified() const
{ // tdf#146547 read-only does not prevent modified, instead try to prevent // setting "internal" documents that may be displayed in some dialog but // which the user didn't load or activate to modified. return pImpl->m_bEnableSetModified && !IsPreview()
&& eCreateMode != SfxObjectCreateMode::ORGANIZER
&& eCreateMode != SfxObjectCreateMode::INTERNAL // tdf#157931 form documents only in design mode
&& ((pImpl->pBaseModel
&& !pImpl->pBaseModel->impl_isDisposed()
&& pImpl->pBaseModel->IsInitialized()
&& pImpl->pBaseModel->getIdentifier() != "com.sun.star.sdb.FormDesign")
|| !IsReadOnly());
}
bool SfxObjectShell::IsModified() const
{ if ( pImpl->m_bIsModified ) returntrue;
if ( !pImpl->m_xDocStorage.is() || IsReadOnly() )
{ // if the document still has no storage and is not set to be modified explicitly it is not modified // a readonly document is also not modified
Invalidate( SID_SIGNATURE );
Invalidate( SID_MACRO_SIGNATURE );
Broadcast( SfxHint( SfxHintId::TitleChanged ) ); // xmlsec05, signed state might change in title...
SfxGetpApp()->NotifyEvent( SfxEventHint( SfxEventHintId::ModifyChanged, GlobalEventConfig::GetEventName(GlobalEventId::MODIFYCHANGED), this ) );
// Don't wait to get this important state via binding notification timeout. if ( comphelper::LibreOfficeKit::isActive() )
{
OString aStatus = ".uno:ModifiedStatus="_ostr;
aStatus += IsModified() ? "true" : "false";
SfxLokHelper::notifyAllViews(LOK_CALLBACK_STATE_CHANGED, aStatus);
}
}
void SfxObjectShell::SetReadOnly()
{ // Let the document be completely readonly, means that the // medium open mode is adjusted accordingly, and the write lock // on the file is removed.
if ( !pMedium || IsReadOnlyMedium() ) return;
bool bWasROUI = IsReadOnly();
pMedium->UnlockFile( false );
// the storage-based mediums are already based on the temporary file // so UnlockFile has already closed the locking stream if ( !pMedium->HasStorage_Impl() && IsLoadingFinished() )
pMedium->CloseInStream();
void SfxObjectShell::SetModalMode_Impl( bool bModal )
{ // Broadcast only if modified, or otherwise it will possibly go into // an endless loop if ( pImpl->bModalMode == bModal ) return;
// Central count
sal_uInt16 &rDocModalCount = SfxGetpApp()->Get_Impl()->nDocModalMode; if ( bModal )
++rDocModalCount; else
--rDocModalCount;
if ( aOrigURL.isEmpty() && bSave )
{ // this is a new document, let it be stored before switching to the shared mode; // the storing should be done without shared flag, since it is possible that the // target location does not allow to create sharing control file; // the shared flag will be set later after creation of sharing control file
SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
if ( pViewFrame )
{ // TODO/LATER: currently the application guards against the reentrance problem const SfxPoolItemHolder aItem(pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC )); const SfxBoolItem* pResult(dynamic_cast<const SfxBoolItem*>(aItem.getItem()));
bResult = ( pResult && pResult->GetValue() ); if ( bResult )
aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
}
}
if ( bResult && bSave )
{
SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );
if ( pViewFrame )
{ // TODO/LATER: currently the application guards against the reentrance problem
SetModified(); // the modified flag has to be set to let the document be stored with the shared flag try
{ // Do *not* use dispatch mechanism in this place - we don't want others (extensions etc.) to intercept this.
pImpl->pBaseModel->store();
bResult = true;
} catch (...)
{
bResult = false;
}
}
}
if ( bResult )
{ // TODO/LATER: Is it possible that the following calls fail? if ( bShared )
{
pImpl->m_aSharedFileURL = aOrigURL;
GetMedium()->SwitchDocumentToTempFile();
} else
{ const OUString aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
pImpl->m_aSharedFileURL.clear();
// now remove the temporary file the document was based on
::utl::UCBContentHelper::Kill( aTempFileURL );
try
{ // aOrigURL can not be used since it contains an old value
::svt::ShareControlFile aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
aControlFile.RemoveFile();
} catch( uno::Exception& )
{
}
}
} else
{ // the saving has failed! if ( bRemoveEntryOnError )
{ try
{
::svt::ShareControlFile aControlFile( aOrigURL );
aControlFile.RemoveEntry();
} catch( uno::Exception& )
{}
}
SetSharedXMLFlag( bOldValue );
}
} else
bResult = false; // the second switch to the same mode
if ( pMed )
{ const SfxStringItem* pNameItem = pMed->GetItemSet().GetItem(SID_DOCINFO_TITLE, false); if ( pNameItem )
aTitle = pNameItem->GetValue();
}
if ( aTitle.isEmpty() )
aTitle = GetTitle( SFX_TITLE_FILENAME );
bRecur = false; return aTitle;
}
if (SFX_TITLE_APINAME == nMaxLength ) return GetAPIName();
// Picklist/Caption is mapped if ( pMed && ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) )
{ // If a specific title was given at open: // important for URLs: use INetProtocol::File for which the set title is not // considered. (See below, analysis of aTitleMap_Impl) const SfxStringItem* pNameItem = pMed->GetItemSet().GetItem(SID_DOCINFO_TITLE, false); if ( pNameItem ) return pNameItem->GetValue();
}
// Still unnamed?
DBG_ASSERT( !HasName() || pMed, "HasName() but no Medium?!?" ); if ( !HasName() || !pMed )
{ // Title already set? if ( !pImpl->aTitle.isEmpty() ) return pImpl->aTitle;
// must it be numbered? const OUString aNoName(SfxResId(STR_NONAME)); if (pImpl->bIsNamedVisible)
{ // Append number return aNoName + " " + OUString::number(pImpl->nVisualDocumentNumber);
}
// Document called "Untitled" for the time being return aNoName;
}
assert(pMed);
// Generate Title from file name if possible if ( pImpl->aTitle.isEmpty() )
pImpl->aTitle = aURL.GetBase();
// workaround for the case when the name can not be retrieved from URL by INetURLObject if ( pImpl->aTitle.isEmpty() )
pImpl->aTitle = aURL.GetMainURL( INetURLObject::DecodeMechanism::WithCharset );
}
void SfxObjectShell::CheckSecurityOnLoading_Impl()
{ if (GetErrorCode() == ERRCODE_IO_BROKENPACKAGE)
{ // safety first: don't run any macros from broken package.
pImpl->aMacroMode.disallowMacroExecution(); return; // do not get signature status - needs to be done after RepairPackage
}
// make sure LO evaluates the macro signatures, so it can be preserved
GetScriptingSignatureState();
if ( aVersion.compareTo( ODFVER_012_TEXT ) < 0 ) return;
// this is ODF1.2 or later if ( !(bIsEncrypted && bHasNonEncrypted) ) return;
if ( !pImpl->m_bIncomplEncrWarnShown )
{ // this is an encrypted document with nonencrypted streams inside, show the warning
css::task::ErrorCodeRequest aErrorCode;
aErrorCode.ErrCode = sal_uInt32(ERRCODE_SFX_INCOMPLETE_ENCRYPTION);
if (!bSilent && aFilterName.indexOf("Excel") != -1)
{
Reference<task::XInteractionHandler> xHandler(pMedium->GetInteractionHandler()); if (xHandler.is())
{
beans::NamedValue aLoadReadOnlyRequest;
aLoadReadOnlyRequest.Name = "LoadReadOnlyRequest";
aLoadReadOnlyRequest.Value <<= aFileName;
Any aRequest(aLoadReadOnlyRequest);
rtl::Reference<ucbhelper::SimpleInteractionRequest> xRequest
= new ucbhelper::SimpleInteractionRequest(aRequest,
ContinuationFlags::Approve |
ContinuationFlags::Disapprove);
if ( pImpl->nFlagsInProgress != SfxLoadedFlags::NONE ) return;
// in case of reentrance calls the first called FinishedLoading() call on the stack // should do the notification, in result the notification is done when all the FinishedLoading() calls are finished
if ( bSetModifiedTRUE )
SetModified(); else
SetModified( false );
// closing the streams on loading should be under control of SFX!
DBG_ASSERT( pMedium->IsOpen(), "Don't close the medium when loading documents!" );
if ( bTemplate )
{
TemplateDisconnectionAfterLoad();
} else
{ // if a readonly medium has storage then it's stream is already based on temporary file if( !(pMedium->GetOpenMode() & StreamMode::WRITE) && !pMedium->HasStorage_Impl() ) // don't lock file opened read only
pMedium->CloseInStream();
}
}
SetInitialized_Impl( false );
// Title is not available until loading has finished
Broadcast( SfxHint( SfxHintId::TitleChanged ) ); if ( pImpl->nEventId != SfxEventHintId::NONE )
PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
}
void SfxObjectShell::TemplateDisconnectionAfterLoad()
{ // document is created from a template //TODO/LATER: should the templates always be XML docs!
SfxMedium* pTmpMedium = pMedium; if ( !pTmpMedium ) return;
const OUString aName( pTmpMedium->GetName() ); const SfxStringItem* pTemplNamItem = pTmpMedium->GetItemSet().GetItem(SID_TEMPLATE_NAME, false);
OUString aTemplateName; if ( pTemplNamItem )
aTemplateName = pTemplNamItem->GetValue(); else
{ // !TODO/LATER: what's this?! // Interactive ( DClick, Contextmenu ) no long name is included
aTemplateName = getDocProperties()->getTitle(); if ( aTemplateName.isEmpty() )
{
INetURLObject aURL( aName );
aURL.CutExtension();
aTemplateName = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset );
}
}
// set medium to noname
pTmpMedium->SetName( OUString(), true );
pTmpMedium->Init_Impl();
// drop resource
SetNoName();
InvalidateName();
if( IsPackageStorageFormat_Impl( *pTmpMedium ) )
{ // untitled document must be based on temporary storage // the medium should not dispose the storage in this case
uno::Reference < embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
GetStorage()->copyToStorage( xTmpStor );
// the medium should disconnect from the original location // the storage should not be disposed since the document is still // based on it, but in DoSaveCompleted it will be disposed
pTmpMedium->CanDisposeStorage_Impl( false );
pTmpMedium->Close();
// setting the new storage the medium will be based on
pTmpMedium->SetStorage_Impl( xTmpStor );
if ( !bSalvage )
{ // some further initializations for templates
SetTemplate_Impl( aName, aTemplateName, this );
}
// the medium should not dispose the storage, DoSaveCompleted() has let it to do so
pTmpMedium->CanDisposeStorage_Impl( false );
} else
{
SetError(ERRCODE_IO_GENERAL);
}
} else
{ // some further initializations for templates
SetTemplate_Impl( aName, aTemplateName, this );
pTmpMedium->CreateTempFile();
}
// templates are never readonly
pTmpMedium->GetItemSet().ClearItem( SID_DOC_READONLY );
pTmpMedium->SetOpenMode( SFX_STREAM_READWRITE, true );
// notifications about possible changes in readonly state and document info
Broadcast( SfxHint(SfxHintId::ModeChanged) );
// created untitled document can't be modified
SetModified( false );
}
if ( pFrame )
{ // Not possible/meaningful at the moment? if ( !pObjSh->CanReload_Impl() || pObjSh->IsAutoLoadLocked() || Application::IsUICaptured() )
{ // Allow a retry
Start(); return;
}
SfxAllItemSet aSet( SfxGetpApp()->GetPool() );
aSet.Put( SfxBoolItem( SID_AUTOLOAD, true ) ); if ( !aUrl.isEmpty() )
aSet.Put( SfxStringItem( SID_FILE_NAME, aUrl ) ); if (pObjSh->HasName()) {
aSet.Put(
SfxStringItem(SID_REFERER, pObjSh->GetMedium()->GetName()));
}
SfxRequest aReq( SID_RELOAD, SfxCallMode::SLOT, aSet ); // this will delete this
pObjSh->Get_Impl()->pReloadTimer.reset();
pFrame->ExecReload_Impl( aReq ); return;
}
// this will delete this
pObjSh->Get_Impl()->pReloadTimer.reset();
}
// don't allow LibreLogo to be used with our mouseover/etc dom-alike events bool SfxObjectShell::UnTrustedScript(const OUString& rScriptURL)
{ if (!rScriptURL.startsWith("vnd.sun.star.script:")) returnfalse;
// check if any path portion matches LibreLogo and ban it if it does
sal_Int32 nIndex = 0; do
{
OUString aToken = sScript.getToken(0, '/', nIndex); if (aToken.startsWithIgnoreAsciiCase("LibreLogo") || aToken.indexOf('~') != -1)
{ returntrue;
}
} while (nIndex >= 0);
// ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
::framework::DocumentUndoGuard aUndoGuard( _rxScriptContext );
if (!xWindow)
{
SfxFrame* pFrame = nullptr; const SfxFrameItem* pFrameItem = rSet.GetItem<SfxFrameItem>(SID_DOCFRAME, false); if( pFrameItem && pFrameItem->GetFrame() ) // get target frame from ItemSet
pFrame = pFrameItem->GetFrame(); else
{ // try the current frame
SfxViewFrame* pView = SfxViewFrame::Current(); if ( !pView || pView->GetObjectShell() != this ) // get any visible frame
pView = SfxViewFrame::GetFirst(this); if ( pView )
pFrame = &pView->GetFrame();
}
if ( pFrame )
{ // get topmost window
xWindow = pFrame->GetFrameInterface()->getContainerWindow();
}
}
if (xWindow)
{ // this frame may be invisible, show it if it is allowed const SfxBoolItem* pHiddenItem = rSet.GetItem(SID_HIDDEN, false); if ( !pHiddenItem || !pHiddenItem->GetValue() )
{
xWindow->setVisible(true);
css::uno::Reference<css::awt::XTopWindow> xTopWindow(xWindow, uno::UNO_QUERY);
SAL_WARN_IF(!xTopWindow, "sfx.appl", "XTopWindow not available from XWindow"); if (xTopWindow)
xTopWindow->toFront();
}
}
const SfxMedium* pMedium( rDocShell.GetMedium() );
OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getDocumentLocation: no medium!" ); if ( pMedium )
{
sLocation = pMedium->GetName(); if ( sLocation.isEmpty() )
{ // for documents made from a template: get the name of the template
sLocation = rDocShell.getDocProperties()->getTemplateURL();
}
// tdf#128006 take document base url as location if (sLocation.isEmpty())
sLocation = rDocShell.getDocumentBaseURL();
}
if ( nSignatureState != SignatureState::NOSIGNATURES && m_bMacroSignBroken )
{ // if there is a macro signature it must be handled as broken
nSignatureState = SignatureState::BROKEN;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.