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