Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/control/request.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
20
#include <memory>
21
#include <com/sun/star/frame/DispatchStatement.hpp>
22
#include <com/sun/star/container/XIndexReplace.hpp>
23
#include <com/sun/star/beans/PropertyValue.hpp>
24
#include <com/sun/star/uno/Sequence.hxx>
25
#include <com/sun/star/beans/XPropertySet.hpp>
26
#include <com/sun/star/util/URLTransformer.hpp>
27
#include <com/sun/star/util/XURLTransformer.hpp>
28
#include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
29
#include <svl/itemiter.hxx>
30
#include <sal/log.hxx>
31
#include <osl/diagnose.h>
32
#include <tools/debug.hxx>
33
34
#include <svl/itempool.hxx>
35
36
#include <comphelper/processfactory.hxx>
37
38
#include <svl/hint.hxx>
39
40
#include <sfx2/request.hxx>
41
#include <sfx2/dispatch.hxx>
42
#include <sfx2/msg.hxx>
43
#include <sfx2/viewfrm.hxx>
44
#include <sfx2/objface.hxx>
45
#include <sfx2/sfxuno.hxx>
46
47
48
using namespace ::com::sun::star;
49
50
struct SfxRequest_Impl: public SfxListener
51
52
/*  [Description]
53
54
    Implementation structure of the <SfxRequest> class.
55
*/
56
57
{
58
    SfxRequest*     pAnti;       // Owner because of dying pool
59
    OUString        aTarget;     // if possible from target object set by App
60
    SfxItemPool*    pPool;       // ItemSet build with this pool
61
    SfxPoolItemHolder aRetVal; // Return value belongs to itself
62
    SfxShell*       pShell;      // run from this shell
63
    const SfxSlot*  pSlot;       // executed Slot
64
    sal_uInt16      nModifier;   // which Modifier was pressed?
65
    bool            bDone;       // at all executed
66
    bool            bIgnored;    // Cancelled by the User
67
    bool            bCancelled;  // no longer notify
68
    SfxCallMode     nCallMode;   // Synch/Asynch/API/Record
69
    bool            bAllowRecording;
70
    std::unique_ptr<SfxAllItemSet>
71
                    pInternalArgs;
72
    SfxViewFrame*   pViewFrame;
73
    int m_nLokViewId = -1;
74
75
    css::uno::Reference< css::frame::XDispatchRecorder > xRecorder;
76
    css::uno::Reference< css::util::XURLTransformer > xTransform;
77
78
    explicit SfxRequest_Impl( SfxRequest *pOwner )
79
0
        : pAnti( pOwner)
80
0
        , pPool(nullptr)
81
0
        , pShell(nullptr)
82
0
        , pSlot(nullptr)
83
0
        , nModifier(0)
84
0
        , bDone(false)
85
0
        , bIgnored(false)
86
0
        , bCancelled(false)
87
0
        , nCallMode( SfxCallMode::SYNCHRON )
88
0
        , bAllowRecording( false )
89
0
        , pViewFrame(nullptr)
90
0
    {
91
0
    }
92
93
    void                SetPool( SfxItemPool *pNewPool );
94
    virtual void        Notify( SfxBroadcaster &rBC, const SfxHint &rHint ) override;
95
    void                Record( const uno::Sequence < beans::PropertyValue >& rArgs );
96
};
97
98
99
void SfxRequest_Impl::Notify( SfxBroadcaster&, const SfxHint &rHint )
100
0
{
101
0
    if ( rHint.GetId() == SfxHintId::Dying )
102
0
        pAnti->Cancel();
103
0
}
104
105
106
void SfxRequest_Impl::SetPool( SfxItemPool *pNewPool )
107
0
{
108
0
    if ( pNewPool != pPool )
109
0
    {
110
0
        if ( pPool )
111
0
            EndListening( pPool->BC() );
112
113
        // tdf#159719 reset SfxPoolItemHolder
114
0
        aRetVal = SfxPoolItemHolder();
115
116
0
        pPool = pNewPool;
117
118
0
        if ( pNewPool )
119
0
            StartListening( pNewPool->BC() );
120
0
    }
121
0
}
122
123
124
SfxRequest::~SfxRequest()
125
0
{
126
    // Leave out Done() marked requests with 'rem'
127
0
    if ( pImpl->xRecorder.is() && !pImpl->bDone && !pImpl->bIgnored )
128
0
        pImpl->Record( uno::Sequence < beans::PropertyValue >() );
129
130
    // Clear object
131
0
    pArgs.reset();
132
0
}
133
134
135
SfxRequest::SfxRequest
136
(
137
    const SfxRequest& rOrig
138
)
139
0
:   nSlot(rOrig.nSlot),
140
0
    pArgs(rOrig.pArgs? new SfxAllItemSet(*rOrig.pArgs): nullptr),
141
0
    pImpl( new SfxRequest_Impl(this) )
142
0
{
143
0
    pImpl->bAllowRecording = rOrig.pImpl->bAllowRecording;
144
0
    pImpl->bDone = false;
145
0
    pImpl->bIgnored = false;
146
0
    pImpl->pShell = nullptr;
147
0
    pImpl->pSlot = nullptr;
148
0
    pImpl->nCallMode = rOrig.pImpl->nCallMode;
149
0
    pImpl->aTarget = rOrig.pImpl->aTarget;
150
0
    pImpl->nModifier = rOrig.pImpl->nModifier;
151
152
    // deep copy needed !
153
0
    pImpl->pInternalArgs.reset( rOrig.pImpl->pInternalArgs ? new SfxAllItemSet(*rOrig.pImpl->pInternalArgs) : nullptr);
154
155
0
    if ( pArgs )
156
0
        pImpl->SetPool( pArgs->GetPool() );
157
0
    else
158
0
        pImpl->SetPool( rOrig.pImpl->pPool );
159
160
    // setup macro recording if it was in the original SfxRequest
161
0
    if (!rOrig.pImpl->pViewFrame || !rOrig.pImpl->xRecorder.is())
162
0
        return;
163
164
0
    nSlot = rOrig.nSlot;
165
0
    pImpl->pViewFrame = rOrig.pImpl->pViewFrame;
166
0
    if (pImpl->pViewFrame->GetDispatcher()->GetShellAndSlot_Impl(nSlot, &pImpl->pShell, &pImpl->pSlot, true, true))
167
0
    {
168
0
        pImpl->SetPool( &pImpl->pShell->GetPool() );
169
0
        pImpl->xRecorder = SfxRequest::GetMacroRecorder(*pImpl->pViewFrame);
170
0
        if (pImpl->xRecorder)
171
0
            pImpl->xTransform = util::URLTransformer::create(comphelper::getProcessComponentContext());
172
0
        pImpl->aTarget = pImpl->pShell->GetName();
173
0
    }
174
0
    else
175
0
    {
176
0
        SAL_WARN("sfx", "Recording unsupported slot: " << pImpl->pPool->GetSlotId(nSlot));
177
0
    }
178
0
}
179
180
181
/*  [Description]
182
183
    With this constructor events can subsequently be recorded that are not run
184
    across SfxDispatcher (eg from KeyInput() or mouse events). For this, a
185
    SfxRequest instance is created by this constructor and then proceed
186
    exactly as with a SfxRequest that in a <Slot-Execute-Method> is given as a
187
    parameter.
188
*/
189
190
SfxRequest::SfxRequest(SfxViewFrame& rViewFrame, sal_uInt16 nSlotId)
191
0
    : nSlot(nSlotId)
192
0
    , pImpl(new SfxRequest_Impl(this))
193
0
{
194
0
    pImpl->bDone = false;
195
0
    pImpl->bIgnored = false;
196
0
    pImpl->SetPool( &rViewFrame.GetPool() );
197
0
    pImpl->pShell = nullptr;
198
0
    pImpl->pSlot = nullptr;
199
0
    pImpl->nCallMode = SfxCallMode::SYNCHRON;
200
0
    pImpl->pViewFrame = &rViewFrame;
201
0
    if( pImpl->pViewFrame->GetDispatcher()->GetShellAndSlot_Impl( nSlotId, &pImpl->pShell, &pImpl->pSlot, true, true ) )
202
0
    {
203
0
        pImpl->SetPool( &pImpl->pShell->GetPool() );
204
0
        pImpl->xRecorder = SfxRequest::GetMacroRecorder(rViewFrame);
205
0
        if (pImpl->xRecorder)
206
0
            pImpl->xTransform = util::URLTransformer::create(comphelper::getProcessComponentContext());
207
0
        pImpl->aTarget = pImpl->pShell->GetName();
208
0
    }
209
0
    else
210
0
    {
211
0
        SAL_WARN( "sfx", "Recording unsupported slot: " << pImpl->pPool->GetSlotId(nSlotId) );
212
0
    }
213
0
}
214
215
216
SfxRequest::SfxRequest
217
(
218
    sal_uInt16        nSlotId,  // executed <Slot-Id>
219
    SfxCallMode     nMode,      // Synch/API/...
220
    SfxItemPool&  rPool     // necessary for the SfxItemSet for parameters
221
)
222
223
// creates a SfxRequest without arguments
224
225
0
:   nSlot(nSlotId),
226
0
    pImpl( new SfxRequest_Impl(this) )
227
0
{
228
0
    pImpl->bDone = false;
229
0
    pImpl->bIgnored = false;
230
0
    pImpl->SetPool( &rPool );
231
0
    pImpl->pShell = nullptr;
232
0
    pImpl->pSlot = nullptr;
233
0
    pImpl->nCallMode = nMode;
234
0
}
235
236
SfxRequest::SfxRequest
237
(
238
    const SfxSlot* pSlot,       // executed <Slot-Id>
239
    const css::uno::Sequence < css::beans::PropertyValue >& rArgs,
240
    SfxCallMode     nMode,      // Synch/API/...
241
    SfxItemPool&   rPool        // necessary for the SfxItemSet for parameters
242
)
243
0
:   nSlot(pSlot->GetSlotId()),
244
0
    pArgs(new SfxAllItemSet(rPool)),
245
0
    pImpl( new SfxRequest_Impl(this) )
246
0
{
247
0
    pImpl->bDone = false;
248
0
    pImpl->bIgnored = false;
249
0
    pImpl->SetPool( &rPool );
250
0
    pImpl->pShell = nullptr;
251
0
    pImpl->pSlot = nullptr;
252
0
    pImpl->nCallMode = nMode;
253
0
    TransformParameters( nSlot, rArgs, *pArgs, pSlot );
254
0
}
255
256
257
SfxRequest::SfxRequest
258
(
259
    sal_uInt16                  nSlotId,
260
    SfxCallMode                 nMode,
261
    const SfxAllItemSet&        rSfxArgs
262
)
263
264
// creates a SfxRequest with arguments
265
266
0
:   nSlot(nSlotId),
267
0
    pArgs(new SfxAllItemSet(rSfxArgs)),
268
0
    pImpl( new SfxRequest_Impl(this) )
269
0
{
270
0
    pImpl->bDone = false;
271
0
    pImpl->bIgnored = false;
272
0
    pImpl->SetPool( rSfxArgs.GetPool() );
273
0
    pImpl->pShell = nullptr;
274
0
    pImpl->pSlot = nullptr;
275
0
    pImpl->nCallMode = nMode;
276
0
}
277
278
279
SfxRequest::SfxRequest
280
(
281
    sal_uInt16                  nSlotId,
282
    SfxCallMode                 nMode,
283
    const SfxAllItemSet&        rSfxArgs,
284
    const SfxAllItemSet&        rSfxInternalArgs
285
)
286
0
: SfxRequest(nSlotId, nMode, rSfxArgs)
287
0
{
288
0
    SetInternalArgs_Impl(rSfxInternalArgs);
289
0
}
290
291
SfxCallMode SfxRequest::GetCallMode() const
292
0
{
293
0
    return pImpl->nCallMode;
294
0
}
295
296
297
bool SfxRequest::IsSynchronCall() const
298
0
{
299
0
    return SfxCallMode::SYNCHRON == ( SfxCallMode::SYNCHRON & pImpl->nCallMode );
300
0
}
301
302
303
void SfxRequest::SetSynchronCall( bool bSynchron )
304
0
{
305
0
    if ( bSynchron )
306
0
        pImpl->nCallMode |= SfxCallMode::SYNCHRON;
307
0
    else
308
0
        pImpl->nCallMode &= ~SfxCallMode::SYNCHRON;
309
0
}
310
311
void SfxRequest::SetInternalArgs_Impl( const SfxAllItemSet& rArgs )
312
0
{
313
0
    pImpl->pInternalArgs.reset( new SfxAllItemSet( rArgs ) );
314
0
}
315
316
const SfxItemSet* SfxRequest::GetInternalArgs_Impl() const
317
0
{
318
0
    return pImpl->pInternalArgs.get();
319
0
}
320
321
322
void SfxRequest_Impl::Record
323
(
324
    const uno::Sequence < beans::PropertyValue >& rArgs  // current Parameter
325
)
326
327
/*  [Description]
328
329
    Internal helper method to create a repeatable description of the just
330
    executed SfxRequest.
331
*/
332
333
0
{
334
0
    if(!xRecorder.is())
335
0
        return;
336
337
0
    OUString aCmd = pSlot->GetCommand();
338
339
0
    uno::Reference< container::XIndexReplace > xReplace( xRecorder, uno::UNO_QUERY );
340
0
    if ( xReplace.is() && aCmd == ".uno:InsertText" )
341
0
    {
342
0
        sal_Int32 nCount = xReplace->getCount();
343
0
        if ( nCount )
344
0
        {
345
0
            frame::DispatchStatement aStatement;
346
0
            uno::Any aElement = xReplace->getByIndex(nCount-1);
347
0
            if ( (aElement >>= aStatement) && aStatement.aCommand == aCmd )
348
0
            {
349
0
                OUString aStr;
350
0
                OUString aNew;
351
0
                aStatement.aArgs[0].Value >>= aStr;
352
0
                rArgs[0].Value >>= aNew;
353
0
                aStr += aNew;
354
0
                aStatement.aArgs.getArray()[0].Value <<= aStr;
355
0
                aElement <<= aStatement;
356
0
                xReplace->replaceByIndex( nCount-1, aElement );
357
0
                return;
358
0
            }
359
0
        }
360
0
    }
361
362
0
    css::util::URL aURL;
363
0
    aURL.Complete = aCmd;
364
0
    xTransform->parseStrict(aURL);
365
366
0
    if (bDone)
367
0
        xRecorder->recordDispatch(aURL,rArgs);
368
0
    else
369
0
        xRecorder->recordDispatchAsComment(aURL,rArgs);
370
0
}
371
372
373
void SfxRequest::Record_Impl
374
(
375
    SfxShell&       rSh,    // the <SfxShell>, which has executed the Request
376
    const SfxSlot&  rSlot,  // the <SfxSlot>, which has executed the Request
377
    const css::uno::Reference< css::frame::XDispatchRecorder >& xRecorder,
378
    SfxViewFrame* pViewFrame
379
)
380
381
/*  [Description]
382
383
    This internal method marks the specified SfxMakro SfxRequest as recorded in
384
    SfxMakro. Pointer to the parameters in Done() is used again, thus has to
385
    still be alive.
386
*/
387
388
0
{
389
0
    pImpl->pShell = &rSh;
390
0
    pImpl->pSlot = &rSlot;
391
0
    pImpl->xRecorder = xRecorder;
392
0
    if (pImpl->xRecorder && !pImpl->xTransform)
393
0
        pImpl->xTransform = util::URLTransformer::create(comphelper::getProcessComponentContext());
394
0
    pImpl->aTarget = rSh.GetName();
395
0
    pImpl->pViewFrame = pViewFrame;
396
0
}
397
398
399
void SfxRequest::SetArgs( const SfxAllItemSet& rArgs )
400
0
{
401
0
    pArgs.reset(new SfxAllItemSet(rArgs));
402
0
    pImpl->SetPool( pArgs->GetPool() );
403
0
}
404
405
406
void SfxRequest::AppendItem(const SfxPoolItem &rItem)
407
0
{
408
0
    if(!pArgs)
409
0
        pArgs.reset( new SfxAllItemSet(*pImpl->pPool) );
410
0
    pArgs->Put(rItem);
411
0
}
412
413
414
void SfxRequest::RemoveItem( sal_uInt16 nID )
415
0
{
416
0
    if (pArgs)
417
0
    {
418
0
        pArgs->ClearItem(nID);
419
0
        if ( !pArgs->Count() )
420
0
            pArgs.reset();
421
0
    }
422
0
}
423
424
void SfxRequest::SetReturnValue(const SfxPoolItem &rItem)
425
0
{
426
0
    DBG_ASSERT(nullptr != pImpl->pPool, "Missing SfxItemPool (!)");
427
0
    if (nullptr != pImpl->pPool)
428
0
        pImpl->aRetVal = SfxPoolItemHolder(*pImpl->pPool, &rItem);
429
0
}
430
431
432
const SfxPoolItemHolder& SfxRequest::GetReturnValue() const
433
0
{
434
0
    return pImpl->aRetVal;
435
0
}
436
437
438
void SfxRequest::Done
439
(
440
    const SfxItemSet&   rSet    /* parameters passed on by the application,
441
                                   that for example were asked for by the user
442
                                   in a dialogue, 0 if no parameters have been
443
                                   set */
444
)
445
446
/*  [Description]
447
448
    This method must be called in the <Execute-Method> of the <SfxSlot>s, which
449
    has performed the SfxRequest when the execution actually took place. If
450
    'Done()' is not called, then the SfxRequest is considered canceled.
451
452
    Any return values are passed only when 'Done()' was called. Similar, when
453
    recording a macro only true statements are generated if 'Done()' was
454
    called; for SfxRequests that were not identified as such will instead
455
    be commented out by inserting ('rem').
456
457
    [Note]
458
459
    'Done ()' is not called, for example when a dialog started by the function
460
    was canceled by the user or if the execution could not be performed due to
461
    a wrong context (without use of separate <SfxShell>s). 'Done ()' will be
462
    launched, when executing the function led to a regular error
463
    (for example, file could not be opened).
464
*/
465
466
0
{
467
0
    Done_Impl( &rSet );
468
469
    // Keep items if possible, so they can be queried by StarDraw.
470
0
    if ( !pArgs )
471
0
    {
472
0
        pArgs.reset( new SfxAllItemSet( rSet ) );
473
0
        pImpl->SetPool( pArgs->GetPool() );
474
0
    }
475
0
    else
476
0
    {
477
0
        SfxItemIter aIter(rSet);
478
0
        for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
479
0
        {
480
0
            if(!IsInvalidItem(pItem))
481
0
                pArgs->Put(*pItem);
482
0
        }
483
0
    }
484
0
}
485
486
487
void SfxRequest::Done( bool bRelease )
488
//  [<SfxRequest::Done(SfxItemSet&)>]
489
0
{
490
0
    Done_Impl( pArgs.get() );
491
0
    if( bRelease )
492
0
        pArgs.reset();
493
0
}
494
495
496
void SfxRequest::ForgetAllArgs()
497
0
{
498
0
    pArgs.reset();
499
0
    pImpl->pInternalArgs.reset();
500
0
}
501
502
503
bool SfxRequest::IsCancelled() const
504
0
{
505
0
    return pImpl->bCancelled;
506
0
}
507
508
509
void SfxRequest::Cancel()
510
511
/*  [Description]
512
513
    Marks this request as no longer executable. For example, if called when
514
    the target (more precisely, its pool) dies.
515
*/
516
517
0
{
518
0
    pImpl->bCancelled = true;
519
0
    pImpl->SetPool( nullptr );
520
0
    pArgs.reset();
521
0
}
522
523
524
void SfxRequest::Ignore()
525
526
/*  [Description]
527
528
    If this method is called instead of <SfxRequest::Done()>, then this
529
    request is not recorded.
530
531
    [Example]
532
533
    The selecting of tools in StarDraw should not be recorded, but the same
534
    slots are to be used from the generation of the tools to the generated
535
    objects. Thus can NoRecords not be specified, i.e. should not be recorded.
536
*/
537
538
0
{
539
    // Mark as actually executed
540
0
    pImpl->bIgnored = true;
541
0
}
542
543
544
void SfxRequest::Done_Impl
545
(
546
    const SfxItemSet*   pSet    /* parameters passed on by the application,
547
                                   that for example were asked for by the user
548
                                   in a dialogue, 0 if no parameters have been
549
                                   set */
550
551
)
552
553
/*  [Description]
554
555
    Internal method to mark SfxRequest with 'done' and to evaluate the
556
    parameters in 'pSet' in case it is recorded.
557
*/
558
559
0
{
560
    // Mark as actually executed
561
0
    pImpl->bDone = true;
562
563
    // not Recording
564
0
    if ( !pImpl->xRecorder.is() )
565
0
        return;
566
567
    // was running a different slot than requested (Delegation)
568
0
    if ( nSlot != pImpl->pSlot->GetSlotId() )
569
0
    {
570
        // Search Slot again
571
0
        pImpl->pSlot = pImpl->pShell->GetInterface()->GetSlot(nSlot);
572
0
        DBG_ASSERT( pImpl->pSlot, "delegated SlotId not found" );
573
0
        if ( !pImpl->pSlot ) // playing it safe
574
0
            return;
575
0
    }
576
577
    // recordable?
578
    // new Recording uses UnoName!
579
0
    SAL_WARN_IF( pImpl->pSlot->aUnoName.isEmpty(), "sfx", "Recording not exported slot: "
580
0
                    << pImpl->pSlot->GetSlotId() );
581
582
0
    if ( pImpl->pSlot->aUnoName.isEmpty() ) // playing it safe
583
0
        return;
584
585
    // often required values
586
0
    SfxItemPool &rPool = pImpl->pShell->GetPool();
587
588
    // Property-Slot?
589
0
    if ( !pImpl->pSlot->IsMode(SfxSlotMode::METHOD) )
590
0
    {
591
        // get the property as SfxPoolItem
592
0
        const SfxPoolItem *pItem(nullptr);
593
0
        const sal_uInt16 nWhich(rPool.GetWhichIDFromSlotID(pImpl->pSlot->GetSlotId()));
594
0
        const bool bItemStateSet(nullptr != pSet);
595
0
        const SfxItemState eState(bItemStateSet ? pSet->GetItemState( nWhich, false, &pItem ) : SfxItemState::DEFAULT);
596
0
        SAL_WARN_IF( !bItemStateSet || SfxItemState::SET != eState, "sfx", "Recording property not available: "
597
0
                     << pImpl->pSlot->GetSlotId() );
598
0
        uno::Sequence < beans::PropertyValue > aSeq;
599
600
0
        if ( bItemStateSet && SfxItemState::SET == eState )
601
0
            aSeq = TransformItems(pImpl->pSlot->GetSlotId(), *pSet, pImpl->pSlot).getAsConstPropertyValueList();
602
603
0
        pImpl->Record( aSeq );
604
0
    }
605
606
    // record everything in a single statement?
607
0
    else if ( pImpl->pSlot->IsMode(SfxSlotMode::RECORDPERSET) )
608
0
    {
609
0
        uno::Sequence < beans::PropertyValue > aSeq;
610
0
        if ( pSet )
611
0
            aSeq = TransformItems(pImpl->pSlot->GetSlotId(), *pSet, pImpl->pSlot).getAsConstPropertyValueList();
612
0
        pImpl->Record( aSeq );
613
0
    }
614
615
    // record each item as a single statement
616
0
    else if ( pImpl->pSlot->IsMode(SfxSlotMode::RECORDPERITEM) )
617
0
    {
618
0
        if ( pSet )
619
0
        {
620
            // iterate over Items
621
0
            SfxItemIter aIter(*pSet);
622
0
            for ( const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem() )
623
0
            {
624
                // to determine the slot ID for the individual item
625
0
                sal_uInt16 nSlotId = rPool.GetSlotId( pItem->Which() );
626
0
                if ( nSlotId == nSlot )
627
0
                {
628
                    // play it safe; repair the wrong flags
629
0
                    OSL_FAIL( "recursion RecordPerItem - use RecordPerSet!" );
630
0
                    SfxSlot *pSlot = const_cast<SfxSlot*>(pImpl->pSlot);
631
0
                    pSlot->nFlags &= ~SfxSlotMode::RECORDPERITEM;
632
0
                    pSlot->nFlags &=  SfxSlotMode::RECORDPERSET;
633
0
                }
634
635
                // Record a Sub-Request
636
0
                SfxRequest aReq( *pImpl->pViewFrame, nSlotId );
637
0
                if ( aReq.pImpl->pSlot )
638
0
                    aReq.AppendItem( *pItem );
639
0
                aReq.Done();
640
0
            }
641
0
        }
642
0
        else
643
0
        {
644
          //HACK(think about this again)
645
0
            pImpl->Record( uno::Sequence < beans::PropertyValue >() );
646
0
        }
647
0
    }
648
0
}
649
650
651
bool SfxRequest::IsDone() const
652
653
/*  [Description]
654
655
    With this method it can be queried whether the SfxRequest was actually
656
    executed or not. If a SfxRequest was not executed, then this is for example
657
    because it was canceled by the user or the context for this request was
658
    wrong, this was not implemented on a separate <SfxShell>.
659
660
    SfxRequest instances that return false will not be recorded.
661
662
    [Cross-reference]
663
664
    <SfxRequest::Done(const SfxItemSet&)>
665
    <SfxRequest::Done()>
666
*/
667
668
0
{
669
0
    return pImpl->bDone;
670
0
}
671
672
673
css::uno::Reference< css::frame::XDispatchRecorder > SfxRequest::GetMacroRecorder(const SfxViewFrame& rView)
674
675
/*  [Description]
676
677
    This recorder is an attempt for dispatch () to get calls from the Frame.
678
    This is then available through a property by a supplier but only when
679
    recording was turned on.
680
681
    (See also SfxViewFrame::MiscExec_Impl() and SID_RECORDING)
682
*/
683
684
0
{
685
0
    css::uno::Reference< css::frame::XDispatchRecorder > xRecorder;
686
687
0
    css::uno::Reference< css::beans::XPropertySet > xSet(
688
0
        rView.GetFrame().GetFrameInterface(),
689
0
        css::uno::UNO_QUERY);
690
691
0
    if(xSet.is())
692
0
    {
693
0
        css::uno::Any aProp = xSet->getPropertyValue(u"DispatchRecorderSupplier"_ustr);
694
0
        css::uno::Reference< css::frame::XDispatchRecorderSupplier > xSupplier;
695
0
        aProp >>= xSupplier;
696
0
        if(xSupplier.is())
697
0
            xRecorder = xSupplier->getDispatchRecorder();
698
0
    }
699
700
0
    return xRecorder;
701
0
}
702
703
bool SfxRequest::HasMacroRecorder(const SfxViewFrame& rView)
704
0
{
705
0
    return GetMacroRecorder(rView).is();
706
0
}
707
708
bool SfxRequest::IsAPI() const
709
710
/*  [Description]
711
712
    Returns true if this SfxRequest was generated by an API (for example BASIC),
713
    otherwise false.
714
*/
715
716
0
{
717
0
    return SfxCallMode::API == ( SfxCallMode::API & pImpl->nCallMode );
718
0
}
719
720
721
void SfxRequest::SetModifier( sal_uInt16 nModi )
722
0
{
723
0
    pImpl->nModifier = nModi;
724
0
}
725
726
727
sal_uInt16 SfxRequest::GetModifier() const
728
0
{
729
0
    return pImpl->nModifier;
730
0
}
731
732
733
void SfxRequest::AllowRecording( bool bSet )
734
0
{
735
0
    pImpl->bAllowRecording = bSet;
736
0
}
737
738
bool SfxRequest::AllowsRecording() const
739
0
{
740
0
    bool bAllow = pImpl->bAllowRecording;
741
0
    if( !bAllow )
742
0
        bAllow = ( SfxCallMode::API != ( SfxCallMode::API & pImpl->nCallMode ) ) &&
743
0
                 ( SfxCallMode::RECORD == ( SfxCallMode::RECORD & pImpl->nCallMode ) );
744
0
    return bAllow;
745
0
}
746
747
void SfxRequest::ReleaseArgs()
748
0
{
749
0
    pArgs.reset();
750
0
    pImpl->pInternalArgs.reset();
751
0
}
752
753
void SfxRequest::SetLokViewId(int nId)
754
0
{
755
0
    pImpl->m_nLokViewId = nId;
756
0
}
757
758
int SfxRequest::GetLokViewId() const
759
0
{
760
0
    return pImpl->m_nLokViewId;
761
0
}
762
763
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */