/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// in case no filter defined use default one if( aFilterName.isEmpty() )
{
std::shared_ptr<const SfxFilter> pFilt = SfxFilter::GetDefaultFilterFromFactory(GetFactory().GetFactoryName());
// use the title that is provided in the media descriptor const SfxStringItem* pDocTitleItem = rItemSet.GetItem<SfxStringItem>(SID_DOCINFO_TITLE, false); if ( pDocTitleItem )
getDocProperties()->setTitle( pDocTitleItem->GetValue() );
bOk = CommonSaveAs_Impl(INetURLObject(aFileName), aFilterName, rItemSet, rArgs);
}
}
void SfxObjectShell::AfterSignContent(bool bHaveWeSigned, weld::Window* pDialogParent)
{ if (comphelper::LibreOfficeKit::isActive())
{ // LOK signing certificates are per-view, don't store them in the model. return;
}
namespace
{ /// Updates the UI so it doesn't try to modify an already finalized signature line shape. void ResetSignatureSelection(SfxObjectShell& rObjectShell, SfxViewShell& rViewShell)
{
rViewShell.SetSignPDFCertificate({});
comphelper::dispatchCommand(".uno:DeSelect", {});
rObjectShell.RecheckSignature(false);
}
}
// Reset the picked certificate for PDF signing, then recheck signatures to show how // the PDF actually looks like after signing. Also change the "finish signing" on // the infobar back to "sign document". if (pViewShell)
{
ResetSignatureSelection(*this, *pViewShell);
pFrame->RemoveInfoBar(u"readonly");
pFrame->AppendReadOnlyInfobar();
}
} else
{ // See if a signing cert is passed as a parameter: if so, parse that.
std::string aSignatureCert;
std::string aSignatureKey; const SfxStringItem* pSignatureCert = rReq.GetArg<SfxStringItem>(FN_PARAM_1); if (pSignatureCert)
{
aSignatureCert = pSignatureCert->GetValue().toUtf8();
} const SfxStringItem* pSignatureKey = rReq.GetArg<SfxStringItem>(FN_PARAM_2); if (pSignatureKey)
{
aSignatureKey = pSignatureKey->GetValue().toUtf8();
}
// See if an external signature time/value is provided: if so, sign with those // instead of interactive signing via the dialog.
svl::crypto::SigningContext aSigningContext; const SfxStringItem* pSignatureTime = rReq.GetArg<SfxStringItem>(FN_PARAM_3); if (pSignatureTime)
{
sal_Int64 nSignatureTime = pSignatureTime->GetValue().toInt64();
aSigningContext.m_nSignatureTime = nSignatureTime;
} const SfxStringItem* pSignatureValue = rReq.GetArg<SfxStringItem>(FN_PARAM_4); if (pSignatureValue)
{
OUString aSignatureValue = pSignatureValue->GetValue();
uno::Sequence<sal_Int8> aBytes;
comphelper::Base64::decode(aBytes, aSignatureValue);
aSigningContext.m_aSignatureValue.assign(
aBytes.getArray(), aBytes.getArray() + aBytes.getLength());
} if (!aSigningContext.m_aSignatureValue.empty())
{
SignDocumentContentUsingCertificate(aSigningContext); if (pViewShell)
{
ResetSignatureSelection(*this, *pViewShell);
}
rReq.Done(); return;
}
if (pViewShell)
{
svl::crypto::CertificateOrName aCertificateOrName; if (!aSignatureCert.empty() && !aSignatureKey.empty())
{
aCertificateOrName.m_xCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey);
} // Always set the signing certificate, to clear data from a previous dispatch.
pViewShell->SetSigningCertificate(aCertificateOrName);
}
// Async, all code before return has to go into the callback.
SignDocumentContent(pDialogParent, [this, pDialogParent] (bool bSigned) {
AfterSignContent(bSigned, pDialogParent);
}); return;
}
} else
{ // Async, all code before return has to go into the callback.
SignScriptingContent(pDialogParent, [this, pDialogParent] (bool bSigned) {
AfterSignContent(bSigned, pDialogParent);
}); return;
}
AfterSignContent(bHaveWeSigned, pDialogParent);
return;
}
if ( !GetMedium() && nId != SID_CLOSEDOC )
{
rReq.Ignore(); return;
}
// this guard is created here to have it destruction at the end of the method
SfxInstanceCloseGuard_Impl aModelGuard;
bool bIsPDFExport = false; bool bIsAutoRedact = false; bool bIsAsync = false;
std::vector<std::pair<RedactionTarget, OUString>> aRedactionTargets; switch(nId)
{ case SID_VERSION:
{
SfxViewFrame* pFrame = GetFrame(); if ( !pFrame )
pFrame = SfxViewFrame::GetFirst( this ); if ( !pFrame ) return;
if ( !IsOwnStorageFormat( *GetMedium() ) ) return;
case SID_AUTOREDACTDOC:
{
weld::Window* pDialogParent = GetReqDialogParent(rReq, *this);
// Actual redaction takes place on a newly generated Draw document if (!SvtModuleOptions().IsDrawInstalled())
{
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
pDialogParent, VclMessageType::Warning, VclButtonsType::Ok,
SfxResId(STR_REDACTION_NO_DRAW_WARNING)));
// Actual redaction takes place on a newly generated Draw document if (!SvtModuleOptions().IsDrawInstalled())
{
weld::Window* pDialogParent = GetReqDialogParent(rReq, *this);
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
pDialogParent, VclMessageType::Warning, VclButtonsType::Ok,
SfxResId(STR_REDACTION_NO_DRAW_WARNING)));
// Get the page margins of the original doc
PageMargins aPageMargins = {-1, -1, -1, -1}; if (aRenderer.isWriter())
aPageMargins = SfxRedactionHelper::getPageMarginsForWriter(xModel); elseif (aRenderer.isCalc())
aPageMargins = SfxRedactionHelper::getPageMarginsForCalc(xModel);
if (!xComponent.is())
{
SAL_WARN("sfx.doc", "SID_REDACTDOC: Failed to load new draw component. loadComponentFromURL returned an empty reference.");
return;
}
// Add the doc pages to the new draw document
SfxRedactionHelper::addPagesToDraw(xComponent, nPages, aMetaFiles, aPageSizes, aPageMargins, aRedactionTargets, bIsAutoRedact);
// Show the Redaction toolbar
SfxViewFrame* pViewFrame = SfxViewFrame::Current(); if (!pViewFrame) return;
SfxRedactionHelper::showRedactionToolbar(pViewFrame);
if (sRedactionStyle == "White")
{
xPropSet->setPropertyValue(u"LineColor"_ustr, css::uno::Any(COL_WHITE));
} else
{
xPropSet->setPropertyValue(u"LineColor"_ustr, css::uno::Any(COL_BLACK));
}
}
}
}
}
}
[[fallthrough]]; case SID_EXPORTDOCASPDF:
bIsPDFExport = true;
[[fallthrough]]; case SID_EXPORTDOCASEPUB: case SID_DIRECTEXPORTDOCASEPUB: case SID_EXPORTDOC: case SID_SAVEASDOC: case SID_SAVEASREMOTE: case SID_SAVEDOC:
{ // so far only pdf and epub support Async interface if (comphelper::LibreOfficeKit::isActive() && rReq.GetCallMode() == SfxCallMode::ASYNCHRON
&& (nId == SID_EXPORTDOCASEPUB || nId == SID_EXPORTDOCASPDF))
bIsAsync = true;
// derived class may decide to abort this if( !QuerySlotExecutable( nId ) )
{
rReq.SetReturnValue( SfxBoolItem( 0, false ) ); return;
}
//!! detailed analysis of an error code
SfxObjectShellRef xLock( this );
// the model can not be closed till the end of this method // if somebody tries to close it during this time the model will be closed // at the end of the method
aModelGuard.Init_Impl( uno::Reference< util::XCloseable >( GetModel(), uno::UNO_QUERY ) );
ErrCodeMsg nErrorCode = ERRCODE_NONE;
// by default versions should be preserved always except in case of an explicit // SaveAs via GUI, so the flag must be set accordingly
pImpl->bPreserveVersions = (nId == SID_SAVEDOC);
// do not save version infos --> (see 'Tools - Options - LibreOffice - Security') if (SvtSecurityOptions::IsOptionSet(
SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo) && !SvtSecurityOptions::IsOptionSet(
SvtSecurityOptions::EOption::DocWarnKeepDocVersionInfo))
{
pImpl->bPreserveVersions = false;
}
if ( nId == SID_SAVEASDOC || nId == SID_SAVEASREMOTE )
{ // in case of plugin mode the SaveAs operation means SaveTo const SfxBoolItem* pViewOnlyItem = GetMedium()->GetItemSet().GetItem(SID_VIEWONLY, false); if ( pViewOnlyItem && pViewOnlyItem->GetValue() )
rReq.AppendItem( SfxBoolItem( SID_SAVETO, true ) );
}
// TODO/LATER: do the following GUI related actions in standalone method
// Introduce a status indicator for GUI operation const SfxUnoAnyItem* pStatusIndicatorItem = rReq.GetArg<SfxUnoAnyItem>(SID_PROGRESS_STATUSBAR_CONTROL); if ( !pStatusIndicatorItem )
{ // get statusindicator
uno::Reference< task::XStatusIndicator > xStatusIndicator;
uno::Reference < frame::XController > xCtrl( GetModel()->getCurrentController() ); if ( xCtrl.is() )
{
uno::Reference< task::XStatusIndicatorFactory > xStatFactory( xCtrl->getFrame(), uno::UNO_QUERY ); if( xStatFactory.is() )
xStatusIndicator = xStatFactory->createStatusIndicator();
}
OSL_ENSURE( xStatusIndicator.is(), "Can not retrieve default status indicator!" );
if ( nId == SID_SAVEDOC )
{ // in case of saving it is not possible to transport the parameters from here // but it is not clear here whether the saving will be done or saveAs operation
GetMedium()->GetItemSet().Put( aStatIndItem );
}
rReq.AppendItem( aStatIndItem );
}
} elseif ( nId == SID_SAVEDOC )
{ // in case of saving it is not possible to transport the parameters from here // but it is not clear here whether the saving will be done or saveAs operation
GetMedium()->GetItemSet().Put( *pStatusIndicatorItem );
}
// Introduce an interaction handler for GUI operation const SfxUnoAnyItem* pInteractionHandlerItem = rReq.GetArg<SfxUnoAnyItem>(SID_INTERACTIONHANDLER); if ( !pInteractionHandlerItem )
{
uno::Reference<css::awt::XWindow> xParentWindow;
uno::Reference<frame::XController> xCtrl(GetModel()->getCurrentController()); if (xCtrl.is())
xParentWindow = xCtrl->getFrame()->getContainerWindow();
SfxUnoAnyItem aInteractionItem( SID_INTERACTIONHANDLER, uno::Any( xInteract ) ); if ( nId == SID_SAVEDOC )
{ // in case of saving it is not possible to transport the parameters from here // but it is not clear here whether the saving will be done or saveAs operation
GetMedium()->GetItemSet().Put( aInteractionItem );
}
rReq.AppendItem( aInteractionItem );
} elseif ( nId == SID_SAVEDOC )
{ // in case of saving it is not possible to transport the parameters from here // but it is not clear here whether the saving will be done or saveAs operation
GetMedium()->GetItemSet().Put( *pInteractionHandlerItem );
}
bool bForceSaveAs = nId == SID_SAVEDOC && IsReadOnlyMedium();
if (comphelper::LibreOfficeKit::isActive() && bForceSaveAs)
{ // Don't force save as in LOK but report that file cannot be written // to avoid confusion with exporting for file download purpose
// Fetch value from the pool item early, because GUIStoreModel() can free the pool // item as part of spinning the main loop if a dialog is opened. constbool bMailPrepareExport(nullptr != pItem && pItem->GetValue()); if (bMailPrepareExport)
{
SfxRequest aRequest(SID_MAIL_PREPAREEXPORT, SfxCallMode::SYNCHRON, GetPool());
aRequest.AppendItem(SfxBoolItem(FN_NOUPDATE, true));
ExecuteSlot(aRequest);
}
if (bMailPrepareExport)
{
SfxRequest aRequest(SID_MAIL_EXPORT_FINISHED, SfxCallMode::SYNCHRON, GetPool());
ExecuteSlot(aRequest);
}
// merge aDispatchArgs to the request
SfxAllItemSet aResultParams( GetPool() );
TransformParameters( nId,
aDispatchArgs,
aResultParams );
rReq.SetArgs( aResultParams );
// the StoreAsURL/StoreToURL method have called this method with false // so it has to be restored to true here since it is a call from GUI
GetMedium()->SetUpdatePickList( true );
// TODO: in future it must be done in following way // if document is opened from GUI, it immediately appears in the picklist // if the document is a new one then it appears in the picklist immediately // after SaveAs operation triggered from GUI
} catch( const task::ErrorCodeIOException& aErrorEx )
{
TOOLS_WARN_EXCEPTION_IF(ErrCode(aErrorEx.ErrCode) != ERRCODE_IO_ABORT, "sfx.doc", "Fatal IO error during save");
nErrorCode = { ErrCode(aErrorEx.ErrCode), aErrorEx.Message };
} catch( Exception& e )
{
nErrorCode = { ERRCODE_IO_GENERAL, e.Message };
}
// by default versions should be preserved always except in case of an explicit // SaveAs via GUI, so the flag must be reset to guarantee this
pImpl->bPreserveVersions = true;
ErrCodeMsg lErr=GetErrorCode();
// may be nErrorCode should be shown in future if ( lErr != ERRCODE_IO_ABORT )
{ if (comphelper::LibreOfficeKit::isActive())
sendErrorToLOK(lErr); else
{
SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC,GetTitle());
weld::Window* pDialogParent = GetReqDialogParent(rReq, *this);
ErrorHandler::HandleError(lErr, pDialogParent);
}
}
if (nId == SID_DIRECTEXPORTDOCASPDF &&
SfxRedactionHelper::isRedactMode(rReq))
{ // Return the finalized redaction shapes back to normal (gray & transparent)
uno::Reference< lang::XComponent > xComponent( GetCurrentComponent(), uno::UNO_QUERY ); if (!xComponent.is()) return;
if ( nId == SID_EXPORTDOCASPDF )
{ // This function is used by the SendMail function that needs information if an export // file was written or not. This could be due to cancellation of the export // or due to an error. So IO abort must be handled like an error!
nErrorCode = ( lErr != ERRCODE_IO_ABORT ) && ( nErrorCode == ERRCODE_NONE ) ? nErrorCode : lErr;
}
if ( ( nId == SID_SAVEASDOC || nId == SID_SAVEASREMOTE ) && nErrorCode == ERRCODE_NONE )
{ const SfxBoolItem* saveTo = rReq.GetArg<SfxBoolItem>(SID_SAVETO); if (saveTo == nullptr || !saveTo->GetValue())
{ if (SfxViewFrame* pFrame = GetFrame())
pFrame->RemoveInfoBar(u"readonly");
SetReadOnlyUI(false);
}
}
if (nId == SID_SAVEDOC && bRememberSignature && rSignatureInfosRemembered.hasElements())
ResignDocument(rSignatureInfosRemembered);
case SID_CHECKOUT:
{
CheckOut( ); break;
} case SID_CANCELCHECKOUT:
{
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
VclMessageType::Question, VclButtonsType::YesNo, SfxResId(STR_QUERY_CANCELCHECKOUT))); if (xBox->run() == RET_YES)
{
CancelCheckOut( );
// Reload the document as we may still have local changes if (SfxViewFrame* pFrame = GetFrame())
pFrame->GetDispatcher()->Execute(SID_RELOAD);
} break;
} case SID_CHECKIN:
{
CheckIn( ); break;
}
}
// Prevent entry in the Pick-lists if ( rReq.IsAPI() )
GetMedium()->SetUpdatePickList( false );
// Ignore()-branches have already returned
rReq.Done();
}
case SID_DOCTEMPLATE: case SID_EXPORTDOC: case SID_EXPORTDOCASPDF: case SID_DIRECTEXPORTDOCASPDF: case SID_EXPORTDOCASEPUB: case SID_DIRECTEXPORTDOCASEPUB: case SID_REDACTDOC: case SID_AUTOREDACTDOC: case SID_SAVEASREMOTE:
{ if (isExportLocked())
rSet.DisableItem( nWhich ); break;
}
switch (eState)
{ case SignatureState::BROKEN:
sMessage = SfxResId(STR_SIGNATURE_BROKEN);
aInfobarType = InfobarType::DANGER; break; case SignatureState::INVALID: // If we are remembering the certificates, it should be kept as valid
sMessage = SfxResId(bRememberSignature ? STR_SIGNATURE_OK : STR_SIGNATURE_INVALID); // Warning only, I've tried Danger and it looked too scary
aInfobarType = ( bRememberSignature ? InfobarType::INFO : InfobarType::WARNING ); break; case SignatureState::NOTVALIDATED:
sMessage = SfxResId(STR_SIGNATURE_NOTVALIDATED);
aInfobarType = InfobarType::WARNING; break; case SignatureState::PARTIAL_OK:
sMessage = SfxResId(STR_SIGNATURE_PARTIAL_OK);
aInfobarType = InfobarType::WARNING;
--> --------------------
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.