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