xref: /trunk/main/sfx2/source/control/request.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_sfx2.hxx"
31 
32 #include <com/sun/star/frame/DispatchStatement.hpp>
33 #include <com/sun/star/container/XIndexReplace.hpp>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/uno/Sequence.hxx>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/util/XURLTransformer.hpp>
38 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp>
39 #include <svl/itemiter.hxx>
40 
41 #ifndef _ARGS_HXX //autogen
42 #include <svl/itempool.hxx>
43 #endif
44 #include <svtools/itemdel.hxx>
45 
46 #include <comphelper/processfactory.hxx>
47 
48 #ifndef GCC
49 #endif
50 
51 #include <svl/smplhint.hxx>
52 
53 #include <sfx2/request.hxx>
54 #include <sfx2/dispatch.hxx>
55 #include <sfx2/msg.hxx>
56 #include <sfx2/viewfrm.hxx>
57 #include "macro.hxx"
58 #include <sfx2/objface.hxx>
59 #include <sfx2/appuno.hxx>
60 
61 //===================================================================
62 
63 using namespace ::com::sun::star;
64 
65 struct SfxRequest_Impl: public SfxListener
66 
67 /*  [Beschreibung]
68 
69     Implementations-Struktur der Klasse <SfxRequest>.
70 */
71 
72 {
73     SfxRequest*         pAnti;       // Owner wegen sterbendem Pool
74     String              aTarget;     // ggf. von App gesetztes Zielobjekt
75     SfxItemPool*        pPool;       // ItemSet mit diesem Pool bauen
76     SfxPoolItem*        pRetVal;     // R"uckgabewert geh"ort sich selbst
77     SfxShell*           pShell;      // ausgef"uhrt an dieser Shell
78     const SfxSlot*      pSlot;       // ausgef"uhrter Slot
79     sal_uInt16              nModifier;   // welche Modifier waren gedrueckt?
80     sal_Bool                bDone;       // "uberhaupt ausgef"uhrt
81     sal_Bool                bIgnored;    // vom User abgebrochen
82     sal_Bool                bCancelled;  // nicht mehr zustellen
83     sal_Bool                bUseTarget;  // aTarget wurde von Applikation gesetzt
84     sal_uInt16              nCallMode;   // Synch/Asynch/API/Record
85     sal_Bool                bAllowRecording;
86     SfxAllItemSet*      pInternalArgs;
87     SfxViewFrame*       pViewFrame;
88 
89     com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder;
90 
91                         SfxRequest_Impl( SfxRequest *pOwner )
92                         : pAnti( pOwner)
93                         , pPool(0)
94                         , nModifier(0)
95                         , bCancelled(sal_False)
96                         , nCallMode( SFX_CALLMODE_SYNCHRON )
97                         , bAllowRecording( sal_False )
98                         , pInternalArgs( 0 )
99                         , pViewFrame(0)
100                         {}
101     ~SfxRequest_Impl() { delete pInternalArgs; }
102 
103 
104     void                SetPool( SfxItemPool *pNewPool );
105     virtual void        Notify( SfxBroadcaster &rBC, const SfxHint &rHint );
106     void                Record( const uno::Sequence < beans::PropertyValue >& rArgs );
107 };
108 
109 
110 //====================================================================
111 
112 void SfxRequest_Impl::Notify( SfxBroadcaster&, const SfxHint &rHint )
113 {
114     SfxSimpleHint *pSimpleHint = PTR_CAST(SfxSimpleHint, &rHint);
115     if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
116         pAnti->Cancel();
117 }
118 
119 //====================================================================
120 
121 void SfxRequest_Impl::SetPool( SfxItemPool *pNewPool )
122 {
123     if ( pNewPool != pPool )
124     {
125         if ( pPool )
126             EndListening( pPool->BC() );
127         pPool = pNewPool;
128         if ( pNewPool )
129             StartListening( pNewPool->BC() );
130     }
131 }
132 
133 //====================================================================
134 
135 
136 SfxRequest::~SfxRequest()
137 {
138     DBG_MEMTEST();
139 
140     // nicht mit Done() marktierte Requests mit 'rem' rausschreiben
141     if ( pImp->xRecorder.is() && !pImp->bDone && !pImp->bIgnored )
142         pImp->Record( uno::Sequence < beans::PropertyValue >() );
143 
144     // Objekt abr"aumen
145     delete pArgs;
146     if ( pImp->pRetVal )
147         DeleteItemOnIdle(pImp->pRetVal);
148     delete pImp;
149 }
150 //--------------------------------------------------------------------
151 
152 
153 SfxRequest::SfxRequest
154 (
155     const SfxRequest& rOrig
156 )
157 :   SfxHint( rOrig ),
158     nSlot(rOrig.nSlot),
159     pArgs(rOrig.pArgs? new SfxAllItemSet(*rOrig.pArgs): 0),
160     pImp( new SfxRequest_Impl(this) )
161 {
162     DBG_MEMTEST();
163 
164     pImp->bAllowRecording = rOrig.pImp->bAllowRecording;
165     pImp->bDone = sal_False;
166     pImp->bIgnored = sal_False;
167     pImp->pRetVal = 0;
168     pImp->pShell = 0;
169     pImp->pSlot = 0;
170     pImp->nCallMode = rOrig.pImp->nCallMode;
171     pImp->bUseTarget = rOrig.pImp->bUseTarget;
172     pImp->aTarget = rOrig.pImp->aTarget;
173     pImp->nModifier = rOrig.pImp->nModifier;
174 
175     // deep copy needed !
176     pImp->pInternalArgs = (rOrig.pImp->pInternalArgs ? new SfxAllItemSet(*rOrig.pImp->pInternalArgs) : 0);
177 
178     if ( pArgs )
179         pImp->SetPool( pArgs->GetPool() );
180     else
181         pImp->SetPool( rOrig.pImp->pPool );
182 }
183 //--------------------------------------------------------------------
184 
185 
186 SfxRequest::SfxRequest
187 (
188     SfxViewFrame*   pViewFrame,
189     sal_uInt16          nSlotId
190 
191 )
192 
193 /*  [Beschreibung]
194 
195     Mit diesem Konstruktor k"onnen Events, die nicht "uber den SfxDispatcher
196     gelaufen sind (z.B aus KeyInput() oder Mouse-Events) nachtr"aglich
197     recorded werden. Dazu wird eine SfxRequest-Instanz mit diesem Konstruktor
198     erzeugt und dann genauso verfahren, wie mit einem SfxRequest, der in
199     eine <Slot-Execute-Methode> als Parameter gegeben wird.
200 */
201 
202 :   nSlot(nSlotId),
203     pArgs(0),
204     pImp( new SfxRequest_Impl(this) )
205 {
206     DBG_MEMTEST();
207 
208     pImp->bDone = sal_False;
209     pImp->bIgnored = sal_False;
210     pImp->SetPool( &pViewFrame->GetPool() );
211     pImp->pRetVal = 0;
212     pImp->pShell = 0;
213     pImp->pSlot = 0;
214     pImp->nCallMode = SFX_CALLMODE_SYNCHRON;
215     pImp->bUseTarget = sal_False;
216     pImp->pViewFrame = pViewFrame;
217     if( pImp->pViewFrame->GetDispatcher()->GetShellAndSlot_Impl( nSlotId, &pImp->pShell, &pImp->pSlot, sal_True, sal_True ) )
218     {
219         pImp->SetPool( &pImp->pShell->GetPool() );
220         pImp->xRecorder = SfxRequest::GetMacroRecorder( pViewFrame );
221         pImp->aTarget = pImp->pShell->GetName();
222     }
223 #ifdef DBG_UTIL
224     else
225     {
226         ByteString aStr( "Recording unsupported slot: ");
227         aStr += ByteString::CreateFromInt32( pImp->pPool->GetSlotId(nSlotId) );
228         DBG_ERROR( aStr.GetBuffer() );
229     }
230 #endif
231 }
232 
233 //--------------------------------------------------------------------
234 
235 
236 SfxRequest::SfxRequest
237 (
238     sal_uInt16          nSlotId,    // auszuf"uhrende <Slot-Id>
239     SfxCallMode     nMode,      // Synch/API/...
240     SfxItemPool&    rPool       // ggf. f"ur das SfxItemSet f"ur Parameter
241 )
242 
243 // creates a SfxRequest without arguments
244 
245 :   nSlot(nSlotId),
246     pArgs(0),
247     pImp( new SfxRequest_Impl(this) )
248 {
249     DBG_MEMTEST();
250 
251     pImp->bDone = sal_False;
252     pImp->bIgnored = sal_False;
253     pImp->SetPool( &rPool );
254     pImp->pRetVal = 0;
255     pImp->pShell = 0;
256     pImp->pSlot = 0;
257     pImp->nCallMode = nMode;
258     pImp->bUseTarget = sal_False;
259 }
260 
261 SfxRequest::SfxRequest
262 (
263     const SfxSlot* pSlot,   // auszuf"uhrende <Slot-Id>
264     const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& rArgs,
265     SfxCallMode     nMode,      // Synch/API/...
266     SfxItemPool&    rPool       // ggf. f"ur das SfxItemSet f"ur Parameter
267 )
268 :   nSlot(pSlot->GetSlotId()),
269     pArgs(new SfxAllItemSet(rPool)),
270     pImp( new SfxRequest_Impl(this) )
271 {
272     DBG_MEMTEST();
273 
274     pImp->bDone = sal_False;
275     pImp->bIgnored = sal_False;
276     pImp->SetPool( &rPool );
277     pImp->pRetVal = 0;
278     pImp->pShell = 0;
279     pImp->pSlot = 0;
280     pImp->nCallMode = nMode;
281     pImp->bUseTarget = sal_False;
282     TransformParameters( nSlot, rArgs, *pArgs, pSlot );
283 }
284 
285 //-----------------------------------------------------------------------
286 
287 SfxRequest::SfxRequest
288 (
289     sal_uInt16                  nSlotId,
290     sal_uInt16                  nMode,
291     const SfxAllItemSet&    rSfxArgs
292 )
293 
294 // creates a SfxRequest with arguments
295 
296 :   nSlot(nSlotId),
297     pArgs(new SfxAllItemSet(rSfxArgs)),
298     pImp( new SfxRequest_Impl(this) )
299 {
300     DBG_MEMTEST();
301 
302     pImp->bDone = sal_False;
303     pImp->bIgnored = sal_False;
304     pImp->SetPool( rSfxArgs.GetPool() );
305     pImp->pRetVal = 0;
306     pImp->pShell = 0;
307     pImp->pSlot = 0;
308     pImp->nCallMode = nMode;
309     pImp->bUseTarget = sal_False;
310 }
311 //--------------------------------------------------------------------
312 
313 sal_uInt16 SfxRequest::GetCallMode() const
314 {
315     return pImp->nCallMode;
316 }
317 
318 //--------------------------------------------------------------------
319 
320 sal_Bool SfxRequest::IsSynchronCall() const
321 {
322     return SFX_CALLMODE_SYNCHRON == ( SFX_CALLMODE_SYNCHRON & pImp->nCallMode );
323 }
324 
325 //--------------------------------------------------------------------
326 
327 void SfxRequest::SetSynchronCall( sal_Bool bSynchron )
328 {
329     if ( bSynchron )
330         pImp->nCallMode |= SFX_CALLMODE_SYNCHRON;
331     else
332         pImp->nCallMode &= ~(sal_uInt16) SFX_CALLMODE_SYNCHRON;
333 }
334 
335 void SfxRequest::SetInternalArgs_Impl( const SfxAllItemSet& rArgs )
336 {
337     delete pImp->pInternalArgs;
338     pImp->pInternalArgs = new SfxAllItemSet( rArgs );
339 }
340 
341 const SfxItemSet* SfxRequest::GetInternalArgs_Impl() const
342 {
343     return pImp->pInternalArgs;
344 }
345 
346 //--------------------------------------------------------------------
347 
348 
349 void SfxRequest_Impl::Record
350 (
351     const uno::Sequence < beans::PropertyValue >& rArgs    // aktuelle Parameter
352 )
353 
354 /*  [Beschreibung]
355 
356     Interne Hilfsmethode zum erzeugen einer <SfxMacroStatement>-Instanz,
357     welche den bereits ausgef"uhrten SfxRequest wiederholbar beschreibt.
358 
359     Die erzeugte Instanz, auf die ein Pointer zur"uckgeliefert wird
360     geht in das Eigentum des Aufrufers "uber.
361 */
362 
363 {
364     String aCommand = String::CreateFromAscii(".uno:");
365     aCommand.AppendAscii( pSlot->GetUnoName() );
366     ::rtl::OUString aCmd( aCommand );
367     if(xRecorder.is())
368     {
369         uno::Reference< container::XIndexReplace > xReplace( xRecorder, uno::UNO_QUERY );
370         if ( xReplace.is() && aCmd.compareToAscii(".uno:InsertText") == COMPARE_EQUAL )
371         {
372             sal_Int32 nCount = xReplace->getCount();
373             if ( nCount )
374             {
375                 frame::DispatchStatement aStatement;
376                 uno::Any aElement = xReplace->getByIndex(nCount-1);
377                 if ( (aElement >>= aStatement) && aStatement.aCommand == aCmd )
378                 {
379                     ::rtl::OUString aStr;
380                     ::rtl::OUString aNew;
381                     aStatement.aArgs[0].Value >>= aStr;
382                     rArgs[0].Value >>= aNew;
383                     aStr += aNew;
384                     aStatement.aArgs[0].Value <<= aStr;
385                     aElement <<= aStatement;
386                     xReplace->replaceByIndex( nCount-1, aElement );
387                     return;
388                 }
389             }
390         }
391 
392         com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xFactory(
393                 ::comphelper::getProcessServiceFactory(),
394                 com::sun::star::uno::UNO_QUERY);
395 
396         com::sun::star::uno::Reference< com::sun::star::util::XURLTransformer > xTransform(
397                 xFactory->createInstance(rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")),
398                 com::sun::star::uno::UNO_QUERY);
399 
400         com::sun::star::util::URL aURL;
401         aURL.Complete = aCmd;
402         xTransform->parseStrict(aURL);
403 
404         if (bDone)
405             xRecorder->recordDispatch(aURL,rArgs);
406         else
407             xRecorder->recordDispatchAsComment(aURL,rArgs);
408     }
409 }
410 
411 //--------------------------------------------------------------------
412 
413 void SfxRequest::Record_Impl
414 (
415     SfxShell& rSh,    // die <SfxShell>, die den Request ausgef"uhrt hat
416     const SfxSlot&  rSlot,  // der <SfxSlot>, der den Request ausgef"uhrt hat
417     com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder,  // der Recorder, mit dem aufgezeichnet wird
418     SfxViewFrame* pViewFrame
419 )
420 
421 /*  [Beschreibung]
422 
423     Diese interne Methode markiert den SfxRequest als in dem angegebenen
424     SfxMakro aufzuzeichnen.
425 
426     Pointer auf die Parameter werden in Done() wieder verwendet, m"usseb
427     dann also noch leben.
428 */
429 
430 {
431     DBG_MEMTEST();
432     pImp->pShell = &rSh;
433     pImp->pSlot = &rSlot;
434     pImp->xRecorder = xRecorder;
435     pImp->aTarget = rSh.GetName();
436     pImp->pViewFrame = pViewFrame;
437 }
438 
439 //--------------------------------------------------------------------
440 
441 void SfxRequest::SetArgs( const SfxAllItemSet& rArgs )
442 {
443     delete pArgs;
444     pArgs = new SfxAllItemSet(rArgs);
445     pImp->SetPool( pArgs->GetPool() );
446 }
447 
448 //--------------------------------------------------------------------
449 
450 void SfxRequest::AppendItem(const SfxPoolItem &rItem)
451 {
452     if(!pArgs)
453         pArgs = new SfxAllItemSet(*pImp->pPool);
454     pArgs->Put(rItem, rItem.Which());
455 }
456 
457 //--------------------------------------------------------------------
458 
459 void SfxRequest::RemoveItem( sal_uInt16 nID )
460 {
461     if (pArgs)
462     {
463         pArgs->ClearItem(nID);
464         if ( !pArgs->Count() )
465             DELETEZ(pArgs);
466     }
467 }
468 
469 //--------------------------------------------------------------------
470 
471 const SfxPoolItem* SfxRequest::GetArg
472 (
473     sal_uInt16          nSlotId,    // Slot-Id oder Which-Id des Parameters
474     bool        bDeep,      // false: nicht in Parent-ItemSets suchen
475     TypeId          aType       // != 0:  RTTI Pruefung mit Assertion
476 )   const
477 {
478     return GetItem( pArgs, nSlotId, bDeep, aType );
479 }
480 
481 
482 //--------------------------------------------------------------------
483 const SfxPoolItem* SfxRequest::GetItem
484 (
485     const SfxItemSet* pArgs,
486     sal_uInt16          nSlotId,    // Slot-Id oder Which-Id des Parameters
487     bool            bDeep,      // false: nicht in Parent-ItemSets suchen
488     TypeId          aType       // != 0:  RTTI Pruefung mit Assertion
489 )
490 
491 /*  [Beschreibung]
492 
493     Mit dieser Methode wird der Zugriff auf einzelne Parameter im
494     SfxRequest wesentlich vereinfacht. Insbesondere wird die Typpr"ufung
495     (per Assertion) durchgef"uhrt, wodurch die Applikations-Sourcen
496     wesentlich "ubersichtlicher werden. In der PRODUCT-Version wird
497     eine 0 zur"uckgegeben, wenn das gefundene Item nicht von der
498     angegebenen Klasse ist.
499 
500 
501     [Beispiel]
502 
503     void MyShell::Execute( SfxRequest &rReq )
504     {
505         switch ( rReq.GetSlot() )
506         {
507             case SID_MY:
508             {
509                 ...
510                 // ein Beispiel ohne Verwendung des Makros
511                 const SfxInt32Item *pPosItem = (const SfxUInt32Item*)
512                     rReq.GetArg( SID_POS, sal_False, TYPE(SfxInt32Item) );
513                 sal_uInt16 nPos = pPosItem ? pPosItem->GetValue() : 0;
514 
515                 // ein Beispiel mit Verwendung des Makros
516                 SFX_REQUEST_ARG(rReq, pSizeItem, SfxInt32Item, SID_SIZE, sal_False);
517                 sal_uInt16 nSize = pSizeItem ? pPosItem->GetValue() : 0;
518 
519                 ...
520             }
521 
522             ...
523         }
524     }
525 */
526 
527 {
528     if ( pArgs )
529     {
530         // ggf. in Which-Id umrechnen
531         sal_uInt16 nWhich = pArgs->GetPool()->GetWhich(nSlotId);
532 
533         // ist das Item gesetzt oder bei bDeep==TRUE verf"ugbar?
534         const SfxPoolItem *pItem = 0;
535         if ( ( bDeep ? SFX_ITEM_AVAILABLE : SFX_ITEM_SET )
536              <= pArgs->GetItemState( nWhich, bDeep, &pItem ) )
537         {
538             // stimmt der Typ "uberein?
539             if ( !pItem || pItem->IsA(aType) )
540                 return pItem;
541 
542             // Item da aber falsch => Programmierfehler
543             DBG_ERROR(  "invalid argument type" );
544         }
545     }
546 
547     // keine Parameter, nicht gefunden oder falschen Typ gefunden
548     return 0;
549 }
550 
551 //--------------------------------------------------------------------
552 
553 void SfxRequest::SetReturnValue(const SfxPoolItem &rItem)
554 {
555     DBG_ASSERT(!pImp->pRetVal, "Returnwert mehrfach setzen?");
556     if(pImp->pRetVal)
557         delete pImp->pRetVal;
558     pImp->pRetVal = rItem.Clone();
559 }
560 
561 //--------------------------------------------------------------------
562 
563 const SfxPoolItem* SfxRequest::GetReturnValue() const
564 {
565     return pImp->pRetVal;
566 }
567 
568 //--------------------------------------------------------------------
569 
570 void SfxRequest::Done
571 (
572     const SfxItemSet&   rSet,   /*  von der Applikation mitgeteilte Parameter,
573                                     die z.B. in einem Dialog vom Benuter
574                                     erfragt wurden, ggf. 0 falls keine
575                                     Parameter gesetzt wurden */
576 
577     bool            bKeep   /*  true (default)
578                                     'rSet' wird gepeichert und ist "uber
579                                     GetArgs() abfragbar
580 
581                                     false
582                                     'rSet' wird nicht kopiert (schneller) */
583 )
584 
585 /*  [Beschreibung]
586 
587     Diese Methode mu\s in der <Execute-Methode> des <SfxSlot>s gerufen
588     werden, der den SfxRequest ausgef"uhrt hat, wenn die Ausf"uhrung
589     tats"achlich stattgefunden hat. Wird 'Done()' nicht gerufen, gilt
590     der SfxRequest als abgebrochen.
591 
592     Etwaige Returnwerte werden nur durchgereicht, wenn 'Done()' gerufen
593     wurde. Ebenso werden beim Aufzeichnen von Makros nur echte
594     Statements erzeugt, wenn 'Done()' gerufen wurde; f"ur SfxRequests,
595     die nicht derart gekennzeichnet wurden, wird anstelle dessen eine
596     auf die abgebrochene Funktion hinweisende Bemerkung ('rem') eingf"ugt.
597 
598 
599     [Anmerkung]
600 
601     'Done()' wird z.B. nicht gerufen, wenn ein durch die Funktion gestarteter
602     Dialog vom Benutzer abgebrochen wurde oder das Ausf"uhren aufgrund
603     eines falschen Kontextes (ohne Verwendung separater <SfxShell>s)
604     nicht durchgef"uhrt werden konnte. 'Done()' mu\s sehr wohl gerufen
605     werden, wenn das Ausf"uhren der Funktion zu einem regul"aren Fehler
606     f"uhrte (z.B. Datei konnte nicht ge"offnet werden).
607 */
608 
609 {
610     Done_Impl( &rSet );
611 
612     // ggf. Items merken, damit StarDraw sie abfragen kann
613     if ( bKeep )
614     {
615         if ( !pArgs )
616         {
617             pArgs = new SfxAllItemSet( rSet );
618             pImp->SetPool( pArgs->GetPool() );
619         }
620         else
621         {
622             SfxItemIter aIter(rSet);
623             const SfxPoolItem* pItem = aIter.FirstItem();
624             while(pItem)
625             {
626                 if(!IsInvalidItem(pItem))
627                     pArgs->Put(*pItem,pItem->Which());
628                 pItem = aIter.NextItem();
629             }
630         }
631     }
632 }
633 
634 //--------------------------------------------------------------------
635 
636 
637 void SfxRequest::Done( sal_Bool bRelease )
638 //  [<SfxRequest::Done(SfxItemSet&)>]
639 {
640     Done_Impl( pArgs );
641     if( bRelease )
642         DELETEZ( pArgs );
643 }
644 
645 //--------------------------------------------------------------------
646 
647 void SfxRequest::ForgetAllArgs()
648 {
649     DELETEZ( pArgs );
650     DELETEZ( pImp->pInternalArgs );
651 }
652 
653 //--------------------------------------------------------------------
654 
655 sal_Bool SfxRequest::IsCancelled() const
656 {
657     return pImp->bCancelled;
658 }
659 
660 //--------------------------------------------------------------------
661 
662 void SfxRequest::Cancel()
663 
664 /*  [Beschreibung]
665 
666     Markiert diesen Request als nicht mehr auszufuehren. Wird z.B. gerufen,
667     wenn das Ziel (genauer dessen Pool) stirbt.
668 */
669 
670 {
671     pImp->bCancelled = sal_True;
672     pImp->SetPool( 0 );
673     DELETEZ( pArgs );
674 }
675 
676 //--------------------------------------------------------------------
677 
678 
679 void SfxRequest::Ignore()
680 
681 /*  [Beschreibung]
682 
683     Wird diese Methode anstelle von <SfxRequest::Done()> gerufen, dann
684     wird dieser Request nicht recorded.
685 
686 
687     [Bespiel]
688 
689     Das Selektieren von Tools im StarDraw soll nicht aufgezeichnet werden,
690     dieselben Slots sollen aber zum erzeugen der von den Tools zu
691     erzeugenden Objekte verwendet werde. Also kann nicht NoRecord
692     angegeben werden, dennoch soll u.U. nicht aufgezeichnet werden.
693 */
694 
695 {
696     // als tats"achlich ausgef"uhrt markieren
697     pImp->bIgnored = sal_True;
698 }
699 
700 //--------------------------------------------------------------------
701 
702 void SfxRequest::Done_Impl
703 (
704     const SfxItemSet*   pSet    /*  von der Applikation mitgeteilte Parameter,
705                                     die z.B. in einem Dialog vom Benuter
706                                     erfragt wurden, ggf. 0 falls keine
707                                     Parameter gesetzt wurden */
708 )
709 
710 /*  [Beschreibung]
711 
712     Interne Methode zum als 'done' markieren des SfxRequest und zum Auswerten
713     der Parameter in 'pSet' falls aufgezeichnet wird.
714 */
715 
716 {
717     // als tats"achlich ausgef"uhrt markieren
718     pImp->bDone = sal_True;
719 
720     // nicht Recorden
721     if ( !pImp->xRecorder.is() )
722         return;
723 
724     // wurde ein anderer Slot ausgef"uhrt als angefordert (Delegation)
725     if ( nSlot != pImp->pSlot->GetSlotId() )
726     {
727         // Slot neu suchen
728         pImp->pSlot = pImp->pShell->GetInterface()->GetSlot(nSlot);
729         DBG_ASSERT( pImp->pSlot, "delegated SlotId not found" );
730         if ( !pImp->pSlot ) // Hosentr"ger und G"urtel
731             return;
732     }
733 
734     // record-f"ahig?
735     // neues Recorden verwendet UnoName!
736     if ( !pImp->pSlot->pUnoName )
737     {
738         ByteString aStr( "Recording not exported slot: ");
739         aStr += ByteString::CreateFromInt32( pImp->pSlot->GetSlotId() );
740         DBG_ERROR( aStr.GetBuffer() );
741     }
742 
743     if ( !pImp->pSlot->pUnoName ) // Hosentr"ger und G"urtel
744         return;
745 
746     // "ofters ben"otigte Werte
747     SfxItemPool &rPool = pImp->pShell->GetPool();
748 
749     // Property-Slot?
750     if ( !pImp->pSlot->IsMode(SFX_SLOT_METHOD) )
751     {
752         // des Property als SfxPoolItem besorgen
753         const SfxPoolItem *pItem;
754         sal_uInt16 nWhich = rPool.GetWhich(pImp->pSlot->GetSlotId());
755         SfxItemState eState = pSet ? pSet->GetItemState( nWhich, sal_False, &pItem ) : SFX_ITEM_UNKNOWN;
756 #ifdef DBG_UTIL
757         if ( SFX_ITEM_SET != eState )
758         {
759             ByteString aStr( "Recording property not available: ");
760             aStr += ByteString::CreateFromInt32( pImp->pSlot->GetSlotId() );
761             DBG_ERROR( aStr.GetBuffer() );
762         }
763 #endif
764         uno::Sequence < beans::PropertyValue > aSeq;
765         if ( eState == SFX_ITEM_SET )
766             TransformItems( pImp->pSlot->GetSlotId(), *pSet, aSeq, pImp->pSlot );
767         pImp->Record( aSeq );
768     }
769 
770     // alles in ein einziges Statement aufzeichnen?
771     else if ( pImp->pSlot->IsMode(SFX_SLOT_RECORDPERSET) )
772     {
773         uno::Sequence < beans::PropertyValue > aSeq;
774         if ( pSet )
775             TransformItems( pImp->pSlot->GetSlotId(), *pSet, aSeq, pImp->pSlot );
776         pImp->Record( aSeq );
777     }
778 
779     // jedes Item als einzelnes Statement recorden
780     else if ( pImp->pSlot->IsMode(SFX_SLOT_RECORDPERITEM) )
781     {
782         if ( pSet )
783         {
784             // "uber die Items iterieren
785             SfxItemIter aIter(*pSet);
786             for ( const SfxPoolItem* pItem = aIter.FirstItem(); pItem; pItem = aIter.NextItem() )
787             {
788                 // die Slot-Id f"ur das einzelne Item ermitteln
789                 sal_uInt16 nSlotId = rPool.GetSlotId( pItem->Which() );
790                 if ( nSlotId == nSlot )
791                 {
792                     // mit Hosentr"ager und G"urtel reparieren des falschen Flags
793                     DBG_ERROR( "recursion RecordPerItem - use RecordPerSet!" );
794                     SfxSlot *pSlot = (SfxSlot*) pImp->pSlot;
795                     pSlot->nFlags &= ~((sal_uIntPtr)SFX_SLOT_RECORDPERITEM);
796                     pSlot->nFlags &=  SFX_SLOT_RECORDPERSET;
797                 }
798 
799                 // einen Sub-Request recorden
800                 SfxRequest aReq( pImp->pViewFrame, nSlotId );
801                 if ( aReq.pImp->pSlot )
802                     aReq.AppendItem( *pItem );
803                 aReq.Done();
804             }
805         }
806         else
807         {
808             HACK(hierueber nochmal nachdenken)
809             pImp->Record( uno::Sequence < beans::PropertyValue >() );
810         }
811     }
812 }
813 
814 //--------------------------------------------------------------------
815 
816 sal_Bool SfxRequest::IsDone() const
817 
818 /*  [Beschreibung]
819 
820     Mit dieser Methode kann abgefragt werden, ob der SfxRequest tats"achlich
821     ausgef"uhrt wurde oder nicht. Wurde ein SfxRequest nicht ausgef"uhrt,
822     liegt dies z.B. daran, da\s der Benutzer abgebrochen hat oder
823     der Kontext f"ur diesen Request falsch war, dieses aber nicht "uber
824     eine separate <SfxShell> realisiert wurde.
825 
826     SfxRequest-Instanzen, die hier sal_False liefern, werden nicht recorded.
827 
828 
829     [Querverweise]
830 
831     <SfxRequest::Done(const SfxItemSet&)>
832     <SfxRequest::Done()>
833 */
834 
835 {
836     return pImp->bDone;
837 }
838 
839 //--------------------------------------------------------------------
840 
841 SfxMacro* SfxRequest::GetRecordingMacro()
842 
843 /*  [Beschreibung]
844 
845     Mit dieser Methode kann abgefragt werden, ob und in welchem <SfxMacro>
846     die SfxRequests gerade aufgezeichnet werden.
847 */
848 
849 {
850     return NULL;
851 }
852 
853 //--------------------------------------------------------------------
854 
855 com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > SfxRequest::GetMacroRecorder( SfxViewFrame* pView )
856 
857 /*  [Beschreibung]
858 
859     Hier wird versucht einen Recorder fuer dispatch() Aufrufe vom Frame zu bekommen.
860     Dieser ist dort per Property an einem Supplier verfuegbar - aber nur dann, wenn
861     recording angeschaltet wurde.
862     (Siehe auch SfxViewFrame::MiscExec_Impl() und SID_RECORDING)
863 */
864 
865 {
866     com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorder > xRecorder;
867 
868     com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xSet(
869         (pView ? pView : SfxViewFrame::Current())->GetFrame().GetFrameInterface(),
870         com::sun::star::uno::UNO_QUERY);
871 
872     if(xSet.is())
873     {
874         com::sun::star::uno::Any aProp = xSet->getPropertyValue(rtl::OUString::createFromAscii("DispatchRecorderSupplier"));
875         com::sun::star::uno::Reference< com::sun::star::frame::XDispatchRecorderSupplier > xSupplier;
876         aProp >>= xSupplier;
877         if(xSupplier.is())
878             xRecorder = xSupplier->getDispatchRecorder();
879     }
880 
881     return xRecorder;
882 }
883 
884 sal_Bool SfxRequest::HasMacroRecorder( SfxViewFrame* pView )
885 {
886     return GetMacroRecorder( pView ).is();
887 }
888 
889 
890 //--------------------------------------------------------------------
891 
892 sal_Bool SfxRequest::IsAPI() const
893 
894 /*  [Beschreibung]
895 
896     Liefert sal_True, wenn dieser SfxRequest von einer API (z.B. BASIC)
897     erzeugt wurde, sonst sal_False.
898 */
899 
900 {
901     return SFX_CALLMODE_API == ( SFX_CALLMODE_API & pImp->nCallMode );
902 }
903 
904 //--------------------------------------------------------------------
905 
906 
907 bool SfxRequest::IsRecording() const
908 
909 /*  [Beschreibung]
910 
911     Liefert sal_True, wenn dieser SfxRequest recorded werden soll, d.h.
912     1. zu Zeit ein Makro aufgezeichnet wird
913     2. dieser Request "uberhaupt aufgezeichnet wird
914     3. der Request nicht von reiner API (z.B. BASIC) ausgeht,
915     sonst sal_False.
916 */
917 
918 {
919     return ( AllowsRecording() && GetMacroRecorder().is() );
920 }
921 
922 //--------------------------------------------------------------------
923 void SfxRequest::SetModifier( sal_uInt16 nModi )
924 {
925     pImp->nModifier = nModi;
926 }
927 
928 //--------------------------------------------------------------------
929 sal_uInt16 SfxRequest::GetModifier() const
930 {
931     return pImp->nModifier;
932 }
933 
934 //--------------------------------------------------------------------
935 
936 void SfxRequest::SetTarget( const String &rTarget )
937 
938 /*  [Beschreibung]
939 
940     Mit dieser Methode kann das zu recordende Zielobjekt umgesetzt werden.
941 
942 
943     [Beispiel]
944 
945     Die BASIC-Methode 'Open' wird zwar von der Shell 'Application' ausgef"uhrt,
946     aber am Objekt 'Documents' (global) recorded:
947 
948         rReq.SetTarget( "Documents" );
949 
950     Dies f"uhrt dann zu:
951 
952         Documents.Open( ... )
953 */
954 
955 {
956     pImp->aTarget = rTarget;
957     pImp->bUseTarget = sal_True;
958 }
959 
960 void SfxRequest::AllowRecording( sal_Bool bSet )
961 {
962     pImp->bAllowRecording = bSet;
963 }
964 
965 sal_Bool SfxRequest::AllowsRecording() const
966 {
967     sal_Bool bAllow = pImp->bAllowRecording;
968     if( !bAllow )
969         bAllow = ( SFX_CALLMODE_API != ( SFX_CALLMODE_API & pImp->nCallMode ) ) &&
970                  ( SFX_CALLMODE_RECORD == ( SFX_CALLMODE_RECORD & pImp->nCallMode ) );
971     return bAllow;
972 }
973 
974 void SfxRequest::ReleaseArgs()
975 {
976     DELETEZ( pArgs );
977     DELETEZ( pImp->pInternalArgs );
978 }
979