LibreOffice Module sc (master)  1
impex.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
22 #include <i18nutil/unicode.hxx>
23 #include <sot/formats.hxx>
24 #include <sfx2/mieclip.hxx>
25 #include <com/sun/star/i18n/CalendarFieldIndex.hpp>
26 #include <sal/log.hxx>
27 #include <unotools/charclass.hxx>
28 #include <osl/module.hxx>
29 
30 #include <global.hxx>
31 #include <docsh.hxx>
32 #include <undoblk.hxx>
33 #include <rangenam.hxx>
34 #include <tabvwsh.hxx>
35 #include <filter.hxx>
36 #include <asciiopt.hxx>
37 #include <formulacell.hxx>
38 #include <cellform.hxx>
39 #include <progress.hxx>
40 #include <scitems.hxx>
41 #include <editable.hxx>
42 #include <compiler.hxx>
43 #include <warnbox.hxx>
44 #include <clipparam.hxx>
45 #include <impex.hxx>
46 #include <editutil.hxx>
47 #include <patattr.hxx>
48 #include <docpool.hxx>
49 #include <stringutil.hxx>
50 #include <cellvalue.hxx>
51 #include <tokenarray.hxx>
52 #include <documentimport.hxx>
53 #include <refundo.hxx>
54 #include <mtvelements.hxx>
55 
56 #include <globstr.hrc>
57 #include <scresid.hxx>
58 #include <o3tl/safeint.hxx>
59 #include <tools/svlibrary.h>
60 #include <unotools/configmgr.hxx>
61 #include <vcl/svapp.hxx>
62 #include <vcl/weld.hxx>
63 #include <editeng/editobj.hxx>
64 
65 #include <memory>
66 #include <string_view>
67 
68 #include <osl/endian.h>
69 
70 // We don't want to end up with 2GB read in one line just because of malformed
71 // multiline fields, so chop it _somewhere_, which is twice supported columns
72 // times arbitrary maximum cell content length, 2*1024*64K=128M, and because
73 // it's sal_Unicode that's 256MB. If it's 2GB of data without LF we're out of
74 // luck anyway.
77 
78 namespace
79 {
80  const char SYLK_LF[] = "\x1b :";
81 
82  bool lcl_IsEndianSwap( const SvStream& rStrm )
83  {
84  #ifdef OSL_BIGENDIAN
85  return rStrm.GetEndian() != SvStreamEndian::BIG;
86  #else
87  return rStrm.GetEndian() != SvStreamEndian::LITTLE;
88  #endif
89  }
90 }
91 
92 namespace {
93 
94 enum class SylkVersion
95 {
96  SCALC3, // Wrote wrongly quoted strings and unescaped semicolons.
97  OOO32, // Correct strings, plus multiline content.
98  OWN, // Place our new versions, if any, before this value.
99  OTHER // Assume that aliens wrote correct strings.
100 };
101 
102 }
103 
104 // Whole document without Undo
106  : pDocSh( dynamic_cast< ScDocShell* >(r.GetDocumentShell()) ), rDoc( r ),
107  nSizeLimit( 0 ), nMaxImportRow(!utl::ConfigManager::IsFuzzing() ? rDoc.MaxRow() : SCROWS32K),
108  cSep( '\t' ), cStr( '"' ),
109  bFormulas( false ), bIncludeFiltered( true ),
110  bAll( true ), bSingle( true ), bUndo( false ),
111  bOverflowRow( false ), bOverflowCol( false ), bOverflowCell( false ),
112  mbApi( true ), mbImportBroadcast(false), mbOverwriting( false ),
113  mExportTextOptions()
114 {
115  pUndoDoc = nullptr;
116  pExtOptions = nullptr;
117 }
118 
119 // Insert am current cell without range(es)
121  : pDocSh( dynamic_cast< ScDocShell* >(r.GetDocumentShell()) ), rDoc( r ),
122  aRange( rPt ),
123  nSizeLimit( 0 ), nMaxImportRow(!utl::ConfigManager::IsFuzzing() ? rDoc.MaxRow() : SCROWS32K),
124  cSep( '\t' ), cStr( '"' ),
125  bFormulas( false ), bIncludeFiltered( true ),
126  bAll( false ), bSingle( true ), bUndo( pDocSh != nullptr ),
127  bOverflowRow( false ), bOverflowCol( false ), bOverflowCell( false ),
128  mbApi( true ), mbImportBroadcast(false), mbOverwriting( false ),
129  mExportTextOptions()
130 {
131  pUndoDoc = nullptr;
132  pExtOptions = nullptr;
133 }
134 
135 // ctor with a range is only used for export
138  : pDocSh( dynamic_cast<ScDocShell* >(r.GetDocumentShell()) ), rDoc( r ),
139  aRange( rRange ),
140  nSizeLimit( 0 ), nMaxImportRow(!utl::ConfigManager::IsFuzzing() ? rDoc.MaxRow() : SCROWS32K),
141  cSep( '\t' ), cStr( '"' ),
142  bFormulas( false ), bIncludeFiltered( true ),
143  bAll( false ), bSingle( false ), bUndo( pDocSh != nullptr ),
144  bOverflowRow( false ), bOverflowCol( false ), bOverflowCell( false ),
145  mbApi( true ), mbImportBroadcast(false), mbOverwriting( false ),
146  mExportTextOptions()
147 {
148  pUndoDoc = nullptr;
149  pExtOptions = nullptr;
150  // Only one sheet (table) supported
152 }
153 
154 // Evaluate input string - either range, cell or the whole document (when error)
155 // If a View exists, the TabNo of the view will be used.
156 ScImportExport::ScImportExport( ScDocument& r, const OUString& rPos )
157  : pDocSh( dynamic_cast< ScDocShell* >(r.GetDocumentShell()) ), rDoc( r ),
158  nSizeLimit( 0 ), nMaxImportRow(!utl::ConfigManager::IsFuzzing() ? rDoc.MaxRow() : SCROWS32K),
159  cSep( '\t' ), cStr( '"' ),
160  bFormulas( false ), bIncludeFiltered( true ),
161  bAll( false ), bSingle( true ), bUndo( pDocSh != nullptr ),
162  bOverflowRow( false ), bOverflowCol( false ), bOverflowCell( false ),
163  mbApi( true ), mbImportBroadcast(false), mbOverwriting( false ),
164  mExportTextOptions()
165 {
166  pUndoDoc = nullptr;
167  pExtOptions = nullptr;
168 
169  SCTAB nTab = ScDocShell::GetCurTab();
170  aRange.aStart.SetTab( nTab );
171  OUString aPos( rPos );
172  // Named range?
173  ScRangeName* pRange = rDoc.GetRangeName();
174  if (pRange)
175  {
176  const ScRangeData* pData = pRange->findByUpperName(ScGlobal::getCharClassPtr()->uppercase(aPos));
177  if (pData)
178  {
179  if( pData->HasType( ScRangeData::Type::RefArea )
181  || pData->HasType( ScRangeData::Type::AbsPos ) )
182  {
183  pData->GetSymbol(aPos);
184  }
185  }
186  }
188  // Range?
189  if (aRange.Parse(aPos, rDoc, eConv) & ScRefFlags::VALID)
190  bSingle = false;
191  // Cell?
192  else if (aRange.aStart.Parse(aPos, rDoc, eConv) & ScRefFlags::VALID)
194  else
195  bAll = true;
196 }
197 
198 ScImportExport::~ScImportExport() COVERITY_NOEXCEPT_FALSE
199 {
200  pUndoDoc.reset();
201  pExtOptions.reset();
202 }
203 
205 {
206  if ( pExtOptions )
207  *pExtOptions = rOpt;
208  else
209  pExtOptions.reset(new ScAsciiOptions( rOpt ));
210 
211  // "normal" Options
212 
214  cStr = rOpt.GetTextSep();
215 }
216 
217 void ScImportExport::SetFilterOptions(const OUString& rFilterOptions)
218 {
219  maFilterOptions = rFilterOptions;
220 }
221 
223 {
224  return nFormat == SotClipboardFormatId::STRING
225  || nFormat == SotClipboardFormatId::STRING_TSVC
226  || nFormat == SotClipboardFormatId::SYLK
227  || nFormat == SotClipboardFormatId::LINK
228  || nFormat == SotClipboardFormatId::HTML
229  || nFormat == SotClipboardFormatId::HTML_SIMPLE
230  || nFormat == SotClipboardFormatId::DIF;
231 }
232 
233 // Prepare for Undo
235 {
236  if ( !bAll )
237  {
238  ScEditableTester aTester( rDoc, aRange );
239  if ( !aTester.IsEditable() )
240  {
242  std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pWin ? pWin->GetFrameWeld() : nullptr,
243  VclMessageType::Info, VclButtonsType::Ok,
244  ScResId(aTester.GetMessageId())));
245  xInfoBox->run();
246  return false;
247  }
248  }
249  if( bUndo && pDocSh && rDoc.IsUndoEnabled())
250  {
251  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
252  pUndoDoc->InitUndo( rDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() );
254  }
255  return true;
256 }
257 
258 // Create Undo/Redo actions, Invalidate/Repaint
259 void ScImportExport::EndPaste(bool bAutoRowHeight)
260 {
261  bool bHeight = bAutoRowHeight && pDocSh && pDocSh->AdjustRowHeight(
263 
264  if( pUndoDoc && rDoc.IsUndoEnabled() && pDocSh )
265  {
267  pRedoDoc->InitUndo( rDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() );
269  ScMarkData aDestMark(pRedoDoc->GetSheetLimits());
270  aDestMark.SetMarkArea(aRange);
272  std::make_unique<ScUndoPaste>(pDocSh, aRange, aDestMark, std::move(pUndoDoc), std::move(pRedoDoc), InsertDeleteFlags::ALL, nullptr));
273  }
274  pUndoDoc.reset();
275  if( pDocSh )
276  {
277  if (!bHeight)
280  }
282  if ( pViewSh )
283  pViewSh->UpdateInputHandler();
284 
285 }
286 
287 bool ScImportExport::ExportData( const OUString& rMimeType,
288  css::uno::Any & rValue )
289 {
290  SvMemoryStream aStrm;
291  // mba: no BaseURL for data exchange
292  if( ExportStream( aStrm, OUString(),
294  {
295  aStrm.WriteUChar( 0 );
296  rValue <<= css::uno::Sequence< sal_Int8 >(
297  static_cast<sal_Int8 const *>(aStrm.GetData()),
298  aStrm.TellEnd() );
299  return true;
300  }
301  return false;
302 }
303 
304 bool ScImportExport::ImportString( const OUString& rText, SotClipboardFormatId nFmt )
305 {
306  switch ( nFmt )
307  {
308  // formats supporting unicode
309  case SotClipboardFormatId::STRING :
310  case SotClipboardFormatId::STRING_TSVC :
311  {
312  ScImportStringStream aStrm( rText);
313  return ImportStream( aStrm, OUString(), nFmt );
314  // ImportStream must handle RTL_TEXTENCODING_UNICODE
315  }
316  default:
317  {
318  rtl_TextEncoding eEnc = osl_getThreadTextEncoding();
319  OString aTmp( rText.getStr(), rText.getLength(), eEnc );
320  SvMemoryStream aStrm( const_cast<char *>(aTmp.getStr()), aTmp.getLength() * sizeof(char), StreamMode::READ );
321  aStrm.SetStreamCharSet( eEnc );
322  SetNoEndianSwap( aStrm );
323  return ImportStream( aStrm, OUString(), nFmt );
324  }
325  }
326 }
327 
329 {
330  if ( nFmt != SotClipboardFormatId::STRING && nFmt != SotClipboardFormatId::STRING_TSVC )
331  {
332  SAL_WARN("sc.ui", "ScImportExport::ExportString: Unicode not supported for other formats than SotClipboardFormatId::STRING[_TSV]");
333  rtl_TextEncoding eEnc = osl_getThreadTextEncoding();
334  OString aTmp;
335  bool bOk = ExportByteString( aTmp, eEnc, nFmt );
336  rText = OStringToOUString( aTmp, eEnc );
337  return bOk;
338  }
339  // nSizeLimit not needed for OUString
340 
341  SvMemoryStream aStrm;
342  aStrm.SetStreamCharSet( RTL_TEXTENCODING_UNICODE );
343  SetNoEndianSwap( aStrm );
344  // mba: no BaseURL for data exc
345  if( ExportStream( aStrm, OUString(), nFmt ) )
346  {
347  aStrm.WriteUInt16( 0 );
348  rText = OUString( static_cast<const sal_Unicode*>(aStrm.GetData()) );
349  return true;
350  }
351  rText.clear();
352  return false;
353 
354  // ExportStream must handle RTL_TEXTENCODING_UNICODE
355 }
356 
357 bool ScImportExport::ExportByteString( OString& rText, rtl_TextEncoding eEnc, SotClipboardFormatId nFmt )
358 {
359  OSL_ENSURE( eEnc != RTL_TEXTENCODING_UNICODE, "ScImportExport::ExportByteString: Unicode not supported" );
360  if ( eEnc == RTL_TEXTENCODING_UNICODE )
361  eEnc = osl_getThreadTextEncoding();
362 
363  if (!nSizeLimit)
365 
366  SvMemoryStream aStrm;
367  aStrm.SetStreamCharSet( eEnc );
368  SetNoEndianSwap( aStrm );
369  // mba: no BaseURL for data exchange
370  if( ExportStream( aStrm, OUString(), nFmt ) )
371  {
372  aStrm.WriteChar( 0 );
373  if( aStrm.TellEnd() <= nSizeLimit )
374  {
375  rText = static_cast<const char*>(aStrm.GetData());
376  return true;
377  }
378  }
379  rText.clear();
380  return false;
381 }
382 
383 bool ScImportExport::ImportStream( SvStream& rStrm, const OUString& rBaseURL, SotClipboardFormatId nFmt )
384 {
385  if( nFmt == SotClipboardFormatId::STRING || nFmt == SotClipboardFormatId::STRING_TSVC )
386  {
387  if( ExtText2Doc( rStrm ) ) // evaluate pExtOptions
388  return true;
389  }
390  if( nFmt == SotClipboardFormatId::SYLK )
391  {
392  if( Sylk2Doc( rStrm ) )
393  return true;
394  }
395  if( nFmt == SotClipboardFormatId::DIF )
396  {
397  if( Dif2Doc( rStrm ) )
398  return true;
399  }
400  if( nFmt == SotClipboardFormatId::RTF || nFmt == SotClipboardFormatId::RICHTEXT )
401  {
402  if( RTF2Doc( rStrm, rBaseURL ) )
403  return true;
404  }
405  if( nFmt == SotClipboardFormatId::LINK )
406  return true; // Link-Import?
407  if ( nFmt == SotClipboardFormatId::HTML )
408  {
409  if( HTML2Doc( rStrm, rBaseURL ) )
410  return true;
411  }
412  if ( nFmt == SotClipboardFormatId::HTML_SIMPLE )
413  {
414  MSE40HTMLClipFormatObj aMSE40ClpObj; // needed to skip the header data
415  SvStream* pHTML = aMSE40ClpObj.IsValid( rStrm );
416  if ( pHTML && HTML2Doc( *pHTML, rBaseURL ) )
417  return true;
418  }
419 
420  return false;
421 }
422 
423 bool ScImportExport::ExportStream( SvStream& rStrm, const OUString& rBaseURL, SotClipboardFormatId nFmt )
424 {
425  if( nFmt == SotClipboardFormatId::STRING || nFmt == SotClipboardFormatId::STRING_TSVC )
426  {
427  if( Doc2Text( rStrm ) )
428  return true;
429  }
430  if( nFmt == SotClipboardFormatId::SYLK )
431  {
432  if( Doc2Sylk( rStrm ) )
433  return true;
434  }
435  if( nFmt == SotClipboardFormatId::DIF )
436  {
437  if( Doc2Dif( rStrm ) )
438  return true;
439  }
440  if( nFmt == SotClipboardFormatId::LINK && !bAll )
441  {
442  OUString aDocName;
443  if ( rDoc.IsClipboard() )
444  aDocName = ScGlobal::GetClipDocName();
445  else
446  {
448  if (pShell)
449  aDocName = pShell->GetTitle( SFX_TITLE_FULLNAME );
450  }
451 
452  OSL_ENSURE( !aDocName.isEmpty(), "ClipBoard document has no name! :-/" );
453  if( !aDocName.isEmpty() )
454  {
455  // Always use Calc A1 syntax for paste link.
456  OUString aRefName;
458  if( bSingle )
460  else
461  {
462  if( aRange.aStart.Tab() != aRange.aEnd.Tab() )
463  nFlags |= ScRefFlags::TAB2_3D;
465  }
466  OUString aAppName = Application::GetAppName();
467 
468  // extra bits are used to tell the client to prefer external
469  // reference link.
470 
471  WriteUnicodeOrByteString( rStrm, aAppName, true );
472  WriteUnicodeOrByteString( rStrm, aDocName, true );
473  WriteUnicodeOrByteString( rStrm, aRefName, true );
474  WriteUnicodeOrByteString( rStrm, "calc:extref", true );
475  if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
476  rStrm.WriteUInt16( 0 );
477  else
478  rStrm.WriteChar( 0 );
479  return rStrm.GetError() == ERRCODE_NONE;
480  }
481  }
482  if( nFmt == SotClipboardFormatId::HTML )
483  {
484  if( Doc2HTML( rStrm, rBaseURL ) )
485  return true;
486  }
487  if( nFmt == SotClipboardFormatId::RTF || nFmt == SotClipboardFormatId::RICHTEXT )
488  {
489  if( Doc2RTF( rStrm ) )
490  return true;
491  }
492 
493  return false;
494 }
495 
496 void ScImportExport::WriteUnicodeOrByteString( SvStream& rStrm, const OUString& rString, bool bZero )
497 {
498  rtl_TextEncoding eEnc = rStrm.GetStreamCharSet();
499  if ( eEnc == RTL_TEXTENCODING_UNICODE )
500  {
501  if ( !lcl_IsEndianSwap( rStrm ) )
502  rStrm.WriteBytes(rString.getStr(), rString.getLength() * sizeof(sal_Unicode));
503  else
504  {
505  const sal_Unicode* p = rString.getStr();
506  const sal_Unicode* const pStop = p + rString.getLength();
507  while ( p < pStop )
508  {
509  rStrm.WriteUInt16( *p );
510  }
511  }
512  if ( bZero )
513  rStrm.WriteUInt16( 0 );
514  }
515  else
516  {
517  OString aByteStr(OUStringToOString(rString, eEnc));
518  rStrm.WriteOString( aByteStr );
519  if ( bZero )
520  rStrm.WriteChar( 0 );
521  }
522 }
523 
524 // This function could be replaced by endlub()
526 {
527  if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE )
528  { // same as endl() but unicode
529  switch ( rStrm.GetLineDelimiter() )
530  {
531  case LINEEND_CR :
532  rStrm.WriteUInt16( '\r' );
533  break;
534  case LINEEND_LF :
535  rStrm.WriteUInt16( '\n' );
536  break;
537  default:
538  rStrm.WriteUInt16( '\r' ).WriteUInt16( '\n' );
539  }
540  }
541  else
542  endl( rStrm );
543 }
544 
545 sal_Int32 ScImportExport::CountVisualWidth(const OUString& rStr, sal_Int32& nIdx, sal_Int32 nMaxWidth)
546 {
547  sal_Int32 nWidth = 0;
548  while(nIdx < rStr.getLength() && nWidth < nMaxWidth)
549  {
550  sal_uInt32 nCode = rStr.iterateCodePoints(&nIdx);
551 
552  if (unicode::isCJKIVSCharacter(nCode) || (nCode >= 0x3000 && nCode <= 0x303F))
553  nWidth += 2;
554  else if (!unicode::isIVSSelector(nCode))
555  nWidth += 1;
556  }
557 
558  if (nIdx < rStr.getLength())
559  {
560  sal_Int32 nTmpIdx = nIdx;
561  sal_uInt32 nCode = rStr.iterateCodePoints(&nTmpIdx);
562 
563  if (unicode::isIVSSelector(nCode))
564  nIdx = nTmpIdx;
565  }
566  return nWidth;
567 }
568 
569 sal_Int32 ScImportExport::CountVisualWidth(const OUString& rStr)
570 {
571  sal_Int32 nIdx = 0;
572  return CountVisualWidth(rStr, nIdx, SAL_MAX_INT32);
573 }
574 
576 {
577 #ifdef OSL_BIGENDIAN
578  rStrm.SetEndian( SvStreamEndian::BIG );
579 #else
580  rStrm.SetEndian( SvStreamEndian::LITTLE );
581 #endif
582 }
583 
584 namespace {
585 
587 {
588  FIELDSTART_QUOTE,
589  FIRST_QUOTE,
590  SECOND_QUOTE,
591  FIELDEND_QUOTE,
592  DONTKNOW_QUOTE
593 };
594 
595 }
596 
605 static QuoteType lcl_isFieldEndQuote( const sal_Unicode* p, const sal_Unicode* pSeps, sal_Unicode& rcDetectSep )
606 {
607  // Due to broken CSV generators that don't double embedded quotes check if
608  // a field separator immediately or with trailing spaces follows the quote,
609  // only then end the field, or at end of string.
610  const sal_Unicode cBlank = ' ';
611  if (p[1] == cBlank && ScGlobal::UnicodeStrChr( pSeps, cBlank))
612  return FIELDEND_QUOTE;
613  // Detect a possible blank separator if it's not already in the list (which
614  // was checked right above for p[1]==cBlank).
615  if (p[1] == cBlank && !rcDetectSep && p[2] && p[2] != cBlank)
616  rcDetectSep = cBlank;
617  while (p[1] == cBlank)
618  ++p;
619  if (!p[1] || ScGlobal::UnicodeStrChr( pSeps, p[1]))
620  return FIELDEND_QUOTE;
621  return DONTKNOW_QUOTE;
622 }
623 
645 static QuoteType lcl_isEscapedOrFieldEndQuote( sal_Int32 nQuotes, const sal_Unicode* p,
646  const sal_Unicode* pSeps, sal_Unicode cStr, sal_Unicode& rcDetectSep )
647 {
648  if ((nQuotes % 2) == 0)
649  {
650  if (p[-1] == cStr)
651  return SECOND_QUOTE;
652  else
653  {
654  SAL_WARN( "sc", "lcl_isEscapedOrFieldEndQuote: really want a FIELDSTART_QUOTE?");
655  return FIELDSTART_QUOTE;
656  }
657  }
658  if (p[1] == cStr)
659  return FIRST_QUOTE;
660  return lcl_isFieldEndQuote( p, pSeps, rcDetectSep);
661 }
662 
667 static bool lcl_appendLineData( OUString& rField, const sal_Unicode* p1, const sal_Unicode* p2 )
668 {
669  if (rField.getLength() + (p2 - p1) <= nArbitraryCellLengthLimit)
670  {
671  rField += OUString( p1, sal::static_int_cast<sal_Int32>( p2 - p1 ) );
672  return true;
673  }
674  else
675  {
676  SAL_WARN( "sc", "lcl_appendLineData: data overflow");
677  rField += OUString( p1, nArbitraryCellLengthLimit - rField.getLength() );
678  return false;
679  }
680 }
681 
682 namespace {
683 
685 {
686  KEEP_ALL, // both are taken, additionally start and end quote are included in string
687  ESCAPE, // escaped quote, one is taken, one ignored
688 };
689 
690 }
691 
692 static const sal_Unicode* lcl_ScanString( const sal_Unicode* p, OUString& rString,
693  const sal_Unicode* pSeps, sal_Unicode cStr, DoubledQuoteMode eMode, bool& rbOverflowCell )
694 {
695  if (eMode != DoubledQuoteMode::KEEP_ALL)
696  p++;
697  bool bCont;
698  do
699  {
700  bCont = false;
701  const sal_Unicode* p0 = p;
702  for( ;; )
703  {
704  if( !*p )
705  break;
706  if( *p == cStr )
707  {
708  if ( *++p != cStr )
709  {
710  // break or continue for loop
711  if (eMode == DoubledQuoteMode::ESCAPE)
712  {
713  sal_Unicode cDetectSep = 0xffff; // No separator detection here.
714  if (lcl_isFieldEndQuote( p-1, pSeps, cDetectSep) == FIELDEND_QUOTE)
715  break;
716  else
717  continue;
718  }
719  else
720  break;
721  }
722  // doubled quote char
723  switch ( eMode )
724  {
725  case DoubledQuoteMode::KEEP_ALL :
726  p++; // both for us (not breaking for-loop)
727  break;
728  case DoubledQuoteMode::ESCAPE :
729  p++; // one for us (breaking for-loop)
730  bCont = true; // and more
731  break;
732  }
733  if ( eMode == DoubledQuoteMode::ESCAPE )
734  break;
735  }
736  else
737  p++;
738  }
739  if ( p0 < p )
740  {
741  if (!lcl_appendLineData( rString, p0, ((eMode != DoubledQuoteMode::KEEP_ALL && (*p || *(p-1) == cStr)) ? p-1 : p)))
742  rbOverflowCell = true;
743  }
744  } while ( bCont );
745  return p;
746 }
747 
748 static void lcl_UnescapeSylk( OUString & rString, SylkVersion eVersion )
749 {
750  // Older versions didn't escape the semicolon.
751  // Older versions quoted the string and doubled embedded quotes, but not
752  // the semicolons, which was plain wrong.
753  if (eVersion >= SylkVersion::OOO32)
754  rString = rString.replaceAll(";;", ";");
755  else
756  rString = rString.replaceAll("\"\"", "\"");
757 
758  rString = rString.replaceAll(SYLK_LF, "\n");
759 }
760 
762  OUString& rString, SylkVersion eVersion )
763 {
764  const sal_Unicode* pStartQuote = p;
765  const sal_Unicode* pEndQuote = nullptr;
766  while( *(++p) )
767  {
768  if( *p == '"' )
769  {
770  pEndQuote = p;
771  if (eVersion >= SylkVersion::OOO32)
772  {
773  if (*(p+1) == ';')
774  {
775  if (*(p+2) == ';')
776  {
777  p += 2; // escaped ';'
778  pEndQuote = nullptr;
779  }
780  else
781  break; // end field
782  }
783  }
784  else
785  {
786  if (*(p+1) == '"')
787  {
788  ++p; // escaped '"'
789  pEndQuote = nullptr;
790  }
791  else if (*(p+1) == ';')
792  break; // end field
793  }
794  }
795  }
796  if (!pEndQuote)
797  pEndQuote = p; // Take all data as string.
798  rString += OUString(pStartQuote + 1, sal::static_int_cast<sal_Int32>( pEndQuote - pStartQuote - 1 ) );
799  lcl_UnescapeSylk( rString, eVersion);
800  return p;
801 }
802 
804  OUString& rString, SylkVersion eVersion )
805 {
806  const sal_Unicode* pStart = p;
807  if (eVersion >= SylkVersion::OOO32)
808  {
809  while (*p)
810  {
811  if (*p == ';')
812  {
813  if (*(p+1) == ';')
814  ++p; // escaped ';'
815  else
816  break; // end field
817  }
818  ++p;
819  }
820  rString += OUString( pStart, sal::static_int_cast<sal_Int32>( p - pStart));
821  lcl_UnescapeSylk( rString, eVersion);
822  }
823  else
824  {
825  // Nasty. If in old versions the formula contained a semicolon, it was
826  // quoted and embedded quotes were doubled, but semicolons were not. If
827  // there was no semicolon, it could still contain quotes and doubled
828  // embedded quotes if it was something like ="a""b", which was saved as
829  // E"a""b" as is and has to be preserved, even if older versions
830  // couldn't even load it correctly. However, theoretically another
831  // field might follow and thus the line contain a semicolon again, such
832  // as ...;E"a""b";...
833  bool bQuoted = false;
834  if (*p == '"')
835  {
836  // May be a quoted expression or just a string constant expression
837  // with quotes.
838  while (*(++p))
839  {
840  if (*p == '"')
841  {
842  if (*(p+1) == '"')
843  ++p; // escaped '"'
844  else
845  break; // closing '"', had no ';' yet
846  }
847  else if (*p == ';')
848  {
849  bQuoted = true; // ';' within quoted expression
850  break;
851  }
852  }
853  p = pStart;
854  }
855  if (bQuoted)
856  p = lcl_ScanSylkString( p, rString, eVersion);
857  else
858  {
859  while (*p && *p != ';')
860  ++p;
861  rString += OUString( pStart, sal::static_int_cast<sal_Int32>( p - pStart));
862  }
863  }
864  return p;
865 }
866 
867 static void lcl_DoubleEscapeChar( OUString& rString, sal_Unicode cStr )
868 {
869  sal_Int32 n = 0;
870  while( ( n = rString.indexOf( cStr, n ) ) != -1 )
871  {
872  rString = rString.replaceAt( n, 0, OUString(cStr) );
873  n += 2;
874  }
875 }
876 
877 static void lcl_WriteString( SvStream& rStrm, OUString& rString, sal_Unicode cQuote, sal_Unicode cEsc )
878 {
879  if (cEsc)
880  lcl_DoubleEscapeChar( rString, cEsc );
881 
882  if (cQuote)
883  {
884  rString = OUStringChar(cQuote) + rString + OUStringChar(cQuote);
885  }
886 
888 }
889 
890 static void lcl_WriteSimpleString( SvStream& rStrm, const OUString& rString )
891 {
893 }
894 
896 {
897  bool bOk = true;
898 
899  sal_Unicode pSeps[2];
900  pSeps[0] = cSep;
901  pSeps[1] = 0;
902 
903  ScSetStringParam aSetStringParam;
904  aSetStringParam.mbCheckLinkFormula = true;
905 
906  SCCOL nStartCol = aRange.aStart.Col();
907  SCROW nStartRow = aRange.aStart.Row();
908  SCCOL nEndCol = aRange.aEnd.Col();
909  SCROW nEndRow = aRange.aEnd.Row();
910  sal_uLong nOldPos = rStrm.Tell();
911  rStrm.StartReadingUnicodeText( rStrm.GetStreamCharSet() );
912  bool bData = !bSingle;
913  if( !bSingle)
914  bOk = StartPaste();
915 
916  while( bOk )
917  {
918  OUString aLine;
919  OUString aCell;
920  SCROW nRow = nStartRow;
921  rStrm.Seek( nOldPos );
922  for( ;; )
923  {
925  // tdf#125440 When inserting tab separated string, consider quotes as field markers
926  DoubledQuoteMode mode = aLine.indexOf("\t") >= 0 ? DoubledQuoteMode::ESCAPE : DoubledQuoteMode::KEEP_ALL;
927  if( rStrm.eof() )
928  break;
929  SCCOL nCol = nStartCol;
930  const sal_Unicode* p = aLine.getStr();
931  while( *p )
932  {
933  aCell.clear();
934  const sal_Unicode* q = p;
935  while (*p && *p != cSep)
936  {
937  // Always look for a pairing quote and ignore separator in between.
938  while (*p && *p == cStr)
939  q = p = lcl_ScanString( p, aCell, pSeps, cStr, mode, bOverflowCell );
940  // All until next separator or quote.
941  while (*p && *p != cSep && *p != cStr)
942  ++p;
943  if (!lcl_appendLineData( aCell, q, p))
944  bOverflowCell = true; // display warning on import
945  q = p;
946  }
947  if (*p)
948  ++p;
949  if (rDoc.ValidCol(nCol) && rDoc.ValidRow(nRow) )
950  {
951  if( bSingle )
952  {
953  if (nCol>nEndCol) nEndCol = nCol;
954  if (nRow>nEndRow) nEndRow = nRow;
955  }
956  if( bData && nCol <= nEndCol && nRow <= nEndRow )
957  rDoc.SetString( nCol, nRow, aRange.aStart.Tab(), aCell, &aSetStringParam );
958  }
959  else // too many columns/rows
960  {
961  if (!rDoc.ValidRow(nRow))
962  bOverflowRow = true; // display warning on import
963  if (!rDoc.ValidCol(nCol))
964  bOverflowCol = true; // display warning on import
965  }
966  ++nCol;
967  }
968  ++nRow;
969  }
970 
971  if( !bData )
972  {
973  aRange.aEnd.SetCol( nEndCol );
974  aRange.aEnd.SetRow( nEndRow );
975  bOk = StartPaste();
976  bData = true;
977  }
978  else
979  break;
980  }
981 
982  EndPaste();
983  if (bOk && mbImportBroadcast)
984  {
985  rDoc.BroadcastCells(aRange, SfxHintId::ScDataChanged);
987  }
988 
989  return bOk;
990 }
991 
992 // Extended Ascii-Import
993 
994 static bool lcl_PutString(
995  ScDocumentImport& rDocImport, bool bUseDocImport,
996  SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rStr, sal_uInt8 nColFormat,
997  SvNumberFormatter* pFormatter, bool bDetectNumFormat, bool bSkipEmptyCells,
998  const ::utl::TransliterationWrapper& rTransliteration, CalendarWrapper& rCalendar,
999  const ::utl::TransliterationWrapper* pSecondTransliteration, CalendarWrapper* pSecondCalendar )
1000 {
1001  ScDocument& rDoc = rDocImport.getDoc();
1002  bool bMultiLine = false;
1003  if ( nColFormat == SC_COL_SKIP || !rDoc.ValidCol(nCol) || !rDoc.ValidRow(nRow) )
1004  return bMultiLine;
1005  if ( rStr.isEmpty() )
1006  {
1007  if ( !bSkipEmptyCells )
1008  { // delete destination cell
1009  if ( bUseDocImport )
1010  rDocImport.setAutoInput(ScAddress(nCol, nRow, nTab), rStr );
1011  else
1012  rDoc.SetString( nCol, nRow, nTab, rStr );
1013  }
1014  return false;
1015  }
1016 
1017  if ( nColFormat == SC_COL_TEXT )
1018  {
1019  double fDummy;
1020  sal_uInt32 nIndex = 0;
1021  if (pFormatter->IsNumberFormat(rStr, nIndex, fDummy))
1022  {
1023  // Set the format of this cell to Text.
1024  sal_uInt32 nFormat = pFormatter->GetStandardFormat(SvNumFormatType::TEXT);
1025  ScPatternAttr aNewAttrs(rDoc.GetPool());
1026  SfxItemSet& rSet = aNewAttrs.GetItemSet();
1027  rSet.Put( SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat) );
1028  rDoc.ApplyPattern(nCol, nRow, nTab, aNewAttrs);
1029  }
1030  if ( bUseDocImport )
1031  {
1032  if(ScStringUtil::isMultiline(rStr))
1033  {
1034  ScFieldEditEngine& rEngine = rDoc.GetEditEngine();
1035  rEngine.SetTextCurrentDefaults(rStr);
1036  rDocImport.setEditCell(ScAddress(nCol, nRow, nTab), rEngine.CreateTextObject());
1037  return true;
1038  }
1039  else
1040  {
1041  rDocImport.setStringCell(ScAddress(nCol, nRow, nTab), rStr);
1042  return false;
1043  }
1044  } else
1045  {
1046  rDoc.SetTextCell(ScAddress(nCol, nRow, nTab), rStr);
1047  return bMultiLine;
1048  }
1049  }
1050 
1051  if ( nColFormat == SC_COL_ENGLISH )
1052  {
1054 
1055  SvNumberFormatter* pDocFormatter = rDoc.GetFormatTable();
1056  sal_uInt32 nEnglish = pDocFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
1057  double fVal;
1058  if ( pDocFormatter->IsNumberFormat( rStr, nEnglish, fVal ) )
1059  {
1060  // Numberformat will not be set to English
1061  if ( bUseDocImport )
1062  rDocImport.setNumericCell( ScAddress( nCol, nRow, nTab ), fVal );
1063  else
1064  rDoc.SetValue( nCol, nRow, nTab, fVal );
1065  return bMultiLine;
1066  }
1067  // else, continue with SetString
1068  }
1069  else if ( nColFormat != SC_COL_STANDARD ) // Datumformats
1070  {
1071  const sal_uInt16 nMaxNumberParts = 7; // Y-M-D h:m:s.t
1072  sal_Int32 nLen = rStr.getLength();
1073  sal_Int32 nStart[nMaxNumberParts];
1074  sal_Int32 nEnd[nMaxNumberParts];
1075 
1076  sal_uInt16 nDP, nMP, nYP;
1077  switch ( nColFormat )
1078  {
1079  case SC_COL_YMD: nDP = 2; nMP = 1; nYP = 0; break;
1080  case SC_COL_MDY: nDP = 1; nMP = 0; nYP = 2; break;
1081  case SC_COL_DMY:
1082  default: nDP = 0; nMP = 1; nYP = 2; break;
1083  }
1084 
1085  sal_uInt16 nFound = 0;
1086  bool bInNum = false;
1087  for ( sal_Int32 nPos=0; nPos<nLen && (bInNum ||
1088  nFound<nMaxNumberParts); nPos++ )
1089  {
1090  if (bInNum && nFound == 3 && nColFormat == SC_COL_YMD &&
1091  nPos <= nStart[nFound]+2 && rStr[nPos] == 'T')
1092  bInNum = false; // ISO-8601: YYYY-MM-DDThh:mm...
1093  else if ((((!bInNum && nFound==nMP) || (bInNum && nFound==nMP+1))
1094  && ScGlobal::getCharClassPtr()->isLetterNumeric( rStr, nPos))
1095  || ScGlobal::getCharClassPtr()->isDigit( rStr, nPos))
1096  {
1097  if (!bInNum)
1098  {
1099  bInNum = true;
1100  nStart[nFound] = nPos;
1101  ++nFound;
1102  }
1103  nEnd[nFound-1] = nPos;
1104  }
1105  else
1106  bInNum = false;
1107  }
1108 
1109  if ( nFound == 1 )
1110  {
1111  // try to break one number (without separators) into date fields
1112 
1113  sal_Int32 nDateStart = nStart[0];
1114  sal_Int32 nDateLen = nEnd[0] + 1 - nDateStart;
1115 
1116  if ( nDateLen >= 5 && nDateLen <= 8 &&
1117  ScGlobal::getCharClassPtr()->isNumeric( rStr.copy( nDateStart, nDateLen ) ) )
1118  {
1119  // 6 digits: 2 each for day, month, year
1120  // 8 digits: 4 for year, 2 each for day and month
1121  // 5 or 7 digits: first field is shortened by 1
1122 
1123  bool bLongYear = ( nDateLen >= 7 );
1124  bool bShortFirst = ( nDateLen == 5 || nDateLen == 7 );
1125 
1126  sal_uInt16 nFieldStart = nDateStart;
1127  for (sal_uInt16 nPos=0; nPos<3; nPos++)
1128  {
1129  sal_uInt16 nFieldEnd = nFieldStart + 1; // default: 2 digits
1130  if ( bLongYear && nPos == nYP )
1131  nFieldEnd += 2; // 2 extra digits for long year
1132  if ( bShortFirst && nPos == 0 )
1133  --nFieldEnd; // first field shortened?
1134 
1135  nStart[nPos] = nFieldStart;
1136  nEnd[nPos] = nFieldEnd;
1137  nFieldStart = nFieldEnd + 1;
1138  }
1139  nFound = 3;
1140  }
1141  }
1142 
1143  if ( nFound >= 3 )
1144  {
1145  using namespace ::com::sun::star;
1146  bool bSecondCal = false;
1147  sal_uInt16 nDay = static_cast<sal_uInt16>(rStr.copy( nStart[nDP], nEnd[nDP]+1-nStart[nDP] ).toInt32());
1148  sal_uInt16 nYear = static_cast<sal_uInt16>(rStr.copy( nStart[nYP], nEnd[nYP]+1-nStart[nYP] ).toInt32());
1149  OUString aMStr = rStr.copy( nStart[nMP], nEnd[nMP]+1-nStart[nMP] );
1150  sal_Int16 nMonth = static_cast<sal_Int16>(aMStr.toInt32());
1151  if (!nMonth)
1152  {
1153  static constexpr OUStringLiteral aSepShortened = u"SEP";
1154  uno::Sequence< i18n::CalendarItem2 > xMonths;
1155  sal_Int32 i, nMonthCount;
1156  // first test all month names from local international
1157  xMonths = rCalendar.getMonths();
1158  nMonthCount = xMonths.getLength();
1159  for (i=0; i<nMonthCount && !nMonth; i++)
1160  {
1161  if ( rTransliteration.isEqual( aMStr, xMonths[i].FullName ) ||
1162  rTransliteration.isEqual( aMStr, xMonths[i].AbbrevName ) )
1163  nMonth = sal::static_int_cast<sal_Int16>( i+1 );
1164  else if ( i == 8 && rTransliteration.isEqual( "SEPT",
1165  xMonths[i].AbbrevName ) &&
1166  rTransliteration.isEqual( aMStr, aSepShortened ) )
1167  { // correct English abbreviation is SEPT,
1168  // but data mostly contains SEP only
1169  nMonth = sal::static_int_cast<sal_Int16>( i+1 );
1170  }
1171  }
1172  // if none found, then test english month names
1173  if ( !nMonth && pSecondCalendar && pSecondTransliteration )
1174  {
1175  xMonths = pSecondCalendar->getMonths();
1176  nMonthCount = xMonths.getLength();
1177  for (i=0; i<nMonthCount && !nMonth; i++)
1178  {
1179  if ( pSecondTransliteration->isEqual( aMStr, xMonths[i].FullName ) ||
1180  pSecondTransliteration->isEqual( aMStr, xMonths[i].AbbrevName ) )
1181  {
1182  nMonth = sal::static_int_cast<sal_Int16>( i+1 );
1183  bSecondCal = true;
1184  }
1185  else if ( i == 8 && pSecondTransliteration->isEqual(
1186  aMStr, aSepShortened ) )
1187  { // correct English abbreviation is SEPT,
1188  // but data mostly contains SEP only
1189  nMonth = sal::static_int_cast<sal_Int16>( i+1 );
1190  bSecondCal = true;
1191  }
1192  }
1193  }
1194  }
1195 
1196  SvNumberFormatter* pDocFormatter = rDoc.GetFormatTable();
1197  if ( nYear < 100 )
1198  nYear = pDocFormatter->ExpandTwoDigitYear( nYear );
1199 
1200  CalendarWrapper* pCalendar = (bSecondCal ? pSecondCalendar : &rCalendar);
1201  sal_Int16 nNumMonths = pCalendar->getNumberOfMonthsInYear();
1202  if ( nDay && nMonth && nDay<=31 && nMonth<=nNumMonths )
1203  {
1204  --nMonth;
1205  pCalendar->setValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, nDay );
1206  pCalendar->setValue( i18n::CalendarFieldIndex::MONTH, nMonth );
1207  pCalendar->setValue( i18n::CalendarFieldIndex::YEAR, nYear );
1208  sal_Int16 nHour, nMinute, nSecond;
1209  // #i14974# The imported value should have no fractional value, so set the
1210  // time fields to zero (ICU calendar instance defaults to current date/time)
1211  nHour = nMinute = nSecond = 0;
1212  if (nFound > 3)
1213  nHour = static_cast<sal_Int16>(rStr.copy( nStart[3], nEnd[3]+1-nStart[3]).toInt32());
1214  if (nFound > 4)
1215  nMinute = static_cast<sal_Int16>(rStr.copy( nStart[4], nEnd[4]+1-nStart[4]).toInt32());
1216  if (nFound > 5)
1217  nSecond = static_cast<sal_Int16>(rStr.copy( nStart[5], nEnd[5]+1-nStart[5]).toInt32());
1218  // do not use calendar's milliseconds, to avoid fractional part truncation
1219  double fFrac = 0.0;
1220  if (nFound > 6)
1221  {
1222  sal_Unicode cDec = '.';
1223  OUString aT = OUStringChar(cDec) + rStr.subView( nStart[6], nEnd[6]+1-nStart[6]);
1224  rtl_math_ConversionStatus eStatus;
1225  double fV = rtl::math::stringToDouble( aT, cDec, 0, &eStatus );
1226  if (eStatus == rtl_math_ConversionStatus_Ok)
1227  fFrac = fV / 86400.0;
1228  }
1229  pCalendar->setValue( i18n::CalendarFieldIndex::HOUR, nHour );
1230  pCalendar->setValue( i18n::CalendarFieldIndex::MINUTE, nMinute );
1231  pCalendar->setValue( i18n::CalendarFieldIndex::SECOND, nSecond );
1232  pCalendar->setValue( i18n::CalendarFieldIndex::MILLISECOND, 0 );
1233  if ( pCalendar->isValid() )
1234  {
1235  double fDiff = DateTime(pDocFormatter->GetNullDate()) -
1236  pCalendar->getEpochStart();
1237  // #i14974# must use getLocalDateTime to get the same
1238  // date values as set above
1239  double fDays = pCalendar->getLocalDateTime() + fFrac;
1240  fDays -= fDiff;
1241 
1242  LanguageType eLatin, eCjk, eCtl;
1243  rDoc.GetLanguage( eLatin, eCjk, eCtl );
1244  LanguageType eDocLang = eLatin;
1245 
1246  SvNumFormatType nType = (nFound > 3 ? SvNumFormatType::DATETIME : SvNumFormatType::DATE);
1247  sal_uLong nFormat = pDocFormatter->GetStandardFormat( nType, eDocLang );
1248  // maybe there is a special format including seconds or milliseconds
1249  if (nFound > 5)
1250  nFormat = pDocFormatter->GetStandardFormat( fDays, nFormat, nType, eDocLang);
1251 
1252  ScAddress aPos(nCol,nRow,nTab);
1253  if ( bUseDocImport )
1254  rDocImport.setNumericCell(aPos, fDays);
1255  else
1256  rDoc.SetValue( aPos, fDays );
1257  rDoc.SetNumberFormat(aPos, nFormat);
1258 
1259  return bMultiLine; // success
1260  }
1261  }
1262  }
1263  }
1264 
1265  // Standard or date not determined -> SetString / EditCell
1266  if( rStr.indexOf( '\n' ) == -1 )
1267  {
1268  ScSetStringParam aParam;
1269  aParam.mpNumFormatter = pFormatter;
1270  aParam.mbDetectNumberFormat = bDetectNumFormat;
1272  aParam.mbHandleApostrophe = false;
1273  aParam.mbCheckLinkFormula = true;
1274  if ( bUseDocImport )
1275  rDocImport.setAutoInput(ScAddress(nCol, nRow, nTab), rStr, &aParam);
1276  else
1277  rDoc.SetString( nCol, nRow, nTab, rStr, &aParam );
1278  }
1279  else
1280  {
1281  bMultiLine = true;
1282  ScFieldEditEngine& rEngine = rDoc.GetEditEngine();
1283  rEngine.SetTextCurrentDefaults(rStr);
1284  if ( bUseDocImport )
1285  rDocImport.setEditCell(ScAddress(nCol, nRow, nTab), rEngine.CreateTextObject());
1286  else
1287  rDoc.SetEditText( ScAddress( nCol, nRow, nTab ), rEngine.CreateTextObject() );
1288  }
1289  return bMultiLine;
1290 }
1291 
1292 static OUString lcl_GetFixed( const OUString& rLine, sal_Int32 nStart, sal_Int32 nNext,
1293  bool& rbIsQuoted, bool& rbOverflowCell )
1294 {
1295  sal_Int32 nLen = rLine.getLength();
1296  if (nNext > nLen)
1297  nNext = nLen;
1298  if ( nNext <= nStart )
1299  return EMPTY_OUSTRING;
1300 
1301  const sal_Unicode* pStr = rLine.getStr();
1302 
1303  sal_Int32 nSpace = nNext;
1304  while ( nSpace > nStart && pStr[nSpace-1] == ' ' )
1305  --nSpace;
1306 
1307  rbIsQuoted = (pStr[nStart] == '"' && pStr[nSpace-1] == '"');
1308  if (rbIsQuoted)
1309  {
1310  bool bFits = (nSpace - nStart - 3 <= nArbitraryCellLengthLimit);
1311  if (bFits)
1312  return rLine.copy(nStart+1, std::max< sal_Int32 >(0, nSpace-nStart-2));
1313  else
1314  {
1315  SAL_WARN( "sc", "lcl_GetFixed: line doesn't fit into data");
1316  rbOverflowCell = true;
1317  return rLine.copy(nStart+1, nArbitraryCellLengthLimit);
1318  }
1319  }
1320  else
1321  {
1322  bool bFits = (nSpace - nStart <= nArbitraryCellLengthLimit);
1323  if (bFits)
1324  return rLine.copy(nStart, nSpace-nStart);
1325  else
1326  {
1327  SAL_WARN( "sc", "lcl_GetFixed: line doesn't fit into data");
1328  rbOverflowCell = true;
1329  return rLine.copy(nStart, nArbitraryCellLengthLimit);
1330  }
1331  }
1332 }
1333 
1335 {
1336  if (!pExtOptions)
1337  return Text2Doc( rStrm );
1338 
1339  sal_uInt64 const nOldPos = rStrm.Tell();
1340  sal_uInt64 const nRemaining = rStrm.remainingSize();
1341  std::unique_ptr<ScProgress> xProgress( new ScProgress( pDocSh,
1342  ScResId( STR_LOAD_DOC ), nRemaining, true ));
1343  rStrm.StartReadingUnicodeText( rStrm.GetStreamCharSet() );
1344 
1345  SCCOL nStartCol = aRange.aStart.Col();
1346  SCCOL nEndCol = aRange.aEnd.Col();
1347  SCROW nStartRow = aRange.aStart.Row();
1348  SCTAB nTab = aRange.aStart.Tab();
1349 
1350  bool bFixed = pExtOptions->IsFixedLen();
1351  OUString aSeps = pExtOptions->GetFieldSeps(); // Need non-const for ReadCsvLine(),
1352  const sal_Unicode* pSeps = aSeps.getStr(); // but it will be const anyway (asserted below).
1353  bool bMerge = pExtOptions->IsMergeSeps();
1354  bool bRemoveSpace = pExtOptions->IsRemoveSpace();
1355  sal_uInt16 nInfoCount = pExtOptions->GetInfoCount();
1356  const sal_Int32* pColStart = pExtOptions->GetColStart();
1357  const sal_uInt8* pColFormat = pExtOptions->GetColFormat();
1358  tools::Long nSkipLines = pExtOptions->GetStartRow();
1359 
1360  LanguageType eDocLang = pExtOptions->GetLanguage();
1361  SvNumberFormatter aNumFormatter( comphelper::getProcessComponentContext(), eDocLang);
1362  bool bDetectNumFormat = pExtOptions->IsDetectSpecialNumber();
1363  bool bSkipEmptyCells = pExtOptions->IsSkipEmptyCells();
1364 
1365  // For date recognition
1366  ::utl::TransliterationWrapper aTransliteration(
1367  comphelper::getProcessComponentContext(), TransliterationFlags::IGNORE_CASE );
1368  aTransliteration.loadModuleIfNeeded( eDocLang );
1370  aCalendar.loadDefaultCalendar(
1371  LanguageTag::convertToLocale( eDocLang ) );
1372  std::unique_ptr< ::utl::TransliterationWrapper > pEnglishTransliteration;
1373  std::unique_ptr< CalendarWrapper > pEnglishCalendar;
1374  if ( eDocLang != LANGUAGE_ENGLISH_US )
1375  {
1376  pEnglishTransliteration.reset(new ::utl::TransliterationWrapper (
1377  comphelper::getProcessComponentContext(), TransliterationFlags::IGNORE_CASE ));
1378  aTransliteration.loadModuleIfNeeded( LANGUAGE_ENGLISH_US );
1379  pEnglishCalendar.reset(new CalendarWrapper ( comphelper::getProcessComponentContext() ));
1380  pEnglishCalendar->loadDefaultCalendar(
1382  }
1383 
1384  OUString aLine;
1385  OUString aCell;
1386  sal_uInt16 i;
1387  SCROW nRow = nStartRow;
1388  sal_Unicode cDetectSep = 0xffff; // No separator detection here.
1389 
1390  while(--nSkipLines>0)
1391  {
1392  aLine = ReadCsvLine(rStrm, !bFixed, aSeps, cStr, cDetectSep); // content is ignored
1393  if ( rStrm.eof() )
1394  break;
1395  }
1396 
1397  // Determine range for Undo.
1398  // We don't need this during import of a file to a new sheet or document...
1399  bool bDetermineRange = bUndo;
1400 
1401  // Row heights don't need to be adjusted on the fly if EndPaste() is called
1402  // afterwards, which happens only if bDetermineRange. This variable also
1403  // survives the toggle of bDetermineRange down at the end of the do{} loop.
1404  bool bRangeIsDetermined = bDetermineRange;
1405 
1406  bool bQuotedAsText = pExtOptions && pExtOptions->IsQuotedAsText();
1407 
1408  sal_uLong nOriginalStreamPos = rStrm.Tell();
1409 
1410  ScDocumentImport aDocImport(rDoc);
1411  do
1412  {
1413  for( ;; )
1414  {
1415  aLine = ReadCsvLine(rStrm, !bFixed, aSeps, cStr, cDetectSep);
1416  if ( rStrm.eof() && aLine.isEmpty() )
1417  break;
1418 
1419  assert(pSeps == aSeps.getStr());
1420 
1421  if ( nRow > rDoc.MaxRow() )
1422  {
1423  bOverflowRow = true; // display warning on import
1424  break; // for
1425  }
1426 
1427  EmbeddedNullTreatment( aLine);
1428 
1429  sal_Int32 nLineLen = aLine.getLength();
1430  SCCOL nCol = nStartCol;
1431  bool bMultiLine = false;
1432  if ( bFixed ) // Fixed line length
1433  {
1434  sal_Int32 nStartIdx = 0;
1435  // Yes, the check is nCol<=rDoc.MaxCol()+1, +1 because it is only an
1436  // overflow if there is really data following to be put behind
1437  // the last column, which doesn't happen if info is
1438  // SC_COL_SKIP.
1439  for ( i=0; i<nInfoCount && nCol <= rDoc.MaxCol()+1; i++ )
1440  {
1441  sal_uInt8 nFmt = pColFormat[i];
1442  if (nFmt != SC_COL_SKIP) // otherwise don't increment nCol either
1443  {
1444  if (nCol > rDoc.MaxCol())
1445  bOverflowCol = true; // display warning on import
1446  else if (!bDetermineRange)
1447  {
1448  sal_Int32 nNextIdx = nStartIdx;
1449  if ( i + 1 < nInfoCount )
1450  CountVisualWidth( aLine, nNextIdx, pColStart[i+1] - pColStart[i] );
1451  else
1452  nNextIdx = nLineLen;
1453 
1454  bool bIsQuoted = false;
1455  aCell = lcl_GetFixed( aLine, nStartIdx, nNextIdx, bIsQuoted, bOverflowCell );
1456  if (bIsQuoted && bQuotedAsText)
1457  nFmt = SC_COL_TEXT;
1458 
1459  bMultiLine |= lcl_PutString(
1460  aDocImport, !mbOverwriting, nCol, nRow, nTab, aCell, nFmt,
1461  &aNumFormatter, bDetectNumFormat, bSkipEmptyCells, aTransliteration, aCalendar,
1462  pEnglishTransliteration.get(), pEnglishCalendar.get());
1463 
1464  nStartIdx = nNextIdx;
1465  }
1466  ++nCol;
1467  }
1468  }
1469  }
1470  else // Search for the separator
1471  {
1472  SCCOL nSourceCol = 0;
1473  sal_uInt16 nInfoStart = 0;
1474  const sal_Unicode* p = aLine.getStr();
1475  // Yes, the check is nCol<=rDoc.MaxCol()+1, +1 because it is only an
1476  // overflow if there is really data following to be put behind
1477  // the last column, which doesn't happen if info is
1478  // SC_COL_SKIP.
1479  while (*p && nCol <= rDoc.MaxCol()+1)
1480  {
1481  bool bIsQuoted = false;
1483  cStr, pSeps, bMerge, bIsQuoted, bOverflowCell, bRemoveSpace );
1484 
1485  sal_uInt8 nFmt = SC_COL_STANDARD;
1486  for ( i=nInfoStart; i<nInfoCount; i++ )
1487  {
1488  if ( pColStart[i] == nSourceCol + 1 ) // pColStart is 1-based
1489  {
1490  nFmt = pColFormat[i];
1491  nInfoStart = i + 1; // ColInfos are in succession
1492  break; // for
1493  }
1494  }
1495  if ( nFmt != SC_COL_SKIP )
1496  {
1497  if (nCol > rDoc.MaxCol())
1498  bOverflowCol = true; // display warning on import
1499  else if (!bDetermineRange)
1500  {
1501  if (bIsQuoted && bQuotedAsText)
1502  nFmt = SC_COL_TEXT;
1503 
1504  bMultiLine |= lcl_PutString(
1505  aDocImport, !mbOverwriting, nCol, nRow, nTab, aCell, nFmt,
1506  &aNumFormatter, bDetectNumFormat, bSkipEmptyCells, aTransliteration,
1507  aCalendar, pEnglishTransliteration.get(), pEnglishCalendar.get());
1508  }
1509  ++nCol;
1510  }
1511 
1512  ++nSourceCol;
1513  }
1514  }
1515  if (nEndCol < nCol)
1516  nEndCol = nCol;
1517 
1518  if (!bDetermineRange)
1519  {
1520  if (bMultiLine && !bRangeIsDetermined && pDocSh)
1521  pDocSh->AdjustRowHeight( nRow, nRow, nTab);
1522  xProgress->SetStateOnPercent( rStrm.Tell() - nOldPos );
1523  }
1524  ++nRow;
1525  }
1526  // so far nRow/nEndCol pointed to the next free
1527  if (nRow > nStartRow)
1528  --nRow;
1529  if (nEndCol > nStartCol)
1530  nEndCol = ::std::min( static_cast<SCCOL>(nEndCol - 1), rDoc.MaxCol());
1531 
1532  if (bDetermineRange)
1533  {
1534  aRange.aEnd.SetCol( nEndCol );
1535  aRange.aEnd.SetRow( nRow );
1536 
1537  if ( !mbApi && nStartCol != nEndCol &&
1538  !rDoc.IsBlockEmpty( nTab, nStartCol + 1, nStartRow, nEndCol, nRow ) )
1539  {
1541  if (aBox.run() != RET_YES)
1542  {
1543  return false;
1544  }
1545  }
1546 
1547  rStrm.Seek( nOriginalStreamPos );
1548  nRow = nStartRow;
1549  if (!StartPaste())
1550  {
1551  EndPaste(false);
1552  return false;
1553  }
1554  }
1555 
1556  bDetermineRange = !bDetermineRange; // toggle
1557  } while (!bDetermineRange);
1558  if ( !mbOverwriting )
1559  aDocImport.finalize();
1560 
1561  xProgress.reset(); // make room for AdjustRowHeight progress
1562  if (bRangeIsDetermined)
1563  EndPaste(false);
1564 
1566  {
1567  rDoc.BroadcastCells(aRange, SfxHintId::ScDataChanged);
1569  }
1570  return true;
1571 }
1572 
1574 {
1575  // A nasty workaround for data with embedded NULL characters. As long as we
1576  // can't handle them properly as cell content (things assume 0-terminated
1577  // strings at too many places) simply strip all NULL characters from raw
1578  // data. Excel does the same. See fdo#57841 for sample data.
1579 
1580  // The normal case is no embedded NULL, check first before de-/allocating
1581  // ustring stuff.
1582  sal_Unicode cNull = 0;
1583  if (rStr.indexOf( cNull) >= 0)
1584  {
1585  rStr = rStr.replaceAll( std::u16string_view( &cNull, 1), "");
1586  }
1587 }
1588 
1590  OUString& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted,
1591  bool& rbOverflowCell, bool bRemoveSpace )
1592 {
1593  rbIsQuoted = false;
1594  rField.clear();
1595  const sal_Unicode cBlank = ' ';
1596  if (!ScGlobal::UnicodeStrChr( pSeps, cBlank))
1597  {
1598  // Cope with broken generators that put leading blanks before a quoted
1599  // field, like "field1", "field2", "..."
1600  // NOTE: this is not in conformance with http://tools.ietf.org/html/rfc4180
1601  const sal_Unicode* pb = p;
1602  while (*pb == cBlank)
1603  ++pb;
1604  if (*pb == cStr)
1605  p = pb;
1606  }
1607  if ( *p == cStr ) // String in quotes
1608  {
1609  rbIsQuoted = true;
1610  const sal_Unicode* p1;
1611  p1 = p = lcl_ScanString( p, rField, pSeps, cStr, DoubledQuoteMode::ESCAPE, rbOverflowCell );
1612  while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
1613  p++;
1614  // Append remaining unquoted and undelimited data (dirty, dirty) to
1615  // this field.
1616  if (p > p1)
1617  {
1618  const sal_Unicode* ptrim_f = p;
1619  if ( bRemoveSpace )
1620  {
1621  while ( ptrim_f > p1 && ( *(ptrim_f - 1) == cBlank ) )
1622  --ptrim_f;
1623  }
1624  if (!lcl_appendLineData( rField, p1, ptrim_f))
1625  rbOverflowCell = true;
1626  }
1627  if( *p )
1628  p++;
1629  }
1630  else // up to delimiter
1631  {
1632  const sal_Unicode* p0 = p;
1633  while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
1634  p++;
1635  const sal_Unicode* ptrim_i = p0;
1636  const sal_Unicode* ptrim_f = p; // [ptrim_i,ptrim_f) is cell data after trimming
1637  if ( bRemoveSpace )
1638  {
1639  while ( *ptrim_i == cBlank )
1640  ++ptrim_i;
1641  while ( ptrim_f > ptrim_i && ( *(ptrim_f - 1) == cBlank ) )
1642  --ptrim_f;
1643  }
1644  if (!lcl_appendLineData( rField, ptrim_i, ptrim_f))
1645  rbOverflowCell = true;
1646  if( *p )
1647  p++;
1648  }
1649  if ( bMergeSeps ) // skip following delimiters
1650  {
1651  while ( *p && ScGlobal::UnicodeStrChr( pSeps, *p ) )
1652  p++;
1653  }
1654  return p;
1655 }
1656 
1657 namespace {
1658 
1665 bool hasLineBreaksOrSeps( const OUString& rStr, sal_Unicode cSep )
1666 {
1667  const sal_Unicode* p = rStr.getStr();
1668  for (sal_Int32 i = 0, n = rStr.getLength(); i < n; ++i, ++p)
1669  {
1670  sal_Unicode c = *p;
1671  if (c == cSep)
1672  // separator found.
1673  return true;
1674 
1675  switch (c)
1676  {
1677  case '\n':
1678  case '\r':
1679  // line break found.
1680  return true;
1681  default:
1682  ;
1683  }
1684  }
1685  return false;
1686 }
1687 
1688 }
1689 
1691 {
1692  SCCOL nCol;
1693  SCROW nRow;
1694  SCCOL nStartCol = aRange.aStart.Col();
1695  SCROW nStartRow = aRange.aStart.Row();
1696  SCTAB nStartTab = aRange.aStart.Tab();
1697  SCCOL nEndCol = aRange.aEnd.Col();
1698  SCROW nEndRow = aRange.aEnd.Row();
1699  SCTAB nEndTab = aRange.aEnd.Tab();
1700 
1701  if (!rDoc.GetClipParam().isMultiRange() && nStartTab == nEndTab)
1702  if (!rDoc.ShrinkToDataArea( nStartTab, nStartCol, nStartRow, nEndCol, nEndRow ))
1703  return false;
1704 
1705  OUString aCellStr;
1706 
1707  bool bConvertLF = (GetSystemLineEnd() != LINEEND_LF);
1708 
1709  // We need to cache sc::ColumnBlockPosition per each column, tab is always nStartTab.
1710  std::vector< sc::ColumnBlockPosition > blockPos( nEndCol - nStartCol + 1 );
1711  for( SCCOL i = nStartCol; i <= nEndCol; ++i )
1712  rDoc.InitColumnBlockPosition( blockPos[ i - nStartCol ], nStartTab, i );
1713  for (nRow = nStartRow; nRow <= nEndRow; nRow++)
1714  {
1715  if (bIncludeFiltered || !rDoc.RowFiltered( nRow, nStartTab ))
1716  {
1717  for (nCol = nStartCol; nCol <= nEndCol; nCol++)
1718  {
1719  ScAddress aPos(nCol, nRow, nStartTab);
1720  sal_uInt32 nNumFmt = rDoc.GetNumberFormat(aPos);
1721  SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
1722 
1723  ScRefCellValue aCell(rDoc, aPos, blockPos[ nCol - nStartCol ]);
1724  switch (aCell.meType)
1725  {
1726  case CELLTYPE_FORMULA:
1727  {
1728  if (bFormulas)
1729  {
1730  aCell.mpFormula->GetFormula( aCellStr );
1731  if( aCellStr.indexOf( cSep ) != -1 )
1732  lcl_WriteString( rStrm, aCellStr, cStr, cStr );
1733  else
1734  lcl_WriteSimpleString( rStrm, aCellStr );
1735  }
1736  else
1737  {
1738  const Color* pColor;
1739  ScCellFormat::GetString(aCell, nNumFmt, aCellStr, &pColor, *pFormatter, rDoc);
1740 
1741  bool bMultiLineText = ( aCellStr.indexOf( '\n' ) != -1 );
1742  if( bMultiLineText )
1743  {
1745  aCellStr = aCellStr.replaceAll( "\n", " " );
1747  aCellStr = convertLineEnd(aCellStr, GetSystemLineEnd());
1748  }
1749 
1751  aCellStr = aCellStr.replaceAll( OUStringChar(cSep), OUStringChar(mExportTextOptions.mcSeparatorConvertTo) );
1752 
1753  if( mExportTextOptions.mbAddQuotes && ( aCellStr.indexOf( cSep ) != -1 ) )
1754  lcl_WriteString( rStrm, aCellStr, cStr, cStr );
1755  else
1756  lcl_WriteSimpleString( rStrm, aCellStr );
1757  }
1758  }
1759  break;
1760  case CELLTYPE_VALUE:
1761  {
1762  const Color* pColor;
1763  ScCellFormat::GetString(aCell, nNumFmt, aCellStr, &pColor, *pFormatter, rDoc);
1764  lcl_WriteSimpleString( rStrm, aCellStr );
1765  }
1766  break;
1767  case CELLTYPE_NONE:
1768  break;
1769  default:
1770  {
1771  const Color* pColor;
1772  ScCellFormat::GetString(aCell, nNumFmt, aCellStr, &pColor, *pFormatter, rDoc);
1773 
1774  bool bMultiLineText = ( aCellStr.indexOf( '\n' ) != -1 );
1775  if( bMultiLineText )
1776  {
1778  aCellStr = aCellStr.replaceAll( "\n", " " );
1780  aCellStr = convertLineEnd(aCellStr, GetSystemLineEnd());
1781  }
1782 
1784  aCellStr = aCellStr.replaceAll( OUStringChar(cSep), OUStringChar(mExportTextOptions.mcSeparatorConvertTo) );
1785 
1786  if( mExportTextOptions.mbAddQuotes && hasLineBreaksOrSeps(aCellStr, cSep) )
1787  lcl_WriteString( rStrm, aCellStr, cStr, cStr );
1788  else
1789  lcl_WriteSimpleString( rStrm, aCellStr );
1790  }
1791  }
1792  if( nCol < nEndCol )
1793  lcl_WriteSimpleString( rStrm, OUString(cSep) );
1794  }
1795  WriteUnicodeOrByteEndl( rStrm );
1796  if( rStrm.GetError() != ERRCODE_NONE )
1797  break;
1798  if( nSizeLimit && rStrm.Tell() > nSizeLimit )
1799  break;
1800  }
1801  }
1802 
1803  return rStrm.GetError() == ERRCODE_NONE;
1804 }
1805 
1807 {
1808  bool bOk = true;
1809  bool bMyDoc = false;
1810  SylkVersion eVersion = SylkVersion::OTHER;
1811 
1812  // US-English separators for StringToDouble
1813  sal_Unicode const cDecSep = '.';
1814  sal_Unicode const cGrpSep = ',';
1815 
1816  SCCOL nStartCol = aRange.aStart.Col();
1817  SCROW nStartRow = aRange.aStart.Row();
1818  SCCOL nEndCol = aRange.aEnd.Col();
1819  SCROW nEndRow = aRange.aEnd.Row();
1820  sal_uLong nOldPos = rStrm.Tell();
1821  bool bData = !bSingle;
1822  ::std::vector< sal_uInt32 > aFormats;
1823 
1824  if( !bSingle)
1825  bOk = StartPaste();
1826 
1827  while( bOk )
1828  {
1829  OUString aLine;
1830  OUString aText;
1831  OString aByteLine;
1832  SCCOL nCol = nStartCol;
1833  SCROW nRow = nStartRow;
1834  SCCOL nRefCol = nCol;
1835  SCROW nRefRow = nRow;
1836  rStrm.Seek( nOldPos );
1837  for( ;; )
1838  {
1840  rStrm.ReadLine( aByteLine );
1841  aLine = OStringToOUString(aByteLine, rStrm.GetStreamCharSet());
1842  if( rStrm.eof() )
1843  break;
1844  bool bInvalidCol = false;
1845  bool bInvalidRow = false;
1846  const sal_Unicode* p = aLine.getStr();
1847  sal_Unicode cTag = *p++;
1848  if( cTag == 'C' ) // Content
1849  {
1850  if( *p++ != ';' )
1851  return false;
1852 
1853  bool bInvalidRefCol = false;
1854  bool bInvalidRefRow = false;
1855  while( *p )
1856  {
1857  sal_Unicode ch = *p++;
1858  ch = ScGlobal::ToUpperAlpha( ch );
1859  switch( ch )
1860  {
1861  case 'X':
1862  {
1863  bInvalidCol = false;
1864  bool bFail = o3tl::checked_add<SCCOL>(OUString(p).toInt32(), nStartCol - 1, nCol);
1865  if (bFail || nCol < 0 || rDoc.MaxCol() < nCol)
1866  {
1867  SAL_WARN("sc.ui","ScImportExport::Sylk2Doc - ;X invalid nCol=" << nCol);
1868  nCol = std::clamp<SCCOL>(nCol, 0, rDoc.MaxCol());
1869  bInvalidCol = bOverflowCol = true;
1870  }
1871  break;
1872  }
1873  case 'Y':
1874  {
1875  bInvalidRow = false;
1876  bool bFail = o3tl::checked_add(OUString(p).toInt32(), nStartRow - 1, nRow);
1877  if (bFail || nRow < 0 || nMaxImportRow < nRow)
1878  {
1879  SAL_WARN("sc.ui","ScImportExport::Sylk2Doc - ;Y invalid nRow=" << nRow);
1880  nRow = std::clamp<SCROW>(nRow, 0, nMaxImportRow);
1881  bInvalidRow = bOverflowRow = true;
1882  }
1883  break;
1884  }
1885  case 'C':
1886  {
1887  bInvalidRefCol = false;
1888  bool bFail = o3tl::checked_add<SCCOL>(OUString(p).toInt32(), nStartCol - 1, nRefCol);
1889  if (bFail || nRefCol < 0 || rDoc.MaxCol() < nRefCol)
1890  {
1891  SAL_WARN("sc.ui","ScImportExport::Sylk2Doc - ;C invalid nRefCol=" << nRefCol);
1892  nRefCol = std::clamp<SCCOL>(nRefCol, 0, rDoc.MaxCol());
1893  bInvalidRefCol = bOverflowCol = true;
1894  }
1895  break;
1896  }
1897  case 'R':
1898  {
1899  bInvalidRefRow = false;
1900  bool bFail = o3tl::checked_add(OUString(p).toInt32(), nStartRow - 1, nRefRow);
1901  if (bFail || nRefRow < 0 || nMaxImportRow < nRefRow)
1902  {
1903  SAL_WARN("sc.ui","ScImportExport::Sylk2Doc - ;R invalid nRefRow=" << nRefRow);
1904  nRefRow = std::clamp<SCROW>(nRefRow, 0, nMaxImportRow);
1905  bInvalidRefRow = bOverflowRow = true;
1906  }
1907  break;
1908  }
1909  case 'K':
1910  {
1911  if( !bSingle &&
1912  ( nCol < nStartCol || nCol > nEndCol
1913  || nRow < nStartRow || nRow > nEndRow
1914  || nCol > rDoc.MaxCol() || nRow > nMaxImportRow
1915  || bInvalidCol || bInvalidRow ) )
1916  break;
1917  if( !bData )
1918  {
1919  if( nRow > nEndRow )
1920  nEndRow = nRow;
1921  if( nCol > nEndCol )
1922  nEndCol = nCol;
1923  break;
1924  }
1925  bool bText;
1926  if( *p == '"' )
1927  {
1928  bText = true;
1929  aText.clear();
1930  p = lcl_ScanSylkString( p, aText, eVersion);
1931  }
1932  else
1933  bText = false;
1934  const sal_Unicode* q = p;
1935  while( *q && *q != ';' )
1936  q++;
1937  if ( (*q != ';' || *(q+1) != 'I') && !bInvalidCol && !bInvalidRow )
1938  { // don't ignore value
1939  if( bText )
1940  {
1942  rDoc.SetTextCell(
1943  ScAddress(nCol, nRow, aRange.aStart.Tab()), aText);
1944  }
1945  else
1946  {
1947  double fVal = rtl_math_uStringToDouble( p,
1948  aLine.getStr() + aLine.getLength(),
1949  cDecSep, cGrpSep, nullptr, nullptr );
1950  rDoc.SetValue( nCol, nRow, aRange.aStart.Tab(), fVal );
1951  }
1952  }
1953  }
1954  break;
1955  case 'E':
1956  case 'M':
1957  {
1958  if ( ch == 'M' )
1959  {
1960  if ( nRefCol < nCol )
1961  nRefCol = nCol;
1962  if ( nRefRow < nRow )
1963  nRefRow = nRow;
1964  if ( !bData )
1965  {
1966  if( nRefRow > nEndRow )
1967  nEndRow = nRefRow;
1968  if( nRefCol > nEndCol )
1969  nEndCol = nRefCol;
1970  }
1971  }
1972  if( !bMyDoc || !bData )
1973  break;
1974  aText = "=";
1975  p = lcl_ScanSylkFormula( p, aText, eVersion);
1976 
1977  if (bInvalidCol || bInvalidRow || (ch == 'M' && (bInvalidRefCol || bInvalidRefRow)))
1978  break;
1979 
1980  ScAddress aPos( nCol, nRow, aRange.aStart.Tab() );
1981  /* FIXME: do we want GRAM_ODFF_A1 instead? At the
1982  * end it probably should be GRAM_ODFF_R1C1, since
1983  * R1C1 is what Excel writes in SYLK, or even
1984  * better GRAM_ENGLISH_XL_R1C1. */
1986  ScCompiler aComp(rDoc, aPos, eGrammar);
1987  std::unique_ptr<ScTokenArray> xCode(aComp.CompileString(aText)); // ctor/InsertMatrixFormula did copy TokenArray
1989  if ( ch == 'M' )
1990  {
1991  ScMarkData aMark(rDoc.GetSheetLimits());
1992  aMark.SelectTable( aPos.Tab(), true );
1993  rDoc.InsertMatrixFormula( nCol, nRow, nRefCol,
1994  nRefRow, aMark, EMPTY_OUSTRING, xCode.get() );
1995  }
1996  else
1997  {
1998  ScFormulaCell* pFCell = new ScFormulaCell(
1999  rDoc, aPos, *xCode, eGrammar, ScMatrixMode::NONE);
2000  rDoc.SetFormulaCell(aPos, pFCell);
2001  }
2002  }
2003  break;
2004  }
2005  while( *p && *p != ';' )
2006  p++;
2007  if( *p )
2008  p++;
2009  }
2010  }
2011  else if( cTag == 'F' ) // Format
2012  {
2013  if( *p++ != ';' )
2014  return false;
2015  sal_Int32 nFormat = -1;
2016  while( *p )
2017  {
2018  sal_Unicode ch = *p++;
2019  ch = ScGlobal::ToUpperAlpha( ch );
2020  switch( ch )
2021  {
2022  case 'X':
2023  {
2024  bInvalidCol = false;
2025  bool bFail = o3tl::checked_add<SCCOL>(OUString(p).toInt32(), nStartCol - 1, nCol);
2026  if (bFail || nCol < 0 || rDoc.MaxCol() < nCol)
2027  {
2028  SAL_WARN("sc.ui","ScImportExport::Sylk2Doc - ;X invalid nCol=" << nCol);
2029  nCol = std::clamp<SCCOL>(nCol, 0, rDoc.MaxCol());
2030  bInvalidCol = bOverflowCol = true;
2031  }
2032  break;
2033  }
2034  case 'Y':
2035  {
2036  bInvalidRow = false;
2037  bool bFail = o3tl::checked_add(OUString(p).toInt32(), nStartRow - 1, nRow);
2038  if (bFail || nRow < 0 || nMaxImportRow < nRow)
2039  {
2040  SAL_WARN("sc.ui","ScImportExport::Sylk2Doc - ;Y invalid nRow=" << nRow);
2041  nRow = std::clamp<SCROW>(nRow, 0, nMaxImportRow);
2042  bInvalidRow = bOverflowRow = true;
2043  }
2044  break;
2045  }
2046  case 'P' :
2047  if ( bData )
2048  {
2049  // F;P<n> sets format code of P;P<code> at
2050  // current position, or at ;X;Y if specified.
2051  // Note that ;X;Y may appear after ;P
2052  const sal_Unicode* p0 = p;
2053  while( *p && *p != ';' )
2054  p++;
2055  OUString aNumber(p0, p - p0);
2056  nFormat = aNumber.toInt32();
2057  }
2058  break;
2059  }
2060  while( *p && *p != ';' )
2061  p++;
2062  if( *p )
2063  p++;
2064  }
2065  if ( !bData )
2066  {
2067  if( nRow > nEndRow )
2068  nEndRow = nRow;
2069  if( nCol > nEndCol )
2070  nEndCol = nCol;
2071  }
2072  if ( 0 <= nFormat && nFormat < static_cast<sal_Int32>(aFormats.size()) && !bInvalidCol && !bInvalidRow )
2073  {
2074  sal_uInt32 nKey = aFormats[nFormat];
2075  rDoc.ApplyAttr( nCol, nRow, aRange.aStart.Tab(),
2076  SfxUInt32Item( ATTR_VALUE_FORMAT, nKey ) );
2077  }
2078  }
2079  else if( cTag == 'P' )
2080  {
2081  if ( bData && *p == ';' && *(p+1) == 'P' )
2082  {
2083  OUString aCode( p+2 );
2084 
2085  sal_uInt32 nKey;
2086  sal_Int32 nCheckPos;
2087 
2088  if (aCode.getLength() > 2048 && utl::ConfigManager::IsFuzzing())
2089  {
2090  // consider an excessive length as a failure when fuzzing
2091  nCheckPos = 1;
2092  }
2093  else
2094  {
2095  // unescape doubled semicolons
2096  aCode = aCode.replaceAll(";;", ";");
2097  // get rid of Xcl escape characters
2098  aCode = aCode.replaceAll("\x1b", "");
2100  rDoc.GetFormatTable()->PutandConvertEntry( aCode, nCheckPos, nType, nKey,
2102  }
2103 
2104  if ( nCheckPos )
2105  nKey = 0;
2106 
2107  aFormats.push_back( nKey );
2108  }
2109  }
2110  else if( cTag == 'I' && *p == 'D' )
2111  {
2112  aLine = aLine.copy(4);
2113  if (aLine == "CALCOOO32")
2114  eVersion = SylkVersion::OOO32;
2115  else if (aLine == "SCALC3")
2116  eVersion = SylkVersion::SCALC3;
2117  bMyDoc = (eVersion <= SylkVersion::OWN);
2118  }
2119  else if( cTag == 'E' ) // End
2120  break;
2121  }
2122  if( !bData )
2123  {
2124  aRange.aEnd.SetCol( nEndCol );
2125  aRange.aEnd.SetRow( nEndRow );
2126  bOk = StartPaste();
2127  bData = true;
2128  }
2129  else
2130  break;
2131  }
2132 
2133  EndPaste();
2134  return bOk;
2135 }
2136 
2138 {
2139  SCCOL nCol;
2140  SCROW nRow;
2141  SCCOL nStartCol = aRange.aStart.Col();
2142  SCROW nStartRow = aRange.aStart.Row();
2143  SCCOL nEndCol = aRange.aEnd.Col();
2144  SCROW nEndRow = aRange.aEnd.Row();
2145  OUString aCellStr;
2146  OUString aValStr;
2147  lcl_WriteSimpleString( rStrm, "ID;PCALCOOO32" );
2148  WriteUnicodeOrByteEndl( rStrm );
2149 
2150  for (nRow = nStartRow; nRow <= nEndRow; nRow++)
2151  {
2152  for (nCol = nStartCol; nCol <= nEndCol; nCol++)
2153  {
2154  OUString aBufStr;
2155  double nVal;
2156  bool bForm = false;
2157  SCROW r = nRow - nStartRow + 1;
2158  SCCOL c = nCol - nStartCol + 1;
2159  ScRefCellValue aCell(rDoc, ScAddress(nCol, nRow, aRange.aStart.Tab()));
2160  CellType eType = aCell.meType;
2161  switch( eType )
2162  {
2163  case CELLTYPE_FORMULA:
2164  bForm = bFormulas;
2165  if( rDoc.HasValueData( nCol, nRow, aRange.aStart.Tab()) )
2166  goto hasvalue;
2167  else
2168  goto hasstring;
2169 
2170  case CELLTYPE_VALUE:
2171  hasvalue:
2172  rDoc.GetValue( nCol, nRow, aRange.aStart.Tab(), nVal );
2173 
2174  aValStr = ::rtl::math::doubleToUString( nVal,
2175  rtl_math_StringFormat_Automatic,
2176  rtl_math_DecimalPlaces_Max, '.', true );
2177 
2178  aBufStr = "C;X"
2179  + OUString::number( c )
2180  + ";Y"
2181  + OUString::number( r )
2182  + ";K"
2183  + aValStr;
2184  lcl_WriteSimpleString( rStrm, aBufStr );
2185  goto checkformula;
2186 
2187  case CELLTYPE_STRING:
2188  case CELLTYPE_EDIT:
2189  hasstring:
2190  aCellStr = rDoc.GetString(nCol, nRow, aRange.aStart.Tab());
2191  aCellStr = aCellStr.replaceAll("\n", SYLK_LF);
2192 
2193  aBufStr = "C;X"
2194  + OUString::number( c )
2195  + ";Y"
2196  + OUString::number( r )
2197  + ";K";
2198  lcl_WriteSimpleString( rStrm, aBufStr );
2199  lcl_WriteString( rStrm, aCellStr, '"', ';' );
2200 
2201  checkformula:
2202  if( bForm )
2203  {
2204  const ScFormulaCell* pFCell = aCell.mpFormula;
2205  switch ( pFCell->GetMatrixFlag() )
2206  {
2208  aCellStr.clear();
2209  break;
2210  default:
2211  OUString aOUCellStr;
2213  aCellStr = aOUCellStr;
2214  /* FIXME: do we want GRAM_ODFF_A1 instead? At
2215  * the end it probably should be
2216  * GRAM_ODFF_R1C1, since R1C1 is what Excel
2217  * writes in SYLK, or even better
2218  * GRAM_ENGLISH_XL_R1C1. */
2219  }
2220  if ( pFCell->GetMatrixFlag() != ScMatrixMode::NONE &&
2221  aCellStr.startsWith("{") &&
2222  aCellStr.endsWith("}") )
2223  { // cut off matrix {} characters
2224  aCellStr = aCellStr.copy(1, aCellStr.getLength()-2);
2225  }
2226  if ( aCellStr[0] == '=' )
2227  aCellStr = aCellStr.copy(1);
2228  OUString aPrefix;
2229  switch ( pFCell->GetMatrixFlag() )
2230  {
2231  case ScMatrixMode::Formula :
2232  { // diff expression with 'M' M$-extension
2233  SCCOL nC;
2234  SCROW nR;
2235  pFCell->GetMatColsRows( nC, nR );
2236  nC += c - 1;
2237  nR += r - 1;
2238  aPrefix = ";R"
2239  + OUString::number( nR )
2240  + ";C"
2241  + OUString::number( nC )
2242  + ";M";
2243  }
2244  break;
2246  { // diff expression with 'I' M$-extension
2247  ScAddress aPos;
2248  (void)pFCell->GetMatrixOrigin( rDoc, aPos );
2249  aPrefix = ";I;R"
2250  + OUString::number( aPos.Row() - nStartRow + 1 )
2251  + ";C"
2252  + OUString::number( aPos.Col() - nStartCol + 1 );
2253  }
2254  break;
2255  default:
2256  // formula Expression
2257  aPrefix = ";E";
2258  }
2259  lcl_WriteSimpleString( rStrm, aPrefix );
2260  if ( !aCellStr.isEmpty() )
2261  lcl_WriteString( rStrm, aCellStr, 0, ';' );
2262  }
2263  WriteUnicodeOrByteEndl( rStrm );
2264  break;
2265 
2266  default:
2267  {
2268  // added to avoid warnings
2269  }
2270  }
2271  }
2272  }
2273  lcl_WriteSimpleString( rStrm, OUString( 'E' ) );
2274  WriteUnicodeOrByteEndl( rStrm );
2275  return rStrm.GetError() == ERRCODE_NONE;
2276 }
2277 
2278 bool ScImportExport::Doc2HTML( SvStream& rStrm, const OUString& rBaseURL )
2279 {
2280  // rtl_TextEncoding is ignored in ScExportHTML, read from Load/Save HTML options
2281  ScFormatFilter::Get().ScExportHTML( rStrm, rBaseURL, &rDoc, aRange, RTL_TEXTENCODING_DONTKNOW, bAll,
2283  return rStrm.GetError() == ERRCODE_NONE;
2284 }
2285 
2287 {
2288  // rtl_TextEncoding is ignored in ScExportRTF
2289  ScFormatFilter::Get().ScExportRTF( rStrm, &rDoc, aRange, RTL_TEXTENCODING_DONTKNOW );
2290  return rStrm.GetError() == ERRCODE_NONE;
2291 }
2292 
2294 {
2295  // for DIF in the clipboard, IBM_850 is always used
2296  ScFormatFilter::Get().ScExportDif( rStrm, &rDoc, aRange, RTL_TEXTENCODING_IBM_850 );
2297  return true;
2298 }
2299 
2301 {
2302  SCTAB nTab = aRange.aStart.Tab();
2303  ScDocumentUniquePtr pImportDoc( new ScDocument( SCDOCMODE_UNDO ) );
2304  pImportDoc->InitUndo( rDoc, nTab, nTab );
2305 
2306  // for DIF in the clipboard, IBM_850 is always used
2307  ScFormatFilter::Get().ScImportDif( rStrm, pImportDoc.get(), aRange.aStart, RTL_TEXTENCODING_IBM_850 );
2308 
2309  SCCOL nEndCol;
2310  SCROW nEndRow;
2311  pImportDoc->GetCellArea( nTab, nEndCol, nEndRow );
2312  // if there are no cells in the imported content, nEndCol/nEndRow may be before the start
2313  if ( nEndCol < aRange.aStart.Col() )
2314  nEndCol = aRange.aStart.Col();
2315  if ( nEndRow < aRange.aStart.Row() )
2316  nEndRow = aRange.aStart.Row();
2317  aRange.aEnd = ScAddress( nEndCol, nEndRow, nTab );
2318 
2319  bool bOk = StartPaste();
2320  if (bOk)
2321  {
2323  rDoc.DeleteAreaTab( aRange, nFlags );
2324  pImportDoc->CopyToDocument(aRange, nFlags, false, rDoc);
2325  EndPaste();
2326  }
2327 
2328  return bOk;
2329 }
2330 
2331 bool ScImportExport::RTF2Doc( SvStream& rStrm, const OUString& rBaseURL )
2332 {
2333  std::unique_ptr<ScEEAbsImport> pImp = ScFormatFilter::Get().CreateRTFImport( &rDoc, aRange );
2334  if (!pImp)
2335  return false;
2336  pImp->Read( rStrm, rBaseURL );
2337  aRange = pImp->GetRange();
2338 
2339  bool bOk = StartPaste();
2340  if (bOk)
2341  {
2343  rDoc.DeleteAreaTab( aRange, nFlags );
2344  pImp->WriteToDocument();
2345  EndPaste();
2346  }
2347  return bOk;
2348 }
2349 
2350 bool ScImportExport::HTML2Doc( SvStream& rStrm, const OUString& rBaseURL )
2351 {
2352  std::unique_ptr<ScEEAbsImport> pImp = ScFormatFilter::Get().CreateHTMLImport( &rDoc, rBaseURL, aRange);
2353  if (!pImp)
2354  return false;
2355  pImp->Read( rStrm, rBaseURL );
2356  aRange = pImp->GetRange();
2357 
2358  bool bOk = StartPaste();
2359  if (bOk)
2360  {
2361  // ScHTMLImport may call ScDocument::InitDrawLayer, resulting in
2362  // a Draw Layer but no Draw View -> create Draw Layer and View here
2363  if (pDocSh)
2364  pDocSh->MakeDrawLayer();
2365 
2367  rDoc.DeleteAreaTab( aRange, nFlags );
2368 
2369  if (pExtOptions)
2370  {
2371  // Pick up import options if available.
2372  LanguageType eLang = pExtOptions->GetLanguage();
2374  bool bSpecialNumber = pExtOptions->IsDetectSpecialNumber();
2375  pImp->WriteToDocument(false, 1.0, &aNumFormatter, bSpecialNumber);
2376  }
2377  else
2378  // Regular import, with no options.
2379  pImp->WriteToDocument();
2380 
2381  EndPaste();
2382  }
2383  return bOk;
2384 }
2385 
2386 #ifndef DISABLE_DYNLOADING
2387 
2388 extern "C" { static void thisModule() {} }
2389 
2390 #else
2391 
2392 extern "C" {
2394 }
2395 
2396 #endif
2397 
2398 typedef ScFormatFilterPlugin * (*FilterFn)();
2400 {
2401  static ScFormatFilterPlugin *plugin = [&]()
2402  {
2403 #ifndef DISABLE_DYNLOADING
2404  OUString sFilterLib(SVLIBRARY("scfilt"));
2405  static ::osl::Module aModule;
2406  bool bLoaded = aModule.is();
2407  if (!bLoaded)
2408  bLoaded = aModule.loadRelative(&thisModule, sFilterLib);
2409  if (!bLoaded)
2410  bLoaded = aModule.load(sFilterLib);
2411  if (bLoaded)
2412  {
2413  oslGenericFunction fn = aModule.getFunctionSymbol( "ScFilterCreate" );
2414  if (fn != nullptr)
2415  return reinterpret_cast<FilterFn>(fn)();
2416  }
2417  assert(false);
2418  return static_cast<ScFormatFilterPlugin*>(nullptr);
2419 #else
2420  return ScFilterCreate();
2421 #endif
2422  }();
2423 
2424  return *plugin;
2425 }
2426 
2427 // Precondition: pStr is guaranteed to be non-NULL and points to a 0-terminated
2428 // array.
2429 static const sal_Unicode* lcl_UnicodeStrChr( const sal_Unicode* pStr,
2430  sal_Unicode c )
2431 {
2432  while (*pStr)
2433  {
2434  if (*pStr == c)
2435  return pStr;
2436  ++pStr;
2437  }
2438  return nullptr;
2439 }
2440 
2442  : SvMemoryStream( const_cast<sal_Unicode *>(rStr.getStr()),
2443  rStr.getLength() * sizeof(sal_Unicode), StreamMode::READ)
2444 {
2445  SetStreamCharSet( RTL_TEXTENCODING_UNICODE );
2446 #ifdef OSL_BIGENDIAN
2447  SetEndian(SvStreamEndian::BIG);
2448 #else
2449  SetEndian(SvStreamEndian::LITTLE);
2450 #endif
2451 }
2452 
2453 OUString ReadCsvLine( SvStream &rStream, bool bEmbeddedLineBreak,
2454  OUString& rFieldSeparators, sal_Unicode cFieldQuote, sal_Unicode& rcDetectSep )
2455 {
2456  enum RetryState
2457  {
2458  FORBID,
2459  ALLOW,
2460  RETRY,
2461  RETRIED
2462  } eRetryState = (bEmbeddedLineBreak && rcDetectSep == 0 ? RetryState::ALLOW : RetryState::FORBID);
2463 
2464  sal_uInt64 nStreamPos = (eRetryState == RetryState::ALLOW ? rStream.Tell() : 0);
2465 
2466 Label_RetryWithNewSep:
2467 
2468  if (eRetryState == RetryState::RETRY)
2469  {
2470  eRetryState = RetryState::RETRIED;
2471  rStream.Seek( nStreamPos);
2472  }
2473 
2474  OUString aStr;
2476 
2477  if (bEmbeddedLineBreak)
2478  {
2479  const sal_Unicode* pSeps = rFieldSeparators.getStr();
2480 
2481  QuoteType eQuoteState = FIELDEND_QUOTE;
2482  bool bFieldStart = true;
2483 
2484  sal_Int32 nLastOffset = 0;
2485  sal_Int32 nQuotes = 0;
2486  while (!rStream.eof() && aStr.getLength() < nArbitraryLineLengthLimit)
2487  {
2488  const sal_Unicode * p = aStr.getStr() + nLastOffset;
2489  while (*p)
2490  {
2491  if (nQuotes)
2492  {
2493  if (*p == cFieldQuote)
2494  {
2495  if (bFieldStart)
2496  {
2497  ++nQuotes;
2498  bFieldStart = false;
2499  eQuoteState = FIELDSTART_QUOTE;
2500  }
2501  // Do not detect a FIELDSTART_QUOTE if not in
2502  // bFieldStart mode, in which case for unquoted content
2503  // we are in FIELDEND_QUOTE state.
2504  else if (eQuoteState != FIELDEND_QUOTE)
2505  {
2506  eQuoteState = lcl_isEscapedOrFieldEndQuote( nQuotes, p, pSeps, cFieldQuote, rcDetectSep);
2507 
2508  if (eRetryState == RetryState::ALLOW && rcDetectSep == ' ')
2509  {
2510  eRetryState = RetryState::RETRY;
2511  rFieldSeparators += OUString(' ');
2512  goto Label_RetryWithNewSep;
2513  }
2514 
2515  // DONTKNOW_QUOTE is an embedded unescaped quote we
2516  // don't count for pairing.
2517  if (eQuoteState != DONTKNOW_QUOTE)
2518  ++nQuotes;
2519  }
2520  }
2521  else if (eQuoteState == FIELDEND_QUOTE)
2522  {
2523  if (bFieldStart)
2524  // If blank is a separator it starts a field, if it
2525  // is not and thus maybe leading before quote we
2526  // are still at start of field regarding quotes.
2527  bFieldStart = (*p == ' ' || lcl_UnicodeStrChr( pSeps, *p) != nullptr);
2528  else
2529  bFieldStart = (lcl_UnicodeStrChr( pSeps, *p) != nullptr);
2530  }
2531  }
2532  else
2533  {
2534  if (*p == cFieldQuote && bFieldStart)
2535  {
2536  nQuotes = 1;
2537  eQuoteState = FIELDSTART_QUOTE;
2538  bFieldStart = false;
2539  }
2540  else if (eQuoteState == FIELDEND_QUOTE)
2541  {
2542  // This also skips leading blanks at beginning of line
2543  // if followed by a quote. It's debatable whether we
2544  // actually want that or not, but congruent with what
2545  // ScanNextFieldFromString() does.
2546  if (bFieldStart)
2547  bFieldStart = (*p == ' ' || lcl_UnicodeStrChr( pSeps, *p) != nullptr);
2548  else
2549  bFieldStart = (lcl_UnicodeStrChr( pSeps, *p) != nullptr);
2550  }
2551  }
2552  // A quote character inside a field content does not start
2553  // a quote.
2554  ++p;
2555  }
2556 
2557  if (nQuotes % 2 == 0)
2558  // We still have a (theoretical?) problem here if due to
2559  // nArbitraryLineLengthLimit we split a string right between a
2560  // doubled quote pair.
2561  break;
2562  else
2563  {
2564  nLastOffset = aStr.getLength();
2565  OUString aNext;
2567  aStr += "\n" + aNext;
2568  }
2569  }
2570  }
2571  return aStr;
2572 }
2573 
2574 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const OUString & GetClipDocName()
Definition: global.cxx:478
static OUString GetAppName()
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2116
const SCROW SCROWS32K
Definition: address.hxx:86
static const sal_Unicode * lcl_ScanString(const sal_Unicode *p, OUString &rString, const sal_Unicode *pSeps, sal_Unicode cStr, DoubledQuoteMode eMode, bool &rbOverflowCell)
Definition: impex.cxx:692
sal_Int32 nIndex
ScAddress aStart
Definition: address.hxx:500
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
static void lcl_WriteSimpleString(SvStream &rStrm, const OUString &rString)
Definition: impex.cxx:890
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
void SetExtOptions(const ScAsciiOptions &rOpt)
Definition: impex.cxx:204
const sal_uInt8 SC_COL_STANDARD
Definition: csvcontrol.hxx:55
Store parameters used in the ScDocument::SetString() method.
Definition: stringutil.hxx:35
sal_Unicode GetTextSep() const
Definition: asciiopt.hxx:63
const sal_uInt8 SC_COL_TEXT
Definition: csvcontrol.hxx:56
bool mbHandleApostrophe
When true, treat input with a leading apostrophe as an escape character for a numeric value content...
Definition: stringutil.hxx:92
#define EMPTY_OUSTRING
Definition: global.hxx:216
static void WriteUnicodeOrByteEndl(SvStream &rStrm)
Definition: impex.cxx:525
bool isDigit(const OUString &rStr, sal_Int32 nPos) const
SvStream & WriteUInt16(sal_uInt16 nUInt16)
void setValue(sal_Int16 nFieldIndex, sal_Int16 nValue)
Sheet / outlining (grouping) information.
SCROW Row() const
Definition: address.hxx:262
bool isNumeric(const OUString &rStr) const
OUString GetTitle(sal_uInt16 nMaxLen=0) const
#define LANGUAGE_ENGLISH_US
bool AdjustRowHeight(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
merge with docfunc
Definition: docsh5.cxx:404
SvNumberFormatter * mpNumFormatter
Stores the pointer to the number formatter instance to be used during number format detection...
Definition: stringutil.hxx:71
bool ExportString(OUString &, SotClipboardFormatId)
Definition: impex.cxx:328
sal_Int16 getNumberOfMonthsInYear() const
std::unique_ptr< ContentProperties > pData
static weld::Window * GetActiveDialogParent()
Definition: docsh.cxx:2950
bool ReadUniOrByteStringLine(OUString &rStr, rtl_TextEncoding eSrcCharSet, sal_Int32 nMaxCodepointsToRead=0xFFFE)
bool Doc2Text(SvStream &)
Definition: impex.cxx:1690
bool mbOverwriting
Definition: impex.hxx:70
signed char sal_Int8
bool Doc2Dif(SvStream &)
Definition: impex.cxx:2293
static bool lcl_appendLineData(OUString &rField, const sal_Unicode *p1, const sal_Unicode *p2)
Append characters of [p1,p2) to rField.
Definition: impex.cxx:667
bool mbCheckLinkFormula
When true and the string results in a compiled formula, check the formula tokens for presence of func...
Definition: stringutil.hxx:101
LineEnd GetLineDelimiter() const
static vcl::Window * GetDefDialogParent()
static bool IsFormatSupported(SotClipboardFormatId nFormat)
Definition: impex.cxx:222
void GetFormula(OUString &rFormula, const formula::FormulaGrammar::Grammar=formula::FormulaGrammar::GRAM_DEFAULT, const ScInterpreterContext *pContext=nullptr) const
sal_uIntPtr sal_uLong
long Long
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:167
sal_Unicode cSep
Definition: impex.hxx:58
sal_Int32 toInt32(OUString const &rStr)
SC_DLLPUBLIC bool InitColumnBlockPosition(sc::ColumnBlockPosition &rBlockPos, SCTAB nTab, SCCOL nCol)
Definition: document.cxx:2609
Warning box for "Replace cell contents?".
Definition: warnbox.hxx:27
sal_Int64 n
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Definition: compiler.cxx:4530
static const sal_Unicode * lcl_ScanSylkFormula(const sal_Unicode *p, OUString &rString, SylkVersion eVersion)
Definition: impex.cxx:803
void SetDocumentModified()
Definition: docsh.cxx:2820
SvStream * IsValid(SvStream &)
sal_uInt64 Seek(sal_uInt64 nPos)
static const sal_Unicode * lcl_ScanSylkString(const sal_Unicode *p, OUString &rString, SylkVersion eVersion)
Definition: impex.cxx:761
static SC_DLLPUBLIC ScFormatFilterPlugin & Get()
Definition: impex.cxx:2399
SC_DLLPUBLIC void GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt32 &rFormat) const
Definition: document.cxx:3639
bool bIncludeFiltered
Definition: impex.hxx:61
ScAddress aEnd
Definition: address.hxx:501
bool bUndo
Definition: impex.hxx:64
SvStream & WriteOString(const OString &rStr)
bool Doc2HTML(SvStream &, const OUString &)
Definition: impex.cxx:2278
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3456
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:104
static bool lcl_PutString(ScDocumentImport &rDocImport, bool bUseDocImport, SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rStr, sal_uInt8 nColFormat, SvNumberFormatter *pFormatter, bool bDetectNumFormat, bool bSkipEmptyCells, const ::utl::TransliterationWrapper &rTransliteration, CalendarWrapper &rCalendar, const ::utl::TransliterationWrapper *pSecondTransliteration, CalendarWrapper *pSecondCalendar)
Definition: impex.cxx:994
const SCCOL MAXCOLCOUNT
Definition: address.hxx:64
SC_DLLPUBLIC void ApplyAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, const SfxPoolItem &rAttr)
Definition: document.cxx:4755
Accessor class to ScDocument.
bool bSingle
Definition: impex.hxx:63
LINEEND_CR
std::unique_ptr< ScAsciiOptions > pExtOptions
Definition: impex.hxx:75
bool ImportStream(SvStream &, const OUString &rBaseURL, SotClipboardFormatId)
Definition: impex.cxx:383
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:488
bool ExportData(const OUString &rMimeType, css::uno::Any &rValue)
Definition: impex.cxx:287
static QuoteType lcl_isFieldEndQuote(const sal_Unicode *p, const sal_Unicode *pSeps, sal_Unicode &rcDetectSep)
Determine if *p is a quote that ends a quoted field.
Definition: impex.cxx:605
void setEditCell(const ScAddress &rPos, std::unique_ptr< EditTextObject > pEditText)
SC_DLLPUBLIC void SetTextCell(const ScAddress &rPos, const OUString &rStr)
Call this if you are not sure whether to put this as an edit text or a simple text.
Definition: document.cxx:3429
virtual sal_uInt64 TellEnd() override
TextFormatPolicy meSetTextNumFormat
Determine when to set the 'Text' number format to the cell where the input string is being set...
Definition: stringutil.hxx:84
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6054
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2806
static QuoteType lcl_isEscapedOrFieldEndQuote(sal_Int32 nQuotes, const sal_Unicode *p, const sal_Unicode *pSeps, sal_Unicode cStr, sal_Unicode &rcDetectSep)
Determine if *p is a quote that is escaped by being doubled or ends a quoted field.
Definition: impex.cxx:645
weld::Window * GetFrameWeld() const
static void lcl_UnescapeSylk(OUString &rString, SylkVersion eVersion)
Definition: impex.cxx:748
static bool SC_DLLPUBLIC isMultiline(const OUString &rStr)
Definition: stringutil.cxx:423
sal_uInt16 sal_Unicode
bool Doc2RTF(SvStream &)
Definition: impex.cxx:2286
void EndPaste(bool bAutoRowHeight=true)
Definition: impex.cxx:259
virtual void ScExportDif(SvStream &, ScDocument *, const ScAddress &rOutPos, const rtl_TextEncoding eDest)=0
SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck(const ScTokenArray &rCode)
Check token array and set link check if ocDde/ocWebservice is contained.
Definition: documen8.cxx:1153
RET_YES
ErrCode GetError() const
static void WriteUnicodeOrByteString(SvStream &rStrm, const OUString &rString, bool bZero=false)
Definition: impex.cxx:496
ScClipParam & GetClipParam()
Definition: document.cxx:2547
bool eof() const
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > pUndoDoc
Definition: impex.hxx:51
void StartReadingUnicodeText(rtl_TextEncoding eReadBomCharSet)
static bool isCJKIVSCharacter(sal_uInt32 nCode)
NewlineConversion meNewlineConversion
Definition: impex.hxx:42
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:870
sal_uInt16 ExpandTwoDigitYear(sal_uInt16 nYear) const
#define SAL_MAX_UINT16
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
static sal_Unicode GetWeightedFieldSep(const OUString &rFieldSeps, bool bDecodeNumbers)
From the import field separators obtain the one most likely to be used for export, if multiple separators weighted comma, tab, semicolon, space and other.
Definition: asciiopt.cxx:246
static OUString lcl_GetFixed(const OUString &rLine, sal_Int32 nStart, sal_Int32 nNext, bool &rbIsQuoted, bool &rbOverflowCell)
Definition: impex.cxx:1292
ScImportStringStream(const OUString &rStr)
Definition: impex.cxx:2441
sal_uInt32 GetStandardIndex(LanguageType eLnge=LANGUAGE_DONTKNOW)
static void thisModule()
Definition: impex.cxx:2388
OUString aStreamPath
Definition: impex.hxx:53
static bool IsFuzzing()
bool ReadLine(OString &rStr, sal_Int32 nMaxBytesToRead=0xFFFE)
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
Definition: document.cxx:3484
LineEnd GetSystemLineEnd()
void CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, InsertDeleteFlags nFlags, bool bMarked, ScDocument &rDestDoc, const ScMarkData *pMarks=nullptr, bool bColRowFlags=true)
Definition: document.cxx:2074
sal_uInt32 nSizeLimit
Definition: impex.hxx:56
void UpdateInputHandler(bool bForce=false, bool bStopEditing=true)
Definition: tabvwsha.cxx:653
ScFormulaCell * mpFormula
Definition: cellvalue.hxx:111
SCTAB Tab() const
Definition: address.hxx:271
void SetRow(SCROW nRowP)
Definition: address.hxx:275
static void lcl_WriteString(SvStream &rStrm, OUString &rString, sal_Unicode cQuote, sal_Unicode cEsc)
Definition: impex.cxx:877
constexpr sal_Int32 nArbitraryCellLengthLimit
Definition: impex.cxx:75
bool Text2Doc(SvStream &)
Definition: impex.cxx:895
OUString aNonConvertibleChars
Definition: impex.hxx:54
SotClipboardFormatId
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
virtual void ScExportHTML(SvStream &, const OUString &rBaseURL, ScDocument *, const ScRange &rRange, const rtl_TextEncoding eDest, bool bAll, const OUString &rStreamPath, OUString &rNonConvertibleChars, const OUString &rFilterOptions)=0
sal_uInt64 remainingSize()
static bool isIVSSelector(sal_uInt32 nCode)
sal_uInt16 nCode
void SetCol(SCCOL nColP)
Definition: address.hxx:279
ScDocShell * pDocSh
Definition: impex.hxx:49
ScDrawLayer * MakeDrawLayer()
Definition: docsh2.cxx:166
bool HTML2Doc(SvStream &, const OUString &rBaseURL)
Definition: impex.cxx:2350
OUString maFilterOptions
Definition: impex.hxx:55
bool IsClipboard() const
Definition: document.hxx:1527
double getLocalDateTime() const
SC_DLLPUBLIC double GetValue(const ScAddress &rPos) const
Definition: document.cxx:3626
DocumentType eType
SC_DLLPUBLIC void InsertMatrixFormula(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rMark, const OUString &rFormula, const ScTokenArray *p=nullptr, const formula::FormulaGrammar::Grammar=formula::FormulaGrammar::GRAM_DEFAULT)
Definition: documen4.cxx:257
SC_DLLPUBLIC bool SetEditText(const ScAddress &rPos, std::unique_ptr< EditTextObject > pEditText)
This method manages the lifecycle of the passed edit text object.
Definition: document.cxx:3392
const char * GetMessageId() const
Definition: editable.cxx:152
virtual std::unique_ptr< ScEEAbsImport > CreateHTMLImport(ScDocument *pDocP, const OUString &rBaseURL, const ScRange &rRange)=0
void SetMarkArea(const ScRange &rRange)
Definition: markdata.cxx:97
SC_DLLPUBLIC bool SetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const ScSetStringParam *pParam=nullptr)
Definition: document.cxx:3361
bool bFormulas
Definition: impex.hxx:60
void SetTab(SCTAB nTabP)
Definition: address.hxx:283
#define SFX_TITLE_FULLNAME
SC_DLLPUBLIC ScRangeData * findByUpperName(const OUString &rName)
Definition: rangenam.cxx:679
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:869
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:437
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
LINEEND_LF
#define SAL_MAX_INT32
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:555
SylkVersion
Definition: impex.cxx:94
SC_DLLPUBLIC void GetSymbol(OUString &rSymbol, const formula::FormulaGrammar::Grammar eGrammar=formula::FormulaGrammar::GRAM_DEFAULT) const
Definition: rangenam.cxx:243
int i
bool PutandConvertEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge, LanguageType eNewLnge, bool bConvertDateOrder)
virtual void ScExportRTF(SvStream &, ScDocument *, const ScRange &rRange, const rtl_TextEncoding eDest)=0
bool ExportByteString(OString &, rtl_TextEncoding, SotClipboardFormatId)
Definition: impex.cxx:357
bool RowFiltered(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4497
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:172
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2610
sal_Int16 SCCOL
Definition: types.hxx:22
InsertDeleteFlags
Definition: global.hxx:160
bool ValidCol(SCCOL nCol) const
Definition: document.hxx:872
Set Text number format only when the input string is considered a special number but we only want to ...
Definition: stringutil.hxx:52
StreamMode
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:871
SC_DLLPUBLIC OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2212
SC_DLLPUBLIC void ApplyPattern(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4761
std::enable_if< std::is_signed< T >::value, bool >::type checked_add(T a, T b, T &result)
std::unique_ptr< EditTextObject > CreateTextObject()
std::size_t WriteBytes(const void *pData, std::size_t nSize)
float u
OUString ScResId(const char *pId)
Definition: scdll.cxx:89
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALUE_FORMAT(146)
bool ShrinkToDataArea(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow) const
Shrink a range to only include data area.
Definition: document.cxx:1038
static void lcl_DoubleEscapeChar(OUString &rString, sal_Unicode cStr)
Definition: impex.cxx:867
SvNumFormatType
bool IsEditable() const
Definition: editable.hxx:84
bool IsBlockEmpty(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bIgnoreNotes=false) const
Definition: document.cxx:5289
~ScImportExport() COVERITY_NOEXCEPT_FALSE
Definition: impex.cxx:198
static SC_DLLPUBLIC LanguageType eLnge
Definition: global.hxx:549
sal_Unicode mcSeparatorConvertTo
Definition: impex.hxx:43
SC_DLLPUBLIC bool HasValueData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3763
bool ExportStream(SvStream &, const OUString &rBaseURL, SotClipboardFormatId)
Definition: impex.cxx:423
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:98
bool HasType(Type nType) const
Definition: rangenam.hxx:177
ScFormatFilterPlugin * ScFilterCreate()
Definition: ftools.cxx:353
void PostDataChanged()
Definition: docsh3.cxx:90
void setAutoInput(const ScAddress &rPos, const OUString &rStr, const ScSetStringParam *pStringParam=nullptr)
void BroadcastCells(const ScRange &rRange, SfxHintId nHint, bool bBroadcastSingleBroadcasters=true)
Definition: documen7.cxx:142
SCCOL Col() const
Definition: address.hxx:267
bool mbImportBroadcast
Definition: impex.hxx:69
SC_DLLPUBLIC void EnsureTable(SCTAB nTab)
Definition: documen2.cxx:536
bool Doc2Sylk(SvStream &)
Definition: impex.cxx:2137
ConversionMode mode
static void EmbeddedNullTreatment(OUString &rStr)
Definition: impex.cxx:1573
bool GetMatrixOrigin(const ScDocument &rDoc, ScAddress &rPos) const
bool mbApi
Definition: impex.hxx:68
ScRange aRange
Definition: impex.hxx:52
CellType meType
Definition: cellvalue.hxx:106
SvStreamEndian GetEndian() const
void SetNumberFormat(const ScAddress &rPos, sal_uInt32 nNumberFormat)
Definition: document.cxx:3687
ScDocument & rDoc
Definition: impex.hxx:50
sal_Int32 SCROW
Definition: types.hxx:18
bool bOverflowCell
Definition: impex.hxx:67
bool ValidRow(SCROW nRow) const
Definition: document.hxx:873
SC_DLLPUBLIC ScFormulaCell * SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell)
Set formula cell, and transfer its ownership to the document.
Definition: documen2.cxx:1080
bool mbDetectNumberFormat
When true, we try to detect special number format (dates etc) from the input string, when false, we only try to detect a basic decimal number format.
Definition: stringutil.hxx:78
static ScTabViewShell * GetActiveViewShell()
Definition: tabvwsh4.cxx:1020
DoubledQuoteMode
Definition: impex.cxx:684
static sal_Unicode ToUpperAlpha(sal_Unicode c)
Definition: global.hxx:620
bool Sylk2Doc(SvStream &)
Definition: impex.cxx:1806
#define ERRCODE_NONE
sal_Unicode cStr
Definition: impex.hxx:59
unsigned char sal_uInt8
ScImportExport(ScDocument &)
Definition: impex.cxx:105
static SotClipboardFormatId GetFormatIdFromMimeType(const OUString &rMimeType)
void GetMatColsRows(SCCOL &nCols, SCROW &nRows) const
CellType
Definition: global.hxx:283
SvStream & endl(SvStream &rStr)
virtual std::unique_ptr< ScEEAbsImport > CreateRTFImport(ScDocument *pDoc, const ScRange &rRange)=0
void SetEndian(SvStreamEndian SvStreamEndian)
void setStringCell(const ScAddress &rPos, const OUString &rStr)
SvStream & WriteUChar(unsigned char nChar)
bool bOverflowCol
Definition: impex.hxx:66
ScExportTextOptions mExportTextOptions
Definition: impex.hxx:73
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
css::uno::Sequence< css::i18n::CalendarItem2 > getMonths() const
void SetStreamCharSet(rtl_TextEncoding eCharSet)
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, ScAddress::ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1742
const sal_uInt8 SC_COL_MDY
Definition: csvcontrol.hxx:57
const sal_uInt8 SC_COL_ENGLISH
Definition: csvcontrol.hxx:61
static const sal_Unicode * lcl_UnicodeStrChr(const sal_Unicode *pStr, sal_Unicode c)
Definition: impex.cxx:2429
rtl_TextEncoding GetStreamCharSet() const
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
Definition: global.cxx:1009
sal_uInt64 Tell() const
void * p
Reference< XComponentContext > getProcessComponentContext()
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:400
bool RTF2Doc(SvStream &, const OUString &rBaseURL)
Definition: impex.cxx:2331
double getLength(const B2DPolygon &rCandidate)
bool ImportString(const OUString &, SotClipboardFormatId)
Definition: impex.cxx:304
SvStream & WriteChar(char nChar)
#define SVLIBRARY(Base)
bool isValid() const
void loadDefaultCalendar(const css::lang::Locale &rLocale, bool bTimeZoneUTC=true)
const DateTime & getEpochStart() const
static const sal_Unicode * UnicodeStrChr(const sal_Unicode *pStr, sal_Unicode c)
strchr() functionality on unicode, as long as we need it for FormulaToken etc.
Definition: global.cxx:640
virtual ErrCode ScImportDif(SvStream &, ScDocument *, const ScAddress &rInsPos, const rtl_TextEncoding eSrc)=0
bool Dif2Doc(SvStream &)
Definition: impex.cxx:2300
OUString ReadCsvLine(SvStream &rStream, bool bEmbeddedLineBreak, OUString &rFieldSeparators, sal_Unicode cFieldQuote, sal_Unicode &rcDetectSep)
Read a CSV (comma separated values) data line using ReadUniOrByteStringLine().
Definition: impex.cxx:2453
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1055
#define SAL_WARN(area, stream)
bool IsUndoEnabled() const
Definition: document.hxx:1528
static void GetString(const ScRefCellValue &rCell, sal_uInt32 nFormat, OUString &rString, const Color **ppColor, SvNumberFormatter &rFormatter, const ScDocument &rDoc, bool bNullVals=true, bool bFormula=false, bool bUseStarFormat=false)
Definition: cellform.cxx:31
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const Details &rDetails=detailsOOOa1, ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, sal_Int32 *pSheetEndPos=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1548
ScRefFlags
Definition: address.hxx:145
void setNumericCell(const ScAddress &rPos, double fVal)
const sal_uInt8 SC_COL_DMY
Definition: csvcontrol.hxx:58
void SetFilterOptions(const OUString &rFilterOptions)
Definition: impex.cxx:217
SC_DLLPUBLIC void GetLanguage(LanguageType &rLatin, LanguageType &rCjk, LanguageType &rCtl) const
Definition: documen3.cxx:1948
bool StartPaste()
Definition: impex.cxx:234
SCROW nMaxImportRow
Definition: impex.hxx:57
SC_DLLPUBLIC void DeleteAreaTab(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, InsertDeleteFlags nDelFlag)
Definition: document.cxx:1953
bool ExtText2Doc(SvStream &)
Definition: impex.cxx:1334
const Date & GetNullDate() const
bool bOverflowRow
Definition: impex.hxx:65
static const sal_Unicode * ScanNextFieldFromString(const sal_Unicode *p, OUString &rField, sal_Unicode cStr, const sal_Unicode *pSeps, bool bMergeSeps, bool &rbIsQuoted, bool &rbOverflowCell, bool bRemoveSpace)
Definition: impex.cxx:1589
void SvStream & rStrm
ScMatrixMode GetMatrixFlag() const
constexpr sal_Int32 nArbitraryLineLengthLimit
Definition: impex.cxx:76
static void SetNoEndianSwap(SvStream &rStrm)
only if stream is only used in own (!) memory
Definition: impex.cxx:575
const OUString & GetFieldSeps() const
Definition: asciiopt.hxx:57
static SCTAB GetCurTab()
Definition: docsh4.cxx:2551
ScFormatFilterPlugin *(* FilterFn)()
Definition: impex.cxx:2398
const sal_uInt8 SC_COL_SKIP
Definition: csvcontrol.hxx:60
aStr
QuoteType
Definition: impex.cxx:586
READ
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:453
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
virtual short run() override
Opens dialog if IsDialogEnabled() returns true.
Definition: warnbox.cxx:35
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:23
void loadModuleIfNeeded(LanguageType nLang)
const void * GetData()
static sal_Int32 CountVisualWidth(const OUString &rStr, sal_Int32 &nIdx, sal_Int32 nMaxWidth)
ScImportExport::CountVisualWidth Count the width of string visually ( in multiple of western characte...
Definition: impex.cxx:545
bool isMultiRange() const
Definition: clipparam.cxx:38
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
const sal_uInt8 SC_COL_YMD
Definition: csvcontrol.hxx:59
ScDocument & getDoc()
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo