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