/**************************************************************
 * 
 * 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_sw.hxx"


#include <float.h>
#include <hintids.hxx>
#include <hints.hxx>
#include <fmtfld.hxx>
#include <txtfld.hxx>
#include <frmfmt.hxx>
#include <layfrm.hxx>
#include <cntfrm.hxx>
#include <tabfrm.hxx>
#include <doc.hxx>
#include <docary.hxx>
#include <ndtxt.hxx>
#include <swtable.hxx>
#include <tblsel.hxx>
#include <cellfml.hxx>
#include <calc.hxx>
#include <expfld.hxx>
#include <usrfld.hxx>
#include <flddat.hxx>
#include <cellatr.hxx>
#include <ndindex.hxx>

const sal_Unicode cRelTrenner = ',';
const sal_Unicode cRelKennung = '';		// CTRL-R

const sal_uInt16 cMAXSTACKSIZE = 50;

const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox );
long lcl_GetLongBoxNum( String& rStr );
const SwTableBox* lcl_RelToBox( const SwTable&, const SwTableBox*, const String& );
String lcl_BoxNmToRel( const SwTable&, const SwTableNode&,
						const String& , const String& , sal_Bool );


/*************************************************************************
|*
|*	double SwTableBox::GetValue() const
|*		gebe den Wert dieser Box zurueck. Der Wert ergibt sich aus dem 1.
|*		TextNode. Beginnt dieser mit einer Zahl/Formel, so berechne diese;
|*		oder mit einem Feld, dann hole den Wert.
|*		Alle anderen Bedingungen returnen einen Fehler (oder 0 ?)
|*
|*	Ersterstellung		JP 30. Jun. 93
|*	Letzte Aenderung	JP 30. Jun. 93
|*
|*************************************************************************/

double SwTableBox::GetValue( SwTblCalcPara& rCalcPara ) const
{
	double nRet = 0;

	if( rCalcPara.rCalc.IsCalcError() )
		return nRet;			// schon ein Fehler in der Berechnung

	rCalcPara.rCalc.SetCalcError( CALC_SYNTAX );	// default immer Fehler

	// keine Content Box ?
	if( !pSttNd  )
		return nRet;

	if( rCalcPara.IncStackCnt() )
		return nRet;

	rCalcPara.SetLastTblBox( this );

	// wird eine Rekursion erzeugt ?
	SwTableBox* pBox = (SwTableBox*)this;
	if( rCalcPara.pBoxStk->Seek_Entry( pBox ))
		return nRet;			// steht schon auf dem Stack: FEHLER

	// bei dieser Box nochmal aufsetzen
	rCalcPara.SetLastTblBox( this );

	rCalcPara.pBoxStk->Insert( pBox );		// eintragen
	do {		// Middle-Check-Loop, damit aus dieser gesprungen werden kann
				// hier aufgespannt, damit am Ende der Box-Pointer aus dem
				// Stack ausgetragen wird
		SwDoc* pDoc = GetFrmFmt()->GetDoc();

		const SfxPoolItem* pItem;
		if( SFX_ITEM_SET == GetFrmFmt()->GetItemState(
								RES_BOXATR_FORMULA, sal_False, &pItem ) )
		{
			rCalcPara.rCalc.SetCalcError( CALC_NOERR );	// wieder zuruecksetzen
			if( !((SwTblBoxFormula*)pItem)->IsValid() )
			{
				// dann berechnen
				const SwTable* pTmp = rCalcPara.pTbl;
				rCalcPara.pTbl = &pBox->GetSttNd()->FindTableNode()->GetTable();
				((SwTblBoxFormula*)pItem)->Calc( rCalcPara, nRet );

				if( !rCalcPara.IsStackOverFlow() )
				{
					SwFrmFmt* pFmt = pBox->ClaimFrmFmt();
					SfxItemSet aTmp( pDoc->GetAttrPool(),
										RES_BOXATR_BEGIN,RES_BOXATR_END-1 );
					aTmp.Put( SwTblBoxValue( nRet ) );
					if( SFX_ITEM_SET != pFmt->GetItemState( RES_BOXATR_FORMAT ))
						aTmp.Put( SwTblBoxNumFormat( 0 ));
                    pFmt->SetFmtAttr( aTmp );
				}
				rCalcPara.pTbl = pTmp;
			}
			else
				nRet = GetFrmFmt()->GetTblBoxValue().GetValue();
			break;
		}
		else if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState(
								RES_BOXATR_VALUE, sal_False, &pItem ) )
		{
			rCalcPara.rCalc.SetCalcError( CALC_NOERR );	// wieder zuruecksetzen
			nRet = ((SwTblBoxValue*)pItem)->GetValue();
			break;
		}

		SwTxtNode* pTxtNd = pDoc->GetNodes()[ pSttNd->GetIndex() + 1 ]->GetTxtNode();
		if( !pTxtNd )
			break;

		xub_StrLen nSttPos = 0;
		const String& rTxt = pTxtNd->GetTxt();
		while( nSttPos < rTxt.Len() &&
				( ' ' ==  rTxt.GetChar( nSttPos ) || '\t' ==  rTxt.GetChar( nSttPos ) ) )
			++nSttPos;

		// beginnt an erster Position ein "RechenFeld", dann erfrage den Wert
		// von diesem
        sal_Unicode const Char = rTxt.GetChar(nSttPos);
        if ( nSttPos < rTxt.Len() &&
             ( CH_TXTATR_BREAKWORD == Char || CH_TXTATR_INWORD == Char ) )
        {
            SwTxtFld * const pTxtFld =
                static_cast<SwTxtFld*>( pTxtNd->GetTxtAttrForCharAt( nSttPos, RES_TXTATR_FIELD ) );
            if ( pTxtFld == NULL )
                break;

            rCalcPara.rCalc.SetCalcError( CALC_NOERR );	// wieder zuruecksetzen

            const SwField* pFld = pTxtFld->GetFmtFld().GetField();
            switch ( pFld->GetTyp()->Which() )
            {
            case RES_SETEXPFLD:
                nRet = ( (SwSetExpField*) pFld )->GetValue();
                break;
            case RES_USERFLD:
                nRet = ( (SwUserFieldType*) pFld )->GetValue();
                break;
            case RES_TABLEFLD:
                {
                    SwTblField* pTblFld = (SwTblField*) pFld;
                    if ( !pTblFld->IsValid() )		// ist der Wert gueltig ??
                    {
                        // die richtige Tabelle mitgeben!
                        const SwTable* pTmp = rCalcPara.pTbl;
                        rCalcPara.pTbl = &pTxtNd->FindTableNode()->GetTable();
                        pTblFld->CalcField( rCalcPara );
                        rCalcPara.pTbl = pTmp;
                    }
                    nRet = pTblFld->GetValue();
                }
                break;

            case RES_DATETIMEFLD:
                nRet = ( (SwDateTimeField*) pFld )->GetValue();
                break;

            case RES_JUMPEDITFLD:
                // placeholder does not have valid content
                nRet = 0;
                break;

            default:
                String const value( pFld->ExpandField( true ) );
                nRet = rCalcPara.rCalc.Calculate( value ).GetDouble();
            }
        }
        else if ( nSttPos < rTxt.Len()
                  && Char == CH_TXT_ATR_INPUTFIELDSTART )
        {
            const SwTxtInputFld * pTxtInputFld =
                dynamic_cast< const SwTxtInputFld* >(
                    pTxtNd->GetTxtAttrAt( nSttPos, RES_TXTATR_INPUTFIELD, SwTxtNode::DEFAULT ) );
            if ( pTxtInputFld == NULL )
                break;
            nRet = rCalcPara.rCalc.Calculate( pTxtInputFld->GetFieldContent() ).GetDouble();
        }
		else
		{
			// Ergebnis ist 0 und kein Fehler!
			rCalcPara.rCalc.SetCalcError( CALC_NOERR );	// wieder zuruecksetzen

			double aNum;
			String sTxt( rTxt.Copy( nSttPos ) );
			sal_uInt32 nFmtIndex = GetFrmFmt()->GetTblBoxNumFmt().GetValue();

			SvNumberFormatter* pNumFmtr = pDoc->GetNumberFormatter();

			if( NUMBERFORMAT_TEXT == nFmtIndex )
				nFmtIndex = 0;
			// JP 22.04.98: Bug 49659 - Sonderbehandlung fuer Prozent
			else if( sTxt.Len() &&
					NUMBERFORMAT_PERCENT == pNumFmtr->GetType( nFmtIndex ))
			{
				sal_uInt32 nTmpFmt = 0;
				if( pNumFmtr->IsNumberFormat( sTxt, nTmpFmt, aNum ) &&
					NUMBERFORMAT_NUMBER == pNumFmtr->GetType( nTmpFmt ))
					sTxt += '%';
			}

			if( pNumFmtr->IsNumberFormat( sTxt, nFmtIndex, aNum ))
				nRet = aNum;
		}

// ?? sonst ist das ein Fehler
	} while( sal_False );

	if( !rCalcPara.IsStackOverFlow() )
	{
		rCalcPara.pBoxStk->Remove( pBox );		// raus aus dem Stack
		rCalcPara.DecStackCnt();
	}

	//JP 12.01.99: mit Fehlererkennung, Bug 60794
	if( DBL_MAX == nRet )
		rCalcPara.rCalc.SetCalcError( CALC_SYNTAX );	// Fehler setzen

	return nRet;
}

/*  */

// Struktur, die zum TabelleRechnen benoetigt wird

SwTblCalcPara::SwTblCalcPara( SwCalc& rCalculator, const SwTable& rTable )
	: pLastTblBox( 0 ), nStackCnt( 0 ), nMaxSize( cMAXSTACKSIZE ),
	rCalc( rCalculator ), pTbl( &rTable )
{
	pBoxStk = new SwTableSortBoxes;
}

SwTblCalcPara::~SwTblCalcPara()
{
	delete pBoxStk;
}

sal_Bool SwTblCalcPara::CalcWithStackOverflow()
{
	// falls ein StackUeberlauf erkannt wurde, sollte mit
	// der letzten Box noch mal aufgesetzt werden. Irgend
	// ein Weg sollte dann
	sal_uInt16 nSaveMaxSize = nMaxSize;

	nMaxSize = cMAXSTACKSIZE - 5;
	sal_uInt16 nCnt = 0;
	SwTableBoxes aStackOverFlows;
	do {
		SwTableBox* pBox = (SwTableBox*)pLastTblBox;
		nStackCnt = 0;
		rCalc.SetCalcError( CALC_NOERR );
		aStackOverFlows.C40_INSERT( SwTableBox, pBox, nCnt++ );

		pBoxStk->Remove( pBox );
		pBox->GetValue( *this );
	} while( IsStackOverFlow() );

	nMaxSize = cMAXSTACKSIZE - 3;		// es muss mind. 1 Stufe tiefer gehen!

	// falls Rekursionen erkannt wurden
	nStackCnt = 0;
	rCalc.SetCalcError( CALC_NOERR );
	pBoxStk->Remove( sal_uInt16(0), pBoxStk->Count() );

	while( !rCalc.IsCalcError() && nCnt )
	{
		aStackOverFlows[ --nCnt ]->GetValue( *this );
		if( IsStackOverFlow() && !CalcWithStackOverflow() )
			break;
	}

	nMaxSize = nSaveMaxSize;
	aStackOverFlows.Remove( 0, aStackOverFlows.Count() );
	return !rCalc.IsCalcError();
}

/*  */

SwTableFormula::SwTableFormula( const String& rFormel )
	: sFormel( rFormel )
{
	eNmType = EXTRNL_NAME;
	bValidValue = sal_False;
}

SwTableFormula::~SwTableFormula()
{
}

void SwTableFormula::_MakeFormel( const SwTable& rTbl, String& rNewStr,
					String& rFirstBox, String* pLastBox, void* pPara ) const
{
	SwTblCalcPara* pCalcPara = (SwTblCalcPara*)pPara;
	if( pCalcPara->rCalc.IsCalcError() )		// ist schon Fehler gesetzt ?
		return;

	SwTableBox* pSttBox, *pEndBox = 0;

	rFirstBox.Erase(0,1);		// Kennung fuer Box loeschen
	// ein Bereich in dieser Klammer ?
	if( pLastBox )
	{
		pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));

		// ist das ueberhaupt ein gueltiger Pointer ??
		if( !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox ))
			pEndBox = 0;
		rFirstBox.Erase( 0, pLastBox->Len()+1 );
	}
	pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
	// ist das ueberhaupt ein gueltiger Pointer ??
	if( !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox ))
		pSttBox = 0;

	rNewStr += ' ';
	if( pEndBox && pSttBox )	// Bereich ?
	{
		// hole ueber das Layout alle "selectierten" Boxen und berechne
		// deren Werte
		SwSelBoxes aBoxes;
		GetBoxes( *pSttBox, *pEndBox, aBoxes );

		rNewStr += '(';
        bool bDelim = false;
		for( sal_uInt16 n = 0; n < aBoxes.Count() &&
						   !pCalcPara->rCalc.IsCalcError(); ++n )
		{
			const SwTableBox* pTblBox = aBoxes[n];
            if ( pTblBox->getRowSpan() >= 1 )
            {
                if( bDelim )
    				rNewStr += cListDelim;
                bDelim = true;
			    rNewStr += pCalcPara->rCalc.GetStrResult(
				    		pTblBox->GetValue( *pCalcPara ), sal_False );
            }
		}
		rNewStr += ')';
	}
	else if( pSttBox && !pLastBox )			// nur die StartBox ?
    {
							//JP 12.01.99: und keine EndBox in der Formel!
		// Berechne den Wert der Box
        if ( pSttBox->getRowSpan() >= 1 )
        {
		    rNewStr += pCalcPara->rCalc.GetStrResult(
							pSttBox->GetValue( *pCalcPara ), sal_False );
        }
    }
	else
		pCalcPara->rCalc.SetCalcError( CALC_SYNTAX );	// Fehler setzen
	rNewStr += ' ';
}

void SwTableFormula::RelNmsToBoxNms( const SwTable& rTbl, String& rNewStr,
			String& rFirstBox, String* pLastBox, void* pPara ) const
{
	// relativen Namen zu Box-Namen (externe Darstellung)
	SwNode* pNd = (SwNode*)pPara;
	ASSERT( pNd, "Feld steht in keinem TextNode" );
	const SwTableBox *pRelBox, *pBox = (SwTableBox *)rTbl.GetTblBox(
					pNd->FindTableBoxStartNode()->GetIndex() );

	rNewStr += rFirstBox.Copy(0,1);		// Kennung fuer Box erhalten
	rFirstBox.Erase(0,1);
	if( pLastBox )
	{
		if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) )
			rNewStr += pRelBox->GetName();
		else
			rNewStr.AppendAscii("A1");
		rNewStr += ':';
		rFirstBox.Erase( 0, pLastBox->Len()+1 );
	}

	if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) )
		rNewStr += pRelBox->GetName();
	else
		rNewStr.AppendAscii("A1");

	// Kennung fuer Box erhalten
	rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
}

void SwTableFormula::RelBoxNmsToPtr( const SwTable& rTbl, String& rNewStr,
			String& rFirstBox, String* pLastBox, void* pPara ) const
{
	// relativen Namen zu Box-Pointern (interne Darstellung)
	SwNode* pNd = (SwNode*)pPara;
	ASSERT( pNd, "Feld steht in keinem Node" );
	const SwTableBox *pRelBox, *pBox = (SwTableBox*)rTbl.GetTblBox(
					pNd->FindTableBoxStartNode()->GetIndex() );

	rNewStr += rFirstBox.Copy(0,1);		// Kennung fuer Box erhalten
	rFirstBox.Erase(0,1);
	if( pLastBox )
	{
		if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, *pLastBox )) )
			rNewStr += String::CreateFromInt64( (sal_PtrDiff)pRelBox );
		else
			rNewStr += '0';
		rNewStr += ':';
		rFirstBox.Erase( 0, pLastBox->Len()+1 );
	}

	if( 0 != ( pRelBox = lcl_RelToBox( rTbl, pBox, rFirstBox )) )
		rNewStr += String::CreateFromInt64( (sal_PtrDiff)pRelBox );
	else
		rNewStr += '0';

	// Kennung fuer Box erhalten
	rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
}


void SwTableFormula::BoxNmsToRelNm( const SwTable& rTbl, String& rNewStr,
					String& rFirstBox, String* pLastBox, void* pPara ) const
{
	// Box-Namen (externe Darstellung) zu relativen Namen
	SwNode* pNd = (SwNode*)pPara;
	ASSERT( pNd, "Feld steht in keinem Node" );
	const SwTableNode* pTblNd = pNd->FindTableNode();

	String sRefBoxNm;
	if( &pTblNd->GetTable() == &rTbl )
	{
		const SwTableBox *pBox = rTbl.GetTblBox(
				pNd->FindTableBoxStartNode()->GetIndex() );
		ASSERT( pBox, "Feld steht in keiner Tabelle" );
		sRefBoxNm = pBox->GetName();
	}

	rNewStr += rFirstBox.Copy(0,1);		// Kennung fuer Box erhalten
	rFirstBox.Erase(0,1);
	if( pLastBox )
	{
		rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, *pLastBox,
								eNmType == EXTRNL_NAME );
		rNewStr += ':';
		rFirstBox.Erase( 0, pLastBox->Len()+1 );
	}

	rNewStr += lcl_BoxNmToRel( rTbl, *pTblNd, sRefBoxNm, rFirstBox,
							eNmType == EXTRNL_NAME );

	// Kennung fuer Box erhalten
	rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
}


void SwTableFormula::PtrToBoxNms( const SwTable& rTbl, String& rNewStr,
						String& rFirstBox, String* pLastBox, void* ) const
{
	// ein Bereich in dieser Klammer ?
	SwTableBox* pBox;

	rNewStr += rFirstBox.Copy(0,1);		// Kennung fuer Box erhalten
	rFirstBox.Erase(0,1);
	if( pLastBox )
	{
		pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));

		// ist das ueberhaupt ein gueltiger Pointer ??
		if( rTbl.GetTabSortBoxes().Seek_Entry( pBox ))
			rNewStr += pBox->GetName();
		else
			rNewStr += '?';
		rNewStr += ':';
		rFirstBox.Erase( 0, pLastBox->Len()+1 );
	}

	pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
	// ist das ueberhaupt ein gueltiger Pointer ??
	if( rTbl.GetTabSortBoxes().Seek_Entry( pBox ))
		rNewStr += pBox->GetName();
	else
		rNewStr += '?';

	// Kennung fuer Box erhalten
	rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
}

void SwTableFormula::BoxNmsToPtr( const SwTable& rTbl, String& rNewStr,
						String& rFirstBox, String* pLastBox, void* ) const
{
	// ein Bereich in dieser Klammer ?
	const SwTableBox* pBox;

	rNewStr += rFirstBox.Copy(0,1);		// Kennung fuer Box erhalten
	rFirstBox.Erase(0,1);
	if( pLastBox )
	{
		pBox = rTbl.GetTblBox( *pLastBox );
		rNewStr += String::CreateFromInt64( (sal_PtrDiff)pBox );
		rNewStr += ':';
		rFirstBox.Erase( 0, pLastBox->Len()+1 );
	}

	pBox = rTbl.GetTblBox( rFirstBox );
	rNewStr += String::CreateFromInt64( (sal_PtrDiff)pBox );

	// Kennung fuer Box erhalten
	rNewStr += rFirstBox.GetChar( rFirstBox.Len() - 1 );
}

	// erzeuge die externe (fuer UI) Formel
void SwTableFormula::PtrToBoxNm( const SwTable* pTbl )
{
	const SwNode* pNd = 0;
	FnScanFormel fnFormel = 0;
	switch( eNmType)
	{
	case INTRNL_NAME:
		if( pTbl )
			fnFormel = &SwTableFormula::PtrToBoxNms;
		break;
	case REL_NAME:
		if( pTbl )
		{
			fnFormel = &SwTableFormula::RelNmsToBoxNms;
			pNd = GetNodeOfFormula();
		}
		break;
	case EXTRNL_NAME:
		return;
	}
	sFormel = ScanString( fnFormel, *pTbl, (void*)pNd );
	eNmType = EXTRNL_NAME;
}

	// erzeuge die interne (in CORE) Formel
void SwTableFormula::BoxNmToPtr( const SwTable* pTbl )
{
	const SwNode* pNd = 0;
	FnScanFormel fnFormel = 0;
	switch( eNmType)
	{
	case EXTRNL_NAME:
		if( pTbl )
			fnFormel = &SwTableFormula::BoxNmsToPtr;
		break;
	case REL_NAME:
		if( pTbl )
		{
			fnFormel = &SwTableFormula::RelBoxNmsToPtr;
			pNd = GetNodeOfFormula();
		}
		break;
	case INTRNL_NAME:
		return;
	}
	sFormel = ScanString( fnFormel, *pTbl, (void*)pNd );
	eNmType = INTRNL_NAME;
}

	// erzeuge die relative (fuers Kopieren) Formel
void SwTableFormula::ToRelBoxNm( const SwTable* pTbl )
{
	const SwNode* pNd = 0;
	FnScanFormel fnFormel = 0;
	switch( eNmType)
	{
	case INTRNL_NAME:
	case EXTRNL_NAME:
		if( pTbl )
		{
			fnFormel = &SwTableFormula::BoxNmsToRelNm;
			pNd = GetNodeOfFormula();
		}
		break;
	case REL_NAME:
		return;
	}
	sFormel = ScanString( fnFormel, *pTbl, (void*)pNd );
	eNmType = REL_NAME;
}


String SwTableFormula::ScanString( FnScanFormel fnFormel, const SwTable& rTbl,
									void* pPara ) const
{
	String aStr;
	sal_uInt16 nFml = 0, nStt = 0, nEnd = 0, nTrenner;

	do {
		// falls der Formel ein Name vorangestellt ist, diese Tabelle
		// benutzen !!
		const SwTable* pTbl = &rTbl;

		nStt = sFormel.Search( '<', nFml );
		if( STRING_NOTFOUND != nStt )
		{
			while( STRING_NOTFOUND != nStt &&
				( ' ' == sFormel.GetChar( nStt + 1 ) ||
				  '=' == sFormel.GetChar( nStt + 1 ) ) )
				nStt = sFormel.Search( '<', nStt + 1 );

			if( STRING_NOTFOUND != nStt )
				nEnd = sFormel.Search( '>', nStt+1 );
		}
		if( STRING_NOTFOUND == nStt || STRING_NOTFOUND == nEnd )
		{
			// den Rest setzen und beenden
			aStr.Insert( sFormel, nFml, sFormel.Len() - nFml );
			break;
		}
		aStr.Insert( sFormel, nFml, nStt - nFml );	// Anfang schreiben

		if( fnFormel != NULL )
		{
			// ist ein TabellenName vorangestellt ??
			// JP 16.02.99: SplitMergeBoxNm behandeln den Namen selbst
			// JP 22.02.99: der CAST muss fuer den Linux-Compiler sein
			// JP 28.06.99: rel. BoxName have no preceding tablename!
			if( fnFormel != (FnScanFormel)&SwTableFormula::_SplitMergeBoxNm &&
				1 < sFormel.Len() && cRelKennung != sFormel.GetChar( 1 ) &&
				STRING_NOTFOUND != ( nTrenner = sFormel.Search( '.', nStt ))
				&& nTrenner < nEnd )
			{
				String sTblNm( sFormel.Copy( nStt, nEnd - nStt ));

				// falls im Namen schon die Punkte enthalten sind,
				// treten diese immer paarig auf!!! (A1.1.1 !!)
				if( (sTblNm.GetTokenCount( '.' ) - 1 ) & 1 )
				{
					sTblNm.Erase( nTrenner - nStt );

					// beim Bauen der Formel ist der TabellenName unerwuenscht
					//JP 22.02.99: der CAST muss fuer den Linux-Compiler sein
					if( fnFormel != (FnScanFormel)&SwTableFormula::_MakeFormel )
						aStr += sTblNm;
					nStt = nTrenner;

					sTblNm.Erase( 0, 1 );	// Trenner loeschen
					if( sTblNm != rTbl.GetFrmFmt()->GetName() )
					{
						// dann suchen wir uns mal unsere Tabelle:
						const SwTable* pFnd = FindTable(
												*rTbl.GetFrmFmt()->GetDoc(),
												sTblNm );
						if( pFnd )
							pTbl = pFnd;
						// ??
						ASSERT( pFnd, "Tabelle nicht gefunden, was nun?" );
					}
				}
			}

			String sBox( sFormel.Copy( nStt, nEnd - nStt + 1 ));
			// ein Bereich in dieser Klammer ?
			if( STRING_NOTFOUND != ( nTrenner = sFormel.Search( ':', nStt ))
				&& nTrenner < nEnd )
			{
				// ohne die Anfangsklammer
				String aFirstBox( sFormel.Copy( nStt+1, nTrenner - nStt - 1 ));
				(this->*fnFormel)( *pTbl, aStr, sBox, &aFirstBox, pPara );
			}
			else
				(this->*fnFormel)( *pTbl, aStr, sBox, 0, pPara );
		}

		nFml = nEnd+1;
	} while( sal_True );
	return aStr;
}

const SwTable* SwTableFormula::FindTable( SwDoc& rDoc, const String& rNm ) const
{
	const SwFrmFmts& rTblFmts = *rDoc.GetTblFrmFmts();
	const SwTable* pTmpTbl, *pRet = 0;
	for( sal_uInt16 nFmtCnt = rTblFmts.Count(); nFmtCnt; )
	{
		SwFrmFmt* pFmt = rTblFmts[ --nFmtCnt ];
		// falls wir von Sw3Writer gerufen werden, dann ist dem
		// FormatNamen eine Nummer anhaengig
		SwTableBox* pFBox;
		if( COMPARE_EQUAL == rNm.CompareTo( pFmt->GetName(),
										pFmt->GetName().Search( 0x0a ) ) &&
			0 != ( pTmpTbl = SwTable::FindTable( pFmt ) ) &&
			0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) &&
			pFBox->GetSttNd() &&
			pFBox->GetSttNd()->GetNodes().IsDocNodes() )
		{
			// eine Tabelle im normalen NodesArr
			pRet = pTmpTbl;
			break;
		}
	}
	return pRet;
}

const SwFrm* lcl_GetBoxFrm( const SwTableBox& rBox )
{
	SwNodeIndex aIdx( *rBox.GetSttNd() );
	SwCntntNode* pCNd = aIdx.GetNodes().GoNext( &aIdx );
	ASSERT( pCNd, "Box hat keinen TextNode" );
	Point aPt;		// den im Layout 1. Frame returnen - Tab.Kopfzeile !!
	return pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aPt, NULL, sal_False );
}

long lcl_GetLongBoxNum( String& rStr )
{
	sal_uInt16 nPos;
	long nRet;
	if( STRING_NOTFOUND == ( nPos = rStr.Search( cRelTrenner ) ))
	{
		nRet = rStr.ToInt32();
		rStr.Erase();
	}
	else
	{
		nRet = rStr.Copy( 0, nPos ).ToInt32();
		rStr.Erase( 0, nPos+1 );
	}
	return nRet;
}

const SwTableBox* lcl_RelToBox( const SwTable& rTbl,
									const SwTableBox* pRefBox,
									const String& rGetName )
{
	// hole die Line
	const SwTableBox* pBox = 0;
	String sGetName( rGetName );

	// ist es denn wirklich eine relative Angabe??
	if( cRelKennung == sGetName.GetChar(0) )			// ja, ...
	{
		if( !pRefBox )
			return 0;

		sGetName.Erase( 0, 1 );

		const SwTableLines* pLines = (SwTableLines*)&rTbl.GetTabLines();
		const SwTableBoxes* pBoxes;
		const SwTableLine* pLine;

		// bestimme erst mal die Start-Werte der Box:
		pBox = (SwTableBox*)pRefBox;
		pLine = pBox->GetUpper();
		while( pLine->GetUpper() )
		{
			pBox = pLine->GetUpper();
			pLine = pBox->GetUpper();
		}
		sal_uInt16 nSttBox = pLine->GetTabBoxes().GetPos( pBox );
		sal_uInt16 nSttLine = rTbl.GetTabLines().GetPos( pLine );

		long nBoxOffset = lcl_GetLongBoxNum( sGetName ) + nSttBox;
		long nLineOffset = lcl_GetLongBoxNum( sGetName ) + nSttLine;

		if( nBoxOffset < 0 || nBoxOffset >= USHRT_MAX ||
			nLineOffset < 0 || nLineOffset >= USHRT_MAX )
			return 0;

		if( nLineOffset >= long(pLines->Count()) )
			return 0;

		pLine = (*pLines)[ sal_uInt16(nLineOffset) ];

		// dann suche die Box
		pBoxes = &pLine->GetTabBoxes();
		if( nBoxOffset >= long(pBoxes->Count()) )
			return 0;
		pBox = (*pBoxes)[ sal_uInt16(nBoxOffset) ];

		while( sGetName.Len() )
		{
			nSttBox = SwTable::_GetBoxNum( sGetName );
			pLines = &pBox->GetTabLines();
			if( nSttBox )
				--nSttBox;

			nSttLine = SwTable::_GetBoxNum( sGetName );

			// bestimme die Line
			if( !nSttLine || nSttLine > pLines->Count() )
				break;
			pLine = (*pLines)[ nSttLine-1 ];

			// bestimme die Box
			pBoxes = &pLine->GetTabBoxes();
			if( nSttBox >= pBoxes->Count() )
				break;
			pBox = (*pBoxes)[ nSttBox ];
		}

		if( pBox )
		{
			if( !pBox->GetSttNd() )
				// "herunterfallen lassen" bis zur ersten Box
				while( pBox->GetTabLines().Count() )
					pBox = pBox->GetTabLines()[0]->GetTabBoxes()[0];
		}
	}
	else
	{
		// sonst ist es eine absolute externe Darstellung:
		pBox = rTbl.GetTblBox( sGetName );
	}
	return pBox;
}

String lcl_BoxNmToRel( const SwTable& rTbl, const SwTableNode& rTblNd,
							const String& rRefBoxNm, const String& rGetStr,
							sal_Bool bExtrnlNm )
{
	String sCpy( rRefBoxNm );
	String sTmp( rGetStr );
	if( !bExtrnlNm )
	{
		// in die Externe Darstellung umwandeln.
		SwTableBox* pBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(sTmp.ToInt64()));
		if( !rTbl.GetTabSortBoxes().Seek_Entry( pBox ))
			return '?';
		sTmp = pBox->GetName();
	}

	// sollte die es eine Tabellen uebergreifende Formel sein, dann behalte
	// die externe Darstellung bei:
	if( &rTbl == &rTblNd.GetTable() )
	{
		long nBox = SwTable::_GetBoxNum( sTmp, sal_True );
		nBox -= SwTable::_GetBoxNum( sCpy, sal_True );
		long nLine = SwTable::_GetBoxNum( sTmp );
		nLine -= SwTable::_GetBoxNum( sCpy );

		sCpy = sTmp;		//JP 01.11.95: den Rest aus dem BoxNamen anhaengen

		sTmp = cRelKennung;
		sTmp += String::CreateFromInt32( nBox );
		sTmp += cRelTrenner;
		sTmp += String::CreateFromInt32( nLine );

		if( sCpy.Len() )
		{
			sTmp += cRelTrenner;
			sTmp += sCpy;
		}
	}

	if( sTmp.Len() && '>' == sTmp.GetChar( sTmp.Len() - 1 ))
		sTmp.Erase( sTmp.Len()-1 );

	return sTmp;
}

sal_uInt16 SwTableFormula::GetBoxesOfFormula( const SwTable& rTbl,
										SwSelBoxes& rBoxes )
{
	if( rBoxes.Count() )
		rBoxes.Remove( sal_uInt16(0), rBoxes.Count() );

	BoxNmToPtr( &rTbl );
	ScanString( &SwTableFormula::_GetFmlBoxes, rTbl, &rBoxes );
	return rBoxes.Count();
}

void SwTableFormula::_GetFmlBoxes( const SwTable& rTbl, String& ,
					String& rFirstBox, String* pLastBox, void* pPara ) const
{
	SwSelBoxes* pBoxes = (SwSelBoxes*)pPara;
	SwTableBox* pSttBox, *pEndBox = 0;

	rFirstBox.Erase(0,1);		// Kennung fuer Box loeschen
	// ein Bereich in dieser Klammer ?
	if( pLastBox )
	{
		pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));

		// ist das ueberhaupt ein gueltiger Pointer ??
		if( !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox ))
			pEndBox = 0;
		rFirstBox.Erase( 0, pLastBox->Len()+1 );
	}

	pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
	// ist das ueberhaupt ein gueltiger Pointer ??
	if( !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox ))
		pSttBox = 0;

	if( pEndBox && pSttBox )	// Bereich ?
	{
		// ueber das Layout alle "selectierten" Boxen und berechne
		// deren Werte
		SwSelBoxes aBoxes;
		GetBoxes( *pSttBox, *pEndBox, aBoxes );
		pBoxes->Insert( &aBoxes );
	}
	else if( pSttBox )			// nur die StartBox ?
		pBoxes->Insert( pSttBox );
}

void SwTableFormula::GetBoxes( const SwTableBox& rSttBox,
								const SwTableBox& rEndBox,
								SwSelBoxes& rBoxes ) const
{
	// hole ueber das Layout alle "selektierten" Boxen
	const SwLayoutFrm *pStt, *pEnd;
	const SwFrm* pFrm = lcl_GetBoxFrm( rSttBox );
	pStt = pFrm ? pFrm->GetUpper() : 0;
	pEnd = ( 0 != (pFrm = lcl_GetBoxFrm( rEndBox ))) ? pFrm->GetUpper() : 0;
	if( !pStt || !pEnd )
		return ;			            // no valid selection

    GetTblSel( pStt, pEnd, rBoxes, 0 );

	const SwTable* pTbl = pStt->FindTabFrm()->GetTable();

	// filter die Kopfzeilen-Boxen heraus:
    if( pTbl->GetRowsToRepeat() > 0 )
    {
		do {	// middle-check loop
            const SwTableLine* pLine = rSttBox.GetUpper();
			while( pLine->GetUpper() )
				pLine = pLine->GetUpper()->GetUpper();

            if( pTbl->IsHeadline( *pLine ) )
                break;      // Headline mit im Bereich !

            // vielleicht ist ja Start und Ende vertauscht
			pLine = rEndBox.GetUpper();
			while ( pLine->GetUpper() )
				pLine = pLine->GetUpper()->GetUpper();

            if( pTbl->IsHeadline( *pLine ) )
				break;		// Headline mit im Bereich !

			const SwTabFrm *pTable = pStt->FindTabFrm();
			const SwTabFrm *pEndTable = pEnd->FindTabFrm();

            if( pTable == pEndTable )       // keine gespl. Tabelle
				break;

			// dann mal die Tabellenkoepfe raus:
			for( sal_uInt16 n = 0; n < rBoxes.Count(); ++n )
			{
                pLine = rBoxes[n]->GetUpper();
				while( pLine->GetUpper() )
					pLine = pLine->GetUpper()->GetUpper();

                if( pTbl->IsHeadline( *pLine ) )
					rBoxes.Remove( n--, 1 );
			}
		} while( sal_False );
    }
}

	// sind alle Boxen gueltig, auf die sich die Formel bezieht?
void SwTableFormula::_HasValidBoxes( const SwTable& rTbl, String& ,
					String& rFirstBox, String* pLastBox, void* pPara ) const
{
	sal_Bool* pBValid = (sal_Bool*)pPara;
	if( *pBValid )		// einmal falsch, immer falsch
	{
		SwTableBox* pSttBox = 0, *pEndBox = 0;
		rFirstBox.Erase(0,1);		// Kennung fuer Box loeschen

		// ein Bereich in dieser Klammer ?
		if( pLastBox )
			rFirstBox.Erase( 0, pLastBox->Len()+1 );

		switch( eNmType)
		{
		case INTRNL_NAME:
			if( pLastBox )
				pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));
			pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
			break;

		case REL_NAME:
			{
				const SwNode* pNd = GetNodeOfFormula();
				const SwTableBox* pBox = !pNd ? 0
											   : (SwTableBox *)rTbl.GetTblBox(
									pNd->FindTableBoxStartNode()->GetIndex() );
				if( pLastBox )
					pEndBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, *pLastBox );
				pSttBox = (SwTableBox*)lcl_RelToBox( rTbl, pBox, rFirstBox );
			}
			break;

		case EXTRNL_NAME:
			if( pLastBox )
				pEndBox = (SwTableBox*)rTbl.GetTblBox( *pLastBox );
			pSttBox = (SwTableBox*)rTbl.GetTblBox( rFirstBox );
			break;
		}

		// sind das gueltige Pointer ?
		if( ( pLastBox &&
			  ( !pEndBox || !rTbl.GetTabSortBoxes().Seek_Entry( pEndBox ) ) ) ||
			( !pSttBox || !rTbl.GetTabSortBoxes().Seek_Entry( pSttBox ) ) )
				*pBValid = sal_False;
	}
}

sal_Bool SwTableFormula::HasValidBoxes() const
{
	sal_Bool bRet = sal_True;
	const SwNode* pNd = GetNodeOfFormula();
	if( pNd && 0 != ( pNd = pNd->FindTableNode() ) )
		ScanString( &SwTableFormula::_HasValidBoxes,
						((SwTableNode*)pNd)->GetTable(), &bRet );
	return bRet;
}


sal_uInt16 SwTableFormula::GetLnPosInTbl( const SwTable& rTbl, const SwTableBox* pBox )
{
	sal_uInt16 nRet = USHRT_MAX;
	if( pBox )
	{
		const SwTableLine* pLn = pBox->GetUpper();
		while( pLn->GetUpper() )
			pLn = pLn->GetUpper()->GetUpper();
		nRet = rTbl.GetTabLines().GetPos( pLn );
	}
	return nRet;
}

void SwTableFormula::_SplitMergeBoxNm( const SwTable& rTbl, String& rNewStr,
					String& rFirstBox, String* pLastBox, void* pPara ) const
{
	SwTableFmlUpdate& rTblUpd = *(SwTableFmlUpdate*)pPara;

	rNewStr += rFirstBox.Copy(0,1);		// Kennung fuer Box erhalten
	rFirstBox.Erase(0,1);

	String sTblNm;
	const SwTable* pTbl = &rTbl;

	String* pTblNmBox = pLastBox ? pLastBox : &rFirstBox;

	sal_uInt16 nLastBoxLen = pTblNmBox->Len();
	sal_uInt16 nTrenner = pTblNmBox->Search( '.' );
	if( STRING_NOTFOUND != nTrenner &&
		// falls im Namen schon die Punkte enthalten sind,
		// treten diese immer paarig auf!!! (A1.1.1 !!)
		(pTblNmBox->GetTokenCount( '.' ) - 1 ) & 1 )
	{
		sTblNm = pTblNmBox->Copy( 0, nTrenner );
		pTblNmBox->Erase( 0, nTrenner + 1);// den Punkt entfernen
		const SwTable* pFnd = FindTable( *rTbl.GetFrmFmt()->GetDoc(), sTblNm );
		if( pFnd )
			pTbl = pFnd;

		if( TBL_MERGETBL == rTblUpd.eFlags )
		{
			if( pFnd )
			{
				if( pFnd == rTblUpd.DATA.pDelTbl )
				{
					if( rTblUpd.pTbl != &rTbl )			// es ist nicht die akt.
						(rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() )
							+= '.';	// den neuen Tabellen Namen setzen
					rTblUpd.bModified = sal_True;
				}
				else if( pFnd != rTblUpd.pTbl ||
					( rTblUpd.pTbl != &rTbl && &rTbl != rTblUpd.DATA.pDelTbl))
					(rNewStr += sTblNm ) += '.';	// den Tabellen Namen behalten
				else
					rTblUpd.bModified = sal_True;
			}
			else
				(rNewStr += sTblNm ) += '.';	// den Tabellen Namen behalten

		}
	}
	if( pTblNmBox == pLastBox )
		rFirstBox.Erase( 0, nLastBoxLen + 1 );

	SwTableBox* pSttBox = 0, *pEndBox = 0;
	switch( eNmType )
	{
	case INTRNL_NAME:
		if( pLastBox )
			pEndBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(pLastBox->ToInt64()));
		pSttBox = reinterpret_cast<SwTableBox*>(sal::static_int_cast<sal_IntPtr>(rFirstBox.ToInt64()));
		break;

	case REL_NAME:
		{
			const SwNode* pNd = GetNodeOfFormula();
			const SwTableBox* pBox = pNd ? pTbl->GetTblBox(
							pNd->FindTableBoxStartNode()->GetIndex() ) : 0;
			if( pLastBox )
				pEndBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, *pLastBox );
			pSttBox = (SwTableBox*)lcl_RelToBox( *pTbl, pBox, rFirstBox );
		}
		break;

	case EXTRNL_NAME:
		if( pLastBox )
			pEndBox = (SwTableBox*)pTbl->GetTblBox( *pLastBox );
		pSttBox = (SwTableBox*)pTbl->GetTblBox( rFirstBox );
		break;
	}

	if( pLastBox && !pTbl->GetTabSortBoxes().Seek_Entry( pEndBox ))
		pEndBox = 0;
	if( !pTbl->GetTabSortBoxes().Seek_Entry( pSttBox ))
		pSttBox = 0;

	if( TBL_SPLITTBL == rTblUpd.eFlags )
	{
		// wo liegen die Boxen, in der "alten" oder in der neuen Tabelle?
		sal_Bool bInNewTbl = sal_False;
		if( pLastBox )
		{
			// das ist die "erste" Box in der Selektion. Die bestimmt ob die
			// Formel in der alten oder neuen Tabelle steht.
			sal_uInt16 nEndLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pEndBox ),
					nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox );

			if( USHRT_MAX != nSttLnPos && USHRT_MAX != nEndLnPos &&
				((rTblUpd.nSplitLine <= nSttLnPos) ==
				(rTblUpd.nSplitLine <= nEndLnPos)) )
			{
				// bleiben in der gleichen Tabelle
				bInNewTbl = rTblUpd.nSplitLine <= nEndLnPos &&
									pTbl == rTblUpd.pTbl;
			}
			else
			{
				// das ist aufjedenfall eine ungueltige Formel, also fuers
				// Undo auf Modified setzen
				rTblUpd.bModified = sal_True;
				if( pEndBox )
					bInNewTbl = USHRT_MAX != nEndLnPos &&
									rTblUpd.nSplitLine <= nEndLnPos &&
									pTbl == rTblUpd.pTbl;
			}
		}
		else
		{
			sal_uInt16 nSttLnPos = SwTableFormula::GetLnPosInTbl( *pTbl, pSttBox );
			// dann landet das Teil in der neuen Tabelle?
			bInNewTbl = USHRT_MAX != nSttLnPos &&
							rTblUpd.nSplitLine <= nSttLnPos &&
							pTbl == rTblUpd.pTbl;
		}

		// wenn die Formel selbst in der neuen Tabellen landet
		if( rTblUpd.bBehindSplitLine )
		{
			if( !bInNewTbl )
			{
				rTblUpd.bModified = sal_True;
				( rNewStr += rTblUpd.pTbl->GetFrmFmt()->GetName() ) += '.';
			}
			else if( sTblNm.Len() )
				( rNewStr += sTblNm ) += '.';
		}
		else if( bInNewTbl )
		{
			rTblUpd.bModified = sal_True;
			( rNewStr += *rTblUpd.DATA.pNewTblNm ) += '.';
		}
		else if( sTblNm.Len() )
			( rNewStr += sTblNm ) += '.';
	}

	if( pLastBox )
		( rNewStr += String::CreateFromInt64((sal_PtrDiff)pEndBox)) += ':';
	( rNewStr += String::CreateFromInt64((sal_PtrDiff)pSttBox))
			  += rFirstBox.GetChar( rFirstBox.Len() - 1 );
}

	// erzeuge die externe Formel, beachte aber das die Formel
	// in einer gesplitteten/gemergten Tabelle landet
void SwTableFormula::ToSplitMergeBoxNm( SwTableFmlUpdate& rTblUpd )
{
	const SwTable* pTbl;
	const SwNode* pNd = GetNodeOfFormula();
	if( pNd && 0 != ( pNd = pNd->FindTableNode() ))
		pTbl = &((SwTableNode*)pNd)->GetTable();
	else
		pTbl = rTblUpd.pTbl;

	sFormel = ScanString( &SwTableFormula::_SplitMergeBoxNm, *pTbl, (void*)&rTblUpd );
	eNmType = INTRNL_NAME;
}


