xref: /AOO41X/main/sc/source/ui/docshell/impex.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sc.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir // System - Includes -----------------------------------------------------
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir class StarBASIC;
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #ifndef PCH
38*cdf0e10cSrcweir #include "sc.hrc"
39*cdf0e10cSrcweir #define GLOBALOVERFLOW
40*cdf0e10cSrcweir #endif
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #include <stdio.h>
45*cdf0e10cSrcweir #include <ctype.h>
46*cdf0e10cSrcweir #include <stdlib.h>
47*cdf0e10cSrcweir #include <osl/endian.h>
48*cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
49*cdf0e10cSrcweir #include <tools/list.hxx>
50*cdf0e10cSrcweir #include <tools/string.hxx>
51*cdf0e10cSrcweir #include <rtl/math.hxx>
52*cdf0e10cSrcweir #include <svtools/htmlout.hxx>
53*cdf0e10cSrcweir #include <svl/zforlist.hxx>
54*cdf0e10cSrcweir #define _SVSTDARR_ULONGS
55*cdf0e10cSrcweir #include <svl/svstdarr.hxx>
56*cdf0e10cSrcweir #include <sot/formats.hxx>
57*cdf0e10cSrcweir #include <sfx2/mieclip.hxx>
58*cdf0e10cSrcweir #include <unotools/charclass.hxx>
59*cdf0e10cSrcweir #include <unotools/collatorwrapper.hxx>
60*cdf0e10cSrcweir #include <unotools/calendarwrapper.hxx>
61*cdf0e10cSrcweir #include <com/sun/star/i18n/CalendarFieldIndex.hpp>
62*cdf0e10cSrcweir #include <unotools/transliterationwrapper.hxx>
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir #include "global.hxx"
65*cdf0e10cSrcweir #include "scerrors.hxx"
66*cdf0e10cSrcweir #include "docsh.hxx"
67*cdf0e10cSrcweir #include "undoblk.hxx"
68*cdf0e10cSrcweir #include "rangenam.hxx"
69*cdf0e10cSrcweir #include "viewdata.hxx"
70*cdf0e10cSrcweir #include "tabvwsh.hxx"
71*cdf0e10cSrcweir #include "filter.hxx"
72*cdf0e10cSrcweir #include "asciiopt.hxx"
73*cdf0e10cSrcweir #include "cell.hxx"
74*cdf0e10cSrcweir #include "docoptio.hxx"
75*cdf0e10cSrcweir #include "progress.hxx"
76*cdf0e10cSrcweir #include "scitems.hxx"
77*cdf0e10cSrcweir #include "editable.hxx"
78*cdf0e10cSrcweir #include "compiler.hxx"
79*cdf0e10cSrcweir #include "warnbox.hxx"
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir #include "impex.hxx"
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir // ause
84*cdf0e10cSrcweir #include "editutil.hxx"
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir #include "globstr.hrc"
87*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
88*cdf0e10cSrcweir #include <vcl/svapp.hxx>
89*cdf0e10cSrcweir #include <osl/module.hxx>
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir //========================================================================
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir namespace
94*cdf0e10cSrcweir {
95*cdf0e10cSrcweir     const String SYLK_LF = String::CreateFromAscii("\x1b :");
96*cdf0e10cSrcweir     const String DOUBLE_SEMICOLON = String::CreateFromAscii(";;");
97*cdf0e10cSrcweir     const String DOUBLE_DOUBLEQUOTE = String::CreateFromAscii("\"\"");
98*cdf0e10cSrcweir }
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir enum SylkVersion
101*cdf0e10cSrcweir {
102*cdf0e10cSrcweir     SYLK_SCALC3,    // Wrote wrongly quoted strings and unescaped semicolons.
103*cdf0e10cSrcweir     SYLK_OOO32,     // Correct strings, plus multiline content.
104*cdf0e10cSrcweir     SYLK_OWN,       // Place our new versions, if any, before this value.
105*cdf0e10cSrcweir     SYLK_OTHER      // Assume that aliens wrote correct strings.
106*cdf0e10cSrcweir };
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir // Gesamtdokument ohne Undo
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir ScImportExport::ScImportExport( ScDocument* p )
113*cdf0e10cSrcweir     : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
114*cdf0e10cSrcweir       nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
115*cdf0e10cSrcweir       bFormulas( sal_False ), bIncludeFiltered( sal_True ),
116*cdf0e10cSrcweir       bAll( sal_True ), bSingle( sal_True ), bUndo( sal_False ),
117*cdf0e10cSrcweir       bOverflow( sal_False ), mbApi( true ), mExportTextOptions()
118*cdf0e10cSrcweir {
119*cdf0e10cSrcweir 	pUndoDoc = NULL;
120*cdf0e10cSrcweir 	pExtOptions = NULL;
121*cdf0e10cSrcweir }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir // Insert am Punkt ohne Bereichschecks
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir ScImportExport::ScImportExport( ScDocument* p, const ScAddress& rPt )
127*cdf0e10cSrcweir     : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
128*cdf0e10cSrcweir 	  aRange( rPt ),
129*cdf0e10cSrcweir       nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
130*cdf0e10cSrcweir       bFormulas( sal_False ), bIncludeFiltered( sal_True ),
131*cdf0e10cSrcweir       bAll( sal_False ), bSingle( sal_True ), bUndo( sal_Bool( pDocSh != NULL ) ),
132*cdf0e10cSrcweir       bOverflow( sal_False ), mbApi( true ), mExportTextOptions()
133*cdf0e10cSrcweir {
134*cdf0e10cSrcweir 	pUndoDoc = NULL;
135*cdf0e10cSrcweir 	pExtOptions = NULL;
136*cdf0e10cSrcweir }
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir //	ctor with a range is only used for export
140*cdf0e10cSrcweir //!	ctor with a string (and bSingle=sal_True) is also used for DdeSetData
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir ScImportExport::ScImportExport( ScDocument* p, const ScRange& r )
143*cdf0e10cSrcweir     : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
144*cdf0e10cSrcweir 	  aRange( r ),
145*cdf0e10cSrcweir       nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
146*cdf0e10cSrcweir       bFormulas( sal_False ), bIncludeFiltered( sal_True ),
147*cdf0e10cSrcweir       bAll( sal_False ), bSingle( sal_False ), bUndo( sal_Bool( pDocSh != NULL ) ),
148*cdf0e10cSrcweir       bOverflow( sal_False ), mbApi( true ), mExportTextOptions()
149*cdf0e10cSrcweir {
150*cdf0e10cSrcweir 	pUndoDoc = NULL;
151*cdf0e10cSrcweir 	pExtOptions = NULL;
152*cdf0e10cSrcweir 	// Zur Zeit nur in einer Tabelle!
153*cdf0e10cSrcweir 	aRange.aEnd.SetTab( aRange.aStart.Tab() );
154*cdf0e10cSrcweir }
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir // String auswerten: Entweder Bereich, Punkt oder Gesamtdoc (bei Fehler)
157*cdf0e10cSrcweir // Falls eine View existiert, wird die TabNo der View entnommen!
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir ScImportExport::ScImportExport( ScDocument* p, const String& rPos )
161*cdf0e10cSrcweir     : pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), pDoc( p ),
162*cdf0e10cSrcweir       nSizeLimit( 0 ), cSep( '\t' ), cStr( '"' ),
163*cdf0e10cSrcweir       bFormulas( sal_False ), bIncludeFiltered( sal_True ),
164*cdf0e10cSrcweir       bAll( sal_False ), bSingle( sal_True ), bUndo( sal_Bool( pDocSh != NULL ) ),
165*cdf0e10cSrcweir       bOverflow( sal_False ), mbApi( true ), mExportTextOptions()
166*cdf0e10cSrcweir {
167*cdf0e10cSrcweir 	pUndoDoc = NULL;
168*cdf0e10cSrcweir 	pExtOptions = NULL;
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir 	SCTAB nTab = ScDocShell::GetCurTab();
171*cdf0e10cSrcweir 	aRange.aStart.SetTab( nTab );
172*cdf0e10cSrcweir 	String aPos( rPos );
173*cdf0e10cSrcweir 	//  Benannter Bereich?
174*cdf0e10cSrcweir 	ScRangeName* pRange = pDoc->GetRangeName();
175*cdf0e10cSrcweir 	if( pRange )
176*cdf0e10cSrcweir 	{
177*cdf0e10cSrcweir 		sal_uInt16 nPos;
178*cdf0e10cSrcweir 		if( pRange->SearchName( aPos, nPos ) )
179*cdf0e10cSrcweir 		{
180*cdf0e10cSrcweir 			ScRangeData* pData = (*pRange)[ nPos ];
181*cdf0e10cSrcweir 			if( pData->HasType( RT_REFAREA )
182*cdf0e10cSrcweir 				|| pData->HasType( RT_ABSAREA )
183*cdf0e10cSrcweir 				|| pData->HasType( RT_ABSPOS ) )
184*cdf0e10cSrcweir 				pData->GetSymbol( aPos );					// mit dem Inhalt weitertesten
185*cdf0e10cSrcweir 		}
186*cdf0e10cSrcweir 	}
187*cdf0e10cSrcweir     formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
188*cdf0e10cSrcweir 	// Bereich?
189*cdf0e10cSrcweir 	if( aRange.Parse( aPos, pDoc, eConv ) & SCA_VALID )
190*cdf0e10cSrcweir 		bSingle = sal_False;
191*cdf0e10cSrcweir 	// Zelle?
192*cdf0e10cSrcweir 	else if( aRange.aStart.Parse( aPos, pDoc, eConv ) & SCA_VALID )
193*cdf0e10cSrcweir 		aRange.aEnd = aRange.aStart;
194*cdf0e10cSrcweir 	else
195*cdf0e10cSrcweir 		bAll = sal_True;
196*cdf0e10cSrcweir }
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir ScImportExport::~ScImportExport()
200*cdf0e10cSrcweir {
201*cdf0e10cSrcweir 	delete pUndoDoc;
202*cdf0e10cSrcweir 	delete pExtOptions;
203*cdf0e10cSrcweir }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir void ScImportExport::SetExtOptions( const ScAsciiOptions& rOpt )
207*cdf0e10cSrcweir {
208*cdf0e10cSrcweir 	if ( pExtOptions )
209*cdf0e10cSrcweir 		*pExtOptions = rOpt;
210*cdf0e10cSrcweir 	else
211*cdf0e10cSrcweir 		pExtOptions = new ScAsciiOptions( rOpt );
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir 	//	"normale" Optionen uebernehmen
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir 	cSep = rOpt.GetFieldSeps().GetChar(0);
216*cdf0e10cSrcweir 	cStr = rOpt.GetTextSep();
217*cdf0e10cSrcweir }
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir sal_Bool ScImportExport::IsFormatSupported( sal_uLong nFormat )
221*cdf0e10cSrcweir {
222*cdf0e10cSrcweir 	return sal_Bool( nFormat == FORMAT_STRING
223*cdf0e10cSrcweir 			  || nFormat == SOT_FORMATSTR_ID_SYLK
224*cdf0e10cSrcweir 			  || nFormat == SOT_FORMATSTR_ID_LINK
225*cdf0e10cSrcweir 			  || nFormat == SOT_FORMATSTR_ID_HTML
226*cdf0e10cSrcweir 			  || nFormat == SOT_FORMATSTR_ID_HTML_SIMPLE
227*cdf0e10cSrcweir 			  || nFormat == SOT_FORMATSTR_ID_DIF );
228*cdf0e10cSrcweir }
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir // Vorbereitung fuer Undo: Undo-Dokument erzeugen
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir sal_Bool ScImportExport::StartPaste()
237*cdf0e10cSrcweir {
238*cdf0e10cSrcweir 	if ( !bAll )
239*cdf0e10cSrcweir 	{
240*cdf0e10cSrcweir 		ScEditableTester aTester( pDoc, aRange );
241*cdf0e10cSrcweir 		if ( !aTester.IsEditable() )
242*cdf0e10cSrcweir 		{
243*cdf0e10cSrcweir 			InfoBox aInfoBox(Application::GetDefDialogParent(),
244*cdf0e10cSrcweir 								ScGlobal::GetRscString( aTester.GetMessageId() ) );
245*cdf0e10cSrcweir 			aInfoBox.Execute();
246*cdf0e10cSrcweir 			return sal_False;
247*cdf0e10cSrcweir 		}
248*cdf0e10cSrcweir 	}
249*cdf0e10cSrcweir 	if( bUndo && pDocSh && pDoc->IsUndoEnabled())
250*cdf0e10cSrcweir 	{
251*cdf0e10cSrcweir 		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
252*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() );
253*cdf0e10cSrcweir         pDoc->CopyToDocument( aRange, IDF_ALL | IDF_NOCAPTIONS, sal_False, pUndoDoc );
254*cdf0e10cSrcweir 	}
255*cdf0e10cSrcweir 	return sal_True;
256*cdf0e10cSrcweir }
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir // Nachbereitung Insert: Undo/Redo-Aktionen erzeugen, Invalidate/Repaint
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir void ScImportExport::EndPaste()
262*cdf0e10cSrcweir {
263*cdf0e10cSrcweir 	sal_Bool bHeight = pDocSh && pDocSh->AdjustRowHeight(
264*cdf0e10cSrcweir 					aRange.aStart.Row(), aRange.aEnd.Row(), aRange.aStart.Tab() );
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir 	if( pUndoDoc && pDoc->IsUndoEnabled() )
267*cdf0e10cSrcweir 	{
268*cdf0e10cSrcweir 		ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
269*cdf0e10cSrcweir 		pRedoDoc->InitUndo( pDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() );
270*cdf0e10cSrcweir         pDoc->CopyToDocument( aRange, IDF_ALL | IDF_NOCAPTIONS, sal_False, pRedoDoc );
271*cdf0e10cSrcweir 		ScMarkData aDestMark;
272*cdf0e10cSrcweir 		aDestMark.SelectOneTable( aRange.aStart.Tab() );
273*cdf0e10cSrcweir 		pDocSh->GetUndoManager()->AddUndoAction(
274*cdf0e10cSrcweir 			new ScUndoPaste( pDocSh,
275*cdf0e10cSrcweir 				aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(),
276*cdf0e10cSrcweir 				aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(), aDestMark,
277*cdf0e10cSrcweir                 pUndoDoc, pRedoDoc, IDF_ALL, NULL,NULL,NULL,NULL ) );
278*cdf0e10cSrcweir 	}
279*cdf0e10cSrcweir 	pUndoDoc = NULL;
280*cdf0e10cSrcweir 	if( pDocSh )
281*cdf0e10cSrcweir 	{
282*cdf0e10cSrcweir 		if (!bHeight)
283*cdf0e10cSrcweir 			pDocSh->PostPaint( aRange, PAINT_GRID );	// AdjustRowHeight paintet evtl. selber
284*cdf0e10cSrcweir 		pDocSh->SetDocumentModified();
285*cdf0e10cSrcweir 	}
286*cdf0e10cSrcweir 	ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
287*cdf0e10cSrcweir 	if ( pViewSh )
288*cdf0e10cSrcweir 		pViewSh->UpdateInputHandler();
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir }
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir #if 0
296*cdf0e10cSrcweir sal_Bool ScImportExport::ImportData( SvData& rData )
297*cdf0e10cSrcweir {
298*cdf0e10cSrcweir 	sal_uLong nFmt = rData.GetFormat();
299*cdf0e10cSrcweir 	if ( nFmt == SOT_FORMATSTR_ID_HTML_SIMPLE )
300*cdf0e10cSrcweir 	{
301*cdf0e10cSrcweir 		MSE40HTMLClipFormatObj aMSE40ClpObj;
302*cdf0e10cSrcweir 		if ( aMSE40ClpObj.GetData( rData ) )
303*cdf0e10cSrcweir 		{
304*cdf0e10cSrcweir 			SvStream* pStream = aMSE40ClpObj.GetStream();
305*cdf0e10cSrcweir 			return ImportStream( *pStream, nFmt );
306*cdf0e10cSrcweir 		}
307*cdf0e10cSrcweir 		return sal_False;
308*cdf0e10cSrcweir 	}
309*cdf0e10cSrcweir 	else
310*cdf0e10cSrcweir 	{
311*cdf0e10cSrcweir 		void* pMem;
312*cdf0e10cSrcweir 		sal_uLong nSize = rData.GetMinMemorySize();
313*cdf0e10cSrcweir 		rData.GetData( &pMem, TRANSFER_REFERENCE );
314*cdf0e10cSrcweir 		if( nFmt == FORMAT_STRING
315*cdf0e10cSrcweir 	 			|| nFmt == FORMAT_RTF
316*cdf0e10cSrcweir 	 			|| nFmt == SOT_FORMATSTR_ID_SYLK
317*cdf0e10cSrcweir 	 			|| nFmt == SOT_FORMATSTR_ID_HTML
318*cdf0e10cSrcweir 	 			|| nFmt == SOT_FORMATSTR_ID_DIF )
319*cdf0e10cSrcweir 		{
320*cdf0e10cSrcweir 			//!	String? Unicode??
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir 			// Stringende ermitteln!
323*cdf0e10cSrcweir 			sal_Char* pBegin = (sal_Char*) pMem;
324*cdf0e10cSrcweir 			sal_Char* pEnd   = (sal_Char*) pMem + nSize;
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir 			nSize = 0;
327*cdf0e10cSrcweir 			while( pBegin != pEnd && *pBegin != '\0' )
328*cdf0e10cSrcweir 				pBegin++, nSize++;
329*cdf0e10cSrcweir 			// #72909# MT says only STRING has to be zero-terminated
330*cdf0e10cSrcweir 			DBG_ASSERT( pBegin != pEnd || nFmt != FORMAT_STRING, "non zero-terminated String" )
331*cdf0e10cSrcweir 		}
332*cdf0e10cSrcweir 		SvMemoryStream aStrm( pMem, nSize, STREAM_READ );
333*cdf0e10cSrcweir 		return ImportStream( aStrm, nFmt );
334*cdf0e10cSrcweir 	}
335*cdf0e10cSrcweir }
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir #endif
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir sal_Bool ScImportExport::ImportData( const String& /* rMimeType */,
340*cdf0e10cSrcweir                      const ::com::sun::star::uno::Any & /* rValue */ )
341*cdf0e10cSrcweir {
342*cdf0e10cSrcweir 	DBG_ASSERT( !this, "Implementation is missing" );
343*cdf0e10cSrcweir 	return sal_False;
344*cdf0e10cSrcweir }
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir sal_Bool ScImportExport::ExportData( const String& rMimeType,
347*cdf0e10cSrcweir 								 ::com::sun::star::uno::Any & rValue )
348*cdf0e10cSrcweir {
349*cdf0e10cSrcweir 	SvMemoryStream aStrm;
350*cdf0e10cSrcweir     // mba: no BaseURL for data exchange
351*cdf0e10cSrcweir     if( ExportStream( aStrm, String(),
352*cdf0e10cSrcweir 				SotExchange::GetFormatIdFromMimeType( rMimeType ) ))
353*cdf0e10cSrcweir 	{
354*cdf0e10cSrcweir 		aStrm << (sal_uInt8) 0;
355*cdf0e10cSrcweir 		rValue <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
356*cdf0e10cSrcweir 										(sal_Int8*)aStrm.GetData(),
357*cdf0e10cSrcweir 										aStrm.Seek( STREAM_SEEK_TO_END ) );
358*cdf0e10cSrcweir 		return sal_True;
359*cdf0e10cSrcweir 	}
360*cdf0e10cSrcweir 	return sal_False;
361*cdf0e10cSrcweir }
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir 
364*cdf0e10cSrcweir sal_Bool ScImportExport::ImportString( const ::rtl::OUString& rText, sal_uLong nFmt )
365*cdf0e10cSrcweir {
366*cdf0e10cSrcweir 	switch ( nFmt )
367*cdf0e10cSrcweir 	{
368*cdf0e10cSrcweir 		// formats supporting unicode
369*cdf0e10cSrcweir 		case FORMAT_STRING :
370*cdf0e10cSrcweir 		{
371*cdf0e10cSrcweir             ScImportStringStream aStrm( rText);
372*cdf0e10cSrcweir             return ImportStream( aStrm, String(), nFmt );
373*cdf0e10cSrcweir 			// ImportStream must handle RTL_TEXTENCODING_UNICODE
374*cdf0e10cSrcweir 		}
375*cdf0e10cSrcweir         //break;
376*cdf0e10cSrcweir 		default:
377*cdf0e10cSrcweir 		{
378*cdf0e10cSrcweir 			rtl_TextEncoding eEnc = gsl_getSystemTextEncoding();
379*cdf0e10cSrcweir             ::rtl::OString aTmp( rText.getStr(), rText.getLength(), eEnc );
380*cdf0e10cSrcweir             SvMemoryStream aStrm( (void*)aTmp.getStr(), aTmp.getLength() * sizeof(sal_Char), STREAM_READ );
381*cdf0e10cSrcweir 			aStrm.SetStreamCharSet( eEnc );
382*cdf0e10cSrcweir 			SetNoEndianSwap( aStrm );		//! no swapping in memory
383*cdf0e10cSrcweir             return ImportStream( aStrm, String(), nFmt );
384*cdf0e10cSrcweir 		}
385*cdf0e10cSrcweir 	}
386*cdf0e10cSrcweir }
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir sal_Bool ScImportExport::ExportString( ::rtl::OUString& rText, sal_uLong nFmt )
390*cdf0e10cSrcweir {
391*cdf0e10cSrcweir 	DBG_ASSERT( nFmt == FORMAT_STRING, "ScImportExport::ExportString: Unicode not supported for other formats than FORMAT_STRING" );
392*cdf0e10cSrcweir 	if ( nFmt != FORMAT_STRING )
393*cdf0e10cSrcweir 	{
394*cdf0e10cSrcweir 		rtl_TextEncoding eEnc = gsl_getSystemTextEncoding();
395*cdf0e10cSrcweir 		ByteString aTmp;
396*cdf0e10cSrcweir 		sal_Bool bOk = ExportByteString( aTmp, eEnc, nFmt );
397*cdf0e10cSrcweir 		rText = UniString( aTmp, eEnc );
398*cdf0e10cSrcweir 		return bOk;
399*cdf0e10cSrcweir 	}
400*cdf0e10cSrcweir 	//	nSizeLimit not needed for OUString
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir 	SvMemoryStream aStrm;
403*cdf0e10cSrcweir 	aStrm.SetStreamCharSet( RTL_TEXTENCODING_UNICODE );
404*cdf0e10cSrcweir 	SetNoEndianSwap( aStrm );		//! no swapping in memory
405*cdf0e10cSrcweir     // mba: no BaseURL for data exc
406*cdf0e10cSrcweir     if( ExportStream( aStrm, String(), nFmt ) )
407*cdf0e10cSrcweir 	{
408*cdf0e10cSrcweir 		aStrm << (sal_Unicode) 0;
409*cdf0e10cSrcweir 		aStrm.Seek( STREAM_SEEK_TO_END );
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir 		rText = rtl::OUString( (const sal_Unicode*) aStrm.GetData() );
412*cdf0e10cSrcweir 		return sal_True;
413*cdf0e10cSrcweir 	}
414*cdf0e10cSrcweir 	rText = rtl::OUString();
415*cdf0e10cSrcweir 	return sal_False;
416*cdf0e10cSrcweir 
417*cdf0e10cSrcweir 	// ExportStream must handle RTL_TEXTENCODING_UNICODE
418*cdf0e10cSrcweir }
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir sal_Bool ScImportExport::ExportByteString( ByteString& rText, rtl_TextEncoding eEnc, sal_uLong nFmt )
422*cdf0e10cSrcweir {
423*cdf0e10cSrcweir 	DBG_ASSERT( eEnc != RTL_TEXTENCODING_UNICODE, "ScImportExport::ExportByteString: Unicode not supported" );
424*cdf0e10cSrcweir 	if ( eEnc == RTL_TEXTENCODING_UNICODE )
425*cdf0e10cSrcweir 		eEnc = gsl_getSystemTextEncoding();
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir 	if (!nSizeLimit)
428*cdf0e10cSrcweir 		nSizeLimit = STRING_MAXLEN;
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir 	SvMemoryStream aStrm;
431*cdf0e10cSrcweir 	aStrm.SetStreamCharSet( eEnc );
432*cdf0e10cSrcweir 	SetNoEndianSwap( aStrm );		//! no swapping in memory
433*cdf0e10cSrcweir     // mba: no BaseURL for data exchange
434*cdf0e10cSrcweir     if( ExportStream( aStrm, String(), nFmt ) )
435*cdf0e10cSrcweir 	{
436*cdf0e10cSrcweir 		aStrm << (sal_Char) 0;
437*cdf0e10cSrcweir 		aStrm.Seek( STREAM_SEEK_TO_END );
438*cdf0e10cSrcweir 		// Sicherheits-Check:
439*cdf0e10cSrcweir 		if( aStrm.Tell() <= (sal_uLong) STRING_MAXLEN )
440*cdf0e10cSrcweir 		{
441*cdf0e10cSrcweir 			rText = (const sal_Char*) aStrm.GetData();
442*cdf0e10cSrcweir 			return sal_True;
443*cdf0e10cSrcweir 		}
444*cdf0e10cSrcweir 	}
445*cdf0e10cSrcweir 	rText.Erase();
446*cdf0e10cSrcweir 	return sal_False;
447*cdf0e10cSrcweir }
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir 
450*cdf0e10cSrcweir sal_Bool ScImportExport::ImportStream( SvStream& rStrm, const String& rBaseURL, sal_uLong nFmt )
451*cdf0e10cSrcweir {
452*cdf0e10cSrcweir 	if( nFmt == FORMAT_STRING )
453*cdf0e10cSrcweir 	{
454*cdf0e10cSrcweir 		if( ExtText2Doc( rStrm ) )		// pExtOptions auswerten
455*cdf0e10cSrcweir 			return sal_True;
456*cdf0e10cSrcweir 	}
457*cdf0e10cSrcweir 	if( nFmt == SOT_FORMATSTR_ID_SYLK )
458*cdf0e10cSrcweir 	{
459*cdf0e10cSrcweir 		if( Sylk2Doc( rStrm ) )
460*cdf0e10cSrcweir 			return sal_True;
461*cdf0e10cSrcweir 	}
462*cdf0e10cSrcweir 	if( nFmt == SOT_FORMATSTR_ID_DIF )
463*cdf0e10cSrcweir 	{
464*cdf0e10cSrcweir 		if( Dif2Doc( rStrm ) )
465*cdf0e10cSrcweir 			return sal_True;
466*cdf0e10cSrcweir 	}
467*cdf0e10cSrcweir 	if( nFmt == FORMAT_RTF )
468*cdf0e10cSrcweir 	{
469*cdf0e10cSrcweir         if( RTF2Doc( rStrm, rBaseURL ) )
470*cdf0e10cSrcweir 			return sal_True;
471*cdf0e10cSrcweir 	}
472*cdf0e10cSrcweir 	if( nFmt == SOT_FORMATSTR_ID_LINK )
473*cdf0e10cSrcweir 		return sal_True;			// Link-Import?
474*cdf0e10cSrcweir 	if ( nFmt == SOT_FORMATSTR_ID_HTML )
475*cdf0e10cSrcweir 	{
476*cdf0e10cSrcweir         if( HTML2Doc( rStrm, rBaseURL ) )
477*cdf0e10cSrcweir 			return sal_True;
478*cdf0e10cSrcweir 	}
479*cdf0e10cSrcweir 	if ( nFmt == SOT_FORMATSTR_ID_HTML_SIMPLE )
480*cdf0e10cSrcweir 	{
481*cdf0e10cSrcweir 		MSE40HTMLClipFormatObj aMSE40ClpObj;				// needed to skip the header data
482*cdf0e10cSrcweir 		SvStream* pHTML = aMSE40ClpObj.IsValid( rStrm );
483*cdf0e10cSrcweir         if ( pHTML && HTML2Doc( *pHTML, rBaseURL ) )
484*cdf0e10cSrcweir 			return sal_True;
485*cdf0e10cSrcweir 	}
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir 	return sal_False;
488*cdf0e10cSrcweir }
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir sal_Bool ScImportExport::ExportStream( SvStream& rStrm, const String& rBaseURL, sal_uLong nFmt )
492*cdf0e10cSrcweir {
493*cdf0e10cSrcweir 	if( nFmt == FORMAT_STRING )
494*cdf0e10cSrcweir 	{
495*cdf0e10cSrcweir 		if( Doc2Text( rStrm ) )
496*cdf0e10cSrcweir 			return sal_True;
497*cdf0e10cSrcweir 	}
498*cdf0e10cSrcweir 	if( nFmt == SOT_FORMATSTR_ID_SYLK )
499*cdf0e10cSrcweir 	{
500*cdf0e10cSrcweir 		if( Doc2Sylk( rStrm ) )
501*cdf0e10cSrcweir 			return sal_True;
502*cdf0e10cSrcweir 	}
503*cdf0e10cSrcweir 	if( nFmt == SOT_FORMATSTR_ID_DIF )
504*cdf0e10cSrcweir 	{
505*cdf0e10cSrcweir 		if( Doc2Dif( rStrm ) )
506*cdf0e10cSrcweir 			return sal_True;
507*cdf0e10cSrcweir 	}
508*cdf0e10cSrcweir 	if( nFmt == SOT_FORMATSTR_ID_LINK && !bAll )
509*cdf0e10cSrcweir 	{
510*cdf0e10cSrcweir 		String aDocName;
511*cdf0e10cSrcweir 		if ( pDoc->IsClipboard() )
512*cdf0e10cSrcweir 			aDocName = ScGlobal::GetClipDocName();
513*cdf0e10cSrcweir 		else
514*cdf0e10cSrcweir 		{
515*cdf0e10cSrcweir 			SfxObjectShell* pShell = pDoc->GetDocumentShell();
516*cdf0e10cSrcweir 			if (pShell)
517*cdf0e10cSrcweir 				aDocName = pShell->GetTitle( SFX_TITLE_FULLNAME );
518*cdf0e10cSrcweir 		}
519*cdf0e10cSrcweir 
520*cdf0e10cSrcweir 		DBG_ASSERT( aDocName.Len(), "ClipBoard document has no name! :-/" );
521*cdf0e10cSrcweir 		if( aDocName.Len() )
522*cdf0e10cSrcweir 		{
523*cdf0e10cSrcweir 			String aRefName;
524*cdf0e10cSrcweir 			sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
525*cdf0e10cSrcweir 			if( bSingle )
526*cdf0e10cSrcweir 				aRange.aStart.Format( aRefName, nFlags, pDoc, pDoc->GetAddressConvention() );
527*cdf0e10cSrcweir 			else
528*cdf0e10cSrcweir 			{
529*cdf0e10cSrcweir 				if( aRange.aStart.Tab() != aRange.aEnd.Tab() )
530*cdf0e10cSrcweir 					nFlags |= SCA_TAB2_3D;
531*cdf0e10cSrcweir 				aRange.Format( aRefName, nFlags, pDoc );
532*cdf0e10cSrcweir 			}
533*cdf0e10cSrcweir 			String aAppName = Application::GetAppName();
534*cdf0e10cSrcweir 
535*cdf0e10cSrcweir 			WriteUnicodeOrByteString( rStrm, aAppName, sal_True );
536*cdf0e10cSrcweir 			WriteUnicodeOrByteString( rStrm, aDocName, sal_True );
537*cdf0e10cSrcweir 			WriteUnicodeOrByteString( rStrm, aRefName, sal_True );
538*cdf0e10cSrcweir 			if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
539*cdf0e10cSrcweir 				rStrm << sal_Unicode(0);
540*cdf0e10cSrcweir 			else
541*cdf0e10cSrcweir 				rStrm << sal_Char(0);
542*cdf0e10cSrcweir 			return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
543*cdf0e10cSrcweir 		}
544*cdf0e10cSrcweir 	}
545*cdf0e10cSrcweir 	if( nFmt == SOT_FORMATSTR_ID_HTML )
546*cdf0e10cSrcweir 	{
547*cdf0e10cSrcweir         if( Doc2HTML( rStrm, rBaseURL ) )
548*cdf0e10cSrcweir 			return sal_True;
549*cdf0e10cSrcweir 	}
550*cdf0e10cSrcweir 	if( nFmt == FORMAT_RTF )
551*cdf0e10cSrcweir 	{
552*cdf0e10cSrcweir 		if( Doc2RTF( rStrm ) )
553*cdf0e10cSrcweir 			return sal_True;
554*cdf0e10cSrcweir 	}
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir 	return sal_False;
557*cdf0e10cSrcweir }
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir 
560*cdf0e10cSrcweir //static
561*cdf0e10cSrcweir void ScImportExport::WriteUnicodeOrByteString( SvStream& rStrm, const String& rString, sal_Bool bZero )
562*cdf0e10cSrcweir {
563*cdf0e10cSrcweir 	rtl_TextEncoding eEnc = rStrm.GetStreamCharSet();
564*cdf0e10cSrcweir 	if ( eEnc == RTL_TEXTENCODING_UNICODE )
565*cdf0e10cSrcweir 	{
566*cdf0e10cSrcweir 		if ( !IsEndianSwap( rStrm ) )
567*cdf0e10cSrcweir 			rStrm.Write( rString.GetBuffer(), rString.Len() * sizeof(sal_Unicode) );
568*cdf0e10cSrcweir 		else
569*cdf0e10cSrcweir 		{
570*cdf0e10cSrcweir 			const sal_Unicode* p = rString.GetBuffer();
571*cdf0e10cSrcweir 			const sal_Unicode* const pStop = p + rString.Len();
572*cdf0e10cSrcweir 			while ( p < pStop )
573*cdf0e10cSrcweir 			{
574*cdf0e10cSrcweir 				rStrm << *p;
575*cdf0e10cSrcweir 			}
576*cdf0e10cSrcweir 		}
577*cdf0e10cSrcweir 		if ( bZero )
578*cdf0e10cSrcweir 			rStrm << sal_Unicode(0);
579*cdf0e10cSrcweir 	}
580*cdf0e10cSrcweir 	else
581*cdf0e10cSrcweir 	{
582*cdf0e10cSrcweir 		ByteString aByteStr( rString, eEnc );
583*cdf0e10cSrcweir 		rStrm << aByteStr.GetBuffer();
584*cdf0e10cSrcweir 		if ( bZero )
585*cdf0e10cSrcweir 			rStrm << sal_Char(0);
586*cdf0e10cSrcweir 	}
587*cdf0e10cSrcweir }
588*cdf0e10cSrcweir 
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir // This function could be replaced by endlub()
591*cdf0e10cSrcweir // static
592*cdf0e10cSrcweir void ScImportExport::WriteUnicodeOrByteEndl( SvStream& rStrm )
593*cdf0e10cSrcweir {
594*cdf0e10cSrcweir 	if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
595*cdf0e10cSrcweir 	{	// same as endl() but unicode
596*cdf0e10cSrcweir 		switch ( rStrm.GetLineDelimiter() )
597*cdf0e10cSrcweir 		{
598*cdf0e10cSrcweir 			case LINEEND_CR :
599*cdf0e10cSrcweir 				rStrm << sal_Unicode(_CR);
600*cdf0e10cSrcweir 			break;
601*cdf0e10cSrcweir 			case LINEEND_LF :
602*cdf0e10cSrcweir 				rStrm << sal_Unicode(_LF);
603*cdf0e10cSrcweir 			break;
604*cdf0e10cSrcweir 			default:
605*cdf0e10cSrcweir 				rStrm << sal_Unicode(_CR) << sal_Unicode(_LF);
606*cdf0e10cSrcweir 		}
607*cdf0e10cSrcweir 	}
608*cdf0e10cSrcweir 	else
609*cdf0e10cSrcweir 		endl( rStrm );
610*cdf0e10cSrcweir }
611*cdf0e10cSrcweir 
612*cdf0e10cSrcweir 
613*cdf0e10cSrcweir enum DoubledQuoteMode
614*cdf0e10cSrcweir {
615*cdf0e10cSrcweir 	DQM_KEEP,		// both are taken
616*cdf0e10cSrcweir 	DQM_ESCAPE,		// escaped quote, one is taken, one ignored
617*cdf0e10cSrcweir 	DQM_CONCAT,		// first is end, next is start, both ignored => strings combined
618*cdf0e10cSrcweir 	DQM_SEPARATE	// end one string and begin next
619*cdf0e10cSrcweir };
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir static const sal_Unicode* lcl_ScanString( const sal_Unicode* p, String& rString,
622*cdf0e10cSrcweir 			sal_Unicode cStr, DoubledQuoteMode eMode )
623*cdf0e10cSrcweir {
624*cdf0e10cSrcweir 	p++;	//! jump over opening quote
625*cdf0e10cSrcweir 	sal_Bool bCont;
626*cdf0e10cSrcweir 	do
627*cdf0e10cSrcweir 	{
628*cdf0e10cSrcweir 		bCont = sal_False;
629*cdf0e10cSrcweir 		const sal_Unicode* p0 = p;
630*cdf0e10cSrcweir 		for( ;; )
631*cdf0e10cSrcweir 		{
632*cdf0e10cSrcweir 			if( !*p )
633*cdf0e10cSrcweir 				break;
634*cdf0e10cSrcweir 			if( *p == cStr )
635*cdf0e10cSrcweir 			{
636*cdf0e10cSrcweir 				if ( *++p != cStr )
637*cdf0e10cSrcweir 					break;
638*cdf0e10cSrcweir 				// doubled quote char
639*cdf0e10cSrcweir 				switch ( eMode )
640*cdf0e10cSrcweir 				{
641*cdf0e10cSrcweir 					case DQM_KEEP :
642*cdf0e10cSrcweir 						p++;			// both for us (not breaking for-loop)
643*cdf0e10cSrcweir 					break;
644*cdf0e10cSrcweir 					case DQM_ESCAPE :
645*cdf0e10cSrcweir 						p++;			// one for us (breaking for-loop)
646*cdf0e10cSrcweir 						bCont = sal_True;	// and more
647*cdf0e10cSrcweir 					break;
648*cdf0e10cSrcweir 					case DQM_CONCAT :
649*cdf0e10cSrcweir 						if ( p0+1 < p )
650*cdf0e10cSrcweir                             rString.Append( p0, sal::static_int_cast<xub_StrLen>( (p-1) - p0 ) );  // first part
651*cdf0e10cSrcweir 						p0 = ++p;		// text of next part starts here
652*cdf0e10cSrcweir 					break;
653*cdf0e10cSrcweir 					case DQM_SEPARATE :
654*cdf0e10cSrcweir 										// positioned on next opening quote
655*cdf0e10cSrcweir 					break;
656*cdf0e10cSrcweir 				}
657*cdf0e10cSrcweir 				if ( eMode == DQM_ESCAPE || eMode == DQM_SEPARATE )
658*cdf0e10cSrcweir 					break;
659*cdf0e10cSrcweir 			}
660*cdf0e10cSrcweir 			else
661*cdf0e10cSrcweir 				p++;
662*cdf0e10cSrcweir 		}
663*cdf0e10cSrcweir 		if ( p0 < p )
664*cdf0e10cSrcweir             rString.Append( p0, sal::static_int_cast<xub_StrLen>( ((*p || *(p-1) == cStr) ? p-1 : p) - p0 ) );
665*cdf0e10cSrcweir 	} while ( bCont );
666*cdf0e10cSrcweir 	return p;
667*cdf0e10cSrcweir }
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir void lcl_UnescapeSylk( String & rString, SylkVersion eVersion )
670*cdf0e10cSrcweir {
671*cdf0e10cSrcweir     // Older versions didn't escape the semicolon.
672*cdf0e10cSrcweir     // Older versions quoted the string and doubled embedded quotes, but not
673*cdf0e10cSrcweir     // the semicolons, which was plain wrong.
674*cdf0e10cSrcweir     if (eVersion >= SYLK_OOO32)
675*cdf0e10cSrcweir         rString.SearchAndReplaceAll( DOUBLE_SEMICOLON, ';' );
676*cdf0e10cSrcweir     else
677*cdf0e10cSrcweir         rString.SearchAndReplaceAll( DOUBLE_DOUBLEQUOTE, '"' );
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir     rString.SearchAndReplaceAll( SYLK_LF, _LF );
680*cdf0e10cSrcweir }
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir static const sal_Unicode* lcl_ScanSylkString( const sal_Unicode* p,
683*cdf0e10cSrcweir         String& rString, SylkVersion eVersion )
684*cdf0e10cSrcweir {
685*cdf0e10cSrcweir     const sal_Unicode* pStartQuote = p;
686*cdf0e10cSrcweir     const sal_Unicode* pEndQuote = 0;
687*cdf0e10cSrcweir     while( *(++p) )
688*cdf0e10cSrcweir     {
689*cdf0e10cSrcweir         if( *p == '"' )
690*cdf0e10cSrcweir         {
691*cdf0e10cSrcweir             pEndQuote = p;
692*cdf0e10cSrcweir             if (eVersion >= SYLK_OOO32)
693*cdf0e10cSrcweir             {
694*cdf0e10cSrcweir                 if (*(p+1) == ';')
695*cdf0e10cSrcweir                 {
696*cdf0e10cSrcweir                     if (*(p+2) == ';')
697*cdf0e10cSrcweir                     {
698*cdf0e10cSrcweir                         p += 2;     // escaped ';'
699*cdf0e10cSrcweir                         pEndQuote = 0;
700*cdf0e10cSrcweir                     }
701*cdf0e10cSrcweir                     else
702*cdf0e10cSrcweir                         break;      // end field
703*cdf0e10cSrcweir                 }
704*cdf0e10cSrcweir             }
705*cdf0e10cSrcweir             else
706*cdf0e10cSrcweir             {
707*cdf0e10cSrcweir                 if (*(p+1) == '"')
708*cdf0e10cSrcweir                 {
709*cdf0e10cSrcweir                     ++p;            // escaped '"'
710*cdf0e10cSrcweir                     pEndQuote = 0;
711*cdf0e10cSrcweir                 }
712*cdf0e10cSrcweir                 else if (*(p+1) == ';')
713*cdf0e10cSrcweir                     break;          // end field
714*cdf0e10cSrcweir             }
715*cdf0e10cSrcweir         }
716*cdf0e10cSrcweir     }
717*cdf0e10cSrcweir     if (!pEndQuote)
718*cdf0e10cSrcweir         pEndQuote = p;  // Take all data as string.
719*cdf0e10cSrcweir     rString.Append( pStartQuote + 1, sal::static_int_cast<xub_StrLen>( pEndQuote - pStartQuote - 1 ) );
720*cdf0e10cSrcweir     lcl_UnescapeSylk( rString, eVersion);
721*cdf0e10cSrcweir     return p;
722*cdf0e10cSrcweir }
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir static const sal_Unicode* lcl_ScanSylkFormula( const sal_Unicode* p,
725*cdf0e10cSrcweir         String& rString, SylkVersion eVersion )
726*cdf0e10cSrcweir {
727*cdf0e10cSrcweir     const sal_Unicode* pStart = p;
728*cdf0e10cSrcweir     if (eVersion >= SYLK_OOO32)
729*cdf0e10cSrcweir     {
730*cdf0e10cSrcweir         while (*p)
731*cdf0e10cSrcweir         {
732*cdf0e10cSrcweir             if (*p == ';')
733*cdf0e10cSrcweir             {
734*cdf0e10cSrcweir                 if (*(p+1) == ';')
735*cdf0e10cSrcweir                     ++p;        // escaped ';'
736*cdf0e10cSrcweir                 else
737*cdf0e10cSrcweir                     break;      // end field
738*cdf0e10cSrcweir             }
739*cdf0e10cSrcweir             ++p;
740*cdf0e10cSrcweir         }
741*cdf0e10cSrcweir         rString.Append( pStart, sal::static_int_cast<xub_StrLen>( p - pStart));
742*cdf0e10cSrcweir         lcl_UnescapeSylk( rString, eVersion);
743*cdf0e10cSrcweir     }
744*cdf0e10cSrcweir     else
745*cdf0e10cSrcweir     {
746*cdf0e10cSrcweir         // Nasty. If in old versions the formula contained a semicolon, it was
747*cdf0e10cSrcweir         // quoted and embedded quotes were doubled, but semicolons were not. If
748*cdf0e10cSrcweir         // there was no semicolon, it could still contain quotes and doubled
749*cdf0e10cSrcweir         // embedded quotes if it was something like ="a""b", which was saved as
750*cdf0e10cSrcweir         // E"a""b" as is and has to be preserved, even if older versions
751*cdf0e10cSrcweir         // couldn't even load it correctly. However, theoretically another
752*cdf0e10cSrcweir         // field might follow and thus the line contain a semicolon again, such
753*cdf0e10cSrcweir         // as ...;E"a""b";...
754*cdf0e10cSrcweir         bool bQuoted = false;
755*cdf0e10cSrcweir         if (*p == '"')
756*cdf0e10cSrcweir         {
757*cdf0e10cSrcweir             // May be a quoted expression or just a string constant expression
758*cdf0e10cSrcweir             // with quotes.
759*cdf0e10cSrcweir             while (*(++p))
760*cdf0e10cSrcweir             {
761*cdf0e10cSrcweir                 if (*p == '"')
762*cdf0e10cSrcweir                 {
763*cdf0e10cSrcweir                     if (*(p+1) == '"')
764*cdf0e10cSrcweir                         ++p;            // escaped '"'
765*cdf0e10cSrcweir                     else
766*cdf0e10cSrcweir                         break;          // closing '"', had no ';' yet
767*cdf0e10cSrcweir                 }
768*cdf0e10cSrcweir                 else if (*p == ';')
769*cdf0e10cSrcweir                 {
770*cdf0e10cSrcweir                     bQuoted = true;     // ';' within quoted expression
771*cdf0e10cSrcweir                     break;
772*cdf0e10cSrcweir                 }
773*cdf0e10cSrcweir             }
774*cdf0e10cSrcweir             p = pStart;
775*cdf0e10cSrcweir         }
776*cdf0e10cSrcweir         if (bQuoted)
777*cdf0e10cSrcweir             p = lcl_ScanSylkString( p, rString, eVersion);
778*cdf0e10cSrcweir         else
779*cdf0e10cSrcweir         {
780*cdf0e10cSrcweir             while (*p && *p != ';')
781*cdf0e10cSrcweir                 ++p;
782*cdf0e10cSrcweir             rString.Append( pStart, sal::static_int_cast<xub_StrLen>( p - pStart));
783*cdf0e10cSrcweir         }
784*cdf0e10cSrcweir     }
785*cdf0e10cSrcweir     return p;
786*cdf0e10cSrcweir }
787*cdf0e10cSrcweir 
788*cdf0e10cSrcweir static void lcl_DoubleEscapeChar( String& rString, sal_Unicode cStr )
789*cdf0e10cSrcweir {
790*cdf0e10cSrcweir 	xub_StrLen n = 0;
791*cdf0e10cSrcweir 	while( ( n = rString.Search( cStr, n ) ) != STRING_NOTFOUND )
792*cdf0e10cSrcweir 	{
793*cdf0e10cSrcweir 		rString.Insert( cStr, n );
794*cdf0e10cSrcweir 		n += 2;
795*cdf0e10cSrcweir 	}
796*cdf0e10cSrcweir }
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir static void lcl_WriteString( SvStream& rStrm, String& rString, sal_Unicode cQuote, sal_Unicode cEsc )
799*cdf0e10cSrcweir {
800*cdf0e10cSrcweir     if (cEsc)
801*cdf0e10cSrcweir         lcl_DoubleEscapeChar( rString, cEsc );
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir     if (cQuote)
804*cdf0e10cSrcweir     {
805*cdf0e10cSrcweir         rString.Insert( cQuote, 0 );
806*cdf0e10cSrcweir         rString.Append( cQuote );
807*cdf0e10cSrcweir     }
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir 	ScImportExport::WriteUnicodeOrByteString( rStrm, rString );
810*cdf0e10cSrcweir }
811*cdf0e10cSrcweir 
812*cdf0e10cSrcweir inline void lcl_WriteSimpleString( SvStream& rStrm, const String& rString )
813*cdf0e10cSrcweir {
814*cdf0e10cSrcweir 	ScImportExport::WriteUnicodeOrByteString( rStrm, rString );
815*cdf0e10cSrcweir }
816*cdf0e10cSrcweir 
817*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
818*cdf0e10cSrcweir 
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir sal_Bool ScImportExport::Text2Doc( SvStream& rStrm )
821*cdf0e10cSrcweir {
822*cdf0e10cSrcweir 	sal_Bool bOk = sal_True;
823*cdf0e10cSrcweir 
824*cdf0e10cSrcweir 	SCCOL nStartCol = aRange.aStart.Col();
825*cdf0e10cSrcweir 	SCROW nStartRow = aRange.aStart.Row();
826*cdf0e10cSrcweir 	SCCOL nEndCol = aRange.aEnd.Col();
827*cdf0e10cSrcweir 	SCROW nEndRow = aRange.aEnd.Row();
828*cdf0e10cSrcweir 	sal_uLong  nOldPos = rStrm.Tell();
829*cdf0e10cSrcweir     rStrm.StartReadingUnicodeText( rStrm.GetStreamCharSet() );
830*cdf0e10cSrcweir 	sal_Bool   bData = sal_Bool( !bSingle );
831*cdf0e10cSrcweir 	if( !bSingle)
832*cdf0e10cSrcweir 		bOk = StartPaste();
833*cdf0e10cSrcweir 
834*cdf0e10cSrcweir 	while( bOk )
835*cdf0e10cSrcweir 	{
836*cdf0e10cSrcweir 		ByteString aByteLine;
837*cdf0e10cSrcweir 		String aLine, aCell;
838*cdf0e10cSrcweir 		SCROW nRow = nStartRow;
839*cdf0e10cSrcweir 		rStrm.Seek( nOldPos );
840*cdf0e10cSrcweir 		for( ;; )
841*cdf0e10cSrcweir 		{
842*cdf0e10cSrcweir 			rStrm.ReadUniOrByteStringLine( aLine );
843*cdf0e10cSrcweir 			if( rStrm.IsEof() )
844*cdf0e10cSrcweir 				break;
845*cdf0e10cSrcweir 			SCCOL nCol = nStartCol;
846*cdf0e10cSrcweir 			const sal_Unicode* p = aLine.GetBuffer();
847*cdf0e10cSrcweir 			while( *p )
848*cdf0e10cSrcweir 			{
849*cdf0e10cSrcweir 				aCell.Erase();
850*cdf0e10cSrcweir 				if( *p == cStr )
851*cdf0e10cSrcweir 				{
852*cdf0e10cSrcweir 					p = lcl_ScanString( p, aCell, cStr, DQM_KEEP );
853*cdf0e10cSrcweir 					while( *p && *p != cSep )
854*cdf0e10cSrcweir 						p++;
855*cdf0e10cSrcweir 					if( *p )
856*cdf0e10cSrcweir 						p++;
857*cdf0e10cSrcweir 				}
858*cdf0e10cSrcweir 				else
859*cdf0e10cSrcweir 				{
860*cdf0e10cSrcweir 					const sal_Unicode* q = p;
861*cdf0e10cSrcweir 					while( *p && *p != cSep )
862*cdf0e10cSrcweir 						p++;
863*cdf0e10cSrcweir                     aCell.Assign( q, sal::static_int_cast<xub_StrLen>( p - q ) );
864*cdf0e10cSrcweir 					if( *p )
865*cdf0e10cSrcweir 						p++;
866*cdf0e10cSrcweir 				}
867*cdf0e10cSrcweir 				if (ValidCol(nCol) && ValidRow(nRow) )
868*cdf0e10cSrcweir 				{
869*cdf0e10cSrcweir 					if( bSingle )
870*cdf0e10cSrcweir 					{
871*cdf0e10cSrcweir 						if (nCol>nEndCol) nEndCol = nCol;
872*cdf0e10cSrcweir 						if (nRow>nEndRow) nEndRow = nRow;
873*cdf0e10cSrcweir 					}
874*cdf0e10cSrcweir 					if( bData && nCol <= nEndCol && nRow <= nEndRow )
875*cdf0e10cSrcweir 						pDoc->SetString( nCol, nRow, aRange.aStart.Tab(), aCell );
876*cdf0e10cSrcweir 				}
877*cdf0e10cSrcweir 				else							// zuviele Spalten/Zeilen
878*cdf0e10cSrcweir 					bOverflow = sal_True;			// beim Import Warnung ausgeben
879*cdf0e10cSrcweir 				++nCol;
880*cdf0e10cSrcweir 			}
881*cdf0e10cSrcweir 			++nRow;
882*cdf0e10cSrcweir 		}
883*cdf0e10cSrcweir 
884*cdf0e10cSrcweir 		if( !bData )
885*cdf0e10cSrcweir 		{
886*cdf0e10cSrcweir 			aRange.aEnd.SetCol( nEndCol );
887*cdf0e10cSrcweir 			aRange.aEnd.SetRow( nEndRow );
888*cdf0e10cSrcweir 			bOk = StartPaste();
889*cdf0e10cSrcweir 			bData = sal_True;
890*cdf0e10cSrcweir 		}
891*cdf0e10cSrcweir 		else
892*cdf0e10cSrcweir 			break;
893*cdf0e10cSrcweir 	}
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir 	EndPaste();
896*cdf0e10cSrcweir 	return bOk;
897*cdf0e10cSrcweir }
898*cdf0e10cSrcweir 
899*cdf0e10cSrcweir 		//
900*cdf0e10cSrcweir 		//	erweiterter Ascii-Import
901*cdf0e10cSrcweir 		//
902*cdf0e10cSrcweir 
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir static bool lcl_PutString(
905*cdf0e10cSrcweir     ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rStr, sal_uInt8 nColFormat,
906*cdf0e10cSrcweir     SvNumberFormatter* pFormatter, bool bDetectNumFormat,
907*cdf0e10cSrcweir     ::utl::TransliterationWrapper& rTransliteration, CalendarWrapper& rCalendar,
908*cdf0e10cSrcweir     ::utl::TransliterationWrapper* pSecondTransliteration, CalendarWrapper* pSecondCalendar )
909*cdf0e10cSrcweir {
910*cdf0e10cSrcweir     bool bMultiLine = false;
911*cdf0e10cSrcweir 	if ( nColFormat == SC_COL_SKIP || !rStr.Len() || !ValidCol(nCol) || !ValidRow(nRow) )
912*cdf0e10cSrcweir 		return bMultiLine;
913*cdf0e10cSrcweir 
914*cdf0e10cSrcweir 	if ( nColFormat == SC_COL_TEXT )
915*cdf0e10cSrcweir 	{
916*cdf0e10cSrcweir 		pDoc->PutCell( nCol, nRow, nTab, ScBaseCell::CreateTextCell( rStr, pDoc ) );
917*cdf0e10cSrcweir 		return bMultiLine;
918*cdf0e10cSrcweir 	}
919*cdf0e10cSrcweir 
920*cdf0e10cSrcweir 	if ( nColFormat == SC_COL_ENGLISH )
921*cdf0e10cSrcweir 	{
922*cdf0e10cSrcweir 		//!	SetString mit Extra-Flag ???
923*cdf0e10cSrcweir 
924*cdf0e10cSrcweir         SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable();
925*cdf0e10cSrcweir         sal_uInt32 nEnglish = pDocFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
926*cdf0e10cSrcweir 		double fVal;
927*cdf0e10cSrcweir         if ( pDocFormatter->IsNumberFormat( rStr, nEnglish, fVal ) )
928*cdf0e10cSrcweir 		{
929*cdf0e10cSrcweir 			//	Zahlformat wird nicht auf englisch gesetzt
930*cdf0e10cSrcweir 			pDoc->SetValue( nCol, nRow, nTab, fVal );
931*cdf0e10cSrcweir 			return bMultiLine;
932*cdf0e10cSrcweir 		}
933*cdf0e10cSrcweir 		//	sonst weiter mit SetString
934*cdf0e10cSrcweir 	}
935*cdf0e10cSrcweir 	else if ( nColFormat != SC_COL_STANDARD )					// Datumsformate
936*cdf0e10cSrcweir 	{
937*cdf0e10cSrcweir         const sal_uInt16 nMaxNumberParts = 7;   // Y-M-D h:m:s.t
938*cdf0e10cSrcweir 		xub_StrLen nLen = rStr.Len();
939*cdf0e10cSrcweir 		xub_StrLen nStart[nMaxNumberParts];
940*cdf0e10cSrcweir 		xub_StrLen nEnd[nMaxNumberParts];
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir         sal_uInt16 nDP, nMP, nYP;
943*cdf0e10cSrcweir         switch ( nColFormat )
944*cdf0e10cSrcweir         {
945*cdf0e10cSrcweir             case SC_COL_YMD: nDP = 2; nMP = 1; nYP = 0; break;
946*cdf0e10cSrcweir             case SC_COL_MDY: nDP = 1; nMP = 0; nYP = 2; break;
947*cdf0e10cSrcweir             case SC_COL_DMY:
948*cdf0e10cSrcweir             default:         nDP = 0; nMP = 1; nYP = 2; break;
949*cdf0e10cSrcweir         }
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir 		sal_uInt16 nFound = 0;
952*cdf0e10cSrcweir 		sal_Bool bInNum = sal_False;
953*cdf0e10cSrcweir         for ( xub_StrLen nPos=0; nPos<nLen && (bInNum ||
954*cdf0e10cSrcweir                     nFound<nMaxNumberParts); nPos++ )
955*cdf0e10cSrcweir 		{
956*cdf0e10cSrcweir             if (bInNum && nFound == 3 && nColFormat == SC_COL_YMD &&
957*cdf0e10cSrcweir                     nPos <= nStart[nFound]+2 && rStr.GetChar(nPos) == 'T')
958*cdf0e10cSrcweir                 bInNum = sal_False;     // ISO-8601: YYYY-MM-DDThh:mm...
959*cdf0e10cSrcweir             else if ((((!bInNum && nFound==nMP) || (bInNum && nFound==nMP+1))
960*cdf0e10cSrcweir                         && ScGlobal::pCharClass->isLetterNumeric( rStr, nPos))
961*cdf0e10cSrcweir                     || ScGlobal::pCharClass->isDigit( rStr, nPos))
962*cdf0e10cSrcweir 			{
963*cdf0e10cSrcweir                 if (!bInNum)
964*cdf0e10cSrcweir                 {
965*cdf0e10cSrcweir                     bInNum = sal_True;
966*cdf0e10cSrcweir                     nStart[nFound] = nPos;
967*cdf0e10cSrcweir                     ++nFound;
968*cdf0e10cSrcweir                 }
969*cdf0e10cSrcweir                 nEnd[nFound-1] = nPos;
970*cdf0e10cSrcweir 			}
971*cdf0e10cSrcweir 			else
972*cdf0e10cSrcweir 				bInNum = sal_False;
973*cdf0e10cSrcweir 		}
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir 		if ( nFound == 1 )
976*cdf0e10cSrcweir 		{
977*cdf0e10cSrcweir 			//	try to break one number (without separators) into date fields
978*cdf0e10cSrcweir 
979*cdf0e10cSrcweir 			xub_StrLen nDateStart = nStart[0];
980*cdf0e10cSrcweir 			xub_StrLen nDateLen = nEnd[0] + 1 - nDateStart;
981*cdf0e10cSrcweir 
982*cdf0e10cSrcweir 			if ( nDateLen >= 5 && nDateLen <= 8 &&
983*cdf0e10cSrcweir 					ScGlobal::pCharClass->isNumeric( rStr.Copy( nDateStart, nDateLen ) ) )
984*cdf0e10cSrcweir 			{
985*cdf0e10cSrcweir 				//	6 digits: 2 each for day, month, year
986*cdf0e10cSrcweir 				//	8 digits: 4 for year, 2 each for day and month
987*cdf0e10cSrcweir 				//	5 or 7 digits: first field is shortened by 1
988*cdf0e10cSrcweir 
989*cdf0e10cSrcweir 				sal_Bool bLongYear = ( nDateLen >= 7 );
990*cdf0e10cSrcweir 				sal_Bool bShortFirst = ( nDateLen == 5 || nDateLen == 7 );
991*cdf0e10cSrcweir 
992*cdf0e10cSrcweir 				sal_uInt16 nFieldStart = nDateStart;
993*cdf0e10cSrcweir 				for (sal_uInt16 nPos=0; nPos<3; nPos++)
994*cdf0e10cSrcweir 				{
995*cdf0e10cSrcweir 					sal_uInt16 nFieldEnd = nFieldStart + 1;		// default: 2 digits
996*cdf0e10cSrcweir 					if ( bLongYear && nPos == nYP )
997*cdf0e10cSrcweir 						nFieldEnd += 2;						// 2 extra digits for long year
998*cdf0e10cSrcweir 					if ( bShortFirst && nPos == 0 )
999*cdf0e10cSrcweir 						--nFieldEnd;						// first field shortened?
1000*cdf0e10cSrcweir 
1001*cdf0e10cSrcweir 					nStart[nPos] = nFieldStart;
1002*cdf0e10cSrcweir 					nEnd[nPos]   = nFieldEnd;
1003*cdf0e10cSrcweir 					nFieldStart  = nFieldEnd + 1;
1004*cdf0e10cSrcweir 				}
1005*cdf0e10cSrcweir 				nFound = 3;
1006*cdf0e10cSrcweir 			}
1007*cdf0e10cSrcweir 		}
1008*cdf0e10cSrcweir 
1009*cdf0e10cSrcweir 		if ( nFound >= 3 )
1010*cdf0e10cSrcweir 		{
1011*cdf0e10cSrcweir 			using namespace ::com::sun::star;
1012*cdf0e10cSrcweir 			sal_Bool bSecondCal = sal_False;
1013*cdf0e10cSrcweir 			sal_uInt16 nDay  = (sal_uInt16) rStr.Copy( nStart[nDP], nEnd[nDP]+1-nStart[nDP] ).ToInt32();
1014*cdf0e10cSrcweir 			sal_uInt16 nYear = (sal_uInt16) rStr.Copy( nStart[nYP], nEnd[nYP]+1-nStart[nYP] ).ToInt32();
1015*cdf0e10cSrcweir 			String aMStr = rStr.Copy( nStart[nMP], nEnd[nMP]+1-nStart[nMP] );
1016*cdf0e10cSrcweir 			sal_Int16 nMonth = (sal_Int16) aMStr.ToInt32();
1017*cdf0e10cSrcweir 			if (!nMonth)
1018*cdf0e10cSrcweir 			{
1019*cdf0e10cSrcweir                 static const String aSeptCorrect( RTL_CONSTASCII_USTRINGPARAM( "SEPT" ) );
1020*cdf0e10cSrcweir                 static const String aSepShortened( RTL_CONSTASCII_USTRINGPARAM( "SEP" ) );
1021*cdf0e10cSrcweir 				uno::Sequence< i18n::CalendarItem > xMonths;
1022*cdf0e10cSrcweir                 sal_Int32 i, nMonthCount;
1023*cdf0e10cSrcweir 				//	first test all month names from local international
1024*cdf0e10cSrcweir 				xMonths = rCalendar.getMonths();
1025*cdf0e10cSrcweir                 nMonthCount = xMonths.getLength();
1026*cdf0e10cSrcweir                 for (i=0; i<nMonthCount && !nMonth; i++)
1027*cdf0e10cSrcweir 				{
1028*cdf0e10cSrcweir                     if ( rTransliteration.isEqual( aMStr, xMonths[i].FullName ) ||
1029*cdf0e10cSrcweir                          rTransliteration.isEqual( aMStr, xMonths[i].AbbrevName ) )
1030*cdf0e10cSrcweir                         nMonth = sal::static_int_cast<sal_Int16>( i+1 );
1031*cdf0e10cSrcweir                     else if ( i == 8 && rTransliteration.isEqual( aSeptCorrect,
1032*cdf0e10cSrcweir                                 xMonths[i].AbbrevName ) &&
1033*cdf0e10cSrcweir                             rTransliteration.isEqual( aMStr, aSepShortened ) )
1034*cdf0e10cSrcweir                     {   // #102136# correct English abbreviation is SEPT,
1035*cdf0e10cSrcweir                         // but data mostly contains SEP only
1036*cdf0e10cSrcweir                         nMonth = sal::static_int_cast<sal_Int16>( i+1 );
1037*cdf0e10cSrcweir                     }
1038*cdf0e10cSrcweir 				}
1039*cdf0e10cSrcweir 				//	if none found, then test english month names
1040*cdf0e10cSrcweir                 if ( !nMonth && pSecondCalendar && pSecondTransliteration )
1041*cdf0e10cSrcweir 				{
1042*cdf0e10cSrcweir 					xMonths = pSecondCalendar->getMonths();
1043*cdf0e10cSrcweir                     nMonthCount = xMonths.getLength();
1044*cdf0e10cSrcweir                     for (i=0; i<nMonthCount && !nMonth; i++)
1045*cdf0e10cSrcweir 					{
1046*cdf0e10cSrcweir                         if ( pSecondTransliteration->isEqual( aMStr, xMonths[i].FullName ) ||
1047*cdf0e10cSrcweir                              pSecondTransliteration->isEqual( aMStr, xMonths[i].AbbrevName ) )
1048*cdf0e10cSrcweir 						{
1049*cdf0e10cSrcweir                             nMonth = sal::static_int_cast<sal_Int16>( i+1 );
1050*cdf0e10cSrcweir 							bSecondCal = sal_True;
1051*cdf0e10cSrcweir 						}
1052*cdf0e10cSrcweir                         else if ( i == 8 && pSecondTransliteration->isEqual(
1053*cdf0e10cSrcweir                                     aMStr, aSepShortened ) )
1054*cdf0e10cSrcweir                         {   // #102136# correct English abbreviation is SEPT,
1055*cdf0e10cSrcweir                             // but data mostly contains SEP only
1056*cdf0e10cSrcweir                             nMonth = sal::static_int_cast<sal_Int16>( i+1 );
1057*cdf0e10cSrcweir 							bSecondCal = sal_True;
1058*cdf0e10cSrcweir                         }
1059*cdf0e10cSrcweir 					}
1060*cdf0e10cSrcweir 				}
1061*cdf0e10cSrcweir 			}
1062*cdf0e10cSrcweir 
1063*cdf0e10cSrcweir             SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable();
1064*cdf0e10cSrcweir 			if ( nYear < 100 )
1065*cdf0e10cSrcweir                 nYear = pDocFormatter->ExpandTwoDigitYear( nYear );
1066*cdf0e10cSrcweir 
1067*cdf0e10cSrcweir 			CalendarWrapper* pCalendar = (bSecondCal ? pSecondCalendar : &rCalendar);
1068*cdf0e10cSrcweir 			sal_Int16 nNumMonths = pCalendar->getNumberOfMonthsInYear();
1069*cdf0e10cSrcweir 			if ( nDay && nMonth && nDay<=31 && nMonth<=nNumMonths )
1070*cdf0e10cSrcweir 			{
1071*cdf0e10cSrcweir 				--nMonth;
1072*cdf0e10cSrcweir 				pCalendar->setValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, nDay );
1073*cdf0e10cSrcweir 				pCalendar->setValue( i18n::CalendarFieldIndex::MONTH, nMonth );
1074*cdf0e10cSrcweir 				pCalendar->setValue( i18n::CalendarFieldIndex::YEAR, nYear );
1075*cdf0e10cSrcweir                 sal_Int16 nHour, nMinute, nSecond, nMilli;
1076*cdf0e10cSrcweir                 // #i14974# The imported value should have no fractional value, so set the
1077*cdf0e10cSrcweir                 // time fields to zero (ICU calendar instance defaults to current date/time)
1078*cdf0e10cSrcweir                 nHour = nMinute = nSecond = nMilli = 0;
1079*cdf0e10cSrcweir                 if (nFound > 3)
1080*cdf0e10cSrcweir                     nHour = (sal_Int16) rStr.Copy( nStart[3], nEnd[3]+1-nStart[3]).ToInt32();
1081*cdf0e10cSrcweir                 if (nFound > 4)
1082*cdf0e10cSrcweir                     nMinute = (sal_Int16) rStr.Copy( nStart[4], nEnd[4]+1-nStart[4]).ToInt32();
1083*cdf0e10cSrcweir                 if (nFound > 5)
1084*cdf0e10cSrcweir                     nSecond = (sal_Int16) rStr.Copy( nStart[5], nEnd[5]+1-nStart[5]).ToInt32();
1085*cdf0e10cSrcweir                 if (nFound > 6)
1086*cdf0e10cSrcweir                 {
1087*cdf0e10cSrcweir                     sal_Unicode cDec = '.';
1088*cdf0e10cSrcweir                     rtl::OUString aT( &cDec, 1);
1089*cdf0e10cSrcweir                     aT += rStr.Copy( nStart[6], nEnd[6]+1-nStart[6]);
1090*cdf0e10cSrcweir                     rtl_math_ConversionStatus eStatus;
1091*cdf0e10cSrcweir                     double fV = rtl::math::stringToDouble( aT, cDec, 0, &eStatus, 0);
1092*cdf0e10cSrcweir                     if (eStatus == rtl_math_ConversionStatus_Ok)
1093*cdf0e10cSrcweir                         nMilli = (sal_Int16) (1000.0 * fV + 0.5);
1094*cdf0e10cSrcweir                 }
1095*cdf0e10cSrcweir                 pCalendar->setValue( i18n::CalendarFieldIndex::HOUR, nHour );
1096*cdf0e10cSrcweir                 pCalendar->setValue( i18n::CalendarFieldIndex::MINUTE, nMinute );
1097*cdf0e10cSrcweir                 pCalendar->setValue( i18n::CalendarFieldIndex::SECOND, nSecond );
1098*cdf0e10cSrcweir                 pCalendar->setValue( i18n::CalendarFieldIndex::MILLISECOND, nMilli );
1099*cdf0e10cSrcweir                 if ( pCalendar->isValid() )
1100*cdf0e10cSrcweir                 {
1101*cdf0e10cSrcweir                     double fDiff = DateTime(*pDocFormatter->GetNullDate()) -
1102*cdf0e10cSrcweir                         pCalendar->getEpochStart();
1103*cdf0e10cSrcweir                     // #i14974# must use getLocalDateTime to get the same
1104*cdf0e10cSrcweir                     // date values as set above
1105*cdf0e10cSrcweir                     double fDays = pCalendar->getLocalDateTime();
1106*cdf0e10cSrcweir                     fDays -= fDiff;
1107*cdf0e10cSrcweir 
1108*cdf0e10cSrcweir                     LanguageType eLatin, eCjk, eCtl;
1109*cdf0e10cSrcweir                     pDoc->GetLanguage( eLatin, eCjk, eCtl );
1110*cdf0e10cSrcweir                     LanguageType eDocLang = eLatin;     //! which language for date formats?
1111*cdf0e10cSrcweir 
1112*cdf0e10cSrcweir                     short nType = (nFound > 3 ? NUMBERFORMAT_DATETIME : NUMBERFORMAT_DATE);
1113*cdf0e10cSrcweir                     sal_uLong nFormat = pDocFormatter->GetStandardFormat( nType, eDocLang );
1114*cdf0e10cSrcweir                     // maybe there is a special format including seconds or milliseconds
1115*cdf0e10cSrcweir                     if (nFound > 5)
1116*cdf0e10cSrcweir                         nFormat = pDocFormatter->GetStandardFormat( fDays, nFormat, nType, eDocLang);
1117*cdf0e10cSrcweir 
1118*cdf0e10cSrcweir                     pDoc->PutCell( nCol, nRow, nTab, new ScValueCell(fDays), nFormat, sal_False );
1119*cdf0e10cSrcweir 
1120*cdf0e10cSrcweir                     return bMultiLine;     // success
1121*cdf0e10cSrcweir                 }
1122*cdf0e10cSrcweir 			}
1123*cdf0e10cSrcweir 		}
1124*cdf0e10cSrcweir 	}
1125*cdf0e10cSrcweir 
1126*cdf0e10cSrcweir     // Standard or date not determined -> SetString / EditCell
1127*cdf0e10cSrcweir     if( rStr.Search( _LF ) == STRING_NOTFOUND )
1128*cdf0e10cSrcweir         pDoc->SetString( nCol, nRow, nTab, rStr, pFormatter, bDetectNumFormat );
1129*cdf0e10cSrcweir     else
1130*cdf0e10cSrcweir     {
1131*cdf0e10cSrcweir         bMultiLine = true;
1132*cdf0e10cSrcweir         pDoc->PutCell( nCol, nRow, nTab, new ScEditCell( rStr, pDoc ) );
1133*cdf0e10cSrcweir     }
1134*cdf0e10cSrcweir     return bMultiLine;
1135*cdf0e10cSrcweir }
1136*cdf0e10cSrcweir 
1137*cdf0e10cSrcweir 
1138*cdf0e10cSrcweir String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext, bool& rbIsQuoted )
1139*cdf0e10cSrcweir {
1140*cdf0e10cSrcweir 	xub_StrLen nLen = rLine.Len();
1141*cdf0e10cSrcweir 	if (nNext > nLen)
1142*cdf0e10cSrcweir 		nNext = nLen;
1143*cdf0e10cSrcweir 	if ( nNext <= nStart )
1144*cdf0e10cSrcweir 		return EMPTY_STRING;
1145*cdf0e10cSrcweir 
1146*cdf0e10cSrcweir 	const sal_Unicode* pStr = rLine.GetBuffer();
1147*cdf0e10cSrcweir 
1148*cdf0e10cSrcweir 	xub_StrLen nSpace = nNext;
1149*cdf0e10cSrcweir 	while ( nSpace > nStart && pStr[nSpace-1] == ' ' )
1150*cdf0e10cSrcweir 		--nSpace;
1151*cdf0e10cSrcweir 
1152*cdf0e10cSrcweir     rbIsQuoted = (pStr[nStart] == sal_Unicode('"') && pStr[nSpace-1] == sal_Unicode('"'));
1153*cdf0e10cSrcweir     if (rbIsQuoted)
1154*cdf0e10cSrcweir         return rLine.Copy(nStart+1, nSpace-nStart-2);
1155*cdf0e10cSrcweir     else
1156*cdf0e10cSrcweir         return rLine.Copy(nStart, nSpace-nStart);
1157*cdf0e10cSrcweir }
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir sal_Bool ScImportExport::ExtText2Doc( SvStream& rStrm )
1160*cdf0e10cSrcweir {
1161*cdf0e10cSrcweir 	if (!pExtOptions)
1162*cdf0e10cSrcweir 		return Text2Doc( rStrm );
1163*cdf0e10cSrcweir 
1164*cdf0e10cSrcweir 	sal_uLong nOldPos = rStrm.Tell();
1165*cdf0e10cSrcweir 	rStrm.Seek( STREAM_SEEK_TO_END );
1166*cdf0e10cSrcweir     ::std::auto_ptr<ScProgress> xProgress( new ScProgress( pDocSh,
1167*cdf0e10cSrcweir             ScGlobal::GetRscString( STR_LOAD_DOC ), rStrm.Tell() - nOldPos ));
1168*cdf0e10cSrcweir 	rStrm.Seek( nOldPos );
1169*cdf0e10cSrcweir     rStrm.StartReadingUnicodeText( rStrm.GetStreamCharSet() );
1170*cdf0e10cSrcweir 
1171*cdf0e10cSrcweir 	sal_Bool bOld = ScColumn::bDoubleAlloc;
1172*cdf0e10cSrcweir 	ScColumn::bDoubleAlloc = sal_True;
1173*cdf0e10cSrcweir 
1174*cdf0e10cSrcweir 	SCCOL nStartCol = aRange.aStart.Col();
1175*cdf0e10cSrcweir     SCCOL nEndCol = aRange.aEnd.Col();
1176*cdf0e10cSrcweir 	SCROW nStartRow = aRange.aStart.Row();
1177*cdf0e10cSrcweir 	SCTAB nTab = aRange.aStart.Tab();
1178*cdf0e10cSrcweir 
1179*cdf0e10cSrcweir 	sal_Bool	bFixed			= pExtOptions->IsFixedLen();
1180*cdf0e10cSrcweir 	const String& rSeps     = pExtOptions->GetFieldSeps();
1181*cdf0e10cSrcweir 	const sal_Unicode* pSeps = rSeps.GetBuffer();
1182*cdf0e10cSrcweir 	sal_Bool	bMerge			= pExtOptions->IsMergeSeps();
1183*cdf0e10cSrcweir 	sal_uInt16	nInfoCount		= pExtOptions->GetInfoCount();
1184*cdf0e10cSrcweir 	const xub_StrLen* pColStart = pExtOptions->GetColStart();
1185*cdf0e10cSrcweir 	const sal_uInt8* pColFormat  = pExtOptions->GetColFormat();
1186*cdf0e10cSrcweir 	long nSkipLines	= pExtOptions->GetStartRow();
1187*cdf0e10cSrcweir 
1188*cdf0e10cSrcweir     LanguageType eDocLang = pExtOptions->GetLanguage();
1189*cdf0e10cSrcweir     SvNumberFormatter aNumFormatter(pDoc->GetServiceManager(), eDocLang);
1190*cdf0e10cSrcweir     bool bDetectNumFormat = pExtOptions->IsDetectSpecialNumber();
1191*cdf0e10cSrcweir 
1192*cdf0e10cSrcweir 	// For date recognition
1193*cdf0e10cSrcweir     ::utl::TransliterationWrapper aTransliteration(
1194*cdf0e10cSrcweir         pDoc->GetServiceManager(), SC_TRANSLITERATION_IGNORECASE );
1195*cdf0e10cSrcweir     aTransliteration.loadModuleIfNeeded( eDocLang );
1196*cdf0e10cSrcweir 	CalendarWrapper aCalendar( pDoc->GetServiceManager() );
1197*cdf0e10cSrcweir 	aCalendar.loadDefaultCalendar(
1198*cdf0e10cSrcweir 		MsLangId::convertLanguageToLocale( eDocLang ) );
1199*cdf0e10cSrcweir     ::utl::TransliterationWrapper* pEnglishTransliteration = NULL;
1200*cdf0e10cSrcweir 	CalendarWrapper* pEnglishCalendar = NULL;
1201*cdf0e10cSrcweir 	if ( eDocLang != LANGUAGE_ENGLISH_US )
1202*cdf0e10cSrcweir 	{
1203*cdf0e10cSrcweir         pEnglishTransliteration = new ::utl::TransliterationWrapper (
1204*cdf0e10cSrcweir             pDoc->GetServiceManager(), SC_TRANSLITERATION_IGNORECASE );
1205*cdf0e10cSrcweir         aTransliteration.loadModuleIfNeeded( LANGUAGE_ENGLISH_US );
1206*cdf0e10cSrcweir 		pEnglishCalendar = new CalendarWrapper ( pDoc->GetServiceManager() );
1207*cdf0e10cSrcweir 		pEnglishCalendar->loadDefaultCalendar(
1208*cdf0e10cSrcweir 			MsLangId::convertLanguageToLocale( LANGUAGE_ENGLISH_US ) );
1209*cdf0e10cSrcweir 	}
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir 	String aLine, aCell;
1212*cdf0e10cSrcweir 	sal_uInt16 i;
1213*cdf0e10cSrcweir 	SCROW nRow = nStartRow;
1214*cdf0e10cSrcweir 
1215*cdf0e10cSrcweir 	while(--nSkipLines>0)
1216*cdf0e10cSrcweir 	{
1217*cdf0e10cSrcweir 		rStrm.ReadCsvLine( aLine, !bFixed, rSeps, cStr); // content is ignored
1218*cdf0e10cSrcweir 		if ( rStrm.IsEof() )
1219*cdf0e10cSrcweir 			break;
1220*cdf0e10cSrcweir 	}
1221*cdf0e10cSrcweir 
1222*cdf0e10cSrcweir     // Determine range for Undo.
1223*cdf0e10cSrcweir     // TODO: we don't need this during import of a file to a new sheet or
1224*cdf0e10cSrcweir     // document, could set bDetermineRange=false then.
1225*cdf0e10cSrcweir     bool bDetermineRange = true;
1226*cdf0e10cSrcweir 
1227*cdf0e10cSrcweir     // Row heights don't need to be adjusted on the fly if EndPaste() is called
1228*cdf0e10cSrcweir     // afterwards, which happens only if bDetermineRange. This variable also
1229*cdf0e10cSrcweir     // survives the toggle of bDetermineRange down at the end of the do{} loop.
1230*cdf0e10cSrcweir     bool bRangeIsDetermined = bDetermineRange;
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir     bool bQuotedAsText = pExtOptions && pExtOptions->IsQuotedAsText();
1233*cdf0e10cSrcweir 
1234*cdf0e10cSrcweir     sal_uLong nOriginalStreamPos = rStrm.Tell();
1235*cdf0e10cSrcweir 
1236*cdf0e10cSrcweir     do
1237*cdf0e10cSrcweir     {
1238*cdf0e10cSrcweir         for( ;; )
1239*cdf0e10cSrcweir         {
1240*cdf0e10cSrcweir             rStrm.ReadCsvLine( aLine, !bFixed, rSeps, cStr);
1241*cdf0e10cSrcweir             if ( rStrm.IsEof() )
1242*cdf0e10cSrcweir                 break;
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir             xub_StrLen nLineLen = aLine.Len();
1245*cdf0e10cSrcweir             SCCOL nCol = nStartCol;
1246*cdf0e10cSrcweir             bool bMultiLine = false;
1247*cdf0e10cSrcweir             if ( bFixed )				//	Feste Satzlaenge
1248*cdf0e10cSrcweir             {
1249*cdf0e10cSrcweir                 // Yes, the check is nCol<=MAXCOL+1, +1 because it is only an
1250*cdf0e10cSrcweir                 // overflow if there is really data following to be put behind
1251*cdf0e10cSrcweir                 // the last column, which doesn't happen if info is
1252*cdf0e10cSrcweir                 // SC_COL_SKIP.
1253*cdf0e10cSrcweir                 for ( i=0; i<nInfoCount && nCol <= MAXCOL+1; i++ )
1254*cdf0e10cSrcweir                 {
1255*cdf0e10cSrcweir                     sal_uInt8 nFmt = pColFormat[i];
1256*cdf0e10cSrcweir                     if (nFmt != SC_COL_SKIP)        // sonst auch nCol nicht hochzaehlen
1257*cdf0e10cSrcweir                     {
1258*cdf0e10cSrcweir                         if (nCol > MAXCOL)
1259*cdf0e10cSrcweir                             bOverflow = sal_True;       // display warning on import
1260*cdf0e10cSrcweir                         else if (!bDetermineRange)
1261*cdf0e10cSrcweir                         {
1262*cdf0e10cSrcweir                             xub_StrLen nStart = pColStart[i];
1263*cdf0e10cSrcweir                             xub_StrLen nNext = ( i+1 < nInfoCount ) ? pColStart[i+1] : nLineLen;
1264*cdf0e10cSrcweir                             bool bIsQuoted = false;
1265*cdf0e10cSrcweir                             aCell = lcl_GetFixed( aLine, nStart, nNext, bIsQuoted );
1266*cdf0e10cSrcweir                             if (bIsQuoted && bQuotedAsText)
1267*cdf0e10cSrcweir                                 nFmt = SC_COL_TEXT;
1268*cdf0e10cSrcweir 
1269*cdf0e10cSrcweir                             bMultiLine |= lcl_PutString(
1270*cdf0e10cSrcweir                                 pDoc, nCol, nRow, nTab, aCell, nFmt,
1271*cdf0e10cSrcweir                                 &aNumFormatter, bDetectNumFormat, aTransliteration, aCalendar,
1272*cdf0e10cSrcweir                                 pEnglishTransliteration, pEnglishCalendar);
1273*cdf0e10cSrcweir                         }
1274*cdf0e10cSrcweir                         ++nCol;
1275*cdf0e10cSrcweir                     }
1276*cdf0e10cSrcweir                 }
1277*cdf0e10cSrcweir             }
1278*cdf0e10cSrcweir             else						//	Nach Trennzeichen suchen
1279*cdf0e10cSrcweir             {
1280*cdf0e10cSrcweir                 SCCOL nSourceCol = 0;
1281*cdf0e10cSrcweir                 sal_uInt16 nInfoStart = 0;
1282*cdf0e10cSrcweir                 const sal_Unicode* p = aLine.GetBuffer();
1283*cdf0e10cSrcweir                 // Yes, the check is nCol<=MAXCOL+1, +1 because it is only an
1284*cdf0e10cSrcweir                 // overflow if there is really data following to be put behind
1285*cdf0e10cSrcweir                 // the last column, which doesn't happen if info is
1286*cdf0e10cSrcweir                 // SC_COL_SKIP.
1287*cdf0e10cSrcweir                 while (*p && nCol <= MAXCOL+1)
1288*cdf0e10cSrcweir                 {
1289*cdf0e10cSrcweir                     bool bIsQuoted = false;
1290*cdf0e10cSrcweir                     p = ScImportExport::ScanNextFieldFromString( p, aCell, cStr, pSeps, bMerge, bIsQuoted );
1291*cdf0e10cSrcweir 
1292*cdf0e10cSrcweir                     sal_uInt8 nFmt = SC_COL_STANDARD;
1293*cdf0e10cSrcweir                     for ( i=nInfoStart; i<nInfoCount; i++ )
1294*cdf0e10cSrcweir                     {
1295*cdf0e10cSrcweir                         if ( pColStart[i] == nSourceCol + 1 )		// pColStart ist 1-basiert
1296*cdf0e10cSrcweir                         {
1297*cdf0e10cSrcweir                             nFmt = pColFormat[i];
1298*cdf0e10cSrcweir                             nInfoStart = i + 1;		// ColInfos sind in Reihenfolge
1299*cdf0e10cSrcweir                             break;	// for
1300*cdf0e10cSrcweir                         }
1301*cdf0e10cSrcweir                     }
1302*cdf0e10cSrcweir                     if ( nFmt != SC_COL_SKIP )
1303*cdf0e10cSrcweir                     {
1304*cdf0e10cSrcweir                         if (nCol > MAXCOL)
1305*cdf0e10cSrcweir                             bOverflow = sal_True;       // display warning on import
1306*cdf0e10cSrcweir                         else if (!bDetermineRange)
1307*cdf0e10cSrcweir                         {
1308*cdf0e10cSrcweir                             if (bIsQuoted && bQuotedAsText)
1309*cdf0e10cSrcweir                                 nFmt = SC_COL_TEXT;
1310*cdf0e10cSrcweir 
1311*cdf0e10cSrcweir                             bMultiLine |= lcl_PutString(
1312*cdf0e10cSrcweir                                 pDoc, nCol, nRow, nTab, aCell, nFmt,
1313*cdf0e10cSrcweir                                 &aNumFormatter, bDetectNumFormat, aTransliteration,
1314*cdf0e10cSrcweir                                 aCalendar, pEnglishTransliteration, pEnglishCalendar);
1315*cdf0e10cSrcweir                         }
1316*cdf0e10cSrcweir                         ++nCol;
1317*cdf0e10cSrcweir                     }
1318*cdf0e10cSrcweir 
1319*cdf0e10cSrcweir                     ++nSourceCol;
1320*cdf0e10cSrcweir                 }
1321*cdf0e10cSrcweir             }
1322*cdf0e10cSrcweir             if (nEndCol < nCol)
1323*cdf0e10cSrcweir                 nEndCol = nCol;     //! points to the next free or even MAXCOL+2
1324*cdf0e10cSrcweir 
1325*cdf0e10cSrcweir             if (!bDetermineRange)
1326*cdf0e10cSrcweir             {
1327*cdf0e10cSrcweir                 if (bMultiLine && !bRangeIsDetermined && pDocSh)
1328*cdf0e10cSrcweir                     pDocSh->AdjustRowHeight( nRow, nRow, nTab);
1329*cdf0e10cSrcweir                 xProgress->SetStateOnPercent( rStrm.Tell() - nOldPos );
1330*cdf0e10cSrcweir             }
1331*cdf0e10cSrcweir             ++nRow;
1332*cdf0e10cSrcweir             if ( nRow > MAXROW )
1333*cdf0e10cSrcweir             {
1334*cdf0e10cSrcweir                 bOverflow = sal_True;       // display warning on import
1335*cdf0e10cSrcweir                 break;  // for
1336*cdf0e10cSrcweir             }
1337*cdf0e10cSrcweir         }
1338*cdf0e10cSrcweir         // so far nRow/nEndCol pointed to the next free
1339*cdf0e10cSrcweir         if (nRow > nStartRow)
1340*cdf0e10cSrcweir             --nRow;
1341*cdf0e10cSrcweir         if (nEndCol > nStartCol)
1342*cdf0e10cSrcweir             nEndCol = ::std::min( static_cast<SCCOL>(nEndCol - 1), MAXCOL);
1343*cdf0e10cSrcweir 
1344*cdf0e10cSrcweir         if (bDetermineRange)
1345*cdf0e10cSrcweir         {
1346*cdf0e10cSrcweir             aRange.aEnd.SetCol( nEndCol );
1347*cdf0e10cSrcweir             aRange.aEnd.SetRow( nRow );
1348*cdf0e10cSrcweir 
1349*cdf0e10cSrcweir             if ( !mbApi && nStartCol != nEndCol &&
1350*cdf0e10cSrcweir                  !pDoc->IsBlockEmpty( nTab, nStartCol + 1, nStartRow, nEndCol, nRow ) )
1351*cdf0e10cSrcweir             {
1352*cdf0e10cSrcweir                 ScReplaceWarnBox aBox( pDocSh->GetActiveDialogParent() );
1353*cdf0e10cSrcweir                 if ( aBox.Execute() != RET_YES )
1354*cdf0e10cSrcweir                 {
1355*cdf0e10cSrcweir                     delete pEnglishTransliteration;
1356*cdf0e10cSrcweir                     delete pEnglishCalendar;
1357*cdf0e10cSrcweir                     return sal_False;
1358*cdf0e10cSrcweir                 }
1359*cdf0e10cSrcweir             }
1360*cdf0e10cSrcweir 
1361*cdf0e10cSrcweir             rStrm.Seek( nOriginalStreamPos );
1362*cdf0e10cSrcweir             nRow = nStartRow;
1363*cdf0e10cSrcweir             if (!StartPaste())
1364*cdf0e10cSrcweir             {
1365*cdf0e10cSrcweir                 EndPaste();
1366*cdf0e10cSrcweir                 return sal_False;
1367*cdf0e10cSrcweir             }
1368*cdf0e10cSrcweir         }
1369*cdf0e10cSrcweir 
1370*cdf0e10cSrcweir         bDetermineRange = !bDetermineRange;     // toggle
1371*cdf0e10cSrcweir     } while (!bDetermineRange);
1372*cdf0e10cSrcweir 
1373*cdf0e10cSrcweir 	ScColumn::bDoubleAlloc = bOld;
1374*cdf0e10cSrcweir 	pDoc->DoColResize( nTab, nStartCol, nEndCol, 0 );
1375*cdf0e10cSrcweir 
1376*cdf0e10cSrcweir     delete pEnglishTransliteration;
1377*cdf0e10cSrcweir 	delete pEnglishCalendar;
1378*cdf0e10cSrcweir 
1379*cdf0e10cSrcweir     xProgress.reset();    // make room for AdjustRowHeight progress
1380*cdf0e10cSrcweir     if (bRangeIsDetermined)
1381*cdf0e10cSrcweir         EndPaste();
1382*cdf0e10cSrcweir 
1383*cdf0e10cSrcweir 	return sal_True;
1384*cdf0e10cSrcweir }
1385*cdf0e10cSrcweir 
1386*cdf0e10cSrcweir 
1387*cdf0e10cSrcweir // static
1388*cdf0e10cSrcweir const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p,
1389*cdf0e10cSrcweir 		String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted )
1390*cdf0e10cSrcweir {
1391*cdf0e10cSrcweir     rbIsQuoted = false;
1392*cdf0e10cSrcweir 	rField.Erase();
1393*cdf0e10cSrcweir 	if ( *p == cStr )			// String in Anfuehrungszeichen
1394*cdf0e10cSrcweir 	{
1395*cdf0e10cSrcweir         rbIsQuoted = true;
1396*cdf0e10cSrcweir         const sal_Unicode* p1;
1397*cdf0e10cSrcweir 		p1 = p = lcl_ScanString( p, rField, cStr, DQM_ESCAPE );
1398*cdf0e10cSrcweir 		while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
1399*cdf0e10cSrcweir 			p++;
1400*cdf0e10cSrcweir         // Append remaining unquoted and undelimited data (dirty, dirty) to
1401*cdf0e10cSrcweir         // this field.
1402*cdf0e10cSrcweir         if (p > p1)
1403*cdf0e10cSrcweir             rField.Append( p1, sal::static_int_cast<xub_StrLen>( p - p1 ) );
1404*cdf0e10cSrcweir 		if( *p )
1405*cdf0e10cSrcweir 			p++;
1406*cdf0e10cSrcweir 	}
1407*cdf0e10cSrcweir 	else						// bis zum Trennzeichen
1408*cdf0e10cSrcweir 	{
1409*cdf0e10cSrcweir 		const sal_Unicode* p0 = p;
1410*cdf0e10cSrcweir 		while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
1411*cdf0e10cSrcweir 			p++;
1412*cdf0e10cSrcweir         rField.Append( p0, sal::static_int_cast<xub_StrLen>( p - p0 ) );
1413*cdf0e10cSrcweir 		if( *p )
1414*cdf0e10cSrcweir 			p++;
1415*cdf0e10cSrcweir 	}
1416*cdf0e10cSrcweir 	if ( bMergeSeps ) 			// folgende Trennzeichen ueberspringen
1417*cdf0e10cSrcweir 	{
1418*cdf0e10cSrcweir 		while ( *p && ScGlobal::UnicodeStrChr( pSeps, *p ) )
1419*cdf0e10cSrcweir 			p++;
1420*cdf0e10cSrcweir 	}
1421*cdf0e10cSrcweir 	return p;
1422*cdf0e10cSrcweir }
1423*cdf0e10cSrcweir 
1424*cdf0e10cSrcweir 		//
1425*cdf0e10cSrcweir 		//
1426*cdf0e10cSrcweir 		//
1427*cdf0e10cSrcweir 
1428*cdf0e10cSrcweir 
1429*cdf0e10cSrcweir sal_Bool ScImportExport::Doc2Text( SvStream& rStrm )
1430*cdf0e10cSrcweir {
1431*cdf0e10cSrcweir 	SCCOL nCol;
1432*cdf0e10cSrcweir 	SCROW nRow;
1433*cdf0e10cSrcweir 	SCCOL nStartCol = aRange.aStart.Col();
1434*cdf0e10cSrcweir 	SCROW nStartRow = aRange.aStart.Row();
1435*cdf0e10cSrcweir 	SCCOL nEndCol = aRange.aEnd.Col();
1436*cdf0e10cSrcweir 	SCROW nEndRow = aRange.aEnd.Row();
1437*cdf0e10cSrcweir 	String aCell;
1438*cdf0e10cSrcweir     bool bConvertLF = (GetSystemLineEnd() != LINEEND_LF);
1439*cdf0e10cSrcweir 
1440*cdf0e10cSrcweir 	for (nRow = nStartRow; nRow <= nEndRow; nRow++)
1441*cdf0e10cSrcweir 	{
1442*cdf0e10cSrcweir 		if (bIncludeFiltered || !pDoc->RowFiltered( nRow, aRange.aStart.Tab() ))
1443*cdf0e10cSrcweir 		{
1444*cdf0e10cSrcweir 			for (nCol = nStartCol; nCol <= nEndCol; nCol++)
1445*cdf0e10cSrcweir 			{
1446*cdf0e10cSrcweir 				CellType eType;
1447*cdf0e10cSrcweir 				pDoc->GetCellType( nCol, nRow, aRange.aStart.Tab(), eType );
1448*cdf0e10cSrcweir 				switch (eType)
1449*cdf0e10cSrcweir 				{
1450*cdf0e10cSrcweir 					case CELLTYPE_FORMULA:
1451*cdf0e10cSrcweir 					{
1452*cdf0e10cSrcweir 						if (bFormulas)
1453*cdf0e10cSrcweir 						{
1454*cdf0e10cSrcweir 							pDoc->GetFormula( nCol, nRow, aRange.aStart.Tab(), aCell, sal_True );
1455*cdf0e10cSrcweir 							if( aCell.Search( cSep ) != STRING_NOTFOUND )
1456*cdf0e10cSrcweir 								lcl_WriteString( rStrm, aCell, cStr, cStr );
1457*cdf0e10cSrcweir 							else
1458*cdf0e10cSrcweir 								lcl_WriteSimpleString( rStrm, aCell );
1459*cdf0e10cSrcweir 						}
1460*cdf0e10cSrcweir 						else
1461*cdf0e10cSrcweir 						{
1462*cdf0e10cSrcweir                             pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell );
1463*cdf0e10cSrcweir 
1464*cdf0e10cSrcweir                             bool bMultiLineText = ( aCell.Search( _LF ) != STRING_NOTFOUND );
1465*cdf0e10cSrcweir                             if( bMultiLineText )
1466*cdf0e10cSrcweir                             {
1467*cdf0e10cSrcweir                                 if( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSpace )
1468*cdf0e10cSrcweir                                     aCell.SearchAndReplaceAll( _LF, ' ' );
1469*cdf0e10cSrcweir                                 else if ( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSystem && bConvertLF )
1470*cdf0e10cSrcweir                                     aCell.ConvertLineEnd();
1471*cdf0e10cSrcweir                             }
1472*cdf0e10cSrcweir 
1473*cdf0e10cSrcweir                             if( mExportTextOptions.mcSeparatorConvertTo && cSep )
1474*cdf0e10cSrcweir                                 aCell.SearchAndReplaceAll( cSep, mExportTextOptions.mcSeparatorConvertTo );
1475*cdf0e10cSrcweir 
1476*cdf0e10cSrcweir                             if( mExportTextOptions.mbAddQuotes && ( aCell.Search( cSep ) != STRING_NOTFOUND ) )
1477*cdf0e10cSrcweir                                 lcl_WriteString( rStrm, aCell, cStr, cStr );
1478*cdf0e10cSrcweir                             else
1479*cdf0e10cSrcweir                                 lcl_WriteSimpleString( rStrm, aCell );
1480*cdf0e10cSrcweir 						}
1481*cdf0e10cSrcweir 					}
1482*cdf0e10cSrcweir 					break;
1483*cdf0e10cSrcweir 					case CELLTYPE_VALUE:
1484*cdf0e10cSrcweir 					{
1485*cdf0e10cSrcweir 						pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell );
1486*cdf0e10cSrcweir 						lcl_WriteSimpleString( rStrm, aCell );
1487*cdf0e10cSrcweir 					}
1488*cdf0e10cSrcweir 					break;
1489*cdf0e10cSrcweir 					case CELLTYPE_NOTE:
1490*cdf0e10cSrcweir 					case CELLTYPE_NONE:
1491*cdf0e10cSrcweir 					break;
1492*cdf0e10cSrcweir 					default:
1493*cdf0e10cSrcweir 					{
1494*cdf0e10cSrcweir 						pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell );
1495*cdf0e10cSrcweir 
1496*cdf0e10cSrcweir                         bool bMultiLineText = ( aCell.Search( _LF ) != STRING_NOTFOUND );
1497*cdf0e10cSrcweir                         if( bMultiLineText )
1498*cdf0e10cSrcweir                         {
1499*cdf0e10cSrcweir                             if( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSpace )
1500*cdf0e10cSrcweir                                 aCell.SearchAndReplaceAll( _LF, ' ' );
1501*cdf0e10cSrcweir                             else if ( mExportTextOptions.meNewlineConversion == ScExportTextOptions::ToSystem && bConvertLF )
1502*cdf0e10cSrcweir                                 aCell.ConvertLineEnd();
1503*cdf0e10cSrcweir                         }
1504*cdf0e10cSrcweir 
1505*cdf0e10cSrcweir                         if( mExportTextOptions.mcSeparatorConvertTo && cSep )
1506*cdf0e10cSrcweir                             aCell.SearchAndReplaceAll( cSep, mExportTextOptions.mcSeparatorConvertTo );
1507*cdf0e10cSrcweir 
1508*cdf0e10cSrcweir                         if( mExportTextOptions.mbAddQuotes && ( aCell.Search( cSep ) != STRING_NOTFOUND ) )
1509*cdf0e10cSrcweir                             lcl_WriteString( rStrm, aCell, cStr, cStr );
1510*cdf0e10cSrcweir                         else
1511*cdf0e10cSrcweir                             lcl_WriteSimpleString( rStrm, aCell );
1512*cdf0e10cSrcweir 					}
1513*cdf0e10cSrcweir 				}
1514*cdf0e10cSrcweir 				if( nCol < nEndCol )
1515*cdf0e10cSrcweir 					lcl_WriteSimpleString( rStrm, String(cSep) );
1516*cdf0e10cSrcweir 			}
1517*cdf0e10cSrcweir //			if( nRow < nEndRow )
1518*cdf0e10cSrcweir 				WriteUnicodeOrByteEndl( rStrm );
1519*cdf0e10cSrcweir 			if( rStrm.GetError() != SVSTREAM_OK )
1520*cdf0e10cSrcweir 				break;
1521*cdf0e10cSrcweir 			if( nSizeLimit && rStrm.Tell() > nSizeLimit )
1522*cdf0e10cSrcweir 				break;
1523*cdf0e10cSrcweir 		}
1524*cdf0e10cSrcweir 	}
1525*cdf0e10cSrcweir 
1526*cdf0e10cSrcweir 	return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
1527*cdf0e10cSrcweir }
1528*cdf0e10cSrcweir 
1529*cdf0e10cSrcweir 
1530*cdf0e10cSrcweir sal_Bool ScImportExport::Sylk2Doc( SvStream& rStrm )
1531*cdf0e10cSrcweir {
1532*cdf0e10cSrcweir 	sal_Bool bOk = sal_True;
1533*cdf0e10cSrcweir 	sal_Bool bMyDoc = sal_False;
1534*cdf0e10cSrcweir     SylkVersion eVersion = SYLK_OTHER;
1535*cdf0e10cSrcweir 
1536*cdf0e10cSrcweir 	// US-English separators for StringToDouble
1537*cdf0e10cSrcweir 	sal_Unicode cDecSep = '.';
1538*cdf0e10cSrcweir 	sal_Unicode cGrpSep = ',';
1539*cdf0e10cSrcweir 
1540*cdf0e10cSrcweir 	SCCOL nStartCol = aRange.aStart.Col();
1541*cdf0e10cSrcweir 	SCROW nStartRow = aRange.aStart.Row();
1542*cdf0e10cSrcweir 	SCCOL nEndCol = aRange.aEnd.Col();
1543*cdf0e10cSrcweir 	SCROW nEndRow = aRange.aEnd.Row();
1544*cdf0e10cSrcweir 	sal_uLong nOldPos = rStrm.Tell();
1545*cdf0e10cSrcweir 	sal_Bool bData = sal_Bool( !bSingle );
1546*cdf0e10cSrcweir     SvULongs aFormats;
1547*cdf0e10cSrcweir 
1548*cdf0e10cSrcweir 	if( !bSingle)
1549*cdf0e10cSrcweir 		bOk = StartPaste();
1550*cdf0e10cSrcweir 
1551*cdf0e10cSrcweir 	while( bOk )
1552*cdf0e10cSrcweir 	{
1553*cdf0e10cSrcweir 		String aLine;
1554*cdf0e10cSrcweir         String aText;
1555*cdf0e10cSrcweir 		ByteString aByteLine;
1556*cdf0e10cSrcweir 		SCCOL nCol = nStartCol;
1557*cdf0e10cSrcweir 		SCROW nRow = nStartRow;
1558*cdf0e10cSrcweir         SCCOL nRefCol = 1;
1559*cdf0e10cSrcweir         SCROW nRefRow = 1;
1560*cdf0e10cSrcweir 		rStrm.Seek( nOldPos );
1561*cdf0e10cSrcweir 		for( ;; )
1562*cdf0e10cSrcweir 		{
1563*cdf0e10cSrcweir 			//!	allow unicode
1564*cdf0e10cSrcweir 			rStrm.ReadLine( aByteLine );
1565*cdf0e10cSrcweir 			aLine = String( aByteLine, rStrm.GetStreamCharSet() );
1566*cdf0e10cSrcweir 			if( rStrm.IsEof() )
1567*cdf0e10cSrcweir 				break;
1568*cdf0e10cSrcweir 			const sal_Unicode* p = aLine.GetBuffer();
1569*cdf0e10cSrcweir 			sal_Unicode cTag = *p++;
1570*cdf0e10cSrcweir             if( cTag == 'C' )       // Content
1571*cdf0e10cSrcweir 			{
1572*cdf0e10cSrcweir 				if( *p++ != ';' )
1573*cdf0e10cSrcweir 					return sal_False;
1574*cdf0e10cSrcweir 				while( *p )
1575*cdf0e10cSrcweir 				{
1576*cdf0e10cSrcweir 					sal_Unicode ch = *p++;
1577*cdf0e10cSrcweir 					ch = ScGlobal::ToUpperAlpha( ch );
1578*cdf0e10cSrcweir 					switch( ch )
1579*cdf0e10cSrcweir 					{
1580*cdf0e10cSrcweir 						case 'X':
1581*cdf0e10cSrcweir 							nCol = static_cast<SCCOL>(String( p ).ToInt32()) + nStartCol - 1;
1582*cdf0e10cSrcweir 							break;
1583*cdf0e10cSrcweir 						case 'Y':
1584*cdf0e10cSrcweir 							nRow = String( p ).ToInt32() + nStartRow - 1;
1585*cdf0e10cSrcweir 							break;
1586*cdf0e10cSrcweir                         case 'C':
1587*cdf0e10cSrcweir                             nRefCol = static_cast<SCCOL>(String( p ).ToInt32()) + nStartCol - 1;
1588*cdf0e10cSrcweir 							break;
1589*cdf0e10cSrcweir                         case 'R':
1590*cdf0e10cSrcweir                             nRefRow = String( p ).ToInt32() + nStartRow - 1;
1591*cdf0e10cSrcweir 							break;
1592*cdf0e10cSrcweir 						case 'K':
1593*cdf0e10cSrcweir                         {
1594*cdf0e10cSrcweir                             if( !bSingle &&
1595*cdf0e10cSrcweir                                     ( nCol < nStartCol || nCol > nEndCol
1596*cdf0e10cSrcweir                                       || nRow < nStartRow || nRow > nEndRow
1597*cdf0e10cSrcweir                                       || nCol > MAXCOL || nRow > MAXROW ) )
1598*cdf0e10cSrcweir 								break;
1599*cdf0e10cSrcweir 							if( !bData )
1600*cdf0e10cSrcweir 							{
1601*cdf0e10cSrcweir 								if( nRow > nEndRow )
1602*cdf0e10cSrcweir 									nEndRow = nRow;
1603*cdf0e10cSrcweir 								if( nCol > nEndCol )
1604*cdf0e10cSrcweir 									nEndCol = nCol;
1605*cdf0e10cSrcweir 								break;
1606*cdf0e10cSrcweir 							}
1607*cdf0e10cSrcweir                             sal_Bool bText;
1608*cdf0e10cSrcweir                             if( *p == '"' )
1609*cdf0e10cSrcweir                             {
1610*cdf0e10cSrcweir                                 bText = sal_True;
1611*cdf0e10cSrcweir                                 aText.Erase();
1612*cdf0e10cSrcweir                                 p = lcl_ScanSylkString( p, aText, eVersion);
1613*cdf0e10cSrcweir                             }
1614*cdf0e10cSrcweir                             else
1615*cdf0e10cSrcweir                                 bText = sal_False;
1616*cdf0e10cSrcweir                             const sal_Unicode* q = p;
1617*cdf0e10cSrcweir                             while( *q && *q != ';' )
1618*cdf0e10cSrcweir                                 q++;
1619*cdf0e10cSrcweir                             if ( !(*q == ';' && *(q+1) == 'I') )
1620*cdf0e10cSrcweir                             {   // don't ignore value
1621*cdf0e10cSrcweir                                 if( bText )
1622*cdf0e10cSrcweir                                 {
1623*cdf0e10cSrcweir                                     pDoc->PutCell( nCol, nRow, aRange.aStart.Tab(),
1624*cdf0e10cSrcweir                                             ScBaseCell::CreateTextCell( aText, pDoc),
1625*cdf0e10cSrcweir                                             (sal_Bool) sal_True);
1626*cdf0e10cSrcweir                                 }
1627*cdf0e10cSrcweir                                 else
1628*cdf0e10cSrcweir                                 {
1629*cdf0e10cSrcweir                                     double fVal = rtl_math_uStringToDouble( p,
1630*cdf0e10cSrcweir                                             aLine.GetBuffer() + aLine.Len(),
1631*cdf0e10cSrcweir                                             cDecSep, cGrpSep, NULL, NULL );
1632*cdf0e10cSrcweir                                     pDoc->SetValue( nCol, nRow, aRange.aStart.Tab(), fVal );
1633*cdf0e10cSrcweir                                 }
1634*cdf0e10cSrcweir                             }
1635*cdf0e10cSrcweir                         }
1636*cdf0e10cSrcweir                         break;
1637*cdf0e10cSrcweir 						case 'E':
1638*cdf0e10cSrcweir                         case 'M':
1639*cdf0e10cSrcweir                         {
1640*cdf0e10cSrcweir                             if ( ch == 'M' )
1641*cdf0e10cSrcweir                             {
1642*cdf0e10cSrcweir                                 if ( nRefCol < nCol )
1643*cdf0e10cSrcweir                                     nRefCol = nCol;
1644*cdf0e10cSrcweir                                 if ( nRefRow < nRow )
1645*cdf0e10cSrcweir                                     nRefRow = nRow;
1646*cdf0e10cSrcweir                                 if ( !bData )
1647*cdf0e10cSrcweir                                 {
1648*cdf0e10cSrcweir                                     if( nRefRow > nEndRow )
1649*cdf0e10cSrcweir                                         nEndRow = nRefRow;
1650*cdf0e10cSrcweir                                     if( nRefCol > nEndCol )
1651*cdf0e10cSrcweir                                         nEndCol = nRefCol;
1652*cdf0e10cSrcweir                                 }
1653*cdf0e10cSrcweir                             }
1654*cdf0e10cSrcweir 							if( !bMyDoc || !bData )
1655*cdf0e10cSrcweir 								break;
1656*cdf0e10cSrcweir                             aText = '=';
1657*cdf0e10cSrcweir                             p = lcl_ScanSylkFormula( p, aText, eVersion);
1658*cdf0e10cSrcweir                             ScAddress aPos( nCol, nRow, aRange.aStart.Tab() );
1659*cdf0e10cSrcweir                             /* FIXME: do we want GRAM_ODFF_A1 instead? At the
1660*cdf0e10cSrcweir                              * end it probably should be GRAM_ODFF_R1C1, since
1661*cdf0e10cSrcweir                              * R1C1 is what Excel writes in SYLK. */
1662*cdf0e10cSrcweir                             const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_PODF_A1;
1663*cdf0e10cSrcweir                             ScCompiler aComp( pDoc, aPos);
1664*cdf0e10cSrcweir                             aComp.SetGrammar(eGrammar);
1665*cdf0e10cSrcweir                             ScTokenArray* pCode = aComp.CompileString( aText );
1666*cdf0e10cSrcweir                             if ( ch == 'M' )
1667*cdf0e10cSrcweir                             {
1668*cdf0e10cSrcweir                                 ScMarkData aMark;
1669*cdf0e10cSrcweir                                 aMark.SelectTable( aPos.Tab(), sal_True );
1670*cdf0e10cSrcweir                                 pDoc->InsertMatrixFormula( nCol, nRow, nRefCol,
1671*cdf0e10cSrcweir                                     nRefRow, aMark, EMPTY_STRING, pCode );
1672*cdf0e10cSrcweir                             }
1673*cdf0e10cSrcweir                             else
1674*cdf0e10cSrcweir                             {
1675*cdf0e10cSrcweir                                 ScFormulaCell* pFCell = new ScFormulaCell(
1676*cdf0e10cSrcweir                                         pDoc, aPos, pCode, eGrammar, MM_NONE);
1677*cdf0e10cSrcweir                                 pDoc->PutCell( aPos, pFCell );
1678*cdf0e10cSrcweir                             }
1679*cdf0e10cSrcweir                             delete pCode;   // ctor/InsertMatrixFormula did copy TokenArray
1680*cdf0e10cSrcweir                         }
1681*cdf0e10cSrcweir                         break;
1682*cdf0e10cSrcweir 					}
1683*cdf0e10cSrcweir 					while( *p && *p != ';' )
1684*cdf0e10cSrcweir 						p++;
1685*cdf0e10cSrcweir 					if( *p )
1686*cdf0e10cSrcweir 						p++;
1687*cdf0e10cSrcweir 				}
1688*cdf0e10cSrcweir 			}
1689*cdf0e10cSrcweir             else if( cTag == 'F' )      // Format
1690*cdf0e10cSrcweir             {
1691*cdf0e10cSrcweir                 if( *p++ != ';' )
1692*cdf0e10cSrcweir                     return sal_False;
1693*cdf0e10cSrcweir                 sal_Int32 nFormat = -1;
1694*cdf0e10cSrcweir                 while( *p )
1695*cdf0e10cSrcweir                 {
1696*cdf0e10cSrcweir                     sal_Unicode ch = *p++;
1697*cdf0e10cSrcweir                     ch = ScGlobal::ToUpperAlpha( ch );
1698*cdf0e10cSrcweir                     switch( ch )
1699*cdf0e10cSrcweir                     {
1700*cdf0e10cSrcweir                         case 'X':
1701*cdf0e10cSrcweir                             nCol = static_cast<SCCOL>(String( p ).ToInt32()) + nStartCol - 1;
1702*cdf0e10cSrcweir                             break;
1703*cdf0e10cSrcweir                         case 'Y':
1704*cdf0e10cSrcweir                             nRow = String( p ).ToInt32() + nStartRow - 1;
1705*cdf0e10cSrcweir                             break;
1706*cdf0e10cSrcweir                         case 'P' :
1707*cdf0e10cSrcweir                             if ( bData )
1708*cdf0e10cSrcweir                             {
1709*cdf0e10cSrcweir                                 // F;P<n> sets format code of P;P<code> at
1710*cdf0e10cSrcweir                                 // current position, or at ;X;Y if specified.
1711*cdf0e10cSrcweir                                 // Note that ;X;Y may appear after ;P
1712*cdf0e10cSrcweir                                 const sal_Unicode* p0 = p;
1713*cdf0e10cSrcweir                                 while( *p && *p != ';' )
1714*cdf0e10cSrcweir                                     p++;
1715*cdf0e10cSrcweir                                 String aNumber( p0, sal::static_int_cast<xub_StrLen>( p - p0 ) );
1716*cdf0e10cSrcweir                                 nFormat = aNumber.ToInt32();
1717*cdf0e10cSrcweir                             }
1718*cdf0e10cSrcweir                             break;
1719*cdf0e10cSrcweir                     }
1720*cdf0e10cSrcweir                     while( *p && *p != ';' )
1721*cdf0e10cSrcweir                         p++;
1722*cdf0e10cSrcweir                     if( *p )
1723*cdf0e10cSrcweir                         p++;
1724*cdf0e10cSrcweir                 }
1725*cdf0e10cSrcweir                 if ( !bData )
1726*cdf0e10cSrcweir                 {
1727*cdf0e10cSrcweir                     if( nRow > nEndRow )
1728*cdf0e10cSrcweir                         nEndRow = nRow;
1729*cdf0e10cSrcweir                     if( nCol > nEndCol )
1730*cdf0e10cSrcweir                         nEndCol = nCol;
1731*cdf0e10cSrcweir                 }
1732*cdf0e10cSrcweir                 if ( 0 <= nFormat && nFormat < aFormats.Count() )
1733*cdf0e10cSrcweir                 {
1734*cdf0e10cSrcweir                     sal_uLong nKey = aFormats[(sal_uInt16)nFormat];
1735*cdf0e10cSrcweir                     pDoc->ApplyAttr( nCol, nRow, aRange.aStart.Tab(),
1736*cdf0e10cSrcweir                             SfxUInt32Item( ATTR_VALUE_FORMAT, nKey ) );
1737*cdf0e10cSrcweir                 }
1738*cdf0e10cSrcweir             }
1739*cdf0e10cSrcweir             else if( cTag == 'P' )
1740*cdf0e10cSrcweir             {
1741*cdf0e10cSrcweir                 if ( bData && *p == ';' && *(p+1) == 'P' )
1742*cdf0e10cSrcweir                 {
1743*cdf0e10cSrcweir                     String aCode( p+2 );
1744*cdf0e10cSrcweir                     // unescape doubled semicolons
1745*cdf0e10cSrcweir                     xub_StrLen nPos = 0;
1746*cdf0e10cSrcweir                     String aSemicolon( RTL_CONSTASCII_USTRINGPARAM(";;"));
1747*cdf0e10cSrcweir                     while ( (nPos = aCode.Search( aSemicolon, nPos )) != STRING_NOTFOUND )
1748*cdf0e10cSrcweir                         aCode.Erase( nPos++, 1 );
1749*cdf0e10cSrcweir                     // get rid of Xcl escape characters
1750*cdf0e10cSrcweir                     nPos = 0;
1751*cdf0e10cSrcweir                     while ( (nPos = aCode.Search( sal_Unicode(0x1b), nPos )) != STRING_NOTFOUND )
1752*cdf0e10cSrcweir                         aCode.Erase( nPos, 1 );
1753*cdf0e10cSrcweir                     xub_StrLen nCheckPos;
1754*cdf0e10cSrcweir                     short nType;
1755*cdf0e10cSrcweir                     sal_uInt32 nKey;
1756*cdf0e10cSrcweir                     pDoc->GetFormatTable()->PutandConvertEntry(
1757*cdf0e10cSrcweir                         aCode, nCheckPos, nType, nKey, LANGUAGE_ENGLISH_US,
1758*cdf0e10cSrcweir                         ScGlobal::eLnge );
1759*cdf0e10cSrcweir                     if ( nCheckPos )
1760*cdf0e10cSrcweir                         nKey = 0;
1761*cdf0e10cSrcweir                     aFormats.Insert( nKey, aFormats.Count() );
1762*cdf0e10cSrcweir                 }
1763*cdf0e10cSrcweir             }
1764*cdf0e10cSrcweir             else if( cTag == 'I' && *p == 'D' )
1765*cdf0e10cSrcweir 			{
1766*cdf0e10cSrcweir 				aLine.Erase( 0, 4 );
1767*cdf0e10cSrcweir 				if (aLine.EqualsAscii( "CALCOOO32" ))
1768*cdf0e10cSrcweir                     eVersion = SYLK_OOO32;
1769*cdf0e10cSrcweir                 else if (aLine.EqualsAscii( "SCALC3" ))
1770*cdf0e10cSrcweir                     eVersion = SYLK_SCALC3;
1771*cdf0e10cSrcweir                 bMyDoc = (eVersion <= SYLK_OWN);
1772*cdf0e10cSrcweir 			}
1773*cdf0e10cSrcweir 			else if( cTag == 'E' )						// Ende
1774*cdf0e10cSrcweir 				break;
1775*cdf0e10cSrcweir 		}
1776*cdf0e10cSrcweir 		if( !bData )
1777*cdf0e10cSrcweir 		{
1778*cdf0e10cSrcweir 			aRange.aEnd.SetCol( nEndCol );
1779*cdf0e10cSrcweir 			aRange.aEnd.SetRow( nEndRow );
1780*cdf0e10cSrcweir 			bOk = StartPaste();
1781*cdf0e10cSrcweir 			bData = sal_True;
1782*cdf0e10cSrcweir 		}
1783*cdf0e10cSrcweir 		else
1784*cdf0e10cSrcweir 			break;
1785*cdf0e10cSrcweir 	}
1786*cdf0e10cSrcweir 
1787*cdf0e10cSrcweir 	EndPaste();
1788*cdf0e10cSrcweir 	return bOk;
1789*cdf0e10cSrcweir }
1790*cdf0e10cSrcweir 
1791*cdf0e10cSrcweir 
1792*cdf0e10cSrcweir sal_Bool ScImportExport::Doc2Sylk( SvStream& rStrm )
1793*cdf0e10cSrcweir {
1794*cdf0e10cSrcweir 	SCCOL nCol;
1795*cdf0e10cSrcweir 	SCROW nRow;
1796*cdf0e10cSrcweir 	SCCOL nStartCol = aRange.aStart.Col();
1797*cdf0e10cSrcweir 	SCROW nStartRow = aRange.aStart.Row();
1798*cdf0e10cSrcweir 	SCCOL nEndCol = aRange.aEnd.Col();
1799*cdf0e10cSrcweir 	SCROW nEndRow = aRange.aEnd.Row();
1800*cdf0e10cSrcweir 	String aCellStr;
1801*cdf0e10cSrcweir 	String aValStr;
1802*cdf0e10cSrcweir 	lcl_WriteSimpleString( rStrm,
1803*cdf0e10cSrcweir             String( RTL_CONSTASCII_USTRINGPARAM( "ID;PCALCOOO32")));
1804*cdf0e10cSrcweir 	WriteUnicodeOrByteEndl( rStrm );
1805*cdf0e10cSrcweir 
1806*cdf0e10cSrcweir 	for (nRow = nStartRow; nRow <= nEndRow; nRow++)
1807*cdf0e10cSrcweir 	{
1808*cdf0e10cSrcweir 		for (nCol = nStartCol; nCol <= nEndCol; nCol++)
1809*cdf0e10cSrcweir 		{
1810*cdf0e10cSrcweir 			String aBufStr;
1811*cdf0e10cSrcweir 			double nVal;
1812*cdf0e10cSrcweir 			sal_Bool bForm = sal_False;
1813*cdf0e10cSrcweir 			SCROW r = nRow - nStartRow + 1;
1814*cdf0e10cSrcweir 			SCCOL c = nCol - nStartCol + 1;
1815*cdf0e10cSrcweir             ScBaseCell* pCell;
1816*cdf0e10cSrcweir             pDoc->GetCell( nCol, nRow, aRange.aStart.Tab(), pCell );
1817*cdf0e10cSrcweir             CellType eType = (pCell ? pCell->GetCellType() : CELLTYPE_NONE);
1818*cdf0e10cSrcweir 			switch( eType )
1819*cdf0e10cSrcweir 			{
1820*cdf0e10cSrcweir 				case CELLTYPE_FORMULA:
1821*cdf0e10cSrcweir 					bForm = bFormulas;
1822*cdf0e10cSrcweir 					if( pDoc->HasValueData( nCol, nRow, aRange.aStart.Tab()) )
1823*cdf0e10cSrcweir 						goto hasvalue;
1824*cdf0e10cSrcweir 					else
1825*cdf0e10cSrcweir 						goto hasstring;
1826*cdf0e10cSrcweir 
1827*cdf0e10cSrcweir 				case CELLTYPE_VALUE:
1828*cdf0e10cSrcweir 				hasvalue:
1829*cdf0e10cSrcweir 					pDoc->GetValue( nCol, nRow, aRange.aStart.Tab(), nVal );
1830*cdf0e10cSrcweir 
1831*cdf0e10cSrcweir                     aValStr = ::rtl::math::doubleToUString( nVal,
1832*cdf0e10cSrcweir                             rtl_math_StringFormat_Automatic,
1833*cdf0e10cSrcweir                             rtl_math_DecimalPlaces_Max, '.', sal_True );
1834*cdf0e10cSrcweir 
1835*cdf0e10cSrcweir 					aBufStr.AssignAscii(RTL_CONSTASCII_STRINGPARAM( "C;X" ));
1836*cdf0e10cSrcweir 					aBufStr += String::CreateFromInt32( c );
1837*cdf0e10cSrcweir 					aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Y" ));
1838*cdf0e10cSrcweir 					aBufStr += String::CreateFromInt32( r );
1839*cdf0e10cSrcweir 					aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";K" ));
1840*cdf0e10cSrcweir 					aBufStr += aValStr;
1841*cdf0e10cSrcweir 					lcl_WriteSimpleString( rStrm, aBufStr );
1842*cdf0e10cSrcweir 					goto checkformula;
1843*cdf0e10cSrcweir 
1844*cdf0e10cSrcweir 				case CELLTYPE_STRING:
1845*cdf0e10cSrcweir 				case CELLTYPE_EDIT:
1846*cdf0e10cSrcweir 				hasstring:
1847*cdf0e10cSrcweir 					pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCellStr );
1848*cdf0e10cSrcweir                     aCellStr.SearchAndReplaceAll( _LF, SYLK_LF );
1849*cdf0e10cSrcweir 
1850*cdf0e10cSrcweir 					aBufStr.AssignAscii(RTL_CONSTASCII_STRINGPARAM( "C;X" ));
1851*cdf0e10cSrcweir 					aBufStr += String::CreateFromInt32( c );
1852*cdf0e10cSrcweir 					aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Y" ));
1853*cdf0e10cSrcweir 					aBufStr += String::CreateFromInt32( r );
1854*cdf0e10cSrcweir 					aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";K" ));
1855*cdf0e10cSrcweir 					lcl_WriteSimpleString( rStrm, aBufStr );
1856*cdf0e10cSrcweir 					lcl_WriteString( rStrm, aCellStr, '"', ';' );
1857*cdf0e10cSrcweir 
1858*cdf0e10cSrcweir 				checkformula:
1859*cdf0e10cSrcweir 					if( bForm )
1860*cdf0e10cSrcweir 					{
1861*cdf0e10cSrcweir                         const ScFormulaCell* pFCell =
1862*cdf0e10cSrcweir                             static_cast<const ScFormulaCell*>(pCell);
1863*cdf0e10cSrcweir                         switch ( pFCell->GetMatrixFlag() )
1864*cdf0e10cSrcweir                         {
1865*cdf0e10cSrcweir                             case MM_REFERENCE :
1866*cdf0e10cSrcweir                                 aCellStr.Erase();
1867*cdf0e10cSrcweir                             break;
1868*cdf0e10cSrcweir                             default:
1869*cdf0e10cSrcweir                                 pFCell->GetFormula( aCellStr,formula::FormulaGrammar::GRAM_PODF_A1);
1870*cdf0e10cSrcweir                                 /* FIXME: do we want GRAM_ODFF_A1 instead? At
1871*cdf0e10cSrcweir                                  * the end it probably should be
1872*cdf0e10cSrcweir                                  * GRAM_ODFF_R1C1, since R1C1 is what Excel
1873*cdf0e10cSrcweir                                  * writes in SYLK. */
1874*cdf0e10cSrcweir                         }
1875*cdf0e10cSrcweir                         if ( pFCell->GetMatrixFlag() != MM_NONE &&
1876*cdf0e10cSrcweir                                 aCellStr.Len() > 2 &&
1877*cdf0e10cSrcweir                                 aCellStr.GetChar(0) == '{' &&
1878*cdf0e10cSrcweir                                 aCellStr.GetChar(aCellStr.Len()-1) == '}' )
1879*cdf0e10cSrcweir                         {   // cut off matrix {} characters
1880*cdf0e10cSrcweir                             aCellStr.Erase(aCellStr.Len()-1,1);
1881*cdf0e10cSrcweir                             aCellStr.Erase(0,1);
1882*cdf0e10cSrcweir                         }
1883*cdf0e10cSrcweir                         if ( aCellStr.GetChar(0) == '=' )
1884*cdf0e10cSrcweir                             aCellStr.Erase(0,1);
1885*cdf0e10cSrcweir                         String aPrefix;
1886*cdf0e10cSrcweir                         switch ( pFCell->GetMatrixFlag() )
1887*cdf0e10cSrcweir                         {
1888*cdf0e10cSrcweir                             case MM_FORMULA :
1889*cdf0e10cSrcweir                             {   // diff expression with 'M' M$-extension
1890*cdf0e10cSrcweir                                 SCCOL nC;
1891*cdf0e10cSrcweir                                 SCROW nR;
1892*cdf0e10cSrcweir                                 pFCell->GetMatColsRows( nC, nR );
1893*cdf0e10cSrcweir                                 nC += c - 1;
1894*cdf0e10cSrcweir                                 nR += r - 1;
1895*cdf0e10cSrcweir                                 aPrefix.AssignAscii( RTL_CONSTASCII_STRINGPARAM( ";R" ) );
1896*cdf0e10cSrcweir                                 aPrefix += String::CreateFromInt32( nR );
1897*cdf0e10cSrcweir                                 aPrefix.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ";C" ) );
1898*cdf0e10cSrcweir                                 aPrefix += String::CreateFromInt32( nC );
1899*cdf0e10cSrcweir                                 aPrefix.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ";M" ) );
1900*cdf0e10cSrcweir                             }
1901*cdf0e10cSrcweir                             break;
1902*cdf0e10cSrcweir                             case MM_REFERENCE :
1903*cdf0e10cSrcweir                             {   // diff expression with 'I' M$-extension
1904*cdf0e10cSrcweir                                 ScAddress aPos;
1905*cdf0e10cSrcweir                                 pFCell->GetMatrixOrigin( aPos );
1906*cdf0e10cSrcweir                                 aPrefix.AssignAscii( RTL_CONSTASCII_STRINGPARAM( ";I;R" ) );
1907*cdf0e10cSrcweir                                 aPrefix += String::CreateFromInt32( aPos.Row() - nStartRow + 1 );
1908*cdf0e10cSrcweir                                 aPrefix.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ";C" ) );
1909*cdf0e10cSrcweir                                 aPrefix += String::CreateFromInt32( aPos.Col() - nStartCol + 1 );
1910*cdf0e10cSrcweir                             }
1911*cdf0e10cSrcweir                             break;
1912*cdf0e10cSrcweir                             default:
1913*cdf0e10cSrcweir                                 // formula Expression
1914*cdf0e10cSrcweir                                 aPrefix.AssignAscii( RTL_CONSTASCII_STRINGPARAM( ";E" ) );
1915*cdf0e10cSrcweir                         }
1916*cdf0e10cSrcweir                         lcl_WriteSimpleString( rStrm, aPrefix );
1917*cdf0e10cSrcweir                         if ( aCellStr.Len() )
1918*cdf0e10cSrcweir                             lcl_WriteString( rStrm, aCellStr, 0, ';' );
1919*cdf0e10cSrcweir 					}
1920*cdf0e10cSrcweir 					WriteUnicodeOrByteEndl( rStrm );
1921*cdf0e10cSrcweir 					break;
1922*cdf0e10cSrcweir 
1923*cdf0e10cSrcweir                 default:
1924*cdf0e10cSrcweir                 {
1925*cdf0e10cSrcweir                     // added to avoid warnings
1926*cdf0e10cSrcweir                 }
1927*cdf0e10cSrcweir 			}
1928*cdf0e10cSrcweir 		}
1929*cdf0e10cSrcweir 	}
1930*cdf0e10cSrcweir 	lcl_WriteSimpleString( rStrm, String( 'E' ) );
1931*cdf0e10cSrcweir 	WriteUnicodeOrByteEndl( rStrm );
1932*cdf0e10cSrcweir 	return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
1933*cdf0e10cSrcweir }
1934*cdf0e10cSrcweir 
1935*cdf0e10cSrcweir 
1936*cdf0e10cSrcweir sal_Bool ScImportExport::Doc2HTML( SvStream& rStrm, const String& rBaseURL )
1937*cdf0e10cSrcweir {
1938*cdf0e10cSrcweir     // CharSet is ignored in ScExportHTML, read from Load/Save HTML options
1939*cdf0e10cSrcweir     ScFormatFilter::Get().ScExportHTML( rStrm, rBaseURL, pDoc, aRange, RTL_TEXTENCODING_DONTKNOW, bAll,
1940*cdf0e10cSrcweir         aStreamPath, aNonConvertibleChars );
1941*cdf0e10cSrcweir 	return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
1942*cdf0e10cSrcweir }
1943*cdf0e10cSrcweir 
1944*cdf0e10cSrcweir sal_Bool ScImportExport::Doc2RTF( SvStream& rStrm )
1945*cdf0e10cSrcweir {
1946*cdf0e10cSrcweir 	//	CharSet is ignored in ScExportRTF
1947*cdf0e10cSrcweir     ScFormatFilter::Get().ScExportRTF( rStrm, pDoc, aRange, RTL_TEXTENCODING_DONTKNOW );
1948*cdf0e10cSrcweir 	return sal_Bool( rStrm.GetError() == SVSTREAM_OK );
1949*cdf0e10cSrcweir }
1950*cdf0e10cSrcweir 
1951*cdf0e10cSrcweir 
1952*cdf0e10cSrcweir sal_Bool ScImportExport::Doc2Dif( SvStream& rStrm )
1953*cdf0e10cSrcweir {
1954*cdf0e10cSrcweir 	// for DIF in the clipboard, IBM_850 is always used
1955*cdf0e10cSrcweir     ScFormatFilter::Get().ScExportDif( rStrm, pDoc, aRange, RTL_TEXTENCODING_IBM_850 );
1956*cdf0e10cSrcweir 	return sal_True;
1957*cdf0e10cSrcweir }
1958*cdf0e10cSrcweir 
1959*cdf0e10cSrcweir 
1960*cdf0e10cSrcweir sal_Bool ScImportExport::Dif2Doc( SvStream& rStrm )
1961*cdf0e10cSrcweir {
1962*cdf0e10cSrcweir 	SCTAB nTab = aRange.aStart.Tab();
1963*cdf0e10cSrcweir 	ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO );
1964*cdf0e10cSrcweir 	pImportDoc->InitUndo( pDoc, nTab, nTab );
1965*cdf0e10cSrcweir 
1966*cdf0e10cSrcweir 	// for DIF in the clipboard, IBM_850 is always used
1967*cdf0e10cSrcweir 	ScFormatFilter::Get().ScImportDif( rStrm, pImportDoc, aRange.aStart, RTL_TEXTENCODING_IBM_850 );
1968*cdf0e10cSrcweir 
1969*cdf0e10cSrcweir 	SCCOL nEndCol;
1970*cdf0e10cSrcweir 	SCROW nEndRow;
1971*cdf0e10cSrcweir 	pImportDoc->GetCellArea( nTab, nEndCol, nEndRow );
1972*cdf0e10cSrcweir     // #131247# if there are no cells in the imported content, nEndCol/nEndRow may be before the start
1973*cdf0e10cSrcweir     if ( nEndCol < aRange.aStart.Col() )
1974*cdf0e10cSrcweir         nEndCol = aRange.aStart.Col();
1975*cdf0e10cSrcweir     if ( nEndRow < aRange.aStart.Row() )
1976*cdf0e10cSrcweir         nEndRow = aRange.aStart.Row();
1977*cdf0e10cSrcweir 	aRange.aEnd = ScAddress( nEndCol, nEndRow, nTab );
1978*cdf0e10cSrcweir 
1979*cdf0e10cSrcweir 	sal_Bool bOk = StartPaste();
1980*cdf0e10cSrcweir 	if (bOk)
1981*cdf0e10cSrcweir 	{
1982*cdf0e10cSrcweir 		sal_uInt16 nFlags = IDF_ALL & ~IDF_STYLES;
1983*cdf0e10cSrcweir 		pDoc->DeleteAreaTab( aRange, nFlags );
1984*cdf0e10cSrcweir 		pImportDoc->CopyToDocument( aRange, nFlags, sal_False, pDoc );
1985*cdf0e10cSrcweir 		EndPaste();
1986*cdf0e10cSrcweir 	}
1987*cdf0e10cSrcweir 
1988*cdf0e10cSrcweir 	delete pImportDoc;
1989*cdf0e10cSrcweir 
1990*cdf0e10cSrcweir 	return bOk;
1991*cdf0e10cSrcweir }
1992*cdf0e10cSrcweir 
1993*cdf0e10cSrcweir 
1994*cdf0e10cSrcweir sal_Bool ScImportExport::RTF2Doc( SvStream& rStrm, const String& rBaseURL )
1995*cdf0e10cSrcweir {
1996*cdf0e10cSrcweir     ScEEAbsImport *pImp = ScFormatFilter::Get().CreateRTFImport( pDoc, aRange );
1997*cdf0e10cSrcweir     if (!pImp)
1998*cdf0e10cSrcweir         return false;
1999*cdf0e10cSrcweir     pImp->Read( rStrm, rBaseURL );
2000*cdf0e10cSrcweir     aRange = pImp->GetRange();
2001*cdf0e10cSrcweir 
2002*cdf0e10cSrcweir     sal_Bool bOk = StartPaste();
2003*cdf0e10cSrcweir     if (bOk)
2004*cdf0e10cSrcweir     {
2005*cdf0e10cSrcweir         sal_uInt16 nFlags = IDF_ALL & ~IDF_STYLES;
2006*cdf0e10cSrcweir         pDoc->DeleteAreaTab( aRange, nFlags );
2007*cdf0e10cSrcweir         pImp->WriteToDocument();
2008*cdf0e10cSrcweir         EndPaste();
2009*cdf0e10cSrcweir     }
2010*cdf0e10cSrcweir     delete pImp;
2011*cdf0e10cSrcweir     return bOk;
2012*cdf0e10cSrcweir }
2013*cdf0e10cSrcweir 
2014*cdf0e10cSrcweir 
2015*cdf0e10cSrcweir sal_Bool ScImportExport::HTML2Doc( SvStream& rStrm, const String& rBaseURL )
2016*cdf0e10cSrcweir {
2017*cdf0e10cSrcweir     ScEEAbsImport *pImp = ScFormatFilter::Get().CreateHTMLImport( pDoc, rBaseURL, aRange, sal_True);
2018*cdf0e10cSrcweir     if (!pImp)
2019*cdf0e10cSrcweir         return false;
2020*cdf0e10cSrcweir     pImp->Read( rStrm, rBaseURL );
2021*cdf0e10cSrcweir     aRange = pImp->GetRange();
2022*cdf0e10cSrcweir 
2023*cdf0e10cSrcweir     sal_Bool bOk = StartPaste();
2024*cdf0e10cSrcweir     if (bOk)
2025*cdf0e10cSrcweir     {
2026*cdf0e10cSrcweir         // ScHTMLImport may call ScDocument::InitDrawLayer, resulting in
2027*cdf0e10cSrcweir         // a Draw Layer but no Draw View -> create Draw Layer and View here
2028*cdf0e10cSrcweir         if (pDocSh)
2029*cdf0e10cSrcweir             pDocSh->MakeDrawLayer();
2030*cdf0e10cSrcweir 
2031*cdf0e10cSrcweir         sal_uInt16 nFlags = IDF_ALL & ~IDF_STYLES;
2032*cdf0e10cSrcweir         pDoc->DeleteAreaTab( aRange, nFlags );
2033*cdf0e10cSrcweir         pImp->WriteToDocument();
2034*cdf0e10cSrcweir         EndPaste();
2035*cdf0e10cSrcweir     }
2036*cdf0e10cSrcweir     delete pImp;
2037*cdf0e10cSrcweir     return bOk;
2038*cdf0e10cSrcweir }
2039*cdf0e10cSrcweir 
2040*cdf0e10cSrcweir #define RETURN_ERROR { return eERR_INTERN; }
2041*cdf0e10cSrcweir class ScFormatFilterMissing : public ScFormatFilterPlugin {
2042*cdf0e10cSrcweir   public:
2043*cdf0e10cSrcweir     ScFormatFilterMissing()
2044*cdf0e10cSrcweir     {
2045*cdf0e10cSrcweir       OSL_ASSERT ("Missing file filters");
2046*cdf0e10cSrcweir     }
2047*cdf0e10cSrcweir     virtual FltError ScImportLotus123( SfxMedium&, ScDocument*, CharSet ) RETURN_ERROR
2048*cdf0e10cSrcweir     virtual FltError ScImportQuattroPro( SfxMedium &, ScDocument * ) RETURN_ERROR
2049*cdf0e10cSrcweir     virtual FltError ScImportExcel( SfxMedium&, ScDocument*, const EXCIMPFORMAT ) RETURN_ERROR
2050*cdf0e10cSrcweir     virtual FltError ScImportStarCalc10( SvStream&, ScDocument* ) RETURN_ERROR
2051*cdf0e10cSrcweir     virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress&,
2052*cdf0e10cSrcweir 				 const CharSet, sal_uInt32 ) RETURN_ERROR
2053*cdf0e10cSrcweir     virtual FltError ScImportRTF( SvStream&, const String&, ScDocument*, ScRange& ) RETURN_ERROR
2054*cdf0e10cSrcweir     virtual FltError ScImportHTML( SvStream&, const String&, ScDocument*, ScRange&, double, sal_Bool, SvNumberFormatter*, bool ) RETURN_ERROR
2055*cdf0e10cSrcweir 
2056*cdf0e10cSrcweir     virtual ScEEAbsImport *CreateRTFImport( ScDocument*, const ScRange& ) { return NULL; }
2057*cdf0e10cSrcweir     virtual ScEEAbsImport *CreateHTMLImport( ScDocument*, const String&, const ScRange&, sal_Bool ) { return NULL; }
2058*cdf0e10cSrcweir     virtual String         GetHTMLRangeNameList( ScDocument*, const String& ) { return String(); }
2059*cdf0e10cSrcweir 
2060*cdf0e10cSrcweir #if ENABLE_LOTUS123_EXPORT
2061*cdf0e10cSrcweir     virtual FltError ScExportLotus123( SvStream&, ScDocument*, ExportFormatLotus, CharSet ) RETURN_ERROR
2062*cdf0e10cSrcweir #endif
2063*cdf0e10cSrcweir     virtual FltError ScExportExcel5( SfxMedium&, ScDocument*, ExportFormatExcel, CharSet ) RETURN_ERROR
2064*cdf0e10cSrcweir     virtual FltError ScExportDif( SvStream&, ScDocument*, const ScAddress&, const CharSet, sal_uInt32 ) RETURN_ERROR
2065*cdf0e10cSrcweir     virtual FltError ScExportDif( SvStream&, ScDocument*, const ScRange&, const CharSet, sal_uInt32 ) RETURN_ERROR
2066*cdf0e10cSrcweir     virtual FltError ScExportHTML( SvStream&, const String&, ScDocument*, const ScRange&, const CharSet, sal_Bool,
2067*cdf0e10cSrcweir 				  const String&, String& ) RETURN_ERROR
2068*cdf0e10cSrcweir     virtual FltError ScExportRTF( SvStream&, ScDocument*, const ScRange&, const CharSet ) RETURN_ERROR
2069*cdf0e10cSrcweir };
2070*cdf0e10cSrcweir 
2071*cdf0e10cSrcweir extern "C" { static void SAL_CALL thisModule() {} }
2072*cdf0e10cSrcweir typedef ScFormatFilterPlugin * (*FilterFn)(void);
2073*cdf0e10cSrcweir ScFormatFilterPlugin &ScFormatFilter::Get()
2074*cdf0e10cSrcweir {
2075*cdf0e10cSrcweir     static ScFormatFilterPlugin *plugin;
2076*cdf0e10cSrcweir 
2077*cdf0e10cSrcweir     if (plugin != NULL)
2078*cdf0e10cSrcweir         return *plugin;
2079*cdf0e10cSrcweir 
2080*cdf0e10cSrcweir     static ::osl::Module aModule;
2081*cdf0e10cSrcweir     if ( aModule.loadRelative( &thisModule,
2082*cdf0e10cSrcweir 			       ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SVLIBRARY( "scfilt" ) ) ) ) )
2083*cdf0e10cSrcweir     {
2084*cdf0e10cSrcweir 	oslGenericFunction fn = aModule.getFunctionSymbol( ::rtl::OUString::createFromAscii( "ScFilterCreate" ) );
2085*cdf0e10cSrcweir 	if (fn != NULL)
2086*cdf0e10cSrcweir 	    plugin = reinterpret_cast<FilterFn>(fn)();
2087*cdf0e10cSrcweir     }
2088*cdf0e10cSrcweir     if (plugin == NULL)
2089*cdf0e10cSrcweir         plugin = new ScFormatFilterMissing();
2090*cdf0e10cSrcweir 
2091*cdf0e10cSrcweir     return *plugin;
2092*cdf0e10cSrcweir }
2093