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