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

// System - Includes -----------------------------------------------------

class StarBASIC;



#ifndef PCH
#include "sc.hrc"
#define GLOBALOVERFLOW
#endif

// INCLUDE ---------------------------------------------------------------

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <osl/endian.h>
#include <i18npool/mslangid.hxx>
#include <tools/list.hxx>
#include <tools/string.hxx>
#include <rtl/math.hxx>
#include <svtools/htmlout.hxx>
#include <svl/zforlist.hxx>
#define _SVSTDARR_ULONGS
#include <svl/svstdarr.hxx>
#include <sot/formats.hxx>
#include <sfx2/mieclip.hxx>
#include <unotools/charclass.hxx>
#include <unotools/collatorwrapper.hxx>
#include <unotools/calendarwrapper.hxx>
#include <com/sun/star/i18n/CalendarFieldIndex.hpp>
#include <unotools/transliterationwrapper.hxx>

#include "global.hxx"
#include "scerrors.hxx"
#include "docsh.hxx"
#include "undoblk.hxx"
#include "rangenam.hxx"
#include "viewdata.hxx"
#include "tabvwsh.hxx"
#include "filter.hxx"
#include "asciiopt.hxx"
#include "cell.hxx"
#include "docoptio.hxx"
#include "progress.hxx"
#include "scitems.hxx"
#include "editable.hxx"
#include "compiler.hxx"
#include "warnbox.hxx"

#include "impex.hxx"

// ause
#include "editutil.hxx"

#include "globstr.hrc"
#include <vcl/msgbox.hxx>
#include <vcl/svapp.hxx>
#include <osl/module.hxx>

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

namespace
{
    const String SYLK_LF = String::CreateFromAscii("\x1b :");
    const String DOUBLE_SEMICOLON = String::CreateFromAscii(";;");
    const String DOUBLE_DOUBLEQUOTE = String::CreateFromAscii("\"\"");
}

enum SylkVersion
{
    SYLK_SCALC3,    // Wrote wrongly quoted strings and unescaped semicolons.
    SYLK_OOO32,     // Correct strings, plus multiline content.
    SYLK_OWN,       // Place our new versions, if any, before this value.
    SYLK_OTHER      // Assume that aliens wrote correct strings.
};


// Gesamtdokument ohne Undo


ScImportExport::ScImportExport( ScDocument* p )
    : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
      nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ), 
      bFormulas( sal_False ), bIncludeFiltered( sal_True ),
      bAll( sal_True ), bSingle( sal_True ), bUndo( sal_False ),
      bOverflow( sal_False ), mbApi( true ), mExportTextOptions()
{
	pUndoDoc = NULL;
	pExtOptions = NULL;
}

// Insert am Punkt ohne Bereichschecks


ScImportExport::ScImportExport( ScDocument* p, const ScAddress& rPt )
    : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
	  aRange( rPt ),
      nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ), 
      bFormulas( sal_False ), bIncludeFiltered( sal_True ),
      bAll( sal_False ), bSingle( sal_True ), bUndo( sal_Bool( pDocSh != NULL ) ),
      bOverflow( sal_False ), mbApi( true ), mExportTextOptions()
{
	pUndoDoc = NULL;
	pExtOptions = NULL;
}


//	ctor with a range is only used for export
//!	ctor with a string (and bSingle=sal_True) is also used for DdeSetData

ScImportExport::ScImportExport( ScDocument* p, const ScRange& r )
    : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
	  aRange( r ),
      nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
      bFormulas( sal_False ), bIncludeFiltered( sal_True ),
      bAll( sal_False ), bSingle( sal_False ), bUndo( sal_Bool( pDocSh != NULL ) ),
      bOverflow( sal_False ), mbApi( true ), mExportTextOptions()
{
	pUndoDoc = NULL;
	pExtOptions = NULL;
	// Zur Zeit nur in einer Tabelle!
	aRange.aEnd.SetTab( aRange.aStart.Tab() );
}

// String auswerten: Entweder Bereich, Punkt oder Gesamtdoc (bei Fehler)
// Falls eine View existiert, wird die TabNo der View entnommen!


ScImportExport::ScImportExport( ScDocument* p, const String& rPos )
    : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
      nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
      bFormulas( sal_False ), bIncludeFiltered( sal_True ),
      bAll( sal_False ), bSingle( sal_True ), bUndo( sal_Bool( pDocSh != NULL ) ),
      bOverflow( sal_False ), mbApi( true ), mExportTextOptions()
{
	pUndoDoc = NULL;
	pExtOptions = NULL;

	SCTAB nTab = ScDocShell::GetCurTab();
	aRange.aStart.SetTab( nTab );
	String aPos( rPos );
	//  Benannter Bereich?
	ScRangeName* pRange = pDoc->GetRangeName();
	if( pRange )
	{
		sal_uInt16 nPos;
		if( pRange->SearchName( aPos, nPos ) )
		{
			ScRangeData* pData = (*pRange)[ nPos ];
			if( pData->HasType( RT_REFAREA )
				|| pData->HasType( RT_ABSAREA )
				|| pData->HasType( RT_ABSPOS ) )
				pData->GetSymbol( aPos );					// mit dem Inhalt weitertesten
		}
	}
    formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
	// Bereich?
	if( aRange.Parse( aPos, pDoc, eConv ) & SCA_VALID )
		bSingle = sal_False;
	// Zelle?
	else if( aRange.aStart.Parse( aPos, pDoc, eConv ) & SCA_VALID )
		aRange.aEnd = aRange.aStart;
	else
		bAll = sal_True;
}


ScImportExport::~ScImportExport()
{
	delete pUndoDoc;
	delete pExtOptions;
}


void ScImportExport::SetExtOptions( const ScAsciiOptions& rOpt )
{
	if ( pExtOptions )
		*pExtOptions = rOpt;
	else
		pExtOptions = new ScAsciiOptions( rOpt );

	//	"normale" Optionen uebernehmen

	cSep = rOpt.GetFieldSeps().GetChar(0);
	cStr = rOpt.GetTextSep();
}


sal_Bool ScImportExport::IsFormatSupported( sal_uLong nFormat )
{
	return sal_Bool( nFormat == FORMAT_STRING
			  || nFormat == SOT_FORMATSTR_ID_SYLK
			  || nFormat == SOT_FORMATSTR_ID_LINK
			  || nFormat == SOT_FORMATSTR_ID_HTML
			  || nFormat == SOT_FORMATSTR_ID_HTML_SIMPLE
			  || nFormat == SOT_FORMATSTR_ID_DIF );
}


//////////////////////////////////////////////////////////////////////////////

// Vorbereitung fuer Undo: Undo-Dokument erzeugen


sal_Bool ScImportExport::StartPaste()
{
	if ( !bAll )
	{
		ScEditableTester aTester( pDoc, aRange );
		if ( !aTester.IsEditable() )
		{
			InfoBox aInfoBox(Application::GetDefDialogParent(),
								ScGlobal::GetRscString( aTester.GetMessageId() ) );
			aInfoBox.Execute();
			return sal_False;
		}
	}
	if( bUndo && pDocSh && pDoc->IsUndoEnabled())
	{
		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
		pUndoDoc->InitUndo( pDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() );
        pDoc->CopyToDocument( aRange, IDF_ALL | IDF_NOCAPTIONS, sal_False, pUndoDoc );
	}
	return sal_True;
}

// Nachbereitung Insert: Undo/Redo-Aktionen erzeugen, Invalidate/Repaint


void ScImportExport::EndPaste()
{
	sal_Bool bHeight = pDocSh && pDocSh->AdjustRowHeight(
					aRange.aStart.Row(), aRange.aEnd.Row(), aRange.aStart.Tab() );

	if( pUndoDoc && pDoc->IsUndoEnabled() )
	{
		ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
		pRedoDoc->InitUndo( pDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() );
        pDoc->CopyToDocument( aRange, IDF_ALL | IDF_NOCAPTIONS, sal_False, pRedoDoc );
		ScMarkData aDestMark;
		aDestMark.SelectOneTable( aRange.aStart.Tab() );
		pDocSh->GetUndoManager()->AddUndoAction(
			new ScUndoPaste( pDocSh,
				aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(),
				aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(), aDestMark,
                pUndoDoc, pRedoDoc, IDF_ALL, NULL,NULL,NULL,NULL ) );
	}
	pUndoDoc = NULL;
	if( pDocSh )
	{
		if (!bHeight)
			pDocSh->PostPaint( aRange, PAINT_GRID );	// AdjustRowHeight paintet evtl. selber
		pDocSh->SetDocumentModified();
	}
	ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
	if ( pViewSh )
		pViewSh->UpdateInputHandler();

}

/////////////////////////////////////////////////////////////////////////////


#if 0
sal_Bool ScImportExport::ImportData( SvData& rData )
{
	sal_uLong nFmt = rData.GetFormat();
	if ( nFmt == SOT_FORMATSTR_ID_HTML_SIMPLE )
	{
		MSE40HTMLClipFormatObj aMSE40ClpObj;
		if ( aMSE40ClpObj.GetData( rData ) )
		{
			SvStream* pStream = aMSE40ClpObj.GetStream();
			return ImportStream( *pStream, nFmt );
		}
		return sal_False;
	}
	else
	{
		void* pMem;
		sal_uLong nSize = rData.GetMinMemorySize();
		rData.GetData( &pMem, TRANSFER_REFERENCE );
		if( nFmt == FORMAT_STRING
	 			|| nFmt == FORMAT_RTF
	 			|| nFmt == SOT_FORMATSTR_ID_SYLK
	 			|| nFmt == SOT_FORMATSTR_ID_HTML
	 			|| nFmt == SOT_FORMATSTR_ID_DIF )
		{
			//!	String? Unicode??

			// Stringende ermitteln!
			sal_Char* pBegin = (sal_Char*) pMem;
			sal_Char* pEnd   = (sal_Char*) pMem + nSize;

			nSize = 0;
			while( pBegin != pEnd && *pBegin != '\0' )
				pBegin++, nSize++;
			// #72909# MT says only STRING has to be zero-terminated
			DBG_ASSERT( pBegin != pEnd || nFmt != FORMAT_STRING, "non zero-terminated String" )
		}
		SvMemoryStream aStrm( pMem, nSize, STREAM_READ );
		return ImportStream( aStrm, nFmt );
	}
}

#endif

sal_Bool ScImportExport::ImportData( const String& /* rMimeType */,
                     const ::com::sun::star::uno::Any & /* rValue */ )
{
	DBG_ASSERT( !this, "Implementation is missing" );
	return sal_False;
}

sal_Bool ScImportExport::ExportData( const String& rMimeType,
								 ::com::sun::star::uno::Any & rValue )
{
	SvMemoryStream aStrm;
    // mba: no BaseURL for data exchange
    if( ExportStream( aStrm, String(),
				SotExchange::GetFormatIdFromMimeType( rMimeType ) ))
	{
		aStrm << (sal_uInt8) 0;
		rValue <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
										(sal_Int8*)aStrm.GetData(),
										aStrm.Seek( STREAM_SEEK_TO_END ) );
		return sal_True;
	}
	return sal_False;
}


sal_Bool ScImportExport::ImportString( const ::rtl::OUString& rText, sal_uLong nFmt )
{
	switch ( nFmt )
	{
		// formats supporting unicode
		case FORMAT_STRING :
		{
            ScImportStringStream aStrm( rText);
            return ImportStream( aStrm, String(), nFmt );
			// ImportStream must handle RTL_TEXTENCODING_UNICODE
		}
        //break;
		default:
		{
			rtl_TextEncoding eEnc = gsl_getSystemTextEncoding();
            ::rtl::OString aTmp( rText.getStr(), rText.getLength(), eEnc );
            SvMemoryStream aStrm( (void*)aTmp.getStr(), aTmp.getLength() * sizeof(sal_Char), STREAM_READ );
			aStrm.SetStreamCharSet( eEnc );
			SetNoEndianSwap( aStrm );		//! no swapping in memory
            return ImportStream( aStrm, String(), nFmt );
		}
	}
}


sal_Bool ScImportExport::ExportString( ::rtl::OUString& rText, sal_uLong nFmt )
{
	DBG_ASSERT( nFmt == FORMAT_STRING, "ScImportExport::ExportString: Unicode not supported for other formats than FORMAT_STRING" );
	if ( nFmt != FORMAT_STRING )
	{
		rtl_TextEncoding eEnc = gsl_getSystemTextEncoding();
		ByteString aTmp;
		sal_Bool bOk = ExportByteString( aTmp, eEnc, nFmt );
		rText = UniString( aTmp, eEnc );
		return bOk;
	}
	//	nSizeLimit not needed for OUString

	SvMemoryStream aStrm;
	aStrm.SetStreamCharSet( RTL_TEXTENCODING_UNICODE );
	SetNoEndianSwap( aStrm );		//! no swapping in memory
    // mba: no BaseURL for data exc
    if( ExportStream( aStrm, String(), nFmt ) )
	{
		aStrm << (sal_Unicode) 0;
		aStrm.Seek( STREAM_SEEK_TO_END );

		rText = rtl::OUString( (const sal_Unicode*) aStrm.GetData() );
		return sal_True;
	}
	rText = rtl::OUString();
	return sal_False;

	// ExportStream must handle RTL_TEXTENCODING_UNICODE
}


sal_Bool ScImportExport::ExportByteString( ByteString& rText, rtl_TextEncoding eEnc, sal_uLong nFmt )
{
	DBG_ASSERT( eEnc != RTL_TEXTENCODING_UNICODE, "ScImportExport::ExportByteString: Unicode not supported" );
	if ( eEnc == RTL_TEXTENCODING_UNICODE )
		eEnc = gsl_getSystemTextEncoding();

	if (!nSizeLimit)
		nSizeLimit = STRING_MAXLEN;

	SvMemoryStream aStrm;
	aStrm.SetStreamCharSet( eEnc );
	SetNoEndianSwap( aStrm );		//! no swapping in memory
    // mba: no BaseURL for data exchange
    if( ExportStream( aStrm, String(), nFmt ) )
	{
		aStrm << (sal_Char) 0;
		aStrm.Seek( STREAM_SEEK_TO_END );
		// Sicherheits-Check:
		if( aStrm.Tell() <= (sal_uLong) STRING_MAXLEN )
		{
			rText = (const sal_Char*) aStrm.GetData();
			return sal_True;
		}
	}
	rText.Erase();
	return sal_False;
}


sal_Bool ScImportExport::ImportStream( SvStream& rStrm, const String& rBaseURL, sal_uLong nFmt )
{
	if( nFmt == FORMAT_STRING )
	{
		if( ExtText2Doc( rStrm ) )		// pExtOptions auswerten
			return sal_True;
	}
	if( nFmt == SOT_FORMATSTR_ID_SYLK )
	{
		if( Sylk2Doc( rStrm ) )
			return sal_True;
	}
	if( nFmt == SOT_FORMATSTR_ID_DIF )
	{
		if( Dif2Doc( rStrm ) )
			return sal_True;
	}
	if( nFmt == FORMAT_RTF )
	{
        if( RTF2Doc( rStrm, rBaseURL ) )
			return sal_True;
	}
	if( nFmt == SOT_FORMATSTR_ID_LINK )
		return sal_True;			// Link-Import?
	if ( nFmt == SOT_FORMATSTR_ID_HTML )
	{
        if( HTML2Doc( rStrm, rBaseURL ) )
			return sal_True;
	}
	if ( nFmt == SOT_FORMATSTR_ID_HTML_SIMPLE )
	{
		MSE40HTMLClipFormatObj aMSE40ClpObj;				// needed to skip the header data
		SvStream* pHTML = aMSE40ClpObj.IsValid( rStrm );
        if ( pHTML && HTML2Doc( *pHTML, rBaseURL ) )
			return sal_True;
	}

	return sal_False;
}


sal_Bool ScImportExport::ExportStream( SvStream& rStrm, const String& rBaseURL, sal_uLong nFmt )
{
	if( nFmt == FORMAT_STRING )
	{
		if( Doc2Text( rStrm ) )
			return sal_True;
	}
	if( nFmt == SOT_FORMATSTR_ID_SYLK )
	{
		if( Doc2Sylk( rStrm ) )
			return sal_True;
	}
	if( nFmt == SOT_FORMATSTR_ID_DIF )
	{
		if( Doc2Dif( rStrm ) )
			return sal_True;
	}
	if( nFmt == SOT_FORMATSTR_ID_LINK && !bAll )
	{
		String aDocName;
		if ( pDoc->IsClipboard() )
			aDocName = ScGlobal::GetClipDocName();
		else
		{
			SfxObjectShell* pShell = pDoc->GetDocumentShell();
			if (pShell)
				aDocName = pShell->GetTitle( SFX_TITLE_FULLNAME );
		}

		DBG_ASSERT( aDocName.Len(), "ClipBoard document has no name! :-/" );
		if( aDocName.Len() )
		{
			String aRefName;
			sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
			if( bSingle )
				aRange.aStart.Format( aRefName, nFlags, pDoc, pDoc->GetAddressConvention() );
			else
			{
				if( aRange.aStart.Tab() != aRange.aEnd.Tab() )
					nFlags |= SCA_TAB2_3D;
				aRange.Format( aRefName, nFlags, pDoc );
			}
			String aAppName = Application::GetAppName();

			WriteUnicodeOrByteString( rStrm, aAppName, sal_True );
			WriteUnicodeOrByteString( rStrm, aDocName, sal_True );
			WriteUnicodeOrByteString( rStrm, aRefName, sal_True );
			if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
				rStrm << sal_Unicode(0);
			else
				rStrm << sal_Char(0);
			return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
		}
	}
	if( nFmt == SOT_FORMATSTR_ID_HTML )
	{
        if( Doc2HTML( rStrm, rBaseURL ) )
			return sal_True;
	}
	if( nFmt == FORMAT_RTF )
	{
		if( Doc2RTF( rStrm ) )
			return sal_True;
	}

	return sal_False;
}


//static
void ScImportExport::WriteUnicodeOrByteString( SvStream& rStrm, const String& rString, sal_Bool bZero )
{
	rtl_TextEncoding eEnc = rStrm.GetStreamCharSet();
	if ( eEnc == RTL_TEXTENCODING_UNICODE )
	{
		if ( !IsEndianSwap( rStrm ) )
			rStrm.Write( rString.GetBuffer(), rString.Len() * sizeof(sal_Unicode) );
		else
		{
			const sal_Unicode* p = rString.GetBuffer();
			const sal_Unicode* const pStop = p + rString.Len();
			while ( p < pStop )
			{
				rStrm << *p;
			}
		}
		if ( bZero )
			rStrm << sal_Unicode(0);
	}
	else
	{
		ByteString aByteStr( rString, eEnc );
		rStrm << aByteStr.GetBuffer();
		if ( bZero )
			rStrm << sal_Char(0);
	}
}


// This function could be replaced by endlub()
// static
void ScImportExport::WriteUnicodeOrByteEndl( SvStream& rStrm )
{
	if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
	{	// same as endl() but unicode
		switch ( rStrm.GetLineDelimiter() )
		{
			case LINEEND_CR :
				rStrm << sal_Unicode(_CR);
			break;
			case LINEEND_LF :
				rStrm << sal_Unicode(_LF);
			break;
			default:
				rStrm << sal_Unicode(_CR) << sal_Unicode(_LF);
		}
	}
	else
		endl( rStrm );
}


enum DoubledQuoteMode
{
	DQM_KEEP,		// both are taken
	DQM_ESCAPE,		// escaped quote, one is taken, one ignored
	DQM_CONCAT,		// first is end, next is start, both ignored => strings combined
	DQM_SEPARATE	// end one string and begin next
};

static const sal_Unicode* lcl_ScanString( const sal_Unicode* p, String& rString,
			sal_Unicode cStr, DoubledQuoteMode eMode )
{
	p++;	//! jump over opening quote
	sal_Bool bCont;
	do
	{
		bCont = sal_False;
		const sal_Unicode* p0 = p;
		for( ;; )
		{
			if( !*p )
				break;
			if( *p == cStr )
			{
				if ( *++p != cStr )
					break;
				// doubled quote char
				switch ( eMode )
				{
					case DQM_KEEP :
						p++;			// both for us (not breaking for-loop)
					break;
					case DQM_ESCAPE :
						p++;			// one for us (breaking for-loop)
						bCont = sal_True;	// and more
					break;
					case DQM_CONCAT :
						if ( p0+1 < p )
                            rString.Append( p0, sal::static_int_cast<xub_StrLen>( (p-1) - p0 ) );  // first part
						p0 = ++p;		// text of next part starts here
					break;
					case DQM_SEPARATE :
										// positioned on next opening quote
					break;
				}
				if ( eMode == DQM_ESCAPE || eMode == DQM_SEPARATE )
					break;
			}
			else
				p++;
		}
		if ( p0 < p )
            rString.Append( p0, sal::static_int_cast<xub_StrLen>( ((*p || *(p-1) == cStr) ? p-1 : p) - p0 ) );
	} while ( bCont );
	return p;
}

void lcl_UnescapeSylk( String & rString, SylkVersion eVersion )
{
    // Older versions didn't escape the semicolon.
    // Older versions quoted the string and doubled embedded quotes, but not 
    // the semicolons, which was plain wrong.
    if (eVersion >= SYLK_OOO32)
        rString.SearchAndReplaceAll( DOUBLE_SEMICOLON, ';' );
    else
        rString.SearchAndReplaceAll( DOUBLE_DOUBLEQUOTE, '"' );

    rString.SearchAndReplaceAll( SYLK_LF, _LF );
}

static const sal_Unicode* lcl_ScanSylkString( const sal_Unicode* p,
        String& rString, SylkVersion eVersion )
{
    const sal_Unicode* pStartQuote = p;
    const sal_Unicode* pEndQuote = 0;
    while( *(++p) )
    {
        if( *p == '"' )
        {
            pEndQuote = p;
            if (eVersion >= SYLK_OOO32)
            {
                if (*(p+1) == ';')
                {
                    if (*(p+2) == ';')
                    {
                        p += 2;     // escaped ';'
                        pEndQuote = 0;
                    }
                    else
                        break;      // end field
                }
            }
            else
            {
                if (*(p+1) == '"')
                {
                    ++p;            // escaped '"'
                    pEndQuote = 0;
                }
                else if (*(p+1) == ';')
                    break;          // end field
            }
        }
    }
    if (!pEndQuote)
        pEndQuote = p;  // Take all data as string.
    rString.Append( pStartQuote + 1, sal::static_int_cast<xub_StrLen>( pEndQuote - pStartQuote - 1 ) );
    lcl_UnescapeSylk( rString, eVersion);
    return p;
}

static const sal_Unicode* lcl_ScanSylkFormula( const sal_Unicode* p,
        String& rString, SylkVersion eVersion )
{
    const sal_Unicode* pStart = p;
    if (eVersion >= SYLK_OOO32)
    {
        while (*p)
        {
            if (*p == ';')
            {
                if (*(p+1) == ';')
                    ++p;        // escaped ';'
                else
                    break;      // end field
            }
            ++p;
        }
        rString.Append( pStart, sal::static_int_cast<xub_StrLen>( p - pStart));
        lcl_UnescapeSylk( rString, eVersion);
    }
    else
    {
        // Nasty. If in old versions the formula contained a semicolon, it was 
        // quoted and embedded quotes were doubled, but semicolons were not. If 
        // there was no semicolon, it could still contain quotes and doubled 
        // embedded quotes if it was something like ="a""b", which was saved as 
        // E"a""b" as is and has to be preserved, even if older versions 
        // couldn't even load it correctly. However, theoretically another 
        // field might follow and thus the line contain a semicolon again, such 
        // as ...;E"a""b";...
        bool bQuoted = false;
        if (*p == '"')
        {
            // May be a quoted expression or just a string constant expression 
            // with quotes.
            while (*(++p))
            {
                if (*p == '"')
                {
                    if (*(p+1) == '"')
                        ++p;            // escaped '"'
                    else
                        break;          // closing '"', had no ';' yet
                }
                else if (*p == ';')
                {
                    bQuoted = true;     // ';' within quoted expression
                    break;
                }
            }
            p = pStart;
        }
        if (bQuoted)
            p = lcl_ScanSylkString( p, rString, eVersion);
        else
        {
            while (*p && *p != ';')
                ++p;
            rString.Append( pStart, sal::static_int_cast<xub_StrLen>( p - pStart));
        }
    }
    return p;
}

static void lcl_DoubleEscapeChar( String& rString, sal_Unicode cStr )
{
	xub_StrLen n = 0;
	while( ( n = rString.Search( cStr, n ) ) != STRING_NOTFOUND )
	{
		rString.Insert( cStr, n );
		n += 2;
	}
}

static void lcl_WriteString( SvStream& rStrm, String& rString, sal_Unicode cQuote, sal_Unicode cEsc )
{
    if (cEsc)
        lcl_DoubleEscapeChar( rString, cEsc );

    if (cQuote)
    {
        rString.Insert( cQuote, 0 );
        rString.Append( cQuote );
    }

	ScImportExport::WriteUnicodeOrByteString( rStrm, rString );
}

inline void lcl_WriteSimpleString( SvStream& rStrm, const String& rString )
{
	ScImportExport::WriteUnicodeOrByteString( rStrm, rString );
}

//////////////////////////////////////////////////////////////////////////////


sal_Bool ScImportExport::Text2Doc( SvStream& rStrm )
{
	sal_Bool bOk = sal_True;

	SCCOL nStartCol = aRange.aStart.Col();
	SCROW nStartRow = aRange.aStart.Row();
	SCCOL nEndCol = aRange.aEnd.Col();
	SCROW nEndRow = aRange.aEnd.Row();
	sal_uLong  nOldPos = rStrm.Tell();
    rStrm.StartReadingUnicodeText( rStrm.GetStreamCharSet() );
	sal_Bool   bData = sal_Bool( !bSingle );
	if( !bSingle)
		bOk = StartPaste();

	while( bOk )
	{
		ByteString aByteLine;
		String aLine, aCell;
		SCROW nRow = nStartRow;
		rStrm.Seek( nOldPos );
		for( ;; )
		{
			rStrm.ReadUniOrByteStringLine( aLine );
			if( rStrm.IsEof() )
				break;
			SCCOL nCol = nStartCol;
			const sal_Unicode* p = aLine.GetBuffer();
			while( *p )
			{
				aCell.Erase();

				if( *p == cStr )//cStr = " 
				{
					p = lcl_ScanString( p, aCell, cStr, DQM_KEEP );
				}

				const sal_Unicode* q = p;
				while( *p && *p != cSep )// cSep = tab
					p++;
                
                aCell.Append( q, sal::static_int_cast<xub_StrLen>( p - q ) );
                
				if( *p )
					p++;
				if (ValidCol(nCol) && ValidRow(nRow) )
				{
					if( bSingle )
					{
						if (nCol>nEndCol) nEndCol = nCol;
						if (nRow>nEndRow) nEndRow = nRow;
					}
					if( bData && nCol <= nEndCol && nRow <= nEndRow )
						pDoc->SetString( nCol, nRow, aRange.aStart.Tab(), aCell );
				}
				else							// zuviele Spalten/Zeilen
					bOverflow = sal_True;			// beim Import Warnung ausgeben
				++nCol;
			}
			++nRow;
		}

		if( !bData )
		{
			aRange.aEnd.SetCol( nEndCol );
			aRange.aEnd.SetRow( nEndRow );
			bOk = StartPaste();
			bData = sal_True;
		}
		else
			break;
	}

	EndPaste();
	return bOk;
}

		//
		//	erweiterter Ascii-Import
		//


static bool lcl_PutString( 
    ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rStr, sal_uInt8 nColFormat,
    SvNumberFormatter* pFormatter, bool bDetectNumFormat,
    ::utl::TransliterationWrapper& rTransliteration, CalendarWrapper& rCalendar,
    ::utl::TransliterationWrapper* pSecondTransliteration, CalendarWrapper* pSecondCalendar )
{
    bool bMultiLine = false;
	if ( nColFormat == SC_COL_SKIP || !rStr.Len() || !ValidCol(nCol) || !ValidRow(nRow) )
		return bMultiLine;

	if ( nColFormat == SC_COL_TEXT )
	{
		pDoc->PutCell( nCol, nRow, nTab, ScBaseCell::CreateTextCell( rStr, pDoc ) );
		return bMultiLine;
	}

	if ( nColFormat == SC_COL_ENGLISH )
	{
		//!	SetString mit Extra-Flag ???

        SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable();
        sal_uInt32 nEnglish = pDocFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
		double fVal;
        if ( pDocFormatter->IsNumberFormat( rStr, nEnglish, fVal ) )
		{
			//	Zahlformat wird nicht auf englisch gesetzt
			pDoc->SetValue( nCol, nRow, nTab, fVal );
			return bMultiLine;
		}
		//	sonst weiter mit SetString
	}
	else if ( nColFormat != SC_COL_STANDARD )					// Datumsformate
	{
        const sal_uInt16 nMaxNumberParts = 7;   // Y-M-D h:m:s.t
		xub_StrLen nLen = rStr.Len();
		xub_StrLen nStart[nMaxNumberParts];
		xub_StrLen nEnd[nMaxNumberParts];

        sal_uInt16 nDP, nMP, nYP;
        switch ( nColFormat )
        {
            case SC_COL_YMD: nDP = 2; nMP = 1; nYP = 0; break;
            case SC_COL_MDY: nDP = 1; nMP = 0; nYP = 2; break;
            case SC_COL_DMY:
            default:         nDP = 0; nMP = 1; nYP = 2; break;
        }

		sal_uInt16 nFound = 0;
		sal_Bool bInNum = sal_False;
        for ( xub_StrLen nPos=0; nPos<nLen && (bInNum ||
                    nFound<nMaxNumberParts); nPos++ )
		{
            if (bInNum && nFound == 3 && nColFormat == SC_COL_YMD &&
                    nPos <= nStart[nFound]+2 && rStr.GetChar(nPos) == 'T')
                bInNum = sal_False;     // ISO-8601: YYYY-MM-DDThh:mm...
            else if ((((!bInNum && nFound==nMP) || (bInNum && nFound==nMP+1))
                        && ScGlobal::pCharClass->isLetterNumeric( rStr, nPos))
                    || ScGlobal::pCharClass->isDigit( rStr, nPos))
			{
                if (!bInNum)
                {
                    bInNum = sal_True;
                    nStart[nFound] = nPos;
                    ++nFound;
                }
                nEnd[nFound-1] = nPos;
			}
			else
				bInNum = sal_False;
		}

		if ( nFound == 1 )
		{
			//	try to break one number (without separators) into date fields

			xub_StrLen nDateStart = nStart[0];
			xub_StrLen nDateLen = nEnd[0] + 1 - nDateStart;

			if ( nDateLen >= 5 && nDateLen <= 8 &&
					ScGlobal::pCharClass->isNumeric( rStr.Copy( nDateStart, nDateLen ) ) )
			{
				//	6 digits: 2 each for day, month, year
				//	8 digits: 4 for year, 2 each for day and month
				//	5 or 7 digits: first field is shortened by 1

				sal_Bool bLongYear = ( nDateLen >= 7 );
				sal_Bool bShortFirst = ( nDateLen == 5 || nDateLen == 7 );

				sal_uInt16 nFieldStart = nDateStart;
				for (sal_uInt16 nPos=0; nPos<3; nPos++)
				{
					sal_uInt16 nFieldEnd = nFieldStart + 1;		// default: 2 digits
					if ( bLongYear && nPos == nYP )
						nFieldEnd += 2;						// 2 extra digits for long year
					if ( bShortFirst && nPos == 0 )
						--nFieldEnd;						// first field shortened?

					nStart[nPos] = nFieldStart;
					nEnd[nPos]   = nFieldEnd;
					nFieldStart  = nFieldEnd + 1;
				}
				nFound = 3;
			}
		}

		if ( nFound >= 3 )
		{
			using namespace ::com::sun::star;
			sal_Bool bSecondCal = sal_False;
			sal_uInt16 nDay  = (sal_uInt16) rStr.Copy( nStart[nDP], nEnd[nDP]+1-nStart[nDP] ).ToInt32();
			sal_uInt16 nYear = (sal_uInt16) rStr.Copy( nStart[nYP], nEnd[nYP]+1-nStart[nYP] ).ToInt32();
			String aMStr = rStr.Copy( nStart[nMP], nEnd[nMP]+1-nStart[nMP] );
			sal_Int16 nMonth = (sal_Int16) aMStr.ToInt32();
			if (!nMonth)
			{
                static const String aSeptCorrect( RTL_CONSTASCII_USTRINGPARAM( "SEPT" ) );
                static const String aSepShortened( RTL_CONSTASCII_USTRINGPARAM( "SEP" ) );
				uno::Sequence< i18n::CalendarItem > xMonths;
                sal_Int32 i, nMonthCount;
				//	first test all month names from local international
				xMonths = rCalendar.getMonths();
                nMonthCount = xMonths.getLength();
                for (i=0; i<nMonthCount && !nMonth; i++)
				{
                    if ( rTransliteration.isEqual( aMStr, xMonths[i].FullName ) ||
                         rTransliteration.isEqual( aMStr, xMonths[i].AbbrevName ) )
                        nMonth = sal::static_int_cast<sal_Int16>( i+1 );
                    else if ( i == 8 && rTransliteration.isEqual( aSeptCorrect,
                                xMonths[i].AbbrevName ) &&
                            rTransliteration.isEqual( aMStr, aSepShortened ) )
                    {   // #102136# correct English abbreviation is SEPT,
                        // but data mostly contains SEP only
                        nMonth = sal::static_int_cast<sal_Int16>( i+1 );
                    }
				}
				//	if none found, then test english month names
                if ( !nMonth && pSecondCalendar && pSecondTransliteration )
				{
					xMonths = pSecondCalendar->getMonths();
                    nMonthCount = xMonths.getLength();
                    for (i=0; i<nMonthCount && !nMonth; i++)
					{
                        if ( pSecondTransliteration->isEqual( aMStr, xMonths[i].FullName ) ||
                             pSecondTransliteration->isEqual( aMStr, xMonths[i].AbbrevName ) )
						{
                            nMonth = sal::static_int_cast<sal_Int16>( i+1 );
							bSecondCal = sal_True;
						}
                        else if ( i == 8 && pSecondTransliteration->isEqual(
                                    aMStr, aSepShortened ) )
                        {   // #102136# correct English abbreviation is SEPT,
                            // but data mostly contains SEP only
                            nMonth = sal::static_int_cast<sal_Int16>( i+1 );
							bSecondCal = sal_True;
                        }
					}
				}
			}

            SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable();
			if ( nYear < 100 )
                nYear = pDocFormatter->ExpandTwoDigitYear( nYear );

			CalendarWrapper* pCalendar = (bSecondCal ? pSecondCalendar : &rCalendar);
			sal_Int16 nNumMonths = pCalendar->getNumberOfMonthsInYear();
			if ( nDay && nMonth && nDay<=31 && nMonth<=nNumMonths )
			{
				--nMonth;
				pCalendar->setValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, nDay );
				pCalendar->setValue( i18n::CalendarFieldIndex::MONTH, nMonth );
				pCalendar->setValue( i18n::CalendarFieldIndex::YEAR, nYear );
                sal_Int16 nHour, nMinute, nSecond, nMilli;
                // #i14974# The imported value should have no fractional value, so set the
                // time fields to zero (ICU calendar instance defaults to current date/time)
                nHour = nMinute = nSecond = nMilli = 0;
                if (nFound > 3)
                    nHour = (sal_Int16) rStr.Copy( nStart[3], nEnd[3]+1-nStart[3]).ToInt32();
                if (nFound > 4)
                    nMinute = (sal_Int16) rStr.Copy( nStart[4], nEnd[4]+1-nStart[4]).ToInt32();
                if (nFound > 5)
                    nSecond = (sal_Int16) rStr.Copy( nStart[5], nEnd[5]+1-nStart[5]).ToInt32();
                if (nFound > 6)
                {
                    sal_Unicode cDec = '.';
                    rtl::OUString aT( &cDec, 1);
                    aT += rStr.Copy( nStart[6], nEnd[6]+1-nStart[6]);
                    rtl_math_ConversionStatus eStatus;
                    double fV = rtl::math::stringToDouble( aT, cDec, 0, &eStatus, 0);
                    if (eStatus == rtl_math_ConversionStatus_Ok)
                        nMilli = (sal_Int16) (1000.0 * fV + 0.5);
                }
                pCalendar->setValue( i18n::CalendarFieldIndex::HOUR, nHour );
                pCalendar->setValue( i18n::CalendarFieldIndex::MINUTE, nMinute );
                pCalendar->setValue( i18n::CalendarFieldIndex::SECOND, nSecond );
                pCalendar->setValue( i18n::CalendarFieldIndex::MILLISECOND, nMilli );
                if ( pCalendar->isValid() )
                {
                    double fDiff = DateTime(*pDocFormatter->GetNullDate()) -
                        pCalendar->getEpochStart();
                    // #i14974# must use getLocalDateTime to get the same
                    // date values as set above
                    double fDays = pCalendar->getLocalDateTime();
                    fDays -= fDiff;

                    LanguageType eLatin, eCjk, eCtl;
                    pDoc->GetLanguage( eLatin, eCjk, eCtl );
                    LanguageType eDocLang = eLatin;     //! which language for date formats?

                    short nType = (nFound > 3 ? NUMBERFORMAT_DATETIME : NUMBERFORMAT_DATE);
                    sal_uLong nFormat = pDocFormatter->GetStandardFormat( nType, eDocLang );
                    // maybe there is a special format including seconds or milliseconds
                    if (nFound > 5)
                        nFormat = pDocFormatter->GetStandardFormat( fDays, nFormat, nType, eDocLang);

                    pDoc->PutCell( nCol, nRow, nTab, new ScValueCell(fDays), nFormat, sal_False );

                    return bMultiLine;     // success
                }
			}
		}
	}

    // Standard or date not determined -> SetString / EditCell
    if( rStr.Search( _LF ) == STRING_NOTFOUND )
        pDoc->SetString( nCol, nRow, nTab, rStr, pFormatter, bDetectNumFormat );
    else 
    {
        bMultiLine = true;
        pDoc->PutCell( nCol, nRow, nTab, new ScEditCell( rStr, pDoc ) );
    }
    return bMultiLine;
}


String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext, bool& rbIsQuoted )
{
	xub_StrLen nLen = rLine.Len();
	if (nNext > nLen)
		nNext = nLen;
	if ( nNext <= nStart )
		return EMPTY_STRING;

	const sal_Unicode* pStr = rLine.GetBuffer();

	xub_StrLen nSpace = nNext;
	while ( nSpace > nStart && pStr[nSpace-1] == ' ' )
		--nSpace;

    rbIsQuoted = (pStr[nStart] == sal_Unicode('"') && pStr[nSpace-1] == sal_Unicode('"'));
    if (rbIsQuoted)
        return rLine.Copy(nStart+1, nSpace-nStart-2);
    else
        return rLine.Copy(nStart, nSpace-nStart);
}

sal_Bool ScImportExport::ExtText2Doc( SvStream& rStrm )
{
	if (!pExtOptions)
		return Text2Doc( rStrm );

	sal_uLong nOldPos = rStrm.Tell();
	rStrm.Seek( STREAM_SEEK_TO_END );
    ::std::auto_ptr<ScProgress> xProgress( new ScProgress( pDocSh,
            ScGlobal::GetRscString( STR_LOAD_DOC ), rStrm.Tell() - nOldPos ));
	rStrm.Seek( nOldPos );
    rStrm.StartReadingUnicodeText( rStrm.GetStreamCharSet() );

	sal_Bool bOld = ScColumn::bDoubleAlloc;
	ScColumn::bDoubleAlloc = sal_True;

	SCCOL nStartCol = aRange.aStart.Col();
    SCCOL nEndCol = aRange.aEnd.Col();
	SCROW nStartRow = aRange.aStart.Row();
	SCTAB nTab = aRange.aStart.Tab();

	sal_Bool	bFixed			= pExtOptions->IsFixedLen();
	const String& rSeps     = pExtOptions->GetFieldSeps();
	const sal_Unicode* pSeps = rSeps.GetBuffer();
	sal_Bool	bMerge			= pExtOptions->IsMergeSeps();
	sal_uInt16	nInfoCount		= pExtOptions->GetInfoCount();
	const xub_StrLen* pColStart = pExtOptions->GetColStart();
	const sal_uInt8* pColFormat  = pExtOptions->GetColFormat();
	long nSkipLines	= pExtOptions->GetStartRow();

    LanguageType eDocLang = pExtOptions->GetLanguage();
    SvNumberFormatter aNumFormatter(pDoc->GetServiceManager(), eDocLang);
    bool bDetectNumFormat = pExtOptions->IsDetectSpecialNumber();

	// For date recognition
    ::utl::TransliterationWrapper aTransliteration(
        pDoc->GetServiceManager(), SC_TRANSLITERATION_IGNORECASE );
    aTransliteration.loadModuleIfNeeded( eDocLang );
	CalendarWrapper aCalendar( pDoc->GetServiceManager() );
	aCalendar.loadDefaultCalendar(
		MsLangId::convertLanguageToLocale( eDocLang ) );
    ::utl::TransliterationWrapper* pEnglishTransliteration = NULL;
	CalendarWrapper* pEnglishCalendar = NULL;
	if ( eDocLang != LANGUAGE_ENGLISH_US )
	{
        pEnglishTransliteration = new ::utl::TransliterationWrapper (
            pDoc->GetServiceManager(), SC_TRANSLITERATION_IGNORECASE );
        aTransliteration.loadModuleIfNeeded( LANGUAGE_ENGLISH_US );
		pEnglishCalendar = new CalendarWrapper ( pDoc->GetServiceManager() );
		pEnglishCalendar->loadDefaultCalendar(
			MsLangId::convertLanguageToLocale( LANGUAGE_ENGLISH_US ) );
	}

	String aLine, aCell;
	sal_uInt16 i;
	SCROW nRow = nStartRow;

	while(--nSkipLines>0)
	{
		rStrm.ReadCsvLine( aLine, !bFixed, rSeps, cStr); // content is ignored
		if ( rStrm.IsEof() )
			break;
	}

    // Determine range for Undo.
    // TODO: we don't need this during import of a file to a new sheet or
    // document, could set bDetermineRange=false then.
    bool bDetermineRange = true;   

    // Row heights don't need to be adjusted on the fly if EndPaste() is called
    // afterwards, which happens only if bDetermineRange. This variable also
    // survives the toggle of bDetermineRange down at the end of the do{} loop.
    bool bRangeIsDetermined = bDetermineRange;

    bool bQuotedAsText = pExtOptions && pExtOptions->IsQuotedAsText();

    sal_uLong nOriginalStreamPos = rStrm.Tell();
 
    do
    {
        for( ;; )
        {
            rStrm.ReadCsvLine( aLine, !bFixed, rSeps, cStr);
            if ( rStrm.IsEof() )
                break;

            xub_StrLen nLineLen = aLine.Len();
            SCCOL nCol = nStartCol;
            bool bMultiLine = false;
            if ( bFixed )				//	Feste Satzlaenge
            {
                // Yes, the check is nCol<=MAXCOL+1, +1 because it is only an
                // overflow if there is really data following to be put behind
                // the last column, which doesn't happen if info is
                // SC_COL_SKIP.
                for ( i=0; i<nInfoCount && nCol <= MAXCOL+1; i++ )
                {
                    sal_uInt8 nFmt = pColFormat[i];
                    if (nFmt != SC_COL_SKIP)        // sonst auch nCol nicht hochzaehlen
                    {
                        if (nCol > MAXCOL)
                            bOverflow = sal_True;       // display warning on import
                        else if (!bDetermineRange)
                        {
                            xub_StrLen nStart = pColStart[i];
                            xub_StrLen nNext = ( i+1 < nInfoCount ) ? pColStart[i+1] : nLineLen;
                            bool bIsQuoted = false;
                            aCell = lcl_GetFixed( aLine, nStart, nNext, bIsQuoted );
                            if (bIsQuoted && bQuotedAsText)
                                nFmt = SC_COL_TEXT;

                            bMultiLine |= lcl_PutString( 
                                pDoc, nCol, nRow, nTab, aCell, nFmt,
                                &aNumFormatter, bDetectNumFormat, aTransliteration, aCalendar,
                                pEnglishTransliteration, pEnglishCalendar);
                        }
                        ++nCol;
                    }
                }
            }
            else						//	Nach Trennzeichen suchen
            {
                SCCOL nSourceCol = 0;
                sal_uInt16 nInfoStart = 0;
                const sal_Unicode* p = aLine.GetBuffer();
                // Yes, the check is nCol<=MAXCOL+1, +1 because it is only an
                // overflow if there is really data following to be put behind
                // the last column, which doesn't happen if info is
                // SC_COL_SKIP.
                while (*p && nCol <= MAXCOL+1)
                {
                    bool bIsQuoted = false;
                    p = ScImportExport::ScanNextFieldFromString( p, aCell, cStr, pSeps, bMerge, bIsQuoted );

                    sal_uInt8 nFmt = SC_COL_STANDARD;
                    for ( i=nInfoStart; i<nInfoCount; i++ )
                    {
                        if ( pColStart[i] == nSourceCol + 1 )		// pColStart ist 1-basiert
                        {
                            nFmt = pColFormat[i];
                            nInfoStart = i + 1;		// ColInfos sind in Reihenfolge
                            break;	// for
                        }
                    }
                    if ( nFmt != SC_COL_SKIP )
                    {
                        if (nCol > MAXCOL)
                            bOverflow = sal_True;       // display warning on import
                        else if (!bDetermineRange)
                        {
                            if (bIsQuoted && bQuotedAsText)
                                nFmt = SC_COL_TEXT;

                            bMultiLine |= lcl_PutString( 
                                pDoc, nCol, nRow, nTab, aCell, nFmt, 
                                &aNumFormatter, bDetectNumFormat, aTransliteration,
                                aCalendar, pEnglishTransliteration, pEnglishCalendar);
                        }
                        ++nCol;
                    }

                    ++nSourceCol;
                }
            }
            if (nEndCol < nCol)
                nEndCol = nCol;     //! points to the next free or even MAXCOL+2

            if (!bDetermineRange)
            {
                if (bMultiLine && !bRangeIsDetermined && pDocSh)
                    pDocSh->AdjustRowHeight( nRow, nRow, nTab);
                xProgress->SetStateOnPercent( rStrm.Tell() - nOldPos );
            }
            ++nRow;
            if ( nRow > MAXROW )
            {
                bOverflow = sal_True;       // display warning on import
                break;  // for
            }
        }
        // so far nRow/nEndCol pointed to the next free
        if (nRow > nStartRow)
            --nRow;      
        if (nEndCol > nStartCol)
            nEndCol = ::std::min( static_cast<SCCOL>(nEndCol - 1), MAXCOL);      

        if (bDetermineRange)
        {
            aRange.aEnd.SetCol( nEndCol );
            aRange.aEnd.SetRow( nRow );

            if ( !mbApi && nStartCol != nEndCol &&
                 !pDoc->IsBlockEmpty( nTab, nStartCol + 1, nStartRow, nEndCol, nRow ) )
            {
                ScReplaceWarnBox aBox( pDocSh->GetActiveDialogParent() );
                if ( aBox.Execute() != RET_YES )
                {
                    delete pEnglishTransliteration;
                    delete pEnglishCalendar;
                    return sal_False;
                }
            }

            rStrm.Seek( nOriginalStreamPos );
            nRow = nStartRow;
            if (!StartPaste())
            {
                EndPaste();
                return sal_False;
            }
        }

        bDetermineRange = !bDetermineRange;     // toggle
    } while (!bDetermineRange);

	ScColumn::bDoubleAlloc = bOld;
	pDoc->DoColResize( nTab, nStartCol, nEndCol, 0 );

    delete pEnglishTransliteration;
	delete pEnglishCalendar;

    xProgress.reset();    // make room for AdjustRowHeight progress
    if (bRangeIsDetermined)
        EndPaste();

	return sal_True;
}


// static
const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p,
		String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted )
{
    rbIsQuoted = false;
	rField.Erase();
	if ( *p == cStr )			// String in Anfuehrungszeichen
	{
        rbIsQuoted = true;
        const sal_Unicode* p1;
		p1 = p = lcl_ScanString( p, rField, cStr, DQM_ESCAPE );
		while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
			p++;
        // Append remaining unquoted and undelimited data (dirty, dirty) to
        // this field.
        if (p > p1)
            rField.Append( p1, sal::static_int_cast<xub_StrLen>( p - p1 ) );
		if( *p )
			p++;
	}
	else						// bis zum Trennzeichen
	{
		const sal_Unicode* p0 = p;
		while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
			p++;
        rField.Append( p0, sal::static_int_cast<xub_StrLen>( p - p0 ) );
		if( *p )
			p++;
	}
	if ( bMergeSeps ) 			// folgende Trennzeichen ueberspringen
	{
		while ( *p && ScGlobal::UnicodeStrChr( pSeps, *p ) )
			p++;
	}
	return p;
}

		//
		//
		//


sal_Bool ScImportExport::Doc2Text( SvStream& rStrm )
{
	SCCOL nCol;
	SCROW nRow;
	SCCOL nStartCol = aRange.aStart.Col();
	SCROW nStartRow = aRange.aStart.Row();
	SCCOL nEndCol = aRange.aEnd.Col();
	SCROW nEndRow = aRange.aEnd.Row();
	String aCell;
    bool bConvertLF = (GetSystemLineEnd() != LINEEND_LF);

	for (nRow = nStartRow; nRow <= nEndRow; nRow++)
	{
		if (bIncludeFiltered || !pDoc->RowFiltered( nRow, aRange.aStart.Tab() ))
		{
			for (nCol = nStartCol; nCol <= nEndCol; nCol++)
			{
				CellType eType;
				pDoc->GetCellType( nCol, nRow, aRange.aStart.Tab(), eType );
				switch (eType)
				{
					case CELLTYPE_FORMULA:
					{
						if (bFormulas)
						{
							pDoc->GetFormula( nCol, nRow, aRange.aStart.Tab(), aCell, sal_True );
							if( aCell.Search( cSep ) != STRING_NOTFOUND )
								lcl_WriteString( rStrm, aCell, cStr, cStr );
							else
								lcl_WriteSimpleString( rStrm, aCell );
						}
						else
						{
                            pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell );

                            bool bMultiLineText = ( aCell.Search( _LF ) != STRING_NOTFOUND );
                            if( bMultiLineText )
                            {
                                if( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSpace )
                                    aCell.SearchAndReplaceAll( _LF, ' ' );
                                else if ( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSystem && bConvertLF )
                                    aCell.ConvertLineEnd();
                            }

                            if( mExportTextOptions.mcSeparatorConvertTo && cSep )
                                aCell.SearchAndReplaceAll( cSep, mExportTextOptions.mcSeparatorConvertTo );

                            if( mExportTextOptions.mbAddQuotes && ( aCell.Search( cSep ) != STRING_NOTFOUND ) )
                                lcl_WriteString( rStrm, aCell, cStr, cStr );
                            else
                                lcl_WriteSimpleString( rStrm, aCell );
						}
					}
					break;
					case CELLTYPE_VALUE:
					{
						pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell );
						lcl_WriteSimpleString( rStrm, aCell );
					}
					break;
					case CELLTYPE_NOTE:
					case CELLTYPE_NONE:
					break;
					default:
					{
						pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell );

                        bool bMultiLineText = ( aCell.Search( _LF ) != STRING_NOTFOUND );
                        if( bMultiLineText )
                        {
                            if( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSpace )
                                aCell.SearchAndReplaceAll( _LF, ' ' );
                            else if ( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSystem && bConvertLF )
                                aCell.ConvertLineEnd();
                        }

                        if( mExportTextOptions.mcSeparatorConvertTo && cSep )
                            aCell.SearchAndReplaceAll( cSep, mExportTextOptions.mcSeparatorConvertTo );

                        if( mExportTextOptions.mbAddQuotes && ( aCell.Search( cSep ) != STRING_NOTFOUND ) )
                            lcl_WriteString( rStrm, aCell, cStr, cStr );
                        else
                            lcl_WriteSimpleString( rStrm, aCell );
					}
				}
				if( nCol < nEndCol )
					lcl_WriteSimpleString( rStrm, String(cSep) );
			}
//			if( nRow < nEndRow )
				WriteUnicodeOrByteEndl( rStrm );
			if( rStrm.GetError() != SVSTREAM_OK )
				break;
			if( nSizeLimit && rStrm.Tell() > nSizeLimit )
				break;
		}
	}

	return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
}


sal_Bool ScImportExport::Sylk2Doc( SvStream& rStrm )
{
	sal_Bool bOk = sal_True;
	sal_Bool bMyDoc = sal_False;
    SylkVersion eVersion = SYLK_OTHER;

	// US-English separators for StringToDouble
	sal_Unicode cDecSep = '.';
	sal_Unicode cGrpSep = ',';

	SCCOL nStartCol = aRange.aStart.Col();
	SCROW nStartRow = aRange.aStart.Row();
	SCCOL nEndCol = aRange.aEnd.Col();
	SCROW nEndRow = aRange.aEnd.Row();
	sal_uLong nOldPos = rStrm.Tell();
	sal_Bool bData = sal_Bool( !bSingle );
    SvULongs aFormats;

	if( !bSingle)
		bOk = StartPaste();

	while( bOk )
	{
		String aLine;
        String aText;
		ByteString aByteLine;
		SCCOL nCol = nStartCol;
		SCROW nRow = nStartRow;
        SCCOL nRefCol = 1;
        SCROW nRefRow = 1;
		rStrm.Seek( nOldPos );
		for( ;; )
		{
			//!	allow unicode
			rStrm.ReadLine( aByteLine );
			aLine = String( aByteLine, rStrm.GetStreamCharSet() );
			if( rStrm.IsEof() )
				break;
			const sal_Unicode* p = aLine.GetBuffer();
			sal_Unicode cTag = *p++;
            if( cTag == 'C' )       // Content
			{
				if( *p++ != ';' )
					return sal_False;
				while( *p )
				{
					sal_Unicode ch = *p++;
					ch = ScGlobal::ToUpperAlpha( ch );
					switch( ch )
					{
						case 'X':
							nCol = static_cast<SCCOL>(String( p ).ToInt32()) + nStartCol - 1;
							break;
						case 'Y':
							nRow = String( p ).ToInt32() + nStartRow - 1;
							break;
                        case 'C':
                            nRefCol = static_cast<SCCOL>(String( p ).ToInt32()) + nStartCol - 1;
							break;
                        case 'R':
                            nRefRow = String( p ).ToInt32() + nStartRow - 1;
							break;
						case 'K':
                        {
                            if( !bSingle &&
                                    ( nCol < nStartCol || nCol > nEndCol
                                      || nRow < nStartRow || nRow > nEndRow
                                      || nCol > MAXCOL || nRow > MAXROW ) )
								break;
							if( !bData )
							{
								if( nRow > nEndRow )
									nEndRow = nRow;
								if( nCol > nEndCol )
									nEndCol = nCol;
								break;
							}
                            sal_Bool bText;
                            if( *p == '"' )
                            {
                                bText = sal_True;
                                aText.Erase();
                                p = lcl_ScanSylkString( p, aText, eVersion);
                            }
                            else
                                bText = sal_False;
                            const sal_Unicode* q = p;
                            while( *q && *q != ';' )
                                q++;
                            if ( !(*q == ';' && *(q+1) == 'I') )
                            {   // don't ignore value
                                if( bText )
                                {
                                    pDoc->PutCell( nCol, nRow, aRange.aStart.Tab(), 
                                            ScBaseCell::CreateTextCell( aText, pDoc),
                                            (sal_Bool) sal_True);
                                }
                                else
                                {
                                    double fVal = rtl_math_uStringToDouble( p,
                                            aLine.GetBuffer() + aLine.Len(),
                                            cDecSep, cGrpSep, NULL, NULL );
                                    pDoc->SetValue( nCol, nRow, aRange.aStart.Tab(), fVal );
                                }
                            }
                        }
                        break;
						case 'E':
                        case 'M':
                        {
                            if ( ch == 'M' )
                            {
                                if ( nRefCol < nCol )
                                    nRefCol = nCol;
                                if ( nRefRow < nRow )
                                    nRefRow = nRow;
                                if ( !bData )
                                {
                                    if( nRefRow > nEndRow )
                                        nEndRow = nRefRow;
                                    if( nRefCol > nEndCol )
                                        nEndCol = nRefCol;
                                }
                            }
							if( !bMyDoc || !bData )
								break;
                            aText = '=';
                            p = lcl_ScanSylkFormula( p, aText, eVersion);
                            ScAddress aPos( nCol, nRow, aRange.aStart.Tab() );
                            /* FIXME: do we want GRAM_ODFF_A1 instead? At the
                             * end it probably should be GRAM_ODFF_R1C1, since
                             * R1C1 is what Excel writes in SYLK. */
                            const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_PODF_A1;
                            ScCompiler aComp( pDoc, aPos);
                            aComp.SetGrammar(eGrammar);
                            ScTokenArray* pCode = aComp.CompileString( aText );
                            if ( ch == 'M' )
                            {
                                ScMarkData aMark;
                                aMark.SelectTable( aPos.Tab(), sal_True );
                                pDoc->InsertMatrixFormula( nCol, nRow, nRefCol,
                                    nRefRow, aMark, EMPTY_STRING, pCode );
                            }
                            else
                            {
                                ScFormulaCell* pFCell = new ScFormulaCell(
                                        pDoc, aPos, pCode, eGrammar, MM_NONE);
                                pDoc->PutCell( aPos, pFCell );
                            }
                            delete pCode;   // ctor/InsertMatrixFormula did copy TokenArray
                        }
                        break;
					}
					while( *p && *p != ';' )
						p++;
					if( *p )
						p++;
				}
			}
            else if( cTag == 'F' )      // Format
            {
                if( *p++ != ';' )
                    return sal_False;
                sal_Int32 nFormat = -1;
                while( *p )
                {
                    sal_Unicode ch = *p++;
                    ch = ScGlobal::ToUpperAlpha( ch );
                    switch( ch )
                    {
                        case 'X':
                            nCol = static_cast<SCCOL>(String( p ).ToInt32()) + nStartCol - 1;
                            break;
                        case 'Y':
                            nRow = String( p ).ToInt32() + nStartRow - 1;
                            break;
                        case 'P' :
                            if ( bData )
                            {
                                // F;P<n> sets format code of P;P<code> at
                                // current position, or at ;X;Y if specified.
                                // Note that ;X;Y may appear after ;P
                                const sal_Unicode* p0 = p;
                                while( *p && *p != ';' )
                                    p++;
                                String aNumber( p0, sal::static_int_cast<xub_StrLen>( p - p0 ) );
                                nFormat = aNumber.ToInt32();
                            }
                            break;
                    }
                    while( *p && *p != ';' )
                        p++;
                    if( *p )
                        p++;
                }
                if ( !bData )
                {
                    if( nRow > nEndRow )
                        nEndRow = nRow;
                    if( nCol > nEndCol )
                        nEndCol = nCol;
                }
                if ( 0 <= nFormat && nFormat < aFormats.Count() )
                {
                    sal_uLong nKey = aFormats[(sal_uInt16)nFormat];
                    pDoc->ApplyAttr( nCol, nRow, aRange.aStart.Tab(),
                            SfxUInt32Item( ATTR_VALUE_FORMAT, nKey ) );
                }
            }
            else if( cTag == 'P' )
            {
                if ( bData && *p == ';' && *(p+1) == 'P' )
                {
                    String aCode( p+2 );
                    // unescape doubled semicolons
                    xub_StrLen nPos = 0;
                    String aSemicolon( RTL_CONSTASCII_USTRINGPARAM(";;"));
                    while ( (nPos = aCode.Search( aSemicolon, nPos )) != STRING_NOTFOUND )
                        aCode.Erase( nPos++, 1 );
                    // get rid of Xcl escape characters
                    nPos = 0;
                    while ( (nPos = aCode.Search( sal_Unicode(0x1b), nPos )) != STRING_NOTFOUND )
                        aCode.Erase( nPos, 1 );
                    xub_StrLen nCheckPos;
                    short nType;
                    sal_uInt32 nKey;
                    pDoc->GetFormatTable()->PutandConvertEntry(
                        aCode, nCheckPos, nType, nKey, LANGUAGE_ENGLISH_US,
                        ScGlobal::eLnge );
                    if ( nCheckPos )
                        nKey = 0;
                    aFormats.Insert( nKey, aFormats.Count() );
                }
            }
            else if( cTag == 'I' && *p == 'D' )
			{
				aLine.Erase( 0, 4 );
				if (aLine.EqualsAscii( "CALCOOO32" ))
                    eVersion = SYLK_OOO32;
                else if (aLine.EqualsAscii( "SCALC3" ))
                    eVersion = SYLK_SCALC3;
                bMyDoc = (eVersion <= SYLK_OWN);
			}
			else if( cTag == 'E' )						// Ende
				break;
		}
		if( !bData )
		{
			aRange.aEnd.SetCol( nEndCol );
			aRange.aEnd.SetRow( nEndRow );
			bOk = StartPaste();
			bData = sal_True;
		}
		else
			break;
	}

	EndPaste();
	return bOk;
}


sal_Bool ScImportExport::Doc2Sylk( SvStream& rStrm )
{
	SCCOL nCol;
	SCROW nRow;
	SCCOL nStartCol = aRange.aStart.Col();
	SCROW nStartRow = aRange.aStart.Row();
	SCCOL nEndCol = aRange.aEnd.Col();
	SCROW nEndRow = aRange.aEnd.Row();
	String aCellStr;
	String aValStr;
	lcl_WriteSimpleString( rStrm,
            String( RTL_CONSTASCII_USTRINGPARAM( "ID;PCALCOOO32")));
	WriteUnicodeOrByteEndl( rStrm );

	for (nRow = nStartRow; nRow <= nEndRow; nRow++)
	{
		for (nCol = nStartCol; nCol <= nEndCol; nCol++)
		{
			String aBufStr;
			double nVal;
			sal_Bool bForm = sal_False;
			SCROW r = nRow - nStartRow + 1;
			SCCOL c = nCol - nStartCol + 1;
            ScBaseCell* pCell;
            pDoc->GetCell( nCol, nRow, aRange.aStart.Tab(), pCell );
            CellType eType = (pCell ? pCell->GetCellType() : CELLTYPE_NONE);
			switch( eType )
			{
				case CELLTYPE_FORMULA:
					bForm = bFormulas;
					if( pDoc->HasValueData( nCol, nRow, aRange.aStart.Tab()) )
						goto hasvalue;
					else
						goto hasstring;

				case CELLTYPE_VALUE:
				hasvalue:
					pDoc->GetValue( nCol, nRow, aRange.aStart.Tab(), nVal );

                    aValStr = ::rtl::math::doubleToUString( nVal,
                            rtl_math_StringFormat_Automatic,
                            rtl_math_DecimalPlaces_Max, '.', sal_True );

					aBufStr.AssignAscii(RTL_CONSTASCII_STRINGPARAM( "C;X" ));
					aBufStr += String::CreateFromInt32( c );
					aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Y" ));
					aBufStr += String::CreateFromInt32( r );
					aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";K" ));
					aBufStr += aValStr;
					lcl_WriteSimpleString( rStrm, aBufStr );
					goto checkformula;

				case CELLTYPE_STRING:
				case CELLTYPE_EDIT:
				hasstring:
					pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCellStr );
                    aCellStr.SearchAndReplaceAll( _LF, SYLK_LF );

					aBufStr.AssignAscii(RTL_CONSTASCII_STRINGPARAM( "C;X" ));
					aBufStr += String::CreateFromInt32( c );
					aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Y" ));
					aBufStr += String::CreateFromInt32( r );
					aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";K" ));
					lcl_WriteSimpleString( rStrm, aBufStr );
					lcl_WriteString( rStrm, aCellStr, '"', ';' );

				checkformula:
					if( bForm )
					{
                        const ScFormulaCell* pFCell =
                            static_cast<const ScFormulaCell*>(pCell);
                        switch ( pFCell->GetMatrixFlag() )
                        {
                            case MM_REFERENCE :
                                aCellStr.Erase();
                            break;
                            default:
                                pFCell->GetFormula( aCellStr,formula::FormulaGrammar::GRAM_PODF_A1);
                                /* FIXME: do we want GRAM_ODFF_A1 instead? At
                                 * the end it probably should be
                                 * GRAM_ODFF_R1C1, since R1C1 is what Excel
                                 * writes in SYLK. */
                        }
                        if ( pFCell->GetMatrixFlag() != MM_NONE &&
                                aCellStr.Len() > 2 &&
                                aCellStr.GetChar(0) == '{' &&
                                aCellStr.GetChar(aCellStr.Len()-1) == '}' )
                        {   // cut off matrix {} characters
                            aCellStr.Erase(aCellStr.Len()-1,1);
                            aCellStr.Erase(0,1);
                        }
                        if ( aCellStr.GetChar(0) == '=' )
                            aCellStr.Erase(0,1);
                        String aPrefix;
                        switch ( pFCell->GetMatrixFlag() )
                        {
                            case MM_FORMULA :
                            {   // diff expression with 'M' M$-extension
                                SCCOL nC;
                                SCROW nR;
                                pFCell->GetMatColsRows( nC, nR );
                                nC += c - 1;
                                nR += r - 1;
                                aPrefix.AssignAscii( RTL_CONSTASCII_STRINGPARAM( ";R" ) );
                                aPrefix += String::CreateFromInt32( nR );
                                aPrefix.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ";C" ) );
                                aPrefix += String::CreateFromInt32( nC );
                                aPrefix.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ";M" ) );
                            }
                            break;
                            case MM_REFERENCE :
                            {   // diff expression with 'I' M$-extension
                                ScAddress aPos;
                                pFCell->GetMatrixOrigin( aPos );
                                aPrefix.AssignAscii( RTL_CONSTASCII_STRINGPARAM( ";I;R" ) );
                                aPrefix += String::CreateFromInt32( aPos.Row() - nStartRow + 1 );
                                aPrefix.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ";C" ) );
                                aPrefix += String::CreateFromInt32( aPos.Col() - nStartCol + 1 );
                            }
                            break;
                            default:
                                // formula Expression
                                aPrefix.AssignAscii( RTL_CONSTASCII_STRINGPARAM( ";E" ) );
                        }
                        lcl_WriteSimpleString( rStrm, aPrefix );
                        if ( aCellStr.Len() )
                            lcl_WriteString( rStrm, aCellStr, 0, ';' );
					}
					WriteUnicodeOrByteEndl( rStrm );
					break;

                default:
                {
                    // added to avoid warnings
                }
			}
		}
	}
	lcl_WriteSimpleString( rStrm, String( 'E' ) );
	WriteUnicodeOrByteEndl( rStrm );
	return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
}


sal_Bool ScImportExport::Doc2HTML( SvStream& rStrm, const String& rBaseURL )
{
    // CharSet is ignored in ScExportHTML, read from Load/Save HTML options
    ScFormatFilter::Get().ScExportHTML( rStrm, rBaseURL, pDoc, aRange, RTL_TEXTENCODING_DONTKNOW, bAll,
        aStreamPath, aNonConvertibleChars );
	return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
}

sal_Bool ScImportExport::Doc2RTF( SvStream& rStrm )
{
	//	CharSet is ignored in ScExportRTF
    ScFormatFilter::Get().ScExportRTF( rStrm, pDoc, aRange, RTL_TEXTENCODING_DONTKNOW );
	return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
}


sal_Bool ScImportExport::Doc2Dif( SvStream& rStrm )
{
	// for DIF in the clipboard, IBM_850 is always used
    ScFormatFilter::Get().ScExportDif( rStrm, pDoc, aRange, RTL_TEXTENCODING_IBM_850 );
	return sal_True;
}


sal_Bool ScImportExport::Dif2Doc( SvStream& rStrm )
{
	SCTAB nTab = aRange.aStart.Tab();
	ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO );
	pImportDoc->InitUndo( pDoc, nTab, nTab );

	// for DIF in the clipboard, IBM_850 is always used
	ScFormatFilter::Get().ScImportDif( rStrm, pImportDoc, aRange.aStart, RTL_TEXTENCODING_IBM_850 );

	SCCOL nEndCol;
	SCROW nEndRow;
	pImportDoc->GetCellArea( nTab, nEndCol, nEndRow );
    // #131247# if there are no cells in the imported content, nEndCol/nEndRow may be before the start
    if ( nEndCol < aRange.aStart.Col() )
        nEndCol = aRange.aStart.Col();
    if ( nEndRow < aRange.aStart.Row() )
        nEndRow = aRange.aStart.Row();
	aRange.aEnd = ScAddress( nEndCol, nEndRow, nTab );

	sal_Bool bOk = StartPaste();
	if (bOk)
	{
		sal_uInt16 nFlags = IDF_ALL & ~IDF_STYLES;
		pDoc->DeleteAreaTab( aRange, nFlags );
		pImportDoc->CopyToDocument( aRange, nFlags, sal_False, pDoc );
		EndPaste();
	}

	delete pImportDoc;

	return bOk;
}


sal_Bool ScImportExport::RTF2Doc( SvStream& rStrm, const String& rBaseURL )
{
    ScEEAbsImport *pImp = ScFormatFilter::Get().CreateRTFImport( pDoc, aRange );
    if (!pImp)
        return false;
    pImp->Read( rStrm, rBaseURL );
    aRange = pImp->GetRange();

    sal_Bool bOk = StartPaste();
    if (bOk)
    {
        sal_uInt16 nFlags = IDF_ALL & ~IDF_STYLES;
        pDoc->DeleteAreaTab( aRange, nFlags );
        pImp->WriteToDocument();
        EndPaste();
    }
    delete pImp;
    return bOk;
}


sal_Bool ScImportExport::HTML2Doc( SvStream& rStrm, const String& rBaseURL )
{
    ScEEAbsImport *pImp = ScFormatFilter::Get().CreateHTMLImport( pDoc, rBaseURL, aRange, sal_True);
    if (!pImp)
        return false;
    pImp->Read( rStrm, rBaseURL );
    aRange = pImp->GetRange();

    sal_Bool bOk = StartPaste();
    if (bOk)
    {
        // ScHTMLImport may call ScDocument::InitDrawLayer, resulting in
        // a Draw Layer but no Draw View -> create Draw Layer and View here
        if (pDocSh)
            pDocSh->MakeDrawLayer();

        sal_uInt16 nFlags = IDF_ALL & ~IDF_STYLES;
        pDoc->DeleteAreaTab( aRange, nFlags );
        pImp->WriteToDocument();
        EndPaste();
    }
    delete pImp;
    return bOk;
}

#define RETURN_ERROR { return eERR_INTERN; }
class ScFormatFilterMissing : public ScFormatFilterPlugin {
  public:
    ScFormatFilterMissing()
    {
      OSL_ASSERT ("Missing file filters");
    }
    virtual FltError ScImportLotus123( SfxMedium&, ScDocument*, CharSet ) RETURN_ERROR
    virtual FltError ScImportQuattroPro( SfxMedium &, ScDocument * ) RETURN_ERROR
    virtual FltError ScImportExcel( SfxMedium&, ScDocument*, const EXCIMPFORMAT ) RETURN_ERROR
    virtual FltError ScImportStarCalc10( SvStream&, ScDocument* ) RETURN_ERROR
    virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress&,
				 const CharSet, sal_uInt32 ) RETURN_ERROR
    virtual FltError ScImportRTF( SvStream&, const String&, ScDocument*, ScRange& ) RETURN_ERROR
    virtual FltError ScImportHTML( SvStream&, const String&, ScDocument*, ScRange&, double, sal_Bool, SvNumberFormatter*, bool ) RETURN_ERROR

    virtual ScEEAbsImport *CreateRTFImport( ScDocument*, const ScRange& ) { return NULL; }
    virtual ScEEAbsImport *CreateHTMLImport( ScDocument*, const String&, const ScRange&, sal_Bool ) { return NULL; }
    virtual String         GetHTMLRangeNameList( ScDocument*, const String& ) { return String(); }

#if ENABLE_LOTUS123_EXPORT
    virtual FltError ScExportLotus123( SvStream&, ScDocument*, ExportFormatLotus, CharSet ) RETURN_ERROR
#endif
    virtual FltError ScExportExcel5( SfxMedium&, ScDocument*, ExportFormatExcel, CharSet ) RETURN_ERROR
    virtual FltError ScExportDif( SvStream&, ScDocument*, const ScAddress&, const CharSet, sal_uInt32 ) RETURN_ERROR
    virtual FltError ScExportDif( SvStream&, ScDocument*, const ScRange&, const CharSet, sal_uInt32 ) RETURN_ERROR
    virtual FltError ScExportHTML( SvStream&, const String&, ScDocument*, const ScRange&, const CharSet, sal_Bool,
				  const String&, String& ) RETURN_ERROR
    virtual FltError ScExportRTF( SvStream&, ScDocument*, const ScRange&, const CharSet ) RETURN_ERROR
};

extern "C" { static void SAL_CALL thisModule() {} }
typedef ScFormatFilterPlugin * (*FilterFn)(void);
ScFormatFilterPlugin &ScFormatFilter::Get()
{
    static ScFormatFilterPlugin *plugin;

    if (plugin != NULL)
        return *plugin;

    static ::osl::Module aModule;
    if ( aModule.loadRelative( &thisModule,
			       ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SVLIBRARY( "scfilt" ) ) ) ) )
    {
	oslGenericFunction fn = aModule.getFunctionSymbol( ::rtl::OUString::createFromAscii( "ScFilterCreate" ) );
	if (fn != NULL)
	    plugin = reinterpret_cast<FilterFn>(fn)();
    }
    if (plugin == NULL)
        plugin = new ScFormatFilterMissing();

    return *plugin;
}
