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 87 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 {} 97 ~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 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 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 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 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 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 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 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 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 309 sal_uInt16 SfxRequest::GetCallMode() const 310 { 311 return pImp->nCallMode; 312 } 313 314 //-------------------------------------------------------------------- 315 316 sal_Bool SfxRequest::IsSynchronCall() const 317 { 318 return SFX_CALLMODE_SYNCHRON == ( SFX_CALLMODE_SYNCHRON & pImp->nCallMode ); 319 } 320 321 //-------------------------------------------------------------------- 322 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 331 void SfxRequest::SetInternalArgs_Impl( const SfxAllItemSet& rArgs ) 332 { 333 delete pImp->pInternalArgs; 334 pImp->pInternalArgs = new SfxAllItemSet( rArgs ); 335 } 336 337 const SfxItemSet* SfxRequest::GetInternalArgs_Impl() const 338 { 339 return pImp->pInternalArgs; 340 } 341 342 //-------------------------------------------------------------------- 343 344 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 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 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 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 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 467 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 //-------------------------------------------------------------------- 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 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 559 const SfxPoolItem* SfxRequest::GetReturnValue() const 560 { 561 return pImp->pRetVal; 562 } 563 564 //-------------------------------------------------------------------- 565 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 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 643 void SfxRequest::ForgetAllArgs() 644 { 645 DELETEZ( pArgs ); 646 DELETEZ( pImp->pInternalArgs ); 647 } 648 649 //-------------------------------------------------------------------- 650 651 sal_Bool SfxRequest::IsCancelled() const 652 { 653 return pImp->bCancelled; 654 } 655 656 //-------------------------------------------------------------------- 657 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 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 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 812 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 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 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 880 sal_Bool SfxRequest::HasMacroRecorder( SfxViewFrame* pView ) 881 { 882 return GetMacroRecorder( pView ).is(); 883 } 884 885 886 //-------------------------------------------------------------------- 887 888 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 903 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 //-------------------------------------------------------------------- 919 void SfxRequest::SetModifier( sal_uInt16 nModi ) 920 { 921 pImp->nModifier = nModi; 922 } 923 924 //-------------------------------------------------------------------- 925 sal_uInt16 SfxRequest::GetModifier() const 926 { 927 return pImp->nModifier; 928 } 929 930 //-------------------------------------------------------------------- 931 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 956 void SfxRequest::AllowRecording( sal_Bool bSet ) 957 { 958 pImp->bAllowRecording = bSet; 959 } 960 961 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 970 void SfxRequest::ReleaseArgs() 971 { 972 DELETEZ( pArgs ); 973 DELETEZ( pImp->pInternalArgs ); 974 } 975