/* -*- 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 .
*/
usingnamespace ::com::sun::star; usingnamespace ::com::sun::star::uno; using ::com::sun::star::beans::PropertyValue; using ::com::sun::star::document::CmisProperty; using ::com::sun::star::frame::XFrame; using ::com::sun::star::frame::XController; using ::com::sun::star::frame::XController2; using ::com::sun::star::lang::IllegalArgumentException; using ::com::sun::star::io::IOException; using ::com::sun::star::uno::Sequence; using ::com::sun::star::document::XDocumentRecovery; using ::com::sun::star::document::XUndoManager; using ::com::sun::star::document::XUndoAction; using ::com::sun::star::frame::XModel;
namespace {
/** This Listener is used to get notified when the XDocumentProperties of the XModel change.
*/ class SfxDocInfoListener_Impl : public ::cppu::WeakImplHelper<
util::XModifyListener >
{
void setModifiedForAutoSave(bool val)
{ if (val)
{ if (!m_oDirtyTimestamp)
m_oDirtyTimestamp.emplace(std::chrono::steady_clock::now());
} else
{
m_oDirtyTimestamp.reset();
}
}
};
namespace {
// Listener that forwards notifications from the PrintHelper to the "real" listeners class SfxPrintHelperListener_Impl : public ::cppu::WeakImplHelper< view::XPrintJobListener >
{ public:
IMPL_SfxBaseModel_DataContainer* m_pData; explicit SfxPrintHelperListener_Impl( IMPL_SfxBaseModel_DataContainer* pData )
: m_pData( pData )
{}
// SfxOwnFramesLocker ==================================================================================== // allows to lock all the frames related to the provided SfxObjectShell class SfxOwnFramesLocker
{
Sequence< Reference< frame::XFrame > > m_aLockedFrames;
if ( comphelper::LibreOfficeKit::isForkedChild() ) return; // no need to tweak UI when in the background
for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjectShell );
pFrame;
pFrame = SfxViewFrame::GetNext( *pFrame, pObjectShell )
)
{
SfxFrame& rSfxFrame = pFrame->GetFrame(); try
{ // get vcl window related to the frame and lock it if it is still not locked const Reference< frame::XFrame >& xFrame = rSfxFrame.GetFrameInterface();
vcl::Window* pWindow = GetVCLWindow( xFrame ); if ( !pWindow ) throw RuntimeException();
SfxOwnFramesLocker::~SfxOwnFramesLocker()
{ for ( auto& rFrame : asNonConstRange(m_aLockedFrames) )
{ try
{ if ( rFrame.is() )
{ // get vcl window related to the frame and unlock it
vcl::Window* pWindow = GetVCLWindow( rFrame ); if ( !pWindow ) throw RuntimeException();
// m_bSuicide was set e.g. in case someone tried to close a document, while it was used for // storing at the same time. Further m_bSuicide was set to sal_True only if close(sal_True) was called. // So the ownership was delegated to the place where a veto exception was thrown. // Now we have to call close() again and delegate the ownership to the next one, which // can't accept that. Close(sal_False) can't work in this case. Because then the document will may be never closed...
if ( !m_pData->m_bSuicide ) return;
// Reset this state. In case the new close() request is not accepted by someone else... // it's not a good idea to have two "owners" for close.-)
m_pData->m_bSuicide = false; try
{
Reference< util::XCloseable > xClose(m_xModel, UNO_QUERY); if (xClose.is())
xClose->close(true);
} catch(const util::CloseVetoException&)
{}
}
void SAL_CALL SfxBaseModel::dispose()
{
SolarMutexGuard aGuard; if (impl_isDisposed()) return;
if ( !m_pData->m_bClosed )
{ // gracefully accept wrong dispose calls instead of close call // and try to make it work (may be really disposed later!) try
{
close( true );
} catch ( util::CloseVetoException& )
{
}
return;
}
if ( m_pData->m_bDisposing ) return;
m_pData->m_bDisposing = true;
if ( m_pData->m_pStorageModifyListen.is() )
{
m_pData->m_pStorageModifyListen->dispose();
m_pData->m_pStorageModifyListen = nullptr;
}
if ( m_pData->m_pDocumentUndoManager.is() )
{
m_pData->m_pDocumentUndoManager->disposing();
m_pData->m_pDocumentUndoManager = nullptr;
}
// m_pData member must be set to zero before delete is called to // force disposed exception whenever someone tries to access our // instance while in the dtor.
m_pData.reset();
}
// we need to know which properties are supported by the transformer // hopefully it is a temporary solution, I guess nonconvertable properties // should not be supported so then there will be only ItemSet from medium
if (requestedArgs.empty() || requestedArgs.count(u"WinExtent"))
{ // "WinExtent" property should be updated always. // We can store it now to overwrite an old value // since it is not from ItemSet
tools::Rectangle aTmpRect = m_pData->m_pObjectShell->GetVisArea( ASPECT_CONTENT );
aTmpRect = OutputDevice::LogicToLogic(aTmpRect, MapMode(m_pData->m_pObjectShell->GetMapUnit()), MapMode(MapUnit::Map100thMM));
if (requestedArgs.empty())
{ // only the values that are not supported by the ItemSet must be cached here
Sequence< beans::PropertyValue > aFinalCache;
sal_Int32 nFinalLength = 0;
for (constauto& rOrg : m_pData->m_seqArguments)
{ auto bNew = std::none_of(std::cbegin(seqArgsOld), std::cend(seqArgsOld),
[&rOrg](const beans::PropertyValue& rOld){ return rOld.Name == rOrg.Name; }); if ( bNew )
{ // the entity with this name should be new for seqArgsNew // since it is not supported by transformer
SfxMedium* pMedium = m_pData->m_pObjectShell->GetMedium(); if (!pMedium)
{ throw util::InvalidStateException(
u"Medium could not be retrieved, unable to execute setArgs"_ustr);
}
for (constauto& rArg : aArgs)
{
OUString sValue; bool bValue; bool ok = false; if (rArg.Name == "SuggestedSaveAsName")
{ if (rArg.Value >>= sValue)
{
pMedium->GetItemSet().Put(SfxStringItem(SID_SUGGESTEDSAVEASNAME, sValue));
ok = true;
}
} elseif (rArg.Name == "SuggestedSaveAsDir")
{ if (rArg.Value >>= sValue)
{
pMedium->GetItemSet().Put(SfxStringItem(SID_SUGGESTEDSAVEASDIR, sValue));
ok = true;
}
} elseif (rArg.Name == "ExportDirectory")
{ if (rArg.Value >>= sValue)
{
pMedium->GetItemSet().Put(SfxStringItem(SID_EXPORTDIRECTORY, sValue));
ok = true;
}
} elseif (rArg.Name == "LockContentExtraction")
{ if (rArg.Value >>= bValue)
{
pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_CONTENT_EXTRACTION, bValue));
ok = true;
}
} elseif (rArg.Name == "LockExport")
{ if (rArg.Value >>= bValue)
{
pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_EXPORT, bValue));
ok = true;
}
} elseif (rArg.Name == "LockPrint")
{ if (rArg.Value >>= bValue)
{
pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_PRINT, bValue));
ok = true;
}
} elseif (rArg.Name == "LockSave")
{ if (rArg.Value >>= bValue)
{
pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_SAVE, bValue));
ok = true;
}
} elseif (rArg.Name == "LockEditDoc")
{ if (rArg.Value >>= bValue)
{
pMedium->GetItemSet().Put(SfxBoolItem(SID_LOCK_EDITDOC, bValue));
ok = true;
}
} elseif (rArg.Name == "Replaceable")
{ if (rArg.Value >>= bValue)
{
pMedium->GetItemSet().Put(SfxBoolItem(SID_REPLACEABLE, bValue));
ok = true;
}
} elseif (rArg.Name == "EncryptionData")
{
pMedium->GetItemSet().Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, rArg.Value));
ok = true;
} if (!ok)
{ throw lang::IllegalArgumentException("Setting property not supported: " + rArg.Name,
comphelper::getProcessComponentContext(), 0);
}
}
}
OUString SAL_CALL ControllerLockUndoAction::getTitle()
{ // this action is intended to be used within an UndoContext only, so nobody will ever see this title ... return OUString();
}
if ( m_pData->m_bSaving )
{ if (bDeliverOwnership)
m_pData->m_bSuicide = true; throw util::CloseVetoException(
u"Can not close while saving."_ustr, static_cast< util::XCloseable* >(this));
}
// no own objections against closing!
m_pData->m_bClosing = true; if (m_pData->m_aCloseListeners.getLength())
{
comphelper::OInterfaceIteratorHelper3 pCloseIterator(m_pData->m_aCloseListeners); while (pCloseIterator.hasMoreElements())
{ try
{
pCloseIterator.next()->notifyClosing( aSource );
} catch( RuntimeException& )
{
pCloseIterator.remove();
}
}
}
if ( m_pData->m_pObjectShell.is() )
{ // TODO/LATER: is it correct that the shared document returns shared file location? if ( m_pData->m_pObjectShell->IsDocShared() ) return m_pData->m_pObjectShell->GetSharedFileURL(); else return m_pData->m_pObjectShell->GetMedium()->GetName();
}
// TODO/LATER: let the embedded case of saving be handled more careful if ( m_pData->m_pObjectShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
{ // If this is an embedded object that has no URL based location it should be stored to own storage. // An embedded object can have a location based on URL in case it is a link, then it should be // stored in normal way. if ( !hasLocation() || getLocation().startsWith("private:") )
{ // actually in this very rare case only UI parameters have sense // TODO/LATER: should be done later, after integration of sb19
bRet = m_pData->m_pObjectShell->DoSave()
&& m_pData->m_pObjectShell->DoSaveCompleted();
} else
{
bRet = m_pData->m_pObjectShell->Save_Impl( &*pParams );
}
} else
{ // Tell the SfxMedium if we are in checkin instead of normal save
m_pData->m_pObjectShell->GetMedium( )->SetInCheckIn( nSlotId == SID_CHECKIN ); if (bOnMainThread)
bRet = vcl::solarthread::syncExecute(
[this, &pParams] { return m_pData->m_pObjectShell->Save_Impl(&*pParams); }); else
bRet = m_pData->m_pObjectShell->Save_Impl(&*pParams);
m_pData->m_pObjectShell->GetMedium( )->SetInCheckIn( nSlotId != SID_CHECKIN );
}
#if OSL_DEBUG_LEVEL > 0 const SfxStringItem* pPasswdItem = m_pData->m_pObjectShell->GetMedium()->GetItemSet().GetItem(SID_PASSWORD, false);
OSL_ENSURE( !pPasswdItem, "There should be no Password property in the document MediaDescriptor!" ); #endif
}
// delegate to our "load" method
::comphelper::NamedValueCollection aMediaDescriptor( i_MediaDescriptor );
// our load implementation expects the SalvagedFile to be in the media descriptor
OSL_ENSURE( !aMediaDescriptor.has( u"SalvagedFile"_ustr ) || ( aMediaDescriptor.getOrDefault( u"SalvagedFile"_ustr, OUString() ) == i_SalvagedFile ), "SfxBaseModel::recoverFromFile: inconsistent information!" );
aMediaDescriptor.put( u"SalvagedFile"_ustr, i_SalvagedFile );
// similar for the to-be-loaded file
OSL_ENSURE( !aMediaDescriptor.has( u"URL"_ustr ) || ( aMediaDescriptor.getOrDefault( u"URL"_ustr, OUString() ) == i_SourceLocation ), "SfxBaseModel::recoverFromFile: inconsistent information!" );
aMediaDescriptor.put( u"URL"_ustr, i_SourceLocation );
load( aMediaDescriptor.getPropertyValues() );
// Note: The XDocumentRecovery interface specification requires us to do an attachResource after loading. // However, we will not do this here, as we know that our load implementation (respectively some method // called from there) already did so. // In particular, the load process might already have modified some elements of the media // descriptor, for instance the MacroExecMode (in case the user was involved to decide about it), and we do // not want to overwrite it with the "old" elements passed to this method here.
}
// the object shell should exist always
DBG_ASSERT( m_pData->m_pObjectShell.is(), "Model is useless without an ObjectShell"); if ( !m_pData->m_pObjectShell.is() ) return;
// the object shell should exist always
DBG_ASSERT( m_pData->m_pObjectShell.is(), "Model is useless without an ObjectShell");
if (!m_pData->m_pObjectShell.is()) return;
if( m_pData->m_pObjectShell->GetMedium() ) // if a Medium is present, the document is already initialized throw frame::DoubleInitializationException();
SfxMedium* pMedium = new SfxMedium( seqArguments );
ErrCodeMsg nError = ERRCODE_NONE; if (!getFilterProvider(*pMedium).isEmpty())
{ if (!m_pData->m_pObjectShell->DoLoadExternal(pMedium))
nError = ERRCODE_IO_GENERAL;
// load document if ( !m_pData->m_pObjectShell->DoLoad(pMedium) )
nError=ERRCODE_IO_GENERAL;
// QUESTION: if the following happens outside of DoLoad, something important is missing there!
Reference< task::XInteractionHandler > xHandler = pMedium->GetInteractionHandler(); if( m_pData->m_pObjectShell->GetErrorCode() )
{
nError = m_pData->m_pObjectShell->GetErrorCode(); if ( nError == ERRCODE_IO_BROKENPACKAGE && xHandler.is() )
{ const OUString aDocName( pMedium->GetURLObject().getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset ) ); if (!pMedium->IsRepairPackage())
{
RequestPackageReparation aRequest( aDocName );
xHandler->handle( aRequest.GetRequest() ); if( aRequest.isApproved() )
{ // lok: we want to overwrite file in jail, so don't use template flag bool bIsLOK = comphelper::LibreOfficeKit::isActive();
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ 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.0.32Bemerkung:
(vorverarbeitet)
¤
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.