/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"

#if OSL_DEBUG_LEVEL > 1
#include <tools/stream.hxx>
#endif

#include "macro.hxx"
#include <sfx2/request.hxx>
#include <sfx2/msg.hxx>

//====================================================================

SV_DECL_PTRARR_DEL( SfxStatements_Impl, SfxMacroStatement*, 16, 8 )
SV_IMPL_PTRARR( SfxStatements_Impl, SfxMacroStatement* );

//--------------------------------------------------------------------

struct SfxMacro_Impl

/*	[Beschreibung]

	Implementations-Struktur der Klasse <SfxMacro>.
*/

{
	SfxMacroMode		eMode;	/*	Zweck der <SfxMacro>-Instanz,
									Bedeutung siehe enum <SfxMacroMode> */
	SfxStatements_Impl	aList;  /* 	Liste von aufgezeichneten Statements */
};

//====================================================================

SfxMacroStatement::SfxMacroStatement
(
	const SfxShell& /*rShell*/,		// <SfxShell>, die den Request ausf"uhrte
	const String&	/*rTarget*/,	// Name des Zielobjektes vor der Ausf"urhung
	sal_Bool			/*bAbsolute*/,	// obsolet
	const SfxSlot&	rSlot,			// der <SfxSlot>, der das Statement abspielen kann
	sal_Bool			bRequestDone,	// wurde der Request tats"achlich ausgef"uhrt
    ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& rArgs
)

/* 	[Beschreibung]

	Dieser Konstruktor der Klasse SfxMacroStatement erzeugt ein Statement,
	bei dem ein Objekt angesprochen wird, welches durch 'rShell' angegeben
	ist. Dabei erfolgt die Addressierung je nach 'bAbsolute' absolut,
	also z.B. als '[mydoc.sdc]' oder relativ, also z.B. 'ActiveDocument'.

	Je nach Art der Subklasse von 'rShell' ergeben sich folgende
	Ausdr"ucke:

                          | absolut                  relativ
	-----------------------------------------------------------------------
	SfxApplication'       | 'StarCalc'  			'Application'
    SfxViewFrame'         | '[mydoc.sdc:1]'         'ActiveWindow'
	SfxViewShell'         | '[mydoc.sdc:1]'         'AvtiveWindow'
	SfxObjectShell'       | '[mydoc.sdc]'           'ActiveDocument'
	sonstige (Sub-Shells) | '[mydoc.sdc:1]'			'ActiveWindow'

    Dabei sind 'StarCalc' stellvertretend fuer den Namen der Applikation
	(Application::GetAppName()const). In der absoluten Fassung k"onnte
	die Selektion auch deskriptiv z.B. als 'CellSelection("A5-D8")')
	angesprochen werden, dazu mu\ jedoch vom Anwendungsprogrammierer der
	Konstruktor <SfxMacroStatement::SfxMacroStatement(const String&,
	const SfxSlot&,sal_Bool,SfxArguments*)> verwendet werden.

	F"ur das so bezeichnete Objekt wird dann je nach Typ des Slots
	eine Zuweisung an eines seiner Properties oder der Aufruf einer seiner
	Methoden ausgedr"uckt.


	[Beispiele]

	absolut:
	SCalc3.OpenDocument( "\docs\mydoc.sdd", "StarDraw Presentation", 0, 0 )
	[mydoc.sdd].Activate()
	[mydoc.sdd:1].SwitchToView( 2 )
	[mydoc.sdc:1:1].CellSelection( "A5-D8" ).LineColor = 192357

	relativ:
	ActiveWindow.LineColor = 192357


	[Querverweise]

	<SfxMacroStatement::SfxMacroStatement(const String&,const SfxSlot&,sal_Bool,SfxArguments*)>
	<SfxMacroStatement::SfxMacroStatement(const String&)>
*/

:	nSlotId( rSlot.GetSlotId() ),
    aArgs( rArgs ),
	bDone( bRequestDone ),
	pDummy( 0 )
{
	// Workaround Recording nicht exportierter Slots (#25386#)
	if ( !rSlot.pName )
		return;
/*
	// Objekt-Typ bestimmen
	bool bIsApp = rShell.ISA(SfxApplication);
	bool bIsDoc = rShell.ISA(SfxObjectShell);
	bool bIsWin = !bIsApp && !bIsDoc &&
					  ( rShell.ISA(SfxViewShell) || rShell.ISA(SfxViewFrame) );
	bool bIsSel = !bIsApp && !bIsDoc && !bIsWin;

	// Objekt nicht schon im Slot-Namen enthalten?
	if ( bIsSel || rSlot.pName[0] == '.' )
	{
		// absolutes Aufzeichnen?
		if ( rSlot.IsMode( SFX_SLOT_RECORDABSOLUTE ) )
		{
			// an der Applikation oder am Modul
			if ( rShell.ISA(SfxApplication) || rShell.ISA(SfxModule) )
				aStatement = rTarget;

			// am Dokument?
			// '[' = 5Bh
			// ']' = 5Dh
			else if ( rShell.ISA(SfxObjectShell) )
			{
				aStatement = 0x005B;
				aStatement += rTarget;
				aStatement += 0x005D;
			}

			else if ( rShell.ISA(SfxViewFrame) )
			{
				aStatement = 0x005B;
                aStatement += String::CreateFromAscii("ViewFrame");//rShell.GetSbxObject()->GetName();
				aStatement += 0x005D;
			}

			else
			{
				// an der View oder Sub-Shell
				SfxViewShell *pViewShell = rShell.GetViewShell();
				aStatement = 0x005B;
                aStatement += String::CreateFromAscii("ViewShell");//pViewShell->GetViewFrame()->GetSbxObject()->GetName();
				aStatement += 0x005D;
				if ( !rShell.ISA(SfxViewFrame) )
                    // an einer Sub-Shell zus"atlich ".Selection" anh"angen
					aStatement += DEFINE_CONST_UNICODE(".Selection");
			}
		}
		else // relatives Aufzeichnen
		{
			// an der Application?
			if ( rShell.ISA(SfxApplication) )
				aStatement = DEFINE_CONST_UNICODE("Application");

			// am Modul?
			else if ( rShell.ISA(SfxModule) )
				aStatement = DEFINE_CONST_UNICODE("ActiveModule");

			// am Dokument
			else if ( rShell.ISA(SfxObjectShell) )
				aStatement = DEFINE_CONST_UNICODE("ActiveDocument");

			// am Window
			else if ( rShell.ISA(SfxViewShell) || rShell.ISA(SfxViewFrame) )
				aStatement = DEFINE_CONST_UNICODE("ActiveWindow");

			else
				// an einer Sub-Shell
				aStatement = DEFINE_CONST_UNICODE("Selection");
		}
	}

	if ( bIsSel )
	{
		// bei Selection ggf. noch den Namen der SubShell anh"angen
		const SfxShellObject *pShObj =
					(const SfxShellObject*) rShell.GetSbxObject();
		if ( pShObj )
		{
			const SfxShellObject *pParentObj =
						(const SfxShellObject*) pShObj->GetParent();
			SfxShell *pParentSh = pParentObj->GetShell();
			DBG_ASSERT( pParentSh->ISA(SfxViewFrame),
						"parent of SubShell must be a Frame" );
			if ( rSlot.pName[0] == '.' )
			{
				aStatement += '.';
				aStatement += rShell.GetSbxObject()->GetName();
			}
		}
		else
			DBG_ASSERT( rSlot.pName[0] != '0', "recording unnamed object" );
	}
*/
    aStatement = DEFINE_CONST_UNICODE("Selection");

	// an diesen Objekt-Ausdruck den Methoden-/Property-Namen und Parameter
    GenerateNameAndArgs_Impl( SfxRequest::GetRecordingMacro(), rSlot, bRequestDone, aArgs);
}

//--------------------------------------------------------------------

SfxMacroStatement::SfxMacroStatement
(
	const String&   rTarget,		// Objekt, was beim Playing angesprochen wird
	const SfxSlot&	rSlot,			// der <SfxSlot>, der das Statement abspielen kann
	sal_Bool			bRequestDone,	// wurde der Request tats"achlich ausgef"uhrt
    ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& rArgs
)

/* 	[Beschreibung]


	[Querverweise]

	<SfxMacroStatement::SfxMacroStatement(const String&)>
	<SfxMacroStatement::SfxMacroStatement(const SfxShell&,sal_Bool,const SfxSlot&,sal_Bool,SfxArguments*)>
*/

:	nSlotId( rSlot.GetSlotId() ),
    aArgs( rArgs ),
	bDone( bRequestDone ),
	pDummy( 0 )
{
	aStatement = rTarget;
	aStatement += '.';
    GenerateNameAndArgs_Impl( SfxRequest::GetRecordingMacro(), rSlot, bRequestDone, aArgs);
}

//--------------------------------------------------------------------

SfxMacroStatement::SfxMacroStatement
(
	const String&   rStatement  	// manuell erzeugte(s) Statement(s)
)

/* 	[Beschreibung]

	Dieser Konstruktor erzeugt eine SfxMacroStatement-Instanz, deren
	Aufbau vollst"andig vom Applikationsentwickler bestimmt wird. Da der
	angegebene String auch mehrere mit CR/LF getrennte Statements
	enthalten darf, ist damit ein weitgehender Eingriff in das Aufzeichnen
	von BASIC-Makros m"oglich, um Spezialf"alle zu behandeln.


	[Querverweise]

	<SfxMacroStatement::SfxMacroStatement(const String&,const SfxSlot&,sal_Bool,SfxArguments*)>
	<SfxMacroStatement::SfxMacroStatement(const SfxShell&,sal_Bool,const SfxSlot&,sal_Bool,SfxArguments*)>
*/

:	nSlotId( 0 ),
       aStatement( rStatement ),
	bDone( sal_True ),
	pDummy( 0 )
{
}

//--------------------------------------------------------------------

SfxMacroStatement::SfxMacroStatement
(
	const SfxMacroStatement&	rOrig // Original, von dem kopiert wird
)

/* 	[Beschreibung]

	Copy-Konstruktor der SfxMacroStatement-Klasse.
*/

:	nSlotId( rOrig.nSlotId ),
	aStatement( rOrig.aStatement ),
       bDone( rOrig.bDone ),
	pDummy( 0 )
{
    aArgs = rOrig.aArgs;
}

//--------------------------------------------------------------------

SfxMacroStatement::~SfxMacroStatement()

/* 	[Beschreibung]

	Destruktor der Klasse SfxMacroStatement. Gibt die Liste der
	aktuellen Parameter frei.
*/

{
}

//--------------------------------------------------------------------

void SfxMacroStatement::GenerateNameAndArgs_Impl
(
	SfxMacro*		/*pMacro*/,			// darin wird aufgezeichnet
	const SfxSlot&	rSlot,			// der Slot, der das Statement abspielen kann
	sal_Bool			bRequestDone,	// sal_True=wurde ausgef"uhrt, sal_False=abgebrochen
    ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& /*rArgs*/
)

/*	[Beschreibung]

	Interne Hilfsmethode zum generieren des Funktions-/Property-Names
	sowie der Parameter. Diese Methode wird nur verwendet, wenn der
	Anwendungsprogrammierer keinen eigenen Source an den <SfxRequest>
	geh"angt hat.
*/

{
	if ( aStatement.Len() && aStatement.GetChar( aStatement.Len() - 1 ) != '.'
         && rSlot.pName[0] != '.' )
		aStatement += '.';

	// der Name des Slots ist der Name der Methode / des Properties
	aStatement += String( rtl::OStringToOUString( rSlot.pName, RTL_TEXTENCODING_UTF8));
	if ( rSlot.IsMode(SFX_SLOT_METHOD) )
		aStatement += DEFINE_CONST_UNICODE("( ");
	else
		aStatement += DEFINE_CONST_UNICODE(" = ");

	// alle zusammengesuchten Parameter rausschreiben
    if ( aArgs.getLength() )
        for ( sal_uInt16 nArg = 0; nArg < aArgs.getLength(); ++nArg )
		{
			// den Parameter textuell darstellen
			String aArg;
            ::com::sun::star::uno::Any& rValue = aArgs[nArg].Value;
            ::com::sun::star::uno::Type pType = rValue.getValueType();
			if ( pType == ::getBooleanCppuType() )
			{
                sal_Bool bTemp = false;
                rValue >>= bTemp;
                aArg = bTemp ? DEFINE_CONST_UNICODE("TRUE") : DEFINE_CONST_UNICODE("FALSE");
			}
            else if ( pType == ::getCppuType((const sal_Int16*)0) )
			{
                sal_uInt16 nTemp = 0;
                rValue >>= nTemp;
                aArg = String::CreateFromInt32( (sal_Int32) nTemp );
			}
            else if ( pType == ::getCppuType((const sal_Int32*)0) )
			{
                sal_uInt32 nTemp = 0;
                rValue >>= nTemp;
                aArg = String::CreateFromInt32( nTemp );
			}
			else if ( pType == ::getCppuType((const ::rtl::OUString*)0) )
			{
                ::rtl::OUString sTemp;
                rValue >>= sTemp;

                // Anf"uhrungszeichen werden verdoppelt
                XubString aRecordable( sTemp );
                sal_uInt16 nPos = 0;
                while ( sal_True )
                {
                    nPos = aRecordable.SearchAndReplace( DEFINE_CONST_UNICODE('"'), DEFINE_CONST_UNICODE("\"\""), nPos );
                    if ( STRING_NOTFOUND == nPos )
                        break;
                    nPos += 2;
                }

                // nicht druckbare Zeichen werden als chr$(...) geschrieben
                bool bPrevReplaced = sal_False;
                for ( sal_uInt16 n = 0; n < aRecordable.Len(); ++n )
                {
                    sal_Unicode cChar = aRecordable.GetChar(n);
                    if ( !( cChar>=32 && cChar!=127 ) ) // ALS ERSATZ FUER String::IsPrintable()!
                    {
                        XubString aReplacement( DEFINE_CONST_UNICODE("+chr$(") );
                        aReplacement += cChar;

                        if ( bPrevReplaced )
                        {
                            aRecordable.Insert( aReplacement, n - 2 );
                            n = n + aReplacement.Len();
                            aRecordable.SetChar((unsigned short) (n-2), 0x0029);// ')' = 29h
                            aRecordable.Replace( n-1, 2, DEFINE_CONST_UNICODE("+\"") );
                            // ++n;
                        }
                        else
                        {
                            aReplacement += DEFINE_CONST_UNICODE(")+\"");
                            aRecordable.SetChar(n, 0x0022 );// '"' = 22h
                            aRecordable.Insert( aReplacement, n + 1 );
                            n = n + aReplacement.Len();
                        }
                        bPrevReplaced = sal_True;
                    }
                    else
                        bPrevReplaced = sal_False;

                    // Argument in Anf"uhrungszeichen
                    aArg = '"';
                    aArg += aRecordable;
                    aArg += '"';
                }
/*
				case SbxBYTE:
				{
					// als Zahl darstellen
					aArg = (sal_uInt16) rVar.GetByte();
					break;
				}
*/
			}
            else
            {
                OSL_ENSURE(
                    pType == ::getVoidCppuType(), "Unknown Type in recorder!" );
            }

			// den Parameter anh"angen
			aStatement += aArg;
			aStatement += DEFINE_CONST_UNICODE(", ");
		}

	// Statement beeden
    if ( aArgs.getLength() )
		aStatement.Erase( aStatement.Len() - 2, 1 );
	else
		aStatement.Erase( aStatement.Len() - 1, 1 );
	if ( rSlot.IsMode(SFX_SLOT_METHOD) )
		aStatement += ')';

	if ( !bRequestDone )
		// nicht als "Done()" gekennzeichnete Statements auskommentieren
		aStatement.InsertAscii( "rem ", 0 );
}

//--------------------------------------------------------------------

SfxMacro::SfxMacro
(
	SfxMacroMode 	eMode		// Zweck der Instanz, siehe <SfxMacroMode>
)

/*	[Beschreibung]

	Konstruktor der Klasse SfxMacro. Instanzen dieser Klasse werden im
	SFx zu zwei Zwecken ben"otigt:

	1. zum Aufzeichnen von Makros
	In diesem Fall wird der Konstruktor mit SFX_MACRO_RECORDINGABSOLUTE
	oder SFX_MACRO_RECORDINGRELATIVE aufgerufen. Es sollte sich um eine
	Instanz einer abgeleiteten Klasse handeln, um in der Ableitung
	die Information dar"uber unterzubringen, wo das Makro gespeichert
	werden soll. Ein solches Makro solle sich dann in seinem Destruktor
	an der vom Benutzer gew"ahlten Stelle speichern.

	2. zum Zuordnen von exisitierenden Makros
	In diesem Fall wird der Konstruktor mit SFX_MACRO_EXISTING aufgerufen.
	Eine solche Instanz wird z.B. ben"otigt, wenn Makros auf Events
	oder <SfxControllerItem>s konfiguriert werden sollen.
*/

:	pImp( new SfxMacro_Impl )

{
	pImp->eMode = eMode;
}

//--------------------------------------------------------------------

SfxMacro::~SfxMacro()

/*	[Beschreibung]

	Virtueller Destruktor der Klasse SfxMacro. Dieser sollte in den
	abgeleiteten Klassen "uberladen werden, um in den Modi
	SFX_MACRO_RECORDINGABSOLUTE und SFX_MACRO_RECORDINGRELATIVE den
	aufgezeichneten Source abzuspeichern.


	[Querverweise]

	<SfxMacro::GenerateSource()const>
*/

{
#if OSL_DEBUG_LEVEL > 1
    SvFileStream aStream( String::CreateFromAscii("file:///f:/testmacro.bas" ), STREAM_STD_READWRITE | STREAM_TRUNC );
    aStream << ByteString( GenerateSource(), RTL_TEXTENCODING_UTF8 ).GetBuffer();
#endif
	delete pImp;
}

//--------------------------------------------------------------------

SfxMacroMode SfxMacro::GetMode() const

/*	[Beschreibung]

	Liefert den Modus, der besagt zu welchem Zweck das SfxMacro konstruiert
	wurde.


	[Querverweise]

	enum <SfxMacroMode>
*/

{
	return pImp->eMode;
}

//--------------------------------------------------------------------

void SfxMacro::Record
(
	SfxMacroStatement*	pStatement 	// aufzuzeichnendes <SfxMacroStatement>
)

/*	[Beschreibung]

	Diese Methode zeichnet das als Parameter "ubergeben Statement auf.
	Die Instanz auf die der "ubergebe Pointer zeigt, geht in das Eigentum
	des SfxMacro "uber.

	Der Aufruf ist nur g"ultig, wenn es sich um ein SfxMacro handelt,
	welches mit SFX_MACRO_RECORDINGABSOLUTE oder SFX_MACRO_RECORDINGRELATIVE
	konstruiert wirde.


	[Querverweise]

	<SfxMacro::Replace(SfxMacroStatement*)>
	<SfxMacro::Remove()>
	<SfxMacro::GetLastStatement()const>
*/

{
    DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" );
	pImp->aList.C40_INSERT( SfxMacroStatement, pStatement, pImp->aList.Count() );
}

//--------------------------------------------------------------------

void SfxMacro::Replace
(
	SfxMacroStatement*	pStatement	// aufzuzeichnendes <SfxMacroStatement>
)

/*	[Beschreibung]

	Diese Methode zeichnet das als Parameter "ubergeben Statement auf.
	Dabei wird das jeweils zuletzt aufgezeichnete Statement "uberschrieben.
	Die Instanz auf die der "ubergebe Pointer zeigt, geht in das Eigentum
	des SfxMacro "uber.

	Mit dieser Methode ist es m"oglich, Statements zusammenzufassen. Z.B.
	anstelle f"unfmal hintereinander 'CursorLeft()' aufzurufen, k"onnte
	das zu 'CursorLeft(5)' zusammengefa\st werden. Oder anstelle ein Wort
	Buchstabe f"ur Buchstabe aufzubauen, k"onnte dies durch ein einziges
	Statement 'InsertString("Hallo")' ersetzt werden.

	Der Aufruf ist nur g"ultig, wenn es sich um ein SfxMacro handelt,
	welches mit SFX_MACRO_RECORDINGABSOLUTE oder SFX_MACRO_RECORDINGRELATIVE
	konstruiert wurde und bereits ein aufgezeichnetes Statement vorhanden
	ist.


	[Anmerkung]

	Diese Methode wird typischerweise aus den Execute-Methoden der
	<SfxSlot>s von den Applikationsentwicklern gerufen.


	[Querverweise]

	<SfxMacro::Record(SfxMacroStatement*)>
	<SfxMacro::Remove()>
	<SfxMacro::GetLastStatement()const>
*/

{
    DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" );
	DBG_ASSERT( pImp->aList.Count(), "no replaceable statement available" );
	pImp->aList.Remove( pImp->aList.Count() - 1 );
	pImp->aList.C40_INSERT( SfxMacroStatement,pStatement, pImp->aList.Count() );
}

//--------------------------------------------------------------------

void SfxMacro::Remove()

/*	[Beschreibung]

	Diese Methode l"oscht das zuletzt aufgezeichnete <SfxMacroStatement>
	und entfernt es aus dem Macro.

	Mit dieser Methode ist es m"oglich, Statements zusammenzufassen. Z.B.
	anstelle f"unfmal hintereinander 'CursorLeft()' aufzurufen, k"onnte
	das zu 'CursorLeft(5)' zusammengefa\st werden. Oder anstelle ein Wort
	Buchstabe f"ur Buchstabe aufzubauen, k"onnte dies durch ein einziges
	Statement 'InsertString("Hallo")' ersetzt werden.

	Der Aufruf ist nur g"ultig, wenn es sich um ein SfxMacro handelt,
	welches mit SFX_MACRO_RECORDINGABSOLUTE oder SFX_MACRO_RECORDINGRELATIVE
	konstruiert wurde und bereits ein aufgezeichnetes Statement vorhanden
	ist.


	[Anmerkung]

	Diese Methode wird typischerweise aus den Execute-Methoden der
	<SfxSlot>s von den Applikationsentwicklern gerufen.


	[Querverweise]

	<SfxMacro::Replace(SfxMacroStatement*)>
	<SfxMacro::Record(SfxMacroStatement*)>
	<SfxMacro::GetLastStatement()const>
*/

{
    DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" );
	DBG_ASSERT( pImp->aList.Count(), "no replaceable statement available" );
	pImp->aList.Remove( pImp->aList.Count() - 1 );
}

//--------------------------------------------------------------------

const SfxMacroStatement* SfxMacro::GetLastStatement() const

/*  [Beschreibung]

	Mit dieser Methode kann auf das jeweils zuletzt aufgezeichnete Statement
	lesend zugegriffen werden. Zusammen mit der Methode
	<SfxMacro::Replace(SfxMacroStatement*)> ergibt sich dadurch die
	M"oglichkeit, Statements zusammenzufassen.

	Der Aufruf ist nur g"ultig, wenn es sich um ein SfxMacro handelt,
	welches mit SFX_MACRO_RECORDINGABSOLUTE oder SFX_MACRO_RECORDINGRELATIVE
	konstruiert wurde.


	[Querverweise]

	<SfxMacro::Record(SfxMacroStatement*)>
	<SfxMacro::Replace(SfxMacroStatement*)>
*/

{
    DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" );
	if ( pImp->aList.Count() )
		return pImp->aList.GetObject( pImp->aList.Count() - 1 );
	return 0;
}

//--------------------------------------------------------------------

String SfxMacro::GenerateSource() const

/*  [Beschreibung]

	Diese Funktion generiert aus den, seit dem Konstruieren der Instanz
	bis zum Zeitpunkt des Aufrufs dieser Methode aufgezeichneten
	<SfxMacroStatement>s einen BASIC-Sourcecode, der die Statements,
	jedoch nicht den Header ('Sub X') und den Footer ('End Sub') enth"alt.


	[Querverweise]

	<SfxMacro::Record(SfxMacroStatement*)>
	<SfxMacro::Repeat(SfxMacroStatement*)>
*/

{
    DBG_ASSERT( pImp->eMode != SFX_MACRO_EXISTING, "invalid call to non-recording SfxMacro" );
	String aSource;
	for ( sal_uInt16 n = 0; n < pImp->aList.Count(); ++n )
	{
		aSource += pImp->aList.GetObject(n)->GetStatement();
		if ( (n+1) < pImp->aList.Count() )
			aSource += DEFINE_CONST_UNICODE("\n");
	}

	return aSource;
}
