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