Line data Source code
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 <com/sun/star/frame/DispatchStatement.hpp>
21 : #include <com/sun/star/container/XIndexReplace.hpp>
22 : #include <com/sun/star/beans/PropertyValue.hpp>
23 : #include <com/sun/star/uno/Sequence.hxx>
24 : #include <com/sun/star/beans/XPropertySet.hpp>
25 : #include <com/sun/star/util/URLTransformer.hpp>
26 : #include <com/sun/star/util/XURLTransformer.hpp>
27 : #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
28 : #include <svl/itemiter.hxx>
29 :
30 : #include <svl/itempool.hxx>
31 : #include <svtools/itemdel.hxx>
32 :
33 : #include <comphelper/processfactory.hxx>
34 :
35 : #include <svl/smplhint.hxx>
36 :
37 : #include <sfx2/request.hxx>
38 : #include <sfx2/dispatch.hxx>
39 : #include <sfx2/msg.hxx>
40 : #include <sfx2/viewfrm.hxx>
41 : #include <sfx2/objface.hxx>
42 : #include <rtl/strbuf.hxx>
43 :
44 :
45 :
46 : using namespace ::com::sun::star;
47 :
48 : struct SfxRequest_Impl: public SfxListener
49 :
50 : /* [Description]
51 :
52 : Implementation structur of the <SfxRequest> class.
53 : */
54 :
55 : {
56 : SfxRequest* pAnti; // Owner because of dying pool
57 : OUString aTarget; // if possible from target object set by App
58 : SfxItemPool* pPool; // ItemSet build with this pool
59 : SfxPoolItem* pRetVal; // Return value belongs to itself
60 : SfxShell* pShell; // run from this shell
61 : const SfxSlot* pSlot; // executed Slot
62 : sal_uInt16 nModifier; // which Modifier was pressed?
63 : bool bDone; // at all executed
64 : bool bIgnored; // Cancelled by the User
65 : bool bCancelled; // no longer notify
66 : sal_uInt16 nCallMode; // Synch/Asynch/API/Record
67 : bool bAllowRecording;
68 : SfxAllItemSet* pInternalArgs;
69 : SfxViewFrame* pViewFrame;
70 :
71 : com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder;
72 :
73 0 : SfxRequest_Impl( SfxRequest *pOwner )
74 : : pAnti( pOwner)
75 : , pPool(0)
76 : , pRetVal(0)
77 : , pShell(0)
78 : , pSlot(0)
79 : , nModifier(0)
80 : , bDone(false)
81 : , bIgnored(false)
82 : , bCancelled(false)
83 : , nCallMode( SFX_CALLMODE_SYNCHRON )
84 : , bAllowRecording( false )
85 : , pInternalArgs( 0 )
86 0 : , pViewFrame(0)
87 0 : {}
88 0 : virtual ~SfxRequest_Impl() { delete pInternalArgs; }
89 :
90 :
91 : void SetPool( SfxItemPool *pNewPool );
92 : virtual void Notify( SfxBroadcaster &rBC, const SfxHint &rHint ) SAL_OVERRIDE;
93 : void Record( const uno::Sequence < beans::PropertyValue >& rArgs );
94 : };
95 :
96 :
97 :
98 :
99 0 : void SfxRequest_Impl::Notify( SfxBroadcaster&, const SfxHint &rHint )
100 : {
101 0 : SfxSimpleHint *pSimpleHint = PTR_CAST(SfxSimpleHint, &rHint);
102 0 : if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
103 0 : pAnti->Cancel();
104 0 : }
105 :
106 :
107 :
108 0 : void SfxRequest_Impl::SetPool( SfxItemPool *pNewPool )
109 : {
110 0 : if ( pNewPool != pPool )
111 : {
112 0 : if ( pPool )
113 0 : EndListening( pPool->BC() );
114 0 : pPool = pNewPool;
115 0 : if ( pNewPool )
116 0 : StartListening( pNewPool->BC() );
117 : }
118 0 : }
119 :
120 :
121 :
122 :
123 0 : SfxRequest::~SfxRequest()
124 : {
125 : // Leave out Done() marked requests with 'rem'
126 0 : if ( pImp->xRecorder.is() && !pImp->bDone && !pImp->bIgnored )
127 0 : pImp->Record( uno::Sequence < beans::PropertyValue >() );
128 :
129 : // Clear object
130 0 : delete pArgs;
131 0 : if ( pImp->pRetVal )
132 0 : DeleteItemOnIdle(pImp->pRetVal);
133 0 : delete pImp;
134 0 : }
135 :
136 :
137 :
138 0 : SfxRequest::SfxRequest
139 : (
140 : const SfxRequest& rOrig
141 : )
142 : : SfxHint( rOrig ),
143 : nSlot(rOrig.nSlot),
144 0 : pArgs(rOrig.pArgs? new SfxAllItemSet(*rOrig.pArgs): 0),
145 0 : pImp( new SfxRequest_Impl(this) )
146 : {
147 0 : pImp->bAllowRecording = rOrig.pImp->bAllowRecording;
148 0 : pImp->bDone = false;
149 0 : pImp->bIgnored = false;
150 0 : pImp->pRetVal = 0;
151 0 : pImp->pShell = 0;
152 0 : pImp->pSlot = 0;
153 0 : pImp->nCallMode = rOrig.pImp->nCallMode;
154 0 : pImp->aTarget = rOrig.pImp->aTarget;
155 0 : pImp->nModifier = rOrig.pImp->nModifier;
156 :
157 : // deep copy needed !
158 0 : pImp->pInternalArgs = (rOrig.pImp->pInternalArgs ? new SfxAllItemSet(*rOrig.pImp->pInternalArgs) : 0);
159 :
160 0 : if ( pArgs )
161 0 : pImp->SetPool( pArgs->GetPool() );
162 : else
163 0 : pImp->SetPool( rOrig.pImp->pPool );
164 0 : }
165 :
166 :
167 :
168 0 : SfxRequest::SfxRequest
169 : (
170 : SfxViewFrame* pViewFrame,
171 : sal_uInt16 nSlotId
172 :
173 : )
174 :
175 : /* [Description]
176 :
177 : With this constructor events can subsequently be recorded that are not run
178 : across SfxDispatcher (eg from KeyInput() or mouse events). For this, a
179 : SfxRequest instance is created by this constructor and then proceed
180 : exactly as with a SfxRequest that in a <Slot-Execute-Method> is given as a
181 : parameter.
182 : */
183 :
184 : : nSlot(nSlotId),
185 : pArgs(0),
186 0 : pImp( new SfxRequest_Impl(this) )
187 : {
188 0 : pImp->bDone = false;
189 0 : pImp->bIgnored = false;
190 0 : pImp->SetPool( &pViewFrame->GetPool() );
191 0 : pImp->pRetVal = 0;
192 0 : pImp->pShell = 0;
193 0 : pImp->pSlot = 0;
194 0 : pImp->nCallMode = SFX_CALLMODE_SYNCHRON;
195 0 : pImp->pViewFrame = pViewFrame;
196 0 : if( pImp->pViewFrame->GetDispatcher()->GetShellAndSlot_Impl( nSlotId, &pImp->pShell, &pImp->pSlot, true, true ) )
197 : {
198 0 : pImp->SetPool( &pImp->pShell->GetPool() );
199 0 : pImp->xRecorder = SfxRequest::GetMacroRecorder( pViewFrame );
200 0 : pImp->aTarget = pImp->pShell->GetName();
201 : }
202 : #ifdef DBG_UTIL
203 : else
204 : {
205 : OStringBuffer aStr("Recording unsupported slot: ");
206 : aStr.append(static_cast<sal_Int32>(pImp->pPool->GetSlotId(nSlotId)));
207 : OSL_FAIL(aStr.getStr());
208 : }
209 : #endif
210 0 : }
211 :
212 :
213 :
214 :
215 0 : SfxRequest::SfxRequest
216 : (
217 : sal_uInt16 nSlotId, // executed <Slot-Id>
218 : SfxCallMode nMode, // Synch/API/...
219 : SfxItemPool& rPool // necessary for the SfxItemSet for parameters
220 : )
221 :
222 : // creates a SfxRequest without arguments
223 :
224 : : nSlot(nSlotId),
225 : pArgs(0),
226 0 : pImp( new SfxRequest_Impl(this) )
227 : {
228 0 : pImp->bDone = false;
229 0 : pImp->bIgnored = false;
230 0 : pImp->SetPool( &rPool );
231 0 : pImp->pRetVal = 0;
232 0 : pImp->pShell = 0;
233 0 : pImp->pSlot = 0;
234 0 : pImp->nCallMode = nMode;
235 0 : }
236 :
237 0 : SfxRequest::SfxRequest
238 : (
239 : const SfxSlot* pSlot, // executed <Slot-Id>
240 : const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& rArgs,
241 : SfxCallMode nMode, // Synch/API/...
242 : SfxItemPool& rPool // necessary for the SfxItemSet for parameters
243 : )
244 0 : : nSlot(pSlot->GetSlotId()),
245 0 : pArgs(new SfxAllItemSet(rPool)),
246 0 : pImp( new SfxRequest_Impl(this) )
247 : {
248 0 : pImp->bDone = false;
249 0 : pImp->bIgnored = false;
250 0 : pImp->SetPool( &rPool );
251 0 : pImp->pRetVal = 0;
252 0 : pImp->pShell = 0;
253 0 : pImp->pSlot = 0;
254 0 : pImp->nCallMode = nMode;
255 0 : TransformParameters( nSlot, rArgs, *pArgs, pSlot );
256 0 : }
257 :
258 :
259 :
260 0 : SfxRequest::SfxRequest
261 : (
262 : sal_uInt16 nSlotId,
263 : sal_uInt16 nMode,
264 : const SfxAllItemSet& rSfxArgs
265 : )
266 :
267 : // creates a SfxRequest with arguments
268 :
269 : : nSlot(nSlotId),
270 0 : pArgs(new SfxAllItemSet(rSfxArgs)),
271 0 : pImp( new SfxRequest_Impl(this) )
272 : {
273 0 : pImp->bDone = false;
274 0 : pImp->bIgnored = false;
275 0 : pImp->SetPool( rSfxArgs.GetPool() );
276 0 : pImp->pRetVal = 0;
277 0 : pImp->pShell = 0;
278 0 : pImp->pSlot = 0;
279 0 : pImp->nCallMode = nMode;
280 0 : }
281 :
282 :
283 0 : sal_uInt16 SfxRequest::GetCallMode() const
284 : {
285 0 : return pImp->nCallMode;
286 : }
287 :
288 :
289 :
290 0 : bool SfxRequest::IsSynchronCall() const
291 : {
292 0 : return SFX_CALLMODE_SYNCHRON == ( SFX_CALLMODE_SYNCHRON & pImp->nCallMode );
293 : }
294 :
295 :
296 :
297 0 : void SfxRequest::SetSynchronCall( bool bSynchron )
298 : {
299 0 : if ( bSynchron )
300 0 : pImp->nCallMode |= SFX_CALLMODE_SYNCHRON;
301 : else
302 0 : pImp->nCallMode &= ~(sal_uInt16) SFX_CALLMODE_SYNCHRON;
303 0 : }
304 :
305 0 : void SfxRequest::SetInternalArgs_Impl( const SfxAllItemSet& rArgs )
306 : {
307 0 : delete pImp->pInternalArgs;
308 0 : pImp->pInternalArgs = new SfxAllItemSet( rArgs );
309 0 : }
310 :
311 0 : const SfxItemSet* SfxRequest::GetInternalArgs_Impl() const
312 : {
313 0 : return pImp->pInternalArgs;
314 : }
315 :
316 :
317 :
318 :
319 0 : void SfxRequest_Impl::Record
320 : (
321 : const uno::Sequence < beans::PropertyValue >& rArgs // current Parameter
322 : )
323 :
324 : /* [Description]
325 :
326 : Internal helper method to create a repeatable description of the just
327 : executed SfxRequest.
328 : */
329 :
330 : {
331 0 : OUString aCommand(".uno:");
332 0 : aCommand += OUString( pSlot->GetUnoName(), strlen( pSlot->GetUnoName() ), RTL_TEXTENCODING_UTF8 );
333 0 : OUString aCmd( aCommand );
334 0 : if(xRecorder.is())
335 : {
336 0 : uno::Reference< container::XIndexReplace > xReplace( xRecorder, uno::UNO_QUERY );
337 0 : if ( xReplace.is() && aCmd == ".uno:InsertText" )
338 : {
339 0 : sal_Int32 nCount = xReplace->getCount();
340 0 : if ( nCount )
341 : {
342 0 : frame::DispatchStatement aStatement;
343 0 : uno::Any aElement = xReplace->getByIndex(nCount-1);
344 0 : if ( (aElement >>= aStatement) && aStatement.aCommand == aCmd )
345 : {
346 0 : OUString aStr;
347 0 : OUString aNew;
348 0 : aStatement.aArgs[0].Value >>= aStr;
349 0 : rArgs[0].Value >>= aNew;
350 0 : aStr += aNew;
351 0 : aStatement.aArgs[0].Value <<= aStr;
352 0 : aElement <<= aStatement;
353 0 : xReplace->replaceByIndex( nCount-1, aElement );
354 0 : return;
355 0 : }
356 : }
357 : }
358 :
359 0 : uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
360 :
361 0 : uno::Reference< util::XURLTransformer > xTransform = util::URLTransformer::create( xContext );
362 :
363 0 : com::sun::star::util::URL aURL;
364 0 : aURL.Complete = aCmd;
365 0 : xTransform->parseStrict(aURL);
366 :
367 0 : if (bDone)
368 0 : xRecorder->recordDispatch(aURL,rArgs);
369 : else
370 0 : xRecorder->recordDispatchAsComment(aURL,rArgs);
371 0 : }
372 : }
373 :
374 :
375 :
376 0 : void SfxRequest::Record_Impl
377 : (
378 : SfxShell& rSh, // the <SfxShell>, which has excecuted the Request
379 : const SfxSlot& rSlot, // the <SfxSlot>, which has executed the Request
380 : com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder,
381 : SfxViewFrame* pViewFrame
382 : )
383 :
384 : /* [Description]
385 :
386 : This internal method marks the specified SfxMakro SfxRequest as recorded in
387 : SfxMakro. Pointer to the parameters in Done() is used again, thus has to
388 : still be alive.
389 : */
390 :
391 : {
392 0 : pImp->pShell = &rSh;
393 0 : pImp->pSlot = &rSlot;
394 0 : pImp->xRecorder = xRecorder;
395 0 : pImp->aTarget = rSh.GetName();
396 0 : pImp->pViewFrame = pViewFrame;
397 0 : }
398 :
399 :
400 :
401 0 : void SfxRequest::SetArgs( const SfxAllItemSet& rArgs )
402 : {
403 0 : delete pArgs;
404 0 : pArgs = new SfxAllItemSet(rArgs);
405 0 : pImp->SetPool( pArgs->GetPool() );
406 0 : }
407 :
408 :
409 :
410 0 : void SfxRequest::AppendItem(const SfxPoolItem &rItem)
411 : {
412 0 : if(!pArgs)
413 0 : pArgs = new SfxAllItemSet(*pImp->pPool);
414 0 : pArgs->Put(rItem, rItem.Which());
415 0 : }
416 :
417 :
418 :
419 0 : void SfxRequest::RemoveItem( sal_uInt16 nID )
420 : {
421 0 : if (pArgs)
422 : {
423 0 : pArgs->ClearItem(nID);
424 0 : if ( !pArgs->Count() )
425 0 : DELETEZ(pArgs);
426 : }
427 0 : }
428 :
429 :
430 :
431 0 : const SfxPoolItem* SfxRequest::GetArg
432 : (
433 : sal_uInt16 nSlotId, // Slot-Id or Which-Id of the parameters
434 : bool bDeep, // sal_False: do not seach in the Parent-ItemSets
435 : TypeId aType // != 0: RTTI check with Assertion
436 : ) const
437 : {
438 0 : return GetItem( pArgs, nSlotId, bDeep, aType );
439 : }
440 :
441 :
442 :
443 0 : const SfxPoolItem* SfxRequest::GetItem
444 : (
445 : const SfxItemSet* pArgs,
446 : sal_uInt16 nSlotId, // Slot-Id or Which-Id of the parameters
447 : bool bDeep, // sal_False: do not seach in the Parent-ItemSets
448 : TypeId aType // != 0: RTTI check with Assertion
449 : )
450 :
451 : /* [Description]
452 :
453 : With this method the access to individual parameters in the SfxRequest is
454 : simplified. In particular the type-examination (by Assertion) is performed,
455 : whereby the application source code will be much clearer. In the product-
456 : version is a 0 returned, if the found item is not of the specified class.
457 :
458 : [Example]
459 :
460 : void MyShell::Execute( SfxRequest &rReq )
461 : {
462 : switch ( rReq.GetSlot() )
463 : {
464 : case SID_MY:
465 : {
466 : ...
467 : // An Example on not using the macros
468 : const SfxInt32Item *pPosItem = (const SfxUInt32Item*)
469 : rReq.GetArg( SID_POS, sal_False, TYPE(SfxInt32Item) );
470 : sal_uInt16 nPos = pPosItem ? pPosItem->GetValue() : 0;
471 :
472 : // An Example on using the macros
473 : SFX_REQUEST_ARG(rReq, pSizeItem, SfxInt32Item, SID_SIZE, sal_False);
474 : sal_uInt16 nSize = pSizeItem ? pPosItem->GetValue() : 0;
475 :
476 : ...
477 : }
478 :
479 : ...
480 : }
481 : }
482 : */
483 :
484 : {
485 0 : if ( pArgs )
486 : {
487 : // Which may be converted to ID
488 0 : sal_uInt16 nWhich = pArgs->GetPool()->GetWhich(nSlotId);
489 :
490 : // Is the item set or available at bDeep == sal_True?
491 0 : const SfxPoolItem *pItem = 0;
492 0 : if ( ( bDeep ? SFX_ITEM_AVAILABLE : SFX_ITEM_SET )
493 0 : <= pArgs->GetItemState( nWhich, bDeep, &pItem ) )
494 : {
495 : // Compare type
496 0 : if ( !pItem || pItem->IsA(aType) )
497 0 : return pItem;
498 :
499 : // Item of wrong type => Programming error
500 : OSL_FAIL( "invalid argument type" );
501 : }
502 : }
503 :
504 : // No Parameter, not found or wrong type
505 0 : return 0;
506 : }
507 :
508 :
509 :
510 0 : void SfxRequest::SetReturnValue(const SfxPoolItem &rItem)
511 : {
512 : DBG_ASSERT(!pImp->pRetVal, "Set Return value multiple times?");
513 0 : if(pImp->pRetVal)
514 0 : delete pImp->pRetVal;
515 0 : pImp->pRetVal = rItem.Clone();
516 0 : }
517 :
518 :
519 :
520 0 : const SfxPoolItem* SfxRequest::GetReturnValue() const
521 : {
522 0 : return pImp->pRetVal;
523 : }
524 :
525 :
526 :
527 0 : void SfxRequest::Done
528 : (
529 : const SfxItemSet& rSet, /* parameters passed on by the application,
530 : that for example were asked for by the user
531 : in a dialogue, 0 if no parameters have been
532 : set */
533 :
534 : bool bKeep /* true (default)
535 : 'rSet' is saved and GetArgs() queriable.
536 :
537 : false
538 : 'rSet' is not copied (faster) */
539 : )
540 :
541 : /* [Description]
542 :
543 : This method must be called in the <Execute-Method> of the <SfxSlot>s, which
544 : has performed the SfxRequest when the execution actually took place. If
545 : 'Done()' is not called, then the SfxRequest is considered canceled.
546 :
547 : Any return values are passed only when 'Done()' was called. Similar, when
548 : recording a macro only true statements are generated if 'Done()' was
549 : called; for SfxRequests that were not identified as such will instead
550 : be commented out by inserting ('rem').
551 :
552 : [Note]
553 :
554 : 'Done ()' is not called, for example when a dialoge started by the function
555 : was canceled by the user or if the execution could not be performed due to
556 : a wrong context (without use of separate <SfxShell>s). 'Done ()' will be
557 : launched, when executing the function led to a regular error
558 : (for example, file could not be opened).
559 : */
560 :
561 : {
562 0 : Done_Impl( &rSet );
563 :
564 : // Keep items if possible, so they can be queried by StarDraw.
565 0 : if ( bKeep )
566 : {
567 0 : if ( !pArgs )
568 : {
569 0 : pArgs = new SfxAllItemSet( rSet );
570 0 : pImp->SetPool( pArgs->GetPool() );
571 : }
572 : else
573 : {
574 0 : SfxItemIter aIter(rSet);
575 0 : const SfxPoolItem* pItem = aIter.FirstItem();
576 0 : while(pItem)
577 : {
578 0 : if(!IsInvalidItem(pItem))
579 0 : pArgs->Put(*pItem,pItem->Which());
580 0 : pItem = aIter.NextItem();
581 0 : }
582 : }
583 : }
584 0 : }
585 :
586 :
587 :
588 :
589 0 : void SfxRequest::Done( bool bRelease )
590 : // [<SfxRequest::Done(SfxItemSet&)>]
591 : {
592 0 : Done_Impl( pArgs );
593 0 : if( bRelease )
594 0 : DELETEZ( pArgs );
595 0 : }
596 :
597 :
598 :
599 0 : void SfxRequest::ForgetAllArgs()
600 : {
601 0 : DELETEZ( pArgs );
602 0 : DELETEZ( pImp->pInternalArgs );
603 0 : }
604 :
605 :
606 :
607 0 : bool SfxRequest::IsCancelled() const
608 : {
609 0 : return pImp->bCancelled;
610 : }
611 :
612 :
613 :
614 0 : void SfxRequest::Cancel()
615 :
616 : /* [Description]
617 :
618 : Marks this request as no longer executable. For example, if called when
619 : the target (more precisely, its pool) dies.
620 : */
621 :
622 : {
623 0 : pImp->bCancelled = true;
624 0 : pImp->SetPool( 0 );
625 0 : DELETEZ( pArgs );
626 0 : }
627 :
628 :
629 :
630 :
631 0 : void SfxRequest::Ignore()
632 :
633 : /* [Description]
634 :
635 : If this method is called instead of <SfxRequest::Done()>, then this
636 : request is not recorded.
637 :
638 : [Example]
639 :
640 : The selecting of tools in StarDraw should not be recorded, but the same
641 : slots are to be used from the generation of the tools to the generated
642 : objects. Thus can NoRecords not be specified, i.e. should not be recorded.
643 : */
644 :
645 : {
646 : // Mark as actually executed
647 0 : pImp->bIgnored = true;
648 0 : }
649 :
650 :
651 :
652 0 : void SfxRequest::Done_Impl
653 : (
654 : const SfxItemSet* pSet /* parameters passed on by the application,
655 : that for example were asked for by the user
656 : in a dialogue, 0 if no parameters have been
657 : set */
658 :
659 : )
660 :
661 : /* [Description]
662 :
663 : Internal method to mark SfxRequest with 'done' and to evaluate the
664 : parameters in 'pSet' in case it is recorded.
665 : */
666 :
667 : {
668 : // Mark as actually executed
669 0 : pImp->bDone = true;
670 :
671 : // not Recording
672 0 : if ( !pImp->xRecorder.is() )
673 0 : return;
674 :
675 : // was running a different slot than requested (Delegation)
676 0 : if ( nSlot != pImp->pSlot->GetSlotId() )
677 : {
678 : // Search Slot again
679 0 : pImp->pSlot = pImp->pShell->GetInterface()->GetSlot(nSlot);
680 : DBG_ASSERT( pImp->pSlot, "delegated SlotId not found" );
681 0 : if ( !pImp->pSlot ) // playing it safe
682 0 : return;
683 : }
684 :
685 : // recordable?
686 : // new Recording uses UnoName!
687 0 : if ( !pImp->pSlot->pUnoName )
688 : {
689 0 : OStringBuffer aStr("Recording not exported slot: ");
690 0 : aStr.append(static_cast<sal_Int32>(pImp->pSlot->GetSlotId()));
691 0 : OSL_FAIL(aStr.getStr());
692 : }
693 :
694 0 : if ( !pImp->pSlot->pUnoName ) // playing it safe
695 0 : return;
696 :
697 : // often required values
698 0 : SfxItemPool &rPool = pImp->pShell->GetPool();
699 :
700 : // Property-Slot?
701 0 : if ( !pImp->pSlot->IsMode(SFX_SLOT_METHOD) )
702 : {
703 : // get the property as SfxPoolItem
704 : const SfxPoolItem *pItem;
705 0 : sal_uInt16 nWhich = rPool.GetWhich(pImp->pSlot->GetSlotId());
706 0 : SfxItemState eState = pSet ? pSet->GetItemState( nWhich, false, &pItem ) : SFX_ITEM_UNKNOWN;
707 : #ifdef DBG_UTIL
708 : if ( SFX_ITEM_SET != eState )
709 : {
710 : OStringBuffer aStr("Recording property not available: ");
711 : aStr.append(static_cast<sal_Int32>(pImp->pSlot->GetSlotId()));
712 : OSL_FAIL(aStr.getStr());
713 : }
714 : #endif
715 0 : uno::Sequence < beans::PropertyValue > aSeq;
716 0 : if ( eState == SFX_ITEM_SET )
717 0 : TransformItems( pImp->pSlot->GetSlotId(), *pSet, aSeq, pImp->pSlot );
718 0 : pImp->Record( aSeq );
719 : }
720 :
721 : // record everything in a single statement?
722 0 : else if ( pImp->pSlot->IsMode(SFX_SLOT_RECORDPERSET) )
723 : {
724 0 : uno::Sequence < beans::PropertyValue > aSeq;
725 0 : if ( pSet )
726 0 : TransformItems( pImp->pSlot->GetSlotId(), *pSet, aSeq, pImp->pSlot );
727 0 : pImp->Record( aSeq );
728 : }
729 :
730 : // record each item as a single statement
731 0 : else if ( pImp->pSlot->IsMode(SFX_SLOT_RECORDPERITEM) )
732 : {
733 0 : if ( pSet )
734 : {
735 : // iterate over Items
736 0 : SfxItemIter aIter(*pSet);
737 0 : for ( const SfxPoolItem* pItem = aIter.FirstItem(); pItem; pItem = aIter.NextItem() )
738 : {
739 : // to determine the slot ID for the individual item
740 0 : sal_uInt16 nSlotId = rPool.GetSlotId( pItem->Which() );
741 0 : if ( nSlotId == nSlot )
742 : {
743 : // play it safe; repair the wrong flags
744 : OSL_FAIL( "recursion RecordPerItem - use RecordPerSet!" );
745 0 : SfxSlot *pSlot = (SfxSlot*) pImp->pSlot;
746 0 : pSlot->nFlags &= ~((sal_uIntPtr)SFX_SLOT_RECORDPERITEM);
747 0 : pSlot->nFlags &= SFX_SLOT_RECORDPERSET;
748 : }
749 :
750 : // Record a Sub-Request
751 0 : SfxRequest aReq( pImp->pViewFrame, nSlotId );
752 0 : if ( aReq.pImp->pSlot )
753 0 : aReq.AppendItem( *pItem );
754 0 : aReq.Done();
755 0 : }
756 : }
757 : else
758 : {
759 : //HACK(think about this again)
760 0 : pImp->Record( uno::Sequence < beans::PropertyValue >() );
761 : }
762 : }
763 : }
764 :
765 :
766 :
767 0 : bool SfxRequest::IsDone() const
768 :
769 : /* [Description]
770 :
771 : With this method it can be queried whether the SfxRequest was actually
772 : executed or not. If a SfxRequest was not executed, then this is for example
773 : because it was canceled by the user or the context for this request was
774 : wrong, this was not implemented on a separate <SfxShell>.
775 :
776 : SfxRequest instances that return false will not be recorded.
777 :
778 : [Cross-reference]
779 :
780 : <SfxRequest::Done(const SfxItemSet&)>
781 : <SfxRequest::Done()>
782 : */
783 :
784 : {
785 0 : return pImp->bDone;
786 : }
787 :
788 :
789 :
790 0 : com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > SfxRequest::GetMacroRecorder( SfxViewFrame* pView )
791 :
792 : /* [Description]
793 :
794 : This recorder is an attempt for dispatch () to get calls from the Frame.
795 : This is then available through a property by a supplier but only when
796 : recording was turned on.
797 :
798 : (See also SfxViewFrame::MiscExec_Impl() and SID_RECORDING)
799 : */
800 :
801 : {
802 0 : com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder;
803 :
804 : com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xSet(
805 0 : (pView ? pView : SfxViewFrame::Current())->GetFrame().GetFrameInterface(),
806 0 : com::sun::star::uno::UNO_QUERY);
807 :
808 0 : if(xSet.is())
809 : {
810 0 : com::sun::star::uno::Any aProp = xSet->getPropertyValue("DispatchRecorderSupplier");
811 0 : com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier;
812 0 : aProp >>= xSupplier;
813 0 : if(xSupplier.is())
814 0 : xRecorder = xSupplier->getDispatchRecorder();
815 : }
816 :
817 0 : return xRecorder;
818 : }
819 :
820 0 : bool SfxRequest::HasMacroRecorder( SfxViewFrame* pView )
821 : {
822 0 : return GetMacroRecorder( pView ).is();
823 : }
824 :
825 :
826 :
827 :
828 0 : bool SfxRequest::IsAPI() const
829 :
830 : /* [Description]
831 :
832 : Returns true if this SfxRequest was generated by an API (for example BASIC),
833 : otherwise false.
834 : */
835 :
836 : {
837 0 : return SFX_CALLMODE_API == ( SFX_CALLMODE_API & pImp->nCallMode );
838 : }
839 :
840 :
841 0 : void SfxRequest::SetModifier( sal_uInt16 nModi )
842 : {
843 0 : pImp->nModifier = nModi;
844 0 : }
845 :
846 :
847 0 : sal_uInt16 SfxRequest::GetModifier() const
848 : {
849 0 : return pImp->nModifier;
850 : }
851 :
852 :
853 :
854 0 : void SfxRequest::AllowRecording( bool bSet )
855 : {
856 0 : pImp->bAllowRecording = bSet;
857 0 : }
858 :
859 0 : bool SfxRequest::AllowsRecording() const
860 : {
861 0 : bool bAllow = pImp->bAllowRecording;
862 0 : if( !bAllow )
863 0 : bAllow = ( SFX_CALLMODE_API != ( SFX_CALLMODE_API & pImp->nCallMode ) ) &&
864 0 : ( SFX_CALLMODE_RECORD == ( SFX_CALLMODE_RECORD & pImp->nCallMode ) );
865 0 : return bAllow;
866 : }
867 :
868 0 : void SfxRequest::ReleaseArgs()
869 : {
870 0 : DELETEZ( pArgs );
871 0 : DELETEZ( pImp->pInternalArgs );
872 0 : }
873 :
874 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|