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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sfx2.hxx" 26 27 #if OSL_DEBUG_LEVEL > 1 28 #include <tools/stream.hxx> 29 #endif 30 31 #include "macro.hxx" 32 #include <sfx2/request.hxx> 33 #include <sfx2/msg.hxx> 34 35 //==================================================================== 36 37 SV_DECL_PTRARR_DEL( SfxStatements_Impl, SfxMacroStatement*, 16, 8 ) 38 SV_IMPL_PTRARR( SfxStatements_Impl, SfxMacroStatement* ); 39 40 //-------------------------------------------------------------------- 41 42 struct SfxMacro_Impl 43 44 /* [Beschreibung] 45 46 Implementations-Struktur der Klasse <SfxMacro>. 47 */ 48 49 { 50 SfxMacroMode eMode; /* Zweck der <SfxMacro>-Instanz, 51 Bedeutung siehe enum <SfxMacroMode> */ 52 SfxStatements_Impl aList; /* Liste von aufgezeichneten Statements */ 53 }; 54 55 //==================================================================== 56 57 SfxMacroStatement::SfxMacroStatement 58 ( 59 const SfxShell& /*rShell*/, // <SfxShell>, die den Request ausf"uhrte 60 const String& /*rTarget*/, // Name des Zielobjektes vor der Ausf"urhung 61 sal_Bool /*bAbsolute*/, // obsolet 62 const SfxSlot& rSlot, // der <SfxSlot>, der das Statement abspielen kann 63 sal_Bool bRequestDone, // wurde der Request tats"achlich ausgef"uhrt 64 ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& rArgs 65 ) 66 67 /* [Beschreibung] 68 69 Dieser Konstruktor der Klasse SfxMacroStatement erzeugt ein Statement, 70 bei dem ein Objekt angesprochen wird, welches durch 'rShell' angegeben 71 ist. Dabei erfolgt die Addressierung je nach 'bAbsolute' absolut, 72 also z.B. als '[mydoc.sdc]' oder relativ, also z.B. 'ActiveDocument'. 73 74 Je nach Art der Subklasse von 'rShell' ergeben sich folgende 75 Ausdr"ucke: 76 77 | absolut relativ 78 ----------------------------------------------------------------------- 79 SfxApplication' | 'StarCalc' 'Application' 80 SfxViewFrame' | '[mydoc.sdc:1]' 'ActiveWindow' 81 SfxViewShell' | '[mydoc.sdc:1]' 'AvtiveWindow' 82 SfxObjectShell' | '[mydoc.sdc]' 'ActiveDocument' 83 sonstige (Sub-Shells) | '[mydoc.sdc:1]' 'ActiveWindow' 84 85 Dabei sind 'StarCalc' stellvertretend fuer den Namen der Applikation 86 (Application::GetAppName()const). In der absoluten Fassung k"onnte 87 die Selektion auch deskriptiv z.B. als 'CellSelection("A5-D8")') 88 angesprochen werden, dazu mu\ jedoch vom Anwendungsprogrammierer der 89 Konstruktor <SfxMacroStatement::SfxMacroStatement(const String&, 90 const SfxSlot&,sal_Bool,SfxArguments*)> verwendet werden. 91 92 F"ur das so bezeichnete Objekt wird dann je nach Typ des Slots 93 eine Zuweisung an eines seiner Properties oder der Aufruf einer seiner 94 Methoden ausgedr"uckt. 95 96 97 [Beispiele] 98 99 absolut: 100 SCalc3.OpenDocument( "\docs\mydoc.sdd", "StarDraw Presentation", 0, 0 ) 101 [mydoc.sdd].Activate() 102 [mydoc.sdd:1].SwitchToView( 2 ) 103 [mydoc.sdc:1:1].CellSelection( "A5-D8" ).LineColor = 192357 104 105 relativ: 106 ActiveWindow.LineColor = 192357 107 108 109 [Querverweise] 110 111 <SfxMacroStatement::SfxMacroStatement(const String&,const SfxSlot&,sal_Bool,SfxArguments*)> 112 <SfxMacroStatement::SfxMacroStatement(const String&)> 113 */ 114 115 : nSlotId( rSlot.GetSlotId() ), 116 aArgs( rArgs ), 117 bDone( bRequestDone ), 118 pDummy( 0 ) 119 { 120 // Workaround Recording nicht exportierter Slots (#25386#) 121 if ( !rSlot.pName ) 122 return; 123 /* 124 // Objekt-Typ bestimmen 125 bool bIsApp = rShell.ISA(SfxApplication); 126 bool bIsDoc = rShell.ISA(SfxObjectShell); 127 bool bIsWin = !bIsApp && !bIsDoc && 128 ( rShell.ISA(SfxViewShell) || rShell.ISA(SfxViewFrame) ); 129 bool bIsSel = !bIsApp && !bIsDoc && !bIsWin; 130 131 // Objekt nicht schon im Slot-Namen enthalten? 132 if ( bIsSel || rSlot.pName[0] == '.' ) 133 { 134 // absolutes Aufzeichnen? 135 if ( rSlot.IsMode( SFX_SLOT_RECORDABSOLUTE ) ) 136 { 137 // an der Applikation oder am Modul 138 if ( rShell.ISA(SfxApplication) || rShell.ISA(SfxModule) ) 139 aStatement = rTarget; 140 141 // am Dokument? 142 // '[' = 5Bh 143 // ']' = 5Dh 144 else if ( rShell.ISA(SfxObjectShell) ) 145 { 146 aStatement = 0x005B; 147 aStatement += rTarget; 148 aStatement += 0x005D; 149 } 150 151 else if ( rShell.ISA(SfxViewFrame) ) 152 { 153 aStatement = 0x005B; 154 aStatement += String::CreateFromAscii("ViewFrame");//rShell.GetSbxObject()->GetName(); 155 aStatement += 0x005D; 156 } 157 158 else 159 { 160 // an der View oder Sub-Shell 161 SfxViewShell *pViewShell = rShell.GetViewShell(); 162 aStatement = 0x005B; 163 aStatement += String::CreateFromAscii("ViewShell");//pViewShell->GetViewFrame()->GetSbxObject()->GetName(); 164 aStatement += 0x005D; 165 if ( !rShell.ISA(SfxViewFrame) ) 166 // an einer Sub-Shell zus"atlich ".Selection" anh"angen 167 aStatement += DEFINE_CONST_UNICODE(".Selection"); 168 } 169 } 170 else // relatives Aufzeichnen 171 { 172 // an der Application? 173 if ( rShell.ISA(SfxApplication) ) 174 aStatement = DEFINE_CONST_UNICODE("Application"); 175 176 // am Modul? 177 else if ( rShell.ISA(SfxModule) ) 178 aStatement = DEFINE_CONST_UNICODE("ActiveModule"); 179 180 // am Dokument 181 else if ( rShell.ISA(SfxObjectShell) ) 182 aStatement = DEFINE_CONST_UNICODE("ActiveDocument"); 183 184 // am Window 185 else if ( rShell.ISA(SfxViewShell) || rShell.ISA(SfxViewFrame) ) 186 aStatement = DEFINE_CONST_UNICODE("ActiveWindow"); 187 188 else 189 // an einer Sub-Shell 190 aStatement = DEFINE_CONST_UNICODE("Selection"); 191 } 192 } 193 194 if ( bIsSel ) 195 { 196 // bei Selection ggf. noch den Namen der SubShell anh"angen 197 const SfxShellObject *pShObj = 198 (const SfxShellObject*) rShell.GetSbxObject(); 199 if ( pShObj ) 200 { 201 const SfxShellObject *pParentObj = 202 (const SfxShellObject*) pShObj->GetParent(); 203 SfxShell *pParentSh = pParentObj->GetShell(); 204 DBG_ASSERT( pParentSh->ISA(SfxViewFrame), 205 "parent of SubShell must be a Frame" ); 206 if ( rSlot.pName[0] == '.' ) 207 { 208 aStatement += '.'; 209 aStatement += rShell.GetSbxObject()->GetName(); 210 } 211 } 212 else 213 DBG_ASSERT( rSlot.pName[0] != '0', "recording unnamed object" ); 214 } 215 */ 216 aStatement = DEFINE_CONST_UNICODE("Selection"); 217 218 // an diesen Objekt-Ausdruck den Methoden-/Property-Namen und Parameter 219 GenerateNameAndArgs_Impl( SfxRequest::GetRecordingMacro(), rSlot, bRequestDone, aArgs); 220 } 221 222 //-------------------------------------------------------------------- 223 224 SfxMacroStatement::SfxMacroStatement 225 ( 226 const String& rTarget, // Objekt, was beim Playing angesprochen wird 227 const SfxSlot& rSlot, // der <SfxSlot>, der das Statement abspielen kann 228 sal_Bool bRequestDone, // wurde der Request tats"achlich ausgef"uhrt 229 ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& rArgs 230 ) 231 232 /* [Beschreibung] 233 234 235 [Querverweise] 236 237 <SfxMacroStatement::SfxMacroStatement(const String&)> 238 <SfxMacroStatement::SfxMacroStatement(const SfxShell&,sal_Bool,const SfxSlot&,sal_Bool,SfxArguments*)> 239 */ 240 241 : nSlotId( rSlot.GetSlotId() ), 242 aArgs( rArgs ), 243 bDone( bRequestDone ), 244 pDummy( 0 ) 245 { 246 aStatement = rTarget; 247 aStatement += '.'; 248 GenerateNameAndArgs_Impl( SfxRequest::GetRecordingMacro(), rSlot, bRequestDone, aArgs); 249 } 250 251 //-------------------------------------------------------------------- 252 253 SfxMacroStatement::SfxMacroStatement 254 ( 255 const String& rStatement // manuell erzeugte(s) Statement(s) 256 ) 257 258 /* [Beschreibung] 259 260 Dieser Konstruktor erzeugt eine SfxMacroStatement-Instanz, deren 261 Aufbau vollst"andig vom Applikationsentwickler bestimmt wird. Da der 262 angegebene String auch mehrere mit CR/LF getrennte Statements 263 enthalten darf, ist damit ein weitgehender Eingriff in das Aufzeichnen 264 von BASIC-Makros m"oglich, um Spezialf"alle zu behandeln. 265 266 267 [Querverweise] 268 269 <SfxMacroStatement::SfxMacroStatement(const String&,const SfxSlot&,sal_Bool,SfxArguments*)> 270 <SfxMacroStatement::SfxMacroStatement(const SfxShell&,sal_Bool,const SfxSlot&,sal_Bool,SfxArguments*)> 271 */ 272 273 : nSlotId( 0 ), 274 aStatement( rStatement ), 275 bDone( sal_True ), 276 pDummy( 0 ) 277 { 278 } 279 280 //-------------------------------------------------------------------- 281 282 SfxMacroStatement::SfxMacroStatement 283 ( 284 const SfxMacroStatement& rOrig // Original, von dem kopiert wird 285 ) 286 287 /* [Beschreibung] 288 289 Copy-Konstruktor der SfxMacroStatement-Klasse. 290 */ 291 292 : nSlotId( rOrig.nSlotId ), 293 aStatement( rOrig.aStatement ), 294 bDone( rOrig.bDone ), 295 pDummy( 0 ) 296 { 297 aArgs = rOrig.aArgs; 298 } 299 300 //-------------------------------------------------------------------- 301 302 SfxMacroStatement::~SfxMacroStatement() 303 304 /* [Beschreibung] 305 306 Destruktor der Klasse SfxMacroStatement. Gibt die Liste der 307 aktuellen Parameter frei. 308 */ 309 310 { 311 } 312 313 //-------------------------------------------------------------------- 314 315 void SfxMacroStatement::GenerateNameAndArgs_Impl 316 ( 317 SfxMacro* /*pMacro*/, // darin wird aufgezeichnet 318 const SfxSlot& rSlot, // der Slot, der das Statement abspielen kann 319 sal_Bool bRequestDone, // sal_True=wurde ausgef"uhrt, sal_False=abgebrochen 320 ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& /*rArgs*/ 321 ) 322 323 /* [Beschreibung] 324 325 Interne Hilfsmethode zum generieren des Funktions-/Property-Names 326 sowie der Parameter. Diese Methode wird nur verwendet, wenn der 327 Anwendungsprogrammierer keinen eigenen Source an den <SfxRequest> 328 geh"angt hat. 329 */ 330 331 { 332 if ( aStatement.Len() && aStatement.GetChar( aStatement.Len() - 1 ) != '.' 333 && rSlot.pName[0] != '.' ) 334 aStatement += '.'; 335 336 // der Name des Slots ist der Name der Methode / des Properties 337 aStatement += String::CreateFromAscii(rSlot.pName); 338 if ( rSlot.IsMode(SFX_SLOT_METHOD) ) 339 aStatement += DEFINE_CONST_UNICODE("( "); 340 else 341 aStatement += DEFINE_CONST_UNICODE(" = "); 342 343 // alle zusammengesuchten Parameter rausschreiben 344 if ( aArgs.getLength() ) 345 for ( sal_uInt16 nArg = 0; nArg < aArgs.getLength(); ++nArg ) 346 { 347 // den Parameter textuell darstellen 348 String aArg; 349 ::com::sun::star::uno::Any& rValue = aArgs[nArg].Value; 350 ::com::sun::star::uno::Type pType = rValue.getValueType(); 351 if ( pType == ::getBooleanCppuType() ) 352 { 353 sal_Bool bTemp = false; 354 rValue >>= bTemp; 355 aArg = bTemp ? DEFINE_CONST_UNICODE("TRUE") : DEFINE_CONST_UNICODE("FALSE"); 356 } 357 else if ( pType == ::getCppuType((const sal_Int16*)0) ) 358 { 359 sal_uInt16 nTemp = 0; 360 rValue >>= nTemp; 361 aArg = String::CreateFromInt32( (sal_Int32) nTemp ); 362 } 363 else if ( pType == ::getCppuType((const sal_Int32*)0) ) 364 { 365 sal_uInt32 nTemp = 0; 366 rValue >>= nTemp; 367 aArg = String::CreateFromInt32( nTemp ); 368 } 369 else if ( pType == ::getCppuType((const ::rtl::OUString*)0) ) 370 { 371 ::rtl::OUString sTemp; 372 rValue >>= sTemp; 373 374 // Anf"uhrungszeichen werden verdoppelt 375 XubString aRecordable( sTemp ); 376 sal_uInt16 nPos = 0; 377 while ( sal_True ) 378 { 379 nPos = aRecordable.SearchAndReplace( DEFINE_CONST_UNICODE('"'), DEFINE_CONST_UNICODE("\"\""), nPos ); 380 if ( STRING_NOTFOUND == nPos ) 381 break; 382 nPos += 2; 383 } 384 385 // nicht druckbare Zeichen werden als chr$(...) geschrieben 386 bool bPrevReplaced = sal_False; 387 for ( sal_uInt16 n = 0; n < aRecordable.Len(); ++n ) 388 { 389 sal_Unicode cChar = aRecordable.GetChar(n); 390 if ( !( cChar>=32 && cChar!=127 ) ) // ALS ERSATZ FUER String::IsPrintable()! 391 { 392 XubString aReplacement( DEFINE_CONST_UNICODE("+chr$(") ); 393 aReplacement += cChar; 394 395 if ( bPrevReplaced ) 396 { 397 aRecordable.Insert( aReplacement, n - 2 ); 398 n = n + aReplacement.Len(); 399 aRecordable.SetChar((unsigned short) (n-2), 0x0029);// ')' = 29h 400 aRecordable.Replace( n-1, 2, DEFINE_CONST_UNICODE("+\"") ); 401 // ++n; 402 } 403 else 404 { 405 aReplacement += DEFINE_CONST_UNICODE(")+\""); 406 aRecordable.SetChar(n, 0x0022 );// '"' = 22h 407 aRecordable.Insert( aReplacement, n + 1 ); 408 n = n + aReplacement.Len(); 409 } 410 bPrevReplaced = sal_True; 411 } 412 else 413 bPrevReplaced = sal_False; 414 415 // Argument in Anf"uhrungszeichen 416 aArg = '"'; 417 aArg += aRecordable; 418 aArg += '"'; 419 } 420 /* 421 case SbxBYTE: 422 { 423 // als Zahl darstellen 424 aArg = (sal_uInt16) rVar.GetByte(); 425 break; 426 } 427 */ 428 } 429 else 430 { 431 OSL_ENSURE( 432 pType == ::getVoidCppuType(), "Unknown Type in recorder!" ); 433 } 434 435 // den Parameter anh"angen 436 aStatement += aArg; 437 aStatement += DEFINE_CONST_UNICODE(", "); 438 } 439 440 // Statement beeden 441 if ( aArgs.getLength() ) 442 aStatement.Erase( aStatement.Len() - 2, 1 ); 443 else 444 aStatement.Erase( aStatement.Len() - 1, 1 ); 445 if ( rSlot.IsMode(SFX_SLOT_METHOD) ) 446 aStatement += ')'; 447 448 if ( !bRequestDone ) 449 // nicht als "Done()" gekennzeichnete Statements auskommentieren 450 aStatement.InsertAscii( "rem ", 0 ); 451 } 452 453 //-------------------------------------------------------------------- 454 455 SfxMacro::SfxMacro 456 ( 457 SfxMacroMode eMode // Zweck der Instanz, siehe <SfxMacroMode> 458 ) 459 460 /* [Beschreibung] 461 462 Konstruktor der Klasse SfxMacro. Instanzen dieser Klasse werden im 463 SFx zu zwei Zwecken ben"otigt: 464 465 1. zum Aufzeichnen von Makros 466 In diesem Fall wird der Konstruktor mit SFX_MACRO_RECORDINGABSOLUTE 467 oder SFX_MACRO_RECORDINGRELATIVE aufgerufen. Es sollte sich um eine 468 Instanz einer abgeleiteten Klasse handeln, um in der Ableitung 469 die Information dar"uber unterzubringen, wo das Makro gespeichert 470 werden soll. Ein solches Makro solle sich dann in seinem Destruktor 471 an der vom Benutzer gew"ahlten Stelle speichern. 472 473 2. zum Zuordnen von exisitierenden Makros 474 In diesem Fall wird der Konstruktor mit SFX_MACRO_EXISTING aufgerufen. 475 Eine solche Instanz wird z.B. ben"otigt, wenn Makros auf Events 476 oder <SfxControllerItem>s konfiguriert werden sollen. 477 */ 478 479 : pImp( new SfxMacro_Impl ) 480 481 { 482 pImp->eMode = eMode; 483 } 484 485 //-------------------------------------------------------------------- 486 487 SfxMacro::~SfxMacro() 488 489 /* [Beschreibung] 490 491 Virtueller Destruktor der Klasse SfxMacro. Dieser sollte in den 492 abgeleiteten Klassen "uberladen werden, um in den Modi 493 SFX_MACRO_RECORDINGABSOLUTE und SFX_MACRO_RECORDINGRELATIVE den 494 aufgezeichneten Source abzuspeichern. 495 496 497 [Querverweise] 498 499 <SfxMacro::GenerateSource()const> 500 */ 501 502 { 503 #if OSL_DEBUG_LEVEL > 1 504 SvFileStream aStream( String::CreateFromAscii("file:///f:/testmacro.bas" ), STREAM_STD_READWRITE | STREAM_TRUNC ); 505 aStream << ByteString( GenerateSource(), RTL_TEXTENCODING_UTF8 ).GetBuffer(); 506 #endif 507 delete pImp; 508 } 509 510 //-------------------------------------------------------------------- 511 512 SfxMacroMode SfxMacro::GetMode() const 513 514 /* [Beschreibung] 515 516 Liefert den Modus, der besagt zu welchem Zweck das SfxMacro konstruiert 517 wurde. 518 519 520 [Querverweise] 521 522 enum <SfxMacroMode> 523 */ 524 525 { 526 return pImp->eMode; 527 } 528 529 //-------------------------------------------------------------------- 530 531 void SfxMacro::Record 532 ( 533 SfxMacroStatement* pStatement // aufzuzeichnendes <SfxMacroStatement> 534 ) 535 536 /* [Beschreibung] 537 538 Diese Methode zeichnet das als Parameter "ubergeben Statement auf. 539 Die Instanz auf die der "ubergebe Pointer zeigt, geht in das Eigentum 540 des SfxMacro "uber. 541 542 Der Aufruf ist nur g"ultig, wenn es sich um ein SfxMacro handelt, 543 welches mit SFX_MACRO_RECORDINGABSOLUTE oder SFX_MACRO_RECORDINGRELATIVE 544 konstruiert wirde. 545 546 547 [Querverweise] 548 549 <SfxMacro::Replace(SfxMacroStatement*)> 550 <SfxMacro::Remove()> 551 <SfxMacro::GetLastStatement()const> 552 */ 553 554 { 555 DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" ); 556 pImp->aList.C40_INSERT( SfxMacroStatement, pStatement, pImp->aList.Count() ); 557 } 558 559 //-------------------------------------------------------------------- 560 561 void SfxMacro::Replace 562 ( 563 SfxMacroStatement* pStatement // aufzuzeichnendes <SfxMacroStatement> 564 ) 565 566 /* [Beschreibung] 567 568 Diese Methode zeichnet das als Parameter "ubergeben Statement auf. 569 Dabei wird das jeweils zuletzt aufgezeichnete Statement "uberschrieben. 570 Die Instanz auf die der "ubergebe Pointer zeigt, geht in das Eigentum 571 des SfxMacro "uber. 572 573 Mit dieser Methode ist es m"oglich, Statements zusammenzufassen. Z.B. 574 anstelle f"unfmal hintereinander 'CursorLeft()' aufzurufen, k"onnte 575 das zu 'CursorLeft(5)' zusammengefa\st werden. Oder anstelle ein Wort 576 Buchstabe f"ur Buchstabe aufzubauen, k"onnte dies durch ein einziges 577 Statement 'InsertString("Hallo")' ersetzt werden. 578 579 Der Aufruf ist nur g"ultig, wenn es sich um ein SfxMacro handelt, 580 welches mit SFX_MACRO_RECORDINGABSOLUTE oder SFX_MACRO_RECORDINGRELATIVE 581 konstruiert wurde und bereits ein aufgezeichnetes Statement vorhanden 582 ist. 583 584 585 [Anmerkung] 586 587 Diese Methode wird typischerweise aus den Execute-Methoden der 588 <SfxSlot>s von den Applikationsentwicklern gerufen. 589 590 591 [Querverweise] 592 593 <SfxMacro::Record(SfxMacroStatement*)> 594 <SfxMacro::Remove()> 595 <SfxMacro::GetLastStatement()const> 596 */ 597 598 { 599 DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" ); 600 DBG_ASSERT( pImp->aList.Count(), "no replaceable statement available" ); 601 pImp->aList.Remove( pImp->aList.Count() - 1 ); 602 pImp->aList.C40_INSERT( SfxMacroStatement,pStatement, pImp->aList.Count() ); 603 } 604 605 //-------------------------------------------------------------------- 606 607 void SfxMacro::Remove() 608 609 /* [Beschreibung] 610 611 Diese Methode l"oscht das zuletzt aufgezeichnete <SfxMacroStatement> 612 und entfernt es aus dem Macro. 613 614 Mit dieser Methode ist es m"oglich, Statements zusammenzufassen. Z.B. 615 anstelle f"unfmal hintereinander 'CursorLeft()' aufzurufen, k"onnte 616 das zu 'CursorLeft(5)' zusammengefa\st werden. Oder anstelle ein Wort 617 Buchstabe f"ur Buchstabe aufzubauen, k"onnte dies durch ein einziges 618 Statement 'InsertString("Hallo")' ersetzt werden. 619 620 Der Aufruf ist nur g"ultig, wenn es sich um ein SfxMacro handelt, 621 welches mit SFX_MACRO_RECORDINGABSOLUTE oder SFX_MACRO_RECORDINGRELATIVE 622 konstruiert wurde und bereits ein aufgezeichnetes Statement vorhanden 623 ist. 624 625 626 [Anmerkung] 627 628 Diese Methode wird typischerweise aus den Execute-Methoden der 629 <SfxSlot>s von den Applikationsentwicklern gerufen. 630 631 632 [Querverweise] 633 634 <SfxMacro::Replace(SfxMacroStatement*)> 635 <SfxMacro::Record(SfxMacroStatement*)> 636 <SfxMacro::GetLastStatement()const> 637 */ 638 639 { 640 DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" ); 641 DBG_ASSERT( pImp->aList.Count(), "no replaceable statement available" ); 642 pImp->aList.Remove( pImp->aList.Count() - 1 ); 643 } 644 645 //-------------------------------------------------------------------- 646 647 const SfxMacroStatement* SfxMacro::GetLastStatement() const 648 649 /* [Beschreibung] 650 651 Mit dieser Methode kann auf das jeweils zuletzt aufgezeichnete Statement 652 lesend zugegriffen werden. Zusammen mit der Methode 653 <SfxMacro::Replace(SfxMacroStatement*)> ergibt sich dadurch die 654 M"oglichkeit, Statements zusammenzufassen. 655 656 Der Aufruf ist nur g"ultig, wenn es sich um ein SfxMacro handelt, 657 welches mit SFX_MACRO_RECORDINGABSOLUTE oder SFX_MACRO_RECORDINGRELATIVE 658 konstruiert wurde. 659 660 661 [Querverweise] 662 663 <SfxMacro::Record(SfxMacroStatement*)> 664 <SfxMacro::Replace(SfxMacroStatement*)> 665 */ 666 667 { 668 DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" ); 669 if ( pImp->aList.Count() ) 670 return pImp->aList.GetObject( pImp->aList.Count() - 1 ); 671 return 0; 672 } 673 674 //-------------------------------------------------------------------- 675 676 String SfxMacro::GenerateSource() const 677 678 /* [Beschreibung] 679 680 Diese Funktion generiert aus den, seit dem Konstruieren der Instanz 681 bis zum Zeitpunkt des Aufrufs dieser Methode aufgezeichneten 682 <SfxMacroStatement>s einen BASIC-Sourcecode, der die Statements, 683 jedoch nicht den Header ('Sub X') und den Footer ('End Sub') enth"alt. 684 685 686 [Querverweise] 687 688 <SfxMacro::Record(SfxMacroStatement*)> 689 <SfxMacro::Repeat(SfxMacroStatement*)> 690 */ 691 692 { 693 DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" ); 694 String aSource; 695 for ( sal_uInt16 n = 0; n < pImp->aList.Count(); ++n ) 696 { 697 aSource += pImp->aList.GetObject(n)->GetStatement(); 698 if ( (n+1) < pImp->aList.Count() ) 699 aSource += DEFINE_CONST_UNICODE("\n"); 700 } 701 702 return aSource; 703 } 704 705