ca5c9591ba
Change-Id: I6306260d03c1208ec250c2f9a3860fa569f6d9c8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167448 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
763 lines
21 KiB
C++
763 lines
21 KiB
C++
/* -*- 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 .
|
|
*/
|
|
|
|
#include <memory>
|
|
#include <com/sun/star/frame/DispatchStatement.hpp>
|
|
#include <com/sun/star/container/XIndexReplace.hpp>
|
|
#include <com/sun/star/beans/PropertyValue.hpp>
|
|
#include <com/sun/star/uno/Sequence.hxx>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/util/URLTransformer.hpp>
|
|
#include <com/sun/star/util/XURLTransformer.hpp>
|
|
#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
|
|
#include <svl/itemiter.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <osl/diagnose.h>
|
|
#include <tools/debug.hxx>
|
|
|
|
#include <svl/itempool.hxx>
|
|
|
|
#include <comphelper/processfactory.hxx>
|
|
|
|
#include <svl/hint.hxx>
|
|
|
|
#include <sfx2/request.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/msg.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <sfx2/objface.hxx>
|
|
#include <sfx2/sfxuno.hxx>
|
|
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
struct SfxRequest_Impl: public SfxListener
|
|
|
|
/* [Description]
|
|
|
|
Implementation structure of the <SfxRequest> class.
|
|
*/
|
|
|
|
{
|
|
SfxRequest* pAnti; // Owner because of dying pool
|
|
OUString aTarget; // if possible from target object set by App
|
|
SfxItemPool* pPool; // ItemSet build with this pool
|
|
SfxPoolItemHolder aRetVal; // Return value belongs to itself
|
|
SfxShell* pShell; // run from this shell
|
|
const SfxSlot* pSlot; // executed Slot
|
|
sal_uInt16 nModifier; // which Modifier was pressed?
|
|
bool bDone; // at all executed
|
|
bool bIgnored; // Cancelled by the User
|
|
bool bCancelled; // no longer notify
|
|
SfxCallMode nCallMode; // Synch/Asynch/API/Record
|
|
bool bAllowRecording;
|
|
std::unique_ptr<SfxAllItemSet>
|
|
pInternalArgs;
|
|
SfxViewFrame* pViewFrame;
|
|
int m_nLokViewId = -1;
|
|
|
|
css::uno::Reference< css::frame::XDispatchRecorder > xRecorder;
|
|
css::uno::Reference< css::util::XURLTransformer > xTransform;
|
|
|
|
explicit SfxRequest_Impl( SfxRequest *pOwner )
|
|
: pAnti( pOwner)
|
|
, pPool(nullptr)
|
|
, pShell(nullptr)
|
|
, pSlot(nullptr)
|
|
, nModifier(0)
|
|
, bDone(false)
|
|
, bIgnored(false)
|
|
, bCancelled(false)
|
|
, nCallMode( SfxCallMode::SYNCHRON )
|
|
, bAllowRecording( false )
|
|
, pViewFrame(nullptr)
|
|
{
|
|
}
|
|
|
|
void SetPool( SfxItemPool *pNewPool );
|
|
virtual void Notify( SfxBroadcaster &rBC, const SfxHint &rHint ) override;
|
|
void Record( const uno::Sequence < beans::PropertyValue >& rArgs );
|
|
};
|
|
|
|
|
|
void SfxRequest_Impl::Notify( SfxBroadcaster&, const SfxHint &rHint )
|
|
{
|
|
if ( rHint.GetId() == SfxHintId::Dying )
|
|
pAnti->Cancel();
|
|
}
|
|
|
|
|
|
void SfxRequest_Impl::SetPool( SfxItemPool *pNewPool )
|
|
{
|
|
if ( pNewPool != pPool )
|
|
{
|
|
if ( pPool )
|
|
EndListening( pPool->BC() );
|
|
|
|
// tdf#159719 reset SfxPoolItemHolder
|
|
aRetVal = SfxPoolItemHolder();
|
|
|
|
pPool = pNewPool;
|
|
|
|
if ( pNewPool )
|
|
StartListening( pNewPool->BC() );
|
|
}
|
|
}
|
|
|
|
|
|
SfxRequest::~SfxRequest()
|
|
{
|
|
// Leave out Done() marked requests with 'rem'
|
|
if ( pImpl->xRecorder.is() && !pImpl->bDone && !pImpl->bIgnored )
|
|
pImpl->Record( uno::Sequence < beans::PropertyValue >() );
|
|
|
|
// Clear object
|
|
pArgs.reset();
|
|
}
|
|
|
|
|
|
SfxRequest::SfxRequest
|
|
(
|
|
const SfxRequest& rOrig
|
|
)
|
|
: nSlot(rOrig.nSlot),
|
|
pArgs(rOrig.pArgs? new SfxAllItemSet(*rOrig.pArgs): nullptr),
|
|
pImpl( new SfxRequest_Impl(this) )
|
|
{
|
|
pImpl->bAllowRecording = rOrig.pImpl->bAllowRecording;
|
|
pImpl->bDone = false;
|
|
pImpl->bIgnored = false;
|
|
pImpl->pShell = nullptr;
|
|
pImpl->pSlot = nullptr;
|
|
pImpl->nCallMode = rOrig.pImpl->nCallMode;
|
|
pImpl->aTarget = rOrig.pImpl->aTarget;
|
|
pImpl->nModifier = rOrig.pImpl->nModifier;
|
|
|
|
// deep copy needed !
|
|
pImpl->pInternalArgs.reset( rOrig.pImpl->pInternalArgs ? new SfxAllItemSet(*rOrig.pImpl->pInternalArgs) : nullptr);
|
|
|
|
if ( pArgs )
|
|
pImpl->SetPool( pArgs->GetPool() );
|
|
else
|
|
pImpl->SetPool( rOrig.pImpl->pPool );
|
|
|
|
// setup macro recording if it was in the original SfxRequest
|
|
if (!rOrig.pImpl->pViewFrame || !rOrig.pImpl->xRecorder.is())
|
|
return;
|
|
|
|
nSlot = rOrig.nSlot;
|
|
pImpl->pViewFrame = rOrig.pImpl->pViewFrame;
|
|
if (pImpl->pViewFrame->GetDispatcher()->GetShellAndSlot_Impl(nSlot, &pImpl->pShell, &pImpl->pSlot, true, true))
|
|
{
|
|
pImpl->SetPool( &pImpl->pShell->GetPool() );
|
|
pImpl->xRecorder = SfxRequest::GetMacroRecorder(*pImpl->pViewFrame);
|
|
if (pImpl->xRecorder)
|
|
pImpl->xTransform = util::URLTransformer::create(comphelper::getProcessComponentContext());
|
|
pImpl->aTarget = pImpl->pShell->GetName();
|
|
}
|
|
else
|
|
{
|
|
SAL_WARN("sfx", "Recording unsupported slot: " << pImpl->pPool->GetSlotId(nSlot));
|
|
}
|
|
}
|
|
|
|
|
|
/* [Description]
|
|
|
|
With this constructor events can subsequently be recorded that are not run
|
|
across SfxDispatcher (eg from KeyInput() or mouse events). For this, a
|
|
SfxRequest instance is created by this constructor and then proceed
|
|
exactly as with a SfxRequest that in a <Slot-Execute-Method> is given as a
|
|
parameter.
|
|
*/
|
|
|
|
SfxRequest::SfxRequest(SfxViewFrame& rViewFrame, sal_uInt16 nSlotId)
|
|
: nSlot(nSlotId)
|
|
, pImpl(new SfxRequest_Impl(this))
|
|
{
|
|
pImpl->bDone = false;
|
|
pImpl->bIgnored = false;
|
|
pImpl->SetPool( &rViewFrame.GetPool() );
|
|
pImpl->pShell = nullptr;
|
|
pImpl->pSlot = nullptr;
|
|
pImpl->nCallMode = SfxCallMode::SYNCHRON;
|
|
pImpl->pViewFrame = &rViewFrame;
|
|
if( pImpl->pViewFrame->GetDispatcher()->GetShellAndSlot_Impl( nSlotId, &pImpl->pShell, &pImpl->pSlot, true, true ) )
|
|
{
|
|
pImpl->SetPool( &pImpl->pShell->GetPool() );
|
|
pImpl->xRecorder = SfxRequest::GetMacroRecorder(rViewFrame);
|
|
if (pImpl->xRecorder)
|
|
pImpl->xTransform = util::URLTransformer::create(comphelper::getProcessComponentContext());
|
|
pImpl->aTarget = pImpl->pShell->GetName();
|
|
}
|
|
else
|
|
{
|
|
SAL_WARN( "sfx", "Recording unsupported slot: " << pImpl->pPool->GetSlotId(nSlotId) );
|
|
}
|
|
}
|
|
|
|
|
|
SfxRequest::SfxRequest
|
|
(
|
|
sal_uInt16 nSlotId, // executed <Slot-Id>
|
|
SfxCallMode nMode, // Synch/API/...
|
|
SfxItemPool& rPool // necessary for the SfxItemSet for parameters
|
|
)
|
|
|
|
// creates a SfxRequest without arguments
|
|
|
|
: nSlot(nSlotId),
|
|
pImpl( new SfxRequest_Impl(this) )
|
|
{
|
|
pImpl->bDone = false;
|
|
pImpl->bIgnored = false;
|
|
pImpl->SetPool( &rPool );
|
|
pImpl->pShell = nullptr;
|
|
pImpl->pSlot = nullptr;
|
|
pImpl->nCallMode = nMode;
|
|
}
|
|
|
|
SfxRequest::SfxRequest
|
|
(
|
|
const SfxSlot* pSlot, // executed <Slot-Id>
|
|
const css::uno::Sequence < css::beans::PropertyValue >& rArgs,
|
|
SfxCallMode nMode, // Synch/API/...
|
|
SfxItemPool& rPool // necessary for the SfxItemSet for parameters
|
|
)
|
|
: nSlot(pSlot->GetSlotId()),
|
|
pArgs(new SfxAllItemSet(rPool)),
|
|
pImpl( new SfxRequest_Impl(this) )
|
|
{
|
|
pImpl->bDone = false;
|
|
pImpl->bIgnored = false;
|
|
pImpl->SetPool( &rPool );
|
|
pImpl->pShell = nullptr;
|
|
pImpl->pSlot = nullptr;
|
|
pImpl->nCallMode = nMode;
|
|
TransformParameters( nSlot, rArgs, *pArgs, pSlot );
|
|
}
|
|
|
|
|
|
SfxRequest::SfxRequest
|
|
(
|
|
sal_uInt16 nSlotId,
|
|
SfxCallMode nMode,
|
|
const SfxAllItemSet& rSfxArgs
|
|
)
|
|
|
|
// creates a SfxRequest with arguments
|
|
|
|
: nSlot(nSlotId),
|
|
pArgs(new SfxAllItemSet(rSfxArgs)),
|
|
pImpl( new SfxRequest_Impl(this) )
|
|
{
|
|
pImpl->bDone = false;
|
|
pImpl->bIgnored = false;
|
|
pImpl->SetPool( rSfxArgs.GetPool() );
|
|
pImpl->pShell = nullptr;
|
|
pImpl->pSlot = nullptr;
|
|
pImpl->nCallMode = nMode;
|
|
}
|
|
|
|
|
|
SfxRequest::SfxRequest
|
|
(
|
|
sal_uInt16 nSlotId,
|
|
SfxCallMode nMode,
|
|
const SfxAllItemSet& rSfxArgs,
|
|
const SfxAllItemSet& rSfxInternalArgs
|
|
)
|
|
: SfxRequest(nSlotId, nMode, rSfxArgs)
|
|
{
|
|
SetInternalArgs_Impl(rSfxInternalArgs);
|
|
}
|
|
|
|
SfxCallMode SfxRequest::GetCallMode() const
|
|
{
|
|
return pImpl->nCallMode;
|
|
}
|
|
|
|
|
|
bool SfxRequest::IsSynchronCall() const
|
|
{
|
|
return SfxCallMode::SYNCHRON == ( SfxCallMode::SYNCHRON & pImpl->nCallMode );
|
|
}
|
|
|
|
|
|
void SfxRequest::SetSynchronCall( bool bSynchron )
|
|
{
|
|
if ( bSynchron )
|
|
pImpl->nCallMode |= SfxCallMode::SYNCHRON;
|
|
else
|
|
pImpl->nCallMode &= ~SfxCallMode::SYNCHRON;
|
|
}
|
|
|
|
void SfxRequest::SetInternalArgs_Impl( const SfxAllItemSet& rArgs )
|
|
{
|
|
pImpl->pInternalArgs.reset( new SfxAllItemSet( rArgs ) );
|
|
}
|
|
|
|
const SfxItemSet* SfxRequest::GetInternalArgs_Impl() const
|
|
{
|
|
return pImpl->pInternalArgs.get();
|
|
}
|
|
|
|
|
|
void SfxRequest_Impl::Record
|
|
(
|
|
const uno::Sequence < beans::PropertyValue >& rArgs // current Parameter
|
|
)
|
|
|
|
/* [Description]
|
|
|
|
Internal helper method to create a repeatable description of the just
|
|
executed SfxRequest.
|
|
*/
|
|
|
|
{
|
|
if(!xRecorder.is())
|
|
return;
|
|
|
|
OUString aCmd = pSlot->GetCommand();
|
|
|
|
uno::Reference< container::XIndexReplace > xReplace( xRecorder, uno::UNO_QUERY );
|
|
if ( xReplace.is() && aCmd == ".uno:InsertText" )
|
|
{
|
|
sal_Int32 nCount = xReplace->getCount();
|
|
if ( nCount )
|
|
{
|
|
frame::DispatchStatement aStatement;
|
|
uno::Any aElement = xReplace->getByIndex(nCount-1);
|
|
if ( (aElement >>= aStatement) && aStatement.aCommand == aCmd )
|
|
{
|
|
OUString aStr;
|
|
OUString aNew;
|
|
aStatement.aArgs[0].Value >>= aStr;
|
|
rArgs[0].Value >>= aNew;
|
|
aStr += aNew;
|
|
aStatement.aArgs.getArray()[0].Value <<= aStr;
|
|
aElement <<= aStatement;
|
|
xReplace->replaceByIndex( nCount-1, aElement );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
css::util::URL aURL;
|
|
aURL.Complete = aCmd;
|
|
xTransform->parseStrict(aURL);
|
|
|
|
if (bDone)
|
|
xRecorder->recordDispatch(aURL,rArgs);
|
|
else
|
|
xRecorder->recordDispatchAsComment(aURL,rArgs);
|
|
}
|
|
|
|
|
|
void SfxRequest::Record_Impl
|
|
(
|
|
SfxShell& rSh, // the <SfxShell>, which has executed the Request
|
|
const SfxSlot& rSlot, // the <SfxSlot>, which has executed the Request
|
|
const css::uno::Reference< css::frame::XDispatchRecorder >& xRecorder,
|
|
SfxViewFrame* pViewFrame
|
|
)
|
|
|
|
/* [Description]
|
|
|
|
This internal method marks the specified SfxMakro SfxRequest as recorded in
|
|
SfxMakro. Pointer to the parameters in Done() is used again, thus has to
|
|
still be alive.
|
|
*/
|
|
|
|
{
|
|
pImpl->pShell = &rSh;
|
|
pImpl->pSlot = &rSlot;
|
|
pImpl->xRecorder = xRecorder;
|
|
if (pImpl->xRecorder && !pImpl->xTransform)
|
|
pImpl->xTransform = util::URLTransformer::create(comphelper::getProcessComponentContext());
|
|
pImpl->aTarget = rSh.GetName();
|
|
pImpl->pViewFrame = pViewFrame;
|
|
}
|
|
|
|
|
|
void SfxRequest::SetArgs( const SfxAllItemSet& rArgs )
|
|
{
|
|
pArgs.reset(new SfxAllItemSet(rArgs));
|
|
pImpl->SetPool( pArgs->GetPool() );
|
|
}
|
|
|
|
|
|
void SfxRequest::AppendItem(const SfxPoolItem &rItem)
|
|
{
|
|
if(!pArgs)
|
|
pArgs.reset( new SfxAllItemSet(*pImpl->pPool) );
|
|
pArgs->Put(rItem);
|
|
}
|
|
|
|
|
|
void SfxRequest::RemoveItem( sal_uInt16 nID )
|
|
{
|
|
if (pArgs)
|
|
{
|
|
pArgs->ClearItem(nID);
|
|
if ( !pArgs->Count() )
|
|
pArgs.reset();
|
|
}
|
|
}
|
|
|
|
void SfxRequest::SetReturnValue(const SfxPoolItem &rItem)
|
|
{
|
|
DBG_ASSERT(nullptr != pImpl->pPool, "Missing SfxItemPool (!)");
|
|
if (nullptr != pImpl->pPool)
|
|
pImpl->aRetVal = SfxPoolItemHolder(*pImpl->pPool, &rItem);
|
|
}
|
|
|
|
|
|
const SfxPoolItemHolder& SfxRequest::GetReturnValue() const
|
|
{
|
|
return pImpl->aRetVal;
|
|
}
|
|
|
|
|
|
void SfxRequest::Done
|
|
(
|
|
const SfxItemSet& rSet /* parameters passed on by the application,
|
|
that for example were asked for by the user
|
|
in a dialogue, 0 if no parameters have been
|
|
set */
|
|
)
|
|
|
|
/* [Description]
|
|
|
|
This method must be called in the <Execute-Method> of the <SfxSlot>s, which
|
|
has performed the SfxRequest when the execution actually took place. If
|
|
'Done()' is not called, then the SfxRequest is considered canceled.
|
|
|
|
Any return values are passed only when 'Done()' was called. Similar, when
|
|
recording a macro only true statements are generated if 'Done()' was
|
|
called; for SfxRequests that were not identified as such will instead
|
|
be commented out by inserting ('rem').
|
|
|
|
[Note]
|
|
|
|
'Done ()' is not called, for example when a dialog started by the function
|
|
was canceled by the user or if the execution could not be performed due to
|
|
a wrong context (without use of separate <SfxShell>s). 'Done ()' will be
|
|
launched, when executing the function led to a regular error
|
|
(for example, file could not be opened).
|
|
*/
|
|
|
|
{
|
|
Done_Impl( &rSet );
|
|
|
|
// Keep items if possible, so they can be queried by StarDraw.
|
|
if ( !pArgs )
|
|
{
|
|
pArgs.reset( new SfxAllItemSet( rSet ) );
|
|
pImpl->SetPool( pArgs->GetPool() );
|
|
}
|
|
else
|
|
{
|
|
SfxItemIter aIter(rSet);
|
|
for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
|
|
{
|
|
if(!IsInvalidItem(pItem))
|
|
pArgs->Put(*pItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SfxRequest::Done( bool bRelease )
|
|
// [<SfxRequest::Done(SfxItemSet&)>]
|
|
{
|
|
Done_Impl( pArgs.get() );
|
|
if( bRelease )
|
|
pArgs.reset();
|
|
}
|
|
|
|
|
|
void SfxRequest::ForgetAllArgs()
|
|
{
|
|
pArgs.reset();
|
|
pImpl->pInternalArgs.reset();
|
|
}
|
|
|
|
|
|
bool SfxRequest::IsCancelled() const
|
|
{
|
|
return pImpl->bCancelled;
|
|
}
|
|
|
|
|
|
void SfxRequest::Cancel()
|
|
|
|
/* [Description]
|
|
|
|
Marks this request as no longer executable. For example, if called when
|
|
the target (more precisely, its pool) dies.
|
|
*/
|
|
|
|
{
|
|
pImpl->bCancelled = true;
|
|
pImpl->SetPool( nullptr );
|
|
pArgs.reset();
|
|
}
|
|
|
|
|
|
void SfxRequest::Ignore()
|
|
|
|
/* [Description]
|
|
|
|
If this method is called instead of <SfxRequest::Done()>, then this
|
|
request is not recorded.
|
|
|
|
[Example]
|
|
|
|
The selecting of tools in StarDraw should not be recorded, but the same
|
|
slots are to be used from the generation of the tools to the generated
|
|
objects. Thus can NoRecords not be specified, i.e. should not be recorded.
|
|
*/
|
|
|
|
{
|
|
// Mark as actually executed
|
|
pImpl->bIgnored = true;
|
|
}
|
|
|
|
|
|
void SfxRequest::Done_Impl
|
|
(
|
|
const SfxItemSet* pSet /* parameters passed on by the application,
|
|
that for example were asked for by the user
|
|
in a dialogue, 0 if no parameters have been
|
|
set */
|
|
|
|
)
|
|
|
|
/* [Description]
|
|
|
|
Internal method to mark SfxRequest with 'done' and to evaluate the
|
|
parameters in 'pSet' in case it is recorded.
|
|
*/
|
|
|
|
{
|
|
// Mark as actually executed
|
|
pImpl->bDone = true;
|
|
|
|
// not Recording
|
|
if ( !pImpl->xRecorder.is() )
|
|
return;
|
|
|
|
// was running a different slot than requested (Delegation)
|
|
if ( nSlot != pImpl->pSlot->GetSlotId() )
|
|
{
|
|
// Search Slot again
|
|
pImpl->pSlot = pImpl->pShell->GetInterface()->GetSlot(nSlot);
|
|
DBG_ASSERT( pImpl->pSlot, "delegated SlotId not found" );
|
|
if ( !pImpl->pSlot ) // playing it safe
|
|
return;
|
|
}
|
|
|
|
// recordable?
|
|
// new Recording uses UnoName!
|
|
SAL_WARN_IF( pImpl->pSlot->aUnoName.isEmpty(), "sfx", "Recording not exported slot: "
|
|
<< pImpl->pSlot->GetSlotId() );
|
|
|
|
if ( pImpl->pSlot->aUnoName.isEmpty() ) // playing it safe
|
|
return;
|
|
|
|
// often required values
|
|
SfxItemPool &rPool = pImpl->pShell->GetPool();
|
|
|
|
// Property-Slot?
|
|
if ( !pImpl->pSlot->IsMode(SfxSlotMode::METHOD) )
|
|
{
|
|
// get the property as SfxPoolItem
|
|
const SfxPoolItem *pItem(nullptr);
|
|
const sal_uInt16 nWhich(rPool.GetWhichIDFromSlotID(pImpl->pSlot->GetSlotId()));
|
|
const bool bItemStateSet(nullptr != pSet);
|
|
const SfxItemState eState(bItemStateSet ? pSet->GetItemState( nWhich, false, &pItem ) : SfxItemState::DEFAULT);
|
|
SAL_WARN_IF( !bItemStateSet || SfxItemState::SET != eState, "sfx", "Recording property not available: "
|
|
<< pImpl->pSlot->GetSlotId() );
|
|
uno::Sequence < beans::PropertyValue > aSeq;
|
|
|
|
if ( bItemStateSet && SfxItemState::SET == eState )
|
|
TransformItems( pImpl->pSlot->GetSlotId(), *pSet, aSeq, pImpl->pSlot );
|
|
|
|
pImpl->Record( aSeq );
|
|
}
|
|
|
|
// record everything in a single statement?
|
|
else if ( pImpl->pSlot->IsMode(SfxSlotMode::RECORDPERSET) )
|
|
{
|
|
uno::Sequence < beans::PropertyValue > aSeq;
|
|
if ( pSet )
|
|
TransformItems( pImpl->pSlot->GetSlotId(), *pSet, aSeq, pImpl->pSlot );
|
|
pImpl->Record( aSeq );
|
|
}
|
|
|
|
// record each item as a single statement
|
|
else if ( pImpl->pSlot->IsMode(SfxSlotMode::RECORDPERITEM) )
|
|
{
|
|
if ( pSet )
|
|
{
|
|
// iterate over Items
|
|
SfxItemIter aIter(*pSet);
|
|
for ( const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem() )
|
|
{
|
|
// to determine the slot ID for the individual item
|
|
sal_uInt16 nSlotId = rPool.GetSlotId( pItem->Which() );
|
|
if ( nSlotId == nSlot )
|
|
{
|
|
// play it safe; repair the wrong flags
|
|
OSL_FAIL( "recursion RecordPerItem - use RecordPerSet!" );
|
|
SfxSlot *pSlot = const_cast<SfxSlot*>(pImpl->pSlot);
|
|
pSlot->nFlags &= ~SfxSlotMode::RECORDPERITEM;
|
|
pSlot->nFlags &= SfxSlotMode::RECORDPERSET;
|
|
}
|
|
|
|
// Record a Sub-Request
|
|
SfxRequest aReq( *pImpl->pViewFrame, nSlotId );
|
|
if ( aReq.pImpl->pSlot )
|
|
aReq.AppendItem( *pItem );
|
|
aReq.Done();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//HACK(think about this again)
|
|
pImpl->Record( uno::Sequence < beans::PropertyValue >() );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool SfxRequest::IsDone() const
|
|
|
|
/* [Description]
|
|
|
|
With this method it can be queried whether the SfxRequest was actually
|
|
executed or not. If a SfxRequest was not executed, then this is for example
|
|
because it was canceled by the user or the context for this request was
|
|
wrong, this was not implemented on a separate <SfxShell>.
|
|
|
|
SfxRequest instances that return false will not be recorded.
|
|
|
|
[Cross-reference]
|
|
|
|
<SfxRequest::Done(const SfxItemSet&)>
|
|
<SfxRequest::Done()>
|
|
*/
|
|
|
|
{
|
|
return pImpl->bDone;
|
|
}
|
|
|
|
|
|
css::uno::Reference< css::frame::XDispatchRecorder > SfxRequest::GetMacroRecorder(const SfxViewFrame& rView)
|
|
|
|
/* [Description]
|
|
|
|
This recorder is an attempt for dispatch () to get calls from the Frame.
|
|
This is then available through a property by a supplier but only when
|
|
recording was turned on.
|
|
|
|
(See also SfxViewFrame::MiscExec_Impl() and SID_RECORDING)
|
|
*/
|
|
|
|
{
|
|
css::uno::Reference< css::frame::XDispatchRecorder > xRecorder;
|
|
|
|
css::uno::Reference< css::beans::XPropertySet > xSet(
|
|
rView.GetFrame().GetFrameInterface(),
|
|
css::uno::UNO_QUERY);
|
|
|
|
if(xSet.is())
|
|
{
|
|
css::uno::Any aProp = xSet->getPropertyValue(u"DispatchRecorderSupplier"_ustr);
|
|
css::uno::Reference< css::frame::XDispatchRecorderSupplier > xSupplier;
|
|
aProp >>= xSupplier;
|
|
if(xSupplier.is())
|
|
xRecorder = xSupplier->getDispatchRecorder();
|
|
}
|
|
|
|
return xRecorder;
|
|
}
|
|
|
|
bool SfxRequest::HasMacroRecorder(const SfxViewFrame& rView)
|
|
{
|
|
return GetMacroRecorder(rView).is();
|
|
}
|
|
|
|
bool SfxRequest::IsAPI() const
|
|
|
|
/* [Description]
|
|
|
|
Returns true if this SfxRequest was generated by an API (for example BASIC),
|
|
otherwise false.
|
|
*/
|
|
|
|
{
|
|
return SfxCallMode::API == ( SfxCallMode::API & pImpl->nCallMode );
|
|
}
|
|
|
|
|
|
void SfxRequest::SetModifier( sal_uInt16 nModi )
|
|
{
|
|
pImpl->nModifier = nModi;
|
|
}
|
|
|
|
|
|
sal_uInt16 SfxRequest::GetModifier() const
|
|
{
|
|
return pImpl->nModifier;
|
|
}
|
|
|
|
|
|
void SfxRequest::AllowRecording( bool bSet )
|
|
{
|
|
pImpl->bAllowRecording = bSet;
|
|
}
|
|
|
|
bool SfxRequest::AllowsRecording() const
|
|
{
|
|
bool bAllow = pImpl->bAllowRecording;
|
|
if( !bAllow )
|
|
bAllow = ( SfxCallMode::API != ( SfxCallMode::API & pImpl->nCallMode ) ) &&
|
|
( SfxCallMode::RECORD == ( SfxCallMode::RECORD & pImpl->nCallMode ) );
|
|
return bAllow;
|
|
}
|
|
|
|
void SfxRequest::ReleaseArgs()
|
|
{
|
|
pArgs.reset();
|
|
pImpl->pInternalArgs.reset();
|
|
}
|
|
|
|
void SfxRequest::SetLokViewId(int nId)
|
|
{
|
|
pImpl->m_nLokViewId = nId;
|
|
}
|
|
|
|
int SfxRequest::GetLokViewId() const
|
|
{
|
|
return pImpl->m_nLokViewId;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|