LCOV - code coverage report
Current view: top level - sc/source/ui/docshell - impex.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 486 1213 40.1 %
Date: 2012-08-25 Functions: 26 65 40.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 450 2038 22.1 %

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

Generated by: LCOV version 1.10