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
SfxMacroStatement(const SfxShell &,const String &,sal_Bool,const SfxSlot & rSlot,sal_Bool bRequestDone,::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> & rArgs)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
SfxMacroStatement(const String & rTarget,const SfxSlot & rSlot,sal_Bool bRequestDone,::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> & rArgs)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
SfxMacroStatement(const String & rStatement)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
SfxMacroStatement(const SfxMacroStatement & rOrig)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
~SfxMacroStatement()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
GenerateNameAndArgs_Impl(SfxMacro *,const SfxSlot & rSlot,sal_Bool bRequestDone,::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> &)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( rtl::OStringToOUString( rSlot.pName, RTL_TEXTENCODING_UTF8));
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
SfxMacro(SfxMacroMode eMode)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
~SfxMacro()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
GetMode() const512 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
Record(SfxMacroStatement * pStatement)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
Replace(SfxMacroStatement * pStatement)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
Remove()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
GetLastStatement() const647 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
GenerateSource() const676 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