LibreOffice Module sc (master)  1
scuiasciiopt.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 
20 #undef SC_DLLIMPLEMENTATION
21 
22 #include <svx/txencbox.hxx>
23 
24 #include <global.hxx>
25 #include <scresid.hxx>
26 #include <impex.hxx>
27 #include <scuiasciiopt.hxx>
28 #include <strings.hrc>
29 #include <strings.hxx>
30 #include <csvtablebox.hxx>
31 #include <osl/thread.h>
33 
34 #include <optutil.hxx>
35 #include <com/sun/star/uno/Any.hxx>
36 #include <com/sun/star/uno/Sequence.hxx>
37 #include <miscuno.hxx>
38 #include <osl/diagnose.h>
39 #include <vcl/svapp.hxx>
40 #include <comphelper/lok.hxx>
41 #include <o3tl/string_view.hxx>
42 
43 #include <unicode/ucsdet.h>
44 
47 
48 // Maximum number of source lines to concatenate while generating the preview
49 // for one logical line. This may result in a wrong preview if the actual
50 // number of embedded line feeds is greater, but a number too high would take
51 // too much time (loop excessively if unlimited and large data) if none of the
52 // selected separators are actually used in data but a field at start of line
53 // is quoted.
54 constexpr sal_uInt32 kMaxEmbeddedLinefeeds = 500;
55 
56 using namespace com::sun::star::uno;
57 
58 namespace {
59 
60 // Defines - CSV Import Preserve Options
61 // For usage of index order see lcl_CreatePropertiesNames() below.
63 {
64  CSVIO_MergeDelimiters = 0,
65  CSVIO_Separators,
66  CSVIO_TextSeparators,
67  CSVIO_FixedWidth,
68  CSVIO_RemoveSpace,
69  CSVIO_EvaluateFormulas,
70  // Settings for *all* dialog invocations above.
71  // Settings not for SC_TEXTTOCOLUMNS below.
72  CSVIO_FromRow,
73  CSVIO_Text2ColSkipEmptyCells = CSVIO_FromRow,
74  CSVIO_CharSet,
75  CSVIO_QuotedAsText,
76  CSVIO_DetectSpecialNum,
77  CSVIO_Language,
78  // Plus one not for SC_IMPORTFILE.
79  CSVIO_PasteSkipEmptyCells
80 };
81 
82 }
83 
84 // Config items for all three paths are defined in
85 // officecfg/registry/schema/org/openoffice/Office/Calc.xcs
86 // If not, options are neither loaded nor saved.
87 const ::std::vector<OUString> CSVImportOptionNames =
88 {
89  "MergeDelimiters",
90  "Separators",
91  "TextSeparators",
92  "FixedWidth",
93  "RemoveSpace",
94  "EvaluateFormulas",
95  "FromRow",
96  "CharSet",
97  "QuotedFieldAsText",
98  "DetectSpecialNumbers",
99  "Language",
100  "SkipEmptyCells"
101 };
102 constexpr OUStringLiteral aSep_Path = u"Office.Calc/Dialogs/CSVImport";
103 constexpr OUStringLiteral aSep_Path_Clpbrd = u"Office.Calc/Dialogs/ClipboardTextImport";
104 constexpr OUStringLiteral aSep_Path_Text2Col = u"Office.Calc/Dialogs/TextToColumnsImport";
105 
106 namespace {
107 CSVImportOptionsIndex getSkipEmptyCellsIndex( ScImportAsciiCall eCall )
108 {
109  return eCall == SC_TEXTTOCOLUMNS ? CSVIO_Text2ColSkipEmptyCells : CSVIO_PasteSkipEmptyCells;
110 }
111 }
112 
113 static void lcl_FillCombo(weld::ComboBox& rCombo, std::u16string_view rList, sal_Unicode cSelect)
114 {
115  OUString aStr;
116  if (!rList.empty())
117  {
118  sal_Int32 nIdx {0};
119  do
120  {
121  const OUString sEntry {o3tl::getToken(rList, 0, '\t', nIdx)};
122  rCombo.append_text(sEntry);
123  if (nIdx>0 && static_cast<sal_Unicode>(o3tl::toInt32(o3tl::getToken(rList, 0, '\t', nIdx))) == cSelect)
124  aStr = sEntry;
125  }
126  while (nIdx>0);
127  }
128 
129  if ( cSelect )
130  {
131  if (aStr.isEmpty())
132  aStr = OUString(cSelect); // Ascii
133 
134  rCombo.set_entry_text(aStr);
135  }
136 }
137 
138 static sal_Unicode lcl_CharFromCombo(const weld::ComboBox& rCombo, std::u16string_view rList)
139 {
140  sal_Unicode c = 0;
141  OUString aStr = rCombo.get_active_text();
142  if ( !aStr.isEmpty() && !rList.empty() )
143  {
144  sal_Int32 nIdx {0};
145  OUString sToken {o3tl::getToken(rList, 0, '\t', nIdx)};
146  while (nIdx>0)
147  {
148  if ( ScGlobal::GetTransliteration().isEqual( aStr, sToken ) )
149  {
150  sal_Int32 nTmpIdx {nIdx};
151  c = static_cast<sal_Unicode>(o3tl::toInt32(o3tl::getToken(rList, 0, '\t', nTmpIdx)));
152  }
153  // Skip to next token at even position
154  sToken = o3tl::getToken(rList, 1, '\t', nIdx);
155  }
156  if (!c)
157  {
158  sal_Unicode cFirst = aStr[0];
159  // #i24235# first try the first character of the string directly
160  if( (aStr.getLength() == 1) || (cFirst < '0') || (cFirst > '9') )
161  c = cFirst;
162  else // keep old behaviour for compatibility (i.e. "39" -> "'")
163  c = static_cast<sal_Unicode>(aStr.toInt32()); // Ascii
164  }
165  }
166  return c;
167 }
168 
169 static void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>& rNames, ScImportAsciiCall eCall )
170 {
171  sal_Int32 nProperties = 0;
172 
173  switch(eCall)
174  {
175  case SC_IMPORTFILE:
176  rSepPath = aSep_Path;
177  nProperties = 11;
178  break;
179  case SC_PASTETEXT:
180  rSepPath = aSep_Path_Clpbrd;
181  nProperties = 12;
182  break;
183  case SC_TEXTTOCOLUMNS:
184  default:
185  rSepPath = aSep_Path_Text2Col;
186  nProperties = 7;
187  break;
188  }
189  rNames.realloc( nProperties );
190  OUString* pNames = rNames.getArray();
191  pNames[ CSVIO_MergeDelimiters ] = CSVImportOptionNames[ CSVIO_MergeDelimiters ];
192  pNames[ CSVIO_Separators ] = CSVImportOptionNames[ CSVIO_Separators ];
193  pNames[ CSVIO_TextSeparators ] = CSVImportOptionNames[ CSVIO_TextSeparators ];
194  pNames[ CSVIO_FixedWidth ] = CSVImportOptionNames[ CSVIO_FixedWidth ];
195  pNames[ CSVIO_RemoveSpace ] = CSVImportOptionNames[ CSVIO_RemoveSpace ];
196  pNames[ CSVIO_EvaluateFormulas ] = CSVImportOptionNames[ CSVIO_EvaluateFormulas ];
197  if (eCall != SC_TEXTTOCOLUMNS)
198  {
199  pNames[ CSVIO_FromRow ] = CSVImportOptionNames[ CSVIO_FromRow ];
200  pNames[ CSVIO_CharSet ] = CSVImportOptionNames[ CSVIO_CharSet ];
201  pNames[ CSVIO_QuotedAsText ] = CSVImportOptionNames[ CSVIO_QuotedAsText ];
202  pNames[ CSVIO_DetectSpecialNum ] = CSVImportOptionNames[ CSVIO_DetectSpecialNum ];
203  pNames[ CSVIO_Language ] = CSVImportOptionNames[ CSVIO_Language ];
204  }
205  if (eCall != SC_IMPORTFILE)
206  {
207  const sal_Int32 nSkipEmptyCells = getSkipEmptyCellsIndex(eCall);
208  assert( nSkipEmptyCells < rNames.getLength());
209  pNames[ nSkipEmptyCells ] = CSVImportOptionNames[ CSVIO_PasteSkipEmptyCells ];
210  }
211 }
212 
213 static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSeparators,
214  bool& rMergeDelimiters, bool& rQuotedAsText, bool& rDetectSpecialNum,
215  bool& rFixedWidth, sal_Int32& rFromRow, sal_Int32& rCharSet,
216  sal_Int32& rLanguage, bool& rSkipEmptyCells, bool& rRemoveSpace,
217  bool& rEvaluateFormulas, ScImportAsciiCall eCall )
218 {
219  Sequence<Any>aValues;
220  const Any *pProperties;
221  Sequence<OUString> aNames;
222  OUString aSepPath;
223  lcl_CreatePropertiesNames ( aSepPath, aNames, eCall);
224  ScLinkConfigItem aItem( aSepPath );
225  aValues = aItem.GetProperties( aNames );
226  pProperties = aValues.getConstArray();
227 
228  if( pProperties[ CSVIO_MergeDelimiters ].hasValue() )
229  rMergeDelimiters = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_MergeDelimiters ] );
230 
231  if( pProperties[ CSVIO_RemoveSpace ].hasValue() )
232  rRemoveSpace = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_RemoveSpace ] );
233 
234  if( pProperties[ CSVIO_Separators ].hasValue() )
235  pProperties[ CSVIO_Separators ] >>= rFieldSeparators;
236 
237  if( pProperties[ CSVIO_TextSeparators ].hasValue() )
238  pProperties[ CSVIO_TextSeparators ] >>= rTextSeparators;
239 
240  if( pProperties[ CSVIO_FixedWidth ].hasValue() )
241  rFixedWidth = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_FixedWidth ] );
242 
243  if( pProperties[ CSVIO_EvaluateFormulas ].hasValue() )
244  rEvaluateFormulas = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_EvaluateFormulas ] );
245 
246  if (eCall != SC_TEXTTOCOLUMNS)
247  {
248  if( pProperties[ CSVIO_FromRow ].hasValue() )
249  pProperties[ CSVIO_FromRow ] >>= rFromRow;
250 
251  if( pProperties[ CSVIO_CharSet ].hasValue() )
252  pProperties[ CSVIO_CharSet ] >>= rCharSet;
253 
254  if ( pProperties[ CSVIO_QuotedAsText ].hasValue() )
255  pProperties[ CSVIO_QuotedAsText ] >>= rQuotedAsText;
256 
257  if ( pProperties[ CSVIO_DetectSpecialNum ].hasValue() )
258  pProperties[ CSVIO_DetectSpecialNum ] >>= rDetectSpecialNum;
259 
260  if ( pProperties[ CSVIO_Language ].hasValue() )
261  pProperties[ CSVIO_Language ] >>= rLanguage;
262  }
263  if (eCall != SC_IMPORTFILE)
264  {
265  const sal_Int32 nSkipEmptyCells = getSkipEmptyCellsIndex(eCall);
266  assert( nSkipEmptyCells < aValues.getLength());
267  if ( pProperties[nSkipEmptyCells].hasValue() )
268  rSkipEmptyCells = ScUnoHelpFunctions::GetBoolFromAny( pProperties[nSkipEmptyCells] );
269  }
270 }
271 
272 static void lcl_SaveSeparators(
273  const OUString& sFieldSeparators, const OUString& sTextSeparators, bool bMergeDelimiters, bool bQuotedAsText,
274  bool bDetectSpecialNum, bool bFixedWidth, sal_Int32 nFromRow,
275  sal_Int32 nCharSet, sal_Int32 nLanguage, bool bSkipEmptyCells, bool bRemoveSpace, bool bEvaluateFormulas,
276  ScImportAsciiCall eCall )
277 {
278  Sequence<Any> aValues;
279  Any *pProperties;
280  Sequence<OUString> aNames;
281  OUString aSepPath;
282  lcl_CreatePropertiesNames ( aSepPath, aNames, eCall );
283  ScLinkConfigItem aItem( aSepPath );
284  aValues = aItem.GetProperties( aNames );
285  pProperties = aValues.getArray();
286 
287  pProperties[ CSVIO_MergeDelimiters ] <<= bMergeDelimiters;
288  pProperties[ CSVIO_RemoveSpace ] <<= bRemoveSpace;
289  pProperties[ CSVIO_Separators ] <<= sFieldSeparators;
290  pProperties[ CSVIO_TextSeparators ] <<= sTextSeparators;
291  pProperties[ CSVIO_FixedWidth ] <<= bFixedWidth;
292  pProperties[ CSVIO_EvaluateFormulas ] <<= bEvaluateFormulas;
293  if (eCall != SC_TEXTTOCOLUMNS)
294  {
295  pProperties[ CSVIO_FromRow ] <<= nFromRow;
296  pProperties[ CSVIO_CharSet ] <<= nCharSet;
297  pProperties[ CSVIO_QuotedAsText ] <<= bQuotedAsText;
298  pProperties[ CSVIO_DetectSpecialNum ] <<= bDetectSpecialNum;
299  pProperties[ CSVIO_Language ] <<= nLanguage;
300  }
301  if (eCall != SC_IMPORTFILE)
302  {
303  const sal_Int32 nSkipEmptyCells = getSkipEmptyCellsIndex(eCall);
304  assert( nSkipEmptyCells < aValues.getLength());
305  pProperties[ nSkipEmptyCells ] <<= bSkipEmptyCells;
306  }
307 
308  aItem.PutProperties(aNames, aValues);
309 }
310 
311 ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, const OUString& aDatName,
312  SvStream* pInStream, ScImportAsciiCall eCall)
313  : GenericDialogController(pParent, "modules/scalc/ui/textimportcsv.ui", "TextImportCsvDialog")
314  , mpDatStream(pInStream)
315  , mnStreamPos(pInStream ? pInStream->Tell() : 0)
316  , mnRowPosCount(0)
317  , mcTextSep(ScAsciiOptions::cDefaultTextSep)
318  , meCall(eCall)
319  , mbDetectSep(eCall != SC_TEXTTOCOLUMNS)
320  , mxFtCharSet(m_xBuilder->weld_label("textcharset"))
321  , mxLbCharSet(new SvxTextEncodingBox(m_xBuilder->weld_combo_box("charset")))
322  , mxFtCustomLang(m_xBuilder->weld_label("textlanguage"))
323  , mxLbCustomLang(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
324  , mxFtRow(m_xBuilder->weld_label("textfromrow"))
325  , mxNfRow(m_xBuilder->weld_spin_button("fromrow"))
326  , mxRbFixed(m_xBuilder->weld_radio_button("tofixedwidth"))
327  , mxRbSeparated(m_xBuilder->weld_radio_button("toseparatedby"))
328  , mxCkbTab(m_xBuilder->weld_check_button("tab"))
329  , mxCkbSemicolon(m_xBuilder->weld_check_button("semicolon"))
330  , mxCkbComma(m_xBuilder->weld_check_button("comma"))
331  , mxCkbRemoveSpace(m_xBuilder->weld_check_button("removespace"))
332  , mxCkbSpace(m_xBuilder->weld_check_button("space"))
333  , mxCkbOther(m_xBuilder->weld_check_button("other"))
334  , mxEdOther(m_xBuilder->weld_entry("inputother"))
335  , mxCkbAsOnce(m_xBuilder->weld_check_button("mergedelimiters"))
336  , mxFtTextSep(m_xBuilder->weld_label("texttextdelimiter"))
337  , mxCbTextSep(m_xBuilder->weld_combo_box("textdelimiter"))
338  , mxCkbQuotedAsText(m_xBuilder->weld_check_button("quotedfieldastext"))
339  , mxCkbDetectNumber(m_xBuilder->weld_check_button("detectspecialnumbers"))
340  , mxCkbEvaluateFormulas(m_xBuilder->weld_check_button("evaluateformulas"))
341  , mxCkbSkipEmptyCells(m_xBuilder->weld_check_button("skipemptycells"))
342  , mxFtType(m_xBuilder->weld_label("textcolumntype"))
343  , mxLbType(m_xBuilder->weld_combo_box("columntype"))
344  , mxAltTitle(m_xBuilder->weld_label("textalttitle"))
345  , mxTableBox(new ScCsvTableBox(*m_xBuilder))
346 {
347  OUString aName = m_xDialog->get_title();
348  switch (meCall)
349  {
350  case SC_TEXTTOCOLUMNS:
351  m_xDialog->set_title(mxAltTitle->get_label());
352  break;
353  case SC_IMPORTFILE:
355  {
356  aName += " - [" + aDatName + "]";
357  m_xDialog->set_title(aName);
358  }
359  break;
360  default:
361  break;
362  }
363 
364  // To be able to prefill the correct values based on the file extension
365  bool bIsTSV = (aDatName.endsWithIgnoreAsciiCase(".tsv") || aDatName.endsWithIgnoreAsciiCase(".tab"));
366 
367  // Default options are set in officecfg/registry/schema/org/openoffice/Office/Calc.xcs
368  OUString sFieldSeparators(",;\t");
369  OUString sTextSeparators(mcTextSep);
370  bool bMergeDelimiters = false;
371  bool bFixedWidth = false;
372  bool bQuotedFieldAsText = false;
373  bool bDetectSpecialNum = true;
374  bool bEvaluateFormulas = (meCall != SC_IMPORTFILE);
375  bool bSkipEmptyCells = true;
376  bool bRemoveSpace = false;
377  sal_Int32 nFromRow = 1;
378  sal_Int32 nCharSet = -1;
379  sal_Int32 nLanguage = 0;
380  lcl_LoadSeparators (sFieldSeparators, sTextSeparators, bMergeDelimiters,
381  bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow,
382  nCharSet, nLanguage, bSkipEmptyCells, bRemoveSpace, bEvaluateFormulas, meCall);
383  // load from saved settings
384  maFieldSeparators = sFieldSeparators;
385 
386  if( bMergeDelimiters && !bIsTSV )
387  mxCkbAsOnce->set_active(true);
388  if (bQuotedFieldAsText)
389  mxCkbQuotedAsText->set_active(true);
390  if (bRemoveSpace)
391  mxCkbRemoveSpace->set_active(true);
392  if (bDetectSpecialNum)
393  mxCkbDetectNumber->set_active(true);
394  if (bEvaluateFormulas)
395  mxCkbEvaluateFormulas->set_active(true);
396  if (bSkipEmptyCells)
397  mxCkbSkipEmptyCells->set_active(true);
398  if (bFixedWidth && !bIsTSV)
399  mxRbFixed->set_active(true);
400  if (nFromRow != 1)
401  mxNfRow->set_value(nFromRow);
402 
403  // Clipboard is always Unicode, else detect.
404  rtl_TextEncoding ePreselectUnicode = (meCall == SC_IMPORTFILE ?
405  RTL_TEXTENCODING_DONTKNOW : RTL_TEXTENCODING_UNICODE);
406  // Sniff for Unicode / not
407  if( ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW && mpDatStream )
408  {
409  mpDatStream->Seek( 0 );
410  constexpr size_t buffsize = 4096;
411  sal_Int8 bytes[buffsize] = { 0 };
412  sal_Int32 nRead = mpDatStream->ReadBytes( bytes, buffsize );
413  mpDatStream->Seek( 0 );
414 
415  if ( nRead > 0 )
416  {
417  UErrorCode uerr = U_ZERO_ERROR;
418  UCharsetDetector* ucd = ucsdet_open( &uerr );
419  ucsdet_setText( ucd, reinterpret_cast<const char*>(bytes), nRead, &uerr );
420 
421  if ( const UCharsetMatch* match = ucsdet_detect(ucd, &uerr) )
422  {
423  const char* pEncodingName = ucsdet_getName( match, &uerr );
424 
425  if ( U_SUCCESS(uerr) && !strcmp("UTF-8", pEncodingName) )
426  {
427  ePreselectUnicode = RTL_TEXTENCODING_UTF8; // UTF-8
428  mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_UTF8 );
429  }
430  else if ( U_SUCCESS(uerr) && !strcmp("UTF-16LE", pEncodingName) )
431  {
432  ePreselectUnicode = RTL_TEXTENCODING_UNICODE; // UTF-16LE
433  mpDatStream->SetEndian( SvStreamEndian::LITTLE );
434  mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_UNICODE );
435  }
436  else if ( U_SUCCESS(uerr) && !strcmp("UTF-16BE", pEncodingName) )
437  {
438  ePreselectUnicode = RTL_TEXTENCODING_UNICODE; // UTF-16BE
439  mpDatStream->SetEndian( SvStreamEndian::BIG );
440  mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_UNICODE );
441  }
442  else // other
443  mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_DONTKNOW );
444  }
445 
446  ucsdet_close( ucd );
447  }
448 
450  }
451 
452  if (bIsTSV)
453  SetSeparators('\t');
454  else
455  {
456  // Some MS-Excel convention is the first line containing the field
457  // separator as "sep=|" (without quotes and any field separator
458  // character). The second possibility seems to be it is present *with*
459  // quotes so it shows up as cell content *including* the separator and
460  // can be preserved during round trips. Check for an exact match of
461  // any such and set separator.
462  /* TODO: it is debatable whether the unquoted form should rather be
463  * treated special to actually include the separator in the field data.
464  * Currently it does not. */
465  sal_Unicode cSep = 0;
466  OUString aLine;
467  // Try to read one more character, if more than 7 it can't be an exact
468  // match of any.
471  if (aLine.getLength() == 8)
472  ; // nothing
473  else if (aLine.getLength() == 5 && aLine.startsWithIgnoreAsciiCase("sep="))
474  cSep = aLine[4];
475  else if (aLine.getLength() == 7 && aLine[6] == '"' && aLine.startsWithIgnoreAsciiCase("\"sep="))
476  cSep = aLine[5];
477 
478  // Set Separators in the dialog from maFieldSeparators (empty are not
479  // set) or an optionally defined by file content field separator.
480  SetSeparators(cSep);
481  }
482 
483  // Get Separators from the dialog (empty are set from default)
485 
486  mxNfRow->connect_value_changed( LINK( this, ScImportAsciiDlg, FirstRowHdl ) );
487 
488  // *** Separator characters ***
490  mxCbTextSep->set_entry_text(sTextSeparators);
491  // tdf#69207 - use selected text delimiter to parse the provided data
493 
494  Link<weld::Toggleable&,void> aSeparatorClickHdl =LINK( this, ScImportAsciiDlg, SeparatorClickHdl );
495  mxCbTextSep->connect_changed( LINK( this, ScImportAsciiDlg, SeparatorComboBoxHdl ) );
496  mxCkbTab->connect_toggled( aSeparatorClickHdl );
497  mxCkbSemicolon->connect_toggled( aSeparatorClickHdl );
498  mxCkbComma->connect_toggled( aSeparatorClickHdl );
499  mxCkbAsOnce->connect_toggled( aSeparatorClickHdl );
500  mxCkbQuotedAsText->connect_toggled( aSeparatorClickHdl );
501  mxCkbDetectNumber->connect_toggled( aSeparatorClickHdl );
502  mxCkbEvaluateFormulas->connect_toggled( aSeparatorClickHdl );
503  mxCkbSkipEmptyCells->connect_toggled( aSeparatorClickHdl );
504  mxCkbSpace->connect_toggled( aSeparatorClickHdl );
505  mxCkbRemoveSpace->connect_toggled( aSeparatorClickHdl );
506  mxCkbOther->connect_toggled( aSeparatorClickHdl );
507  mxEdOther->connect_changed(LINK(this, ScImportAsciiDlg, SeparatorEditHdl));
508 
509  // *** text encoding ListBox ***
510  // all encodings allowed, including Unicode, but subsets are excluded
511  mxLbCharSet->FillFromTextEncodingTable( true );
512  // Insert one "SYSTEM" entry for compatibility in AsciiOptions and system
513  // independent document linkage.
514  mxLbCharSet->InsertTextEncoding( RTL_TEXTENCODING_DONTKNOW, ScResId( SCSTR_CHARSET_USER ) );
515  if ( ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW )
516  {
517  rtl_TextEncoding eSystemEncoding = osl_getThreadTextEncoding();
518  // Prefer UTF-8, as UTF-16 would have already been detected from the stream.
519  // This gives a better chance that the file is going to be opened correctly.
520  if ( ( eSystemEncoding == RTL_TEXTENCODING_UNICODE ) && mpDatStream )
521  eSystemEncoding = RTL_TEXTENCODING_UTF8;
522  mxLbCharSet->SelectTextEncoding( eSystemEncoding );
523  }
524  else
525  {
526  mxLbCharSet->SelectTextEncoding( ePreselectUnicode );
527  }
528 
529  if (nCharSet >= 0 && ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW)
530  mxLbCharSet->set_active(nCharSet);
531 
533  mxLbCharSet->connect_changed( LINK( this, ScImportAsciiDlg, CharSetHdl ) );
534 
535  mxLbCustomLang->SetLanguageList(
536  SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false, false);
537  mxLbCustomLang->InsertLanguage(LANGUAGE_SYSTEM);
538  mxLbCustomLang->set_active_id(static_cast<LanguageType>(nLanguage));
539 
540  // *** column type ListBox ***
541  OUString aColumnUser( ScResId( SCSTR_COLUMN_USER ) );
542  for (sal_Int32 nIdx {0}; nIdx>=0; )
543  {
544  mxLbType->append_text(aColumnUser.getToken(0, ';', nIdx));
545  }
546 
547  mxLbType->connect_changed( LINK( this, ScImportAsciiDlg, LbColTypeHdl ) );
548  mxFtType->set_sensitive(false);
549  mxLbType->set_sensitive(false);
550 
551  // *** table box preview ***
552  mxTableBox->Init();
553  mxTableBox->SetUpdateTextHdl( LINK( this, ScImportAsciiDlg, UpdateTextHdl ) );
554  mxTableBox->InitTypes( *mxLbType );
555  mxTableBox->SetColTypeHdl( LINK( this, ScImportAsciiDlg, ColTypeHdl ) );
556 
557  mxRbSeparated->connect_toggled( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
558  mxRbFixed->connect_toggled( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
559 
561  RbSepFix();
562 
563  UpdateVertical();
564 
565  mxTableBox->GetGrid().Execute( CSVCMD_NEWCELLTEXTS );
566 
567  if (meCall == SC_TEXTTOCOLUMNS)
568  {
569  mxFtCharSet->set_sensitive(false);
570  mxLbCharSet->set_sensitive(false);
571  mxFtCustomLang->set_sensitive(false);
572  mxLbCustomLang->set_active_id(LANGUAGE_SYSTEM);
573  mxLbCustomLang->set_sensitive(false);
574  mxFtRow->set_sensitive(false);
575  mxNfRow->set_sensitive(false);
576 
577  // Quoted field as text option is not used for text-to-columns mode.
578  mxCkbQuotedAsText->set_active(false);
579  mxCkbQuotedAsText->set_sensitive(false);
580 
581  // Always detect special numbers for text-to-columns mode.
582  mxCkbDetectNumber->set_active(true);
583  mxCkbDetectNumber->set_sensitive(false);
584  }
585  if (meCall == SC_IMPORTFILE)
586  {
587  //Empty cells in imported file are empty
588  mxCkbSkipEmptyCells->set_active(false);
589  mxCkbSkipEmptyCells->hide();
590  }
591  m_xDialog->SetInstallLOKNotifierHdl(LINK(this, ScImportAsciiDlg, InstallLOKNotifierHdl));
592 }
593 
594 IMPL_STATIC_LINK_NOARG(ScImportAsciiDlg, InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*)
595 {
596  return GetpApp();
597 }
598 
600 {
601 }
602 
603 bool ScImportAsciiDlg::GetLine( sal_uLong nLine, OUString &rText, sal_Unicode& rcDetectSep )
604 {
605  if (nLine >= ASCIIDLG_MAXROWS || !mpDatStream)
606  return false;
607 
608  bool bRet = true;
609  bool bFixed = mxRbFixed->get_active();
610 
611  if (!mpRowPosArray)
612  mpRowPosArray.reset( new sal_uLong[ASCIIDLG_MAXROWS + 2] );
613 
614  if (!mnRowPosCount) // complete re-fresh
615  {
616  memset( mpRowPosArray.get(), 0, sizeof(mpRowPosArray[0]) * (ASCIIDLG_MAXROWS+2));
617 
618  Seek(0);
620 
623  }
624 
625  if (nLine >= mnRowPosCount)
626  {
627  // need to work out some more line information
628  do
629  {
631  {
632  bRet = false;
633  break;
634  }
635  rText = ReadCsvLine(*mpDatStream, !bFixed, maFieldSeparators,
636  mcTextSep, rcDetectSep, kMaxEmbeddedLinefeeds);
639  } while (nLine >= mnRowPosCount && mpDatStream->good());
640  if (mpDatStream->eof() &&
642  {
643  // the very end, not even an empty line read
644  bRet = false;
645  --mnRowPosCount;
646  }
647  }
648  else
649  {
650  Seek( mpRowPosArray[nLine]);
651  rText = ReadCsvLine(*mpDatStream, !bFixed, maFieldSeparators, mcTextSep, rcDetectSep, kMaxEmbeddedLinefeeds);
653  }
654 
655  // If the file content isn't unicode, ReadUniStringLine
656  // may try to seek beyond the file's end and cause a CANTSEEK error
657  // (depending on the stream type). The error code has to be cleared,
658  // or further read operations (including non-unicode) will fail.
661 
663 
664  return bRet;
665 }
666 
668 {
669  rOpt.SetCharSet( meCharSet );
671  rOpt.SetLanguage(mxLbCustomLang->get_active_id());
672  rOpt.SetFixedLen( mxRbFixed->get_active() );
673  rOpt.SetStartRow( mxNfRow->get_value() );
674  mxTableBox->FillColumnData( rOpt );
675  if( mxRbSeparated->get_active() )
676  {
677  rOpt.SetFieldSeps( GetSeparators() );
678  rOpt.SetMergeSeps( mxCkbAsOnce->get_active() );
679  rOpt.SetRemoveSpace( mxCkbRemoveSpace->get_active() );
681  }
682 
683  rOpt.SetQuotedAsText(mxCkbQuotedAsText->get_active());
684  rOpt.SetDetectSpecialNumber(mxCkbDetectNumber->get_active());
685  rOpt.SetEvaluateFormulas(mxCkbEvaluateFormulas->get_active());
686  rOpt.SetSkipEmptyCells(mxCkbSkipEmptyCells->get_active());
687 }
688 
690 {
691  lcl_SaveSeparators( maFieldSeparators, mxCbTextSep->get_active_text(), mxCkbAsOnce->get_active(),
692  mxCkbQuotedAsText->get_active(), mxCkbDetectNumber->get_active(),
693  mxRbFixed->get_active(),
694  mxNfRow->get_value(),
695  mxLbCharSet->get_active(),
696  static_cast<sal_uInt16>(mxLbCustomLang->get_active_id()),
697  mxCkbSkipEmptyCells->get_active(), mxCkbRemoveSpace->get_active(),
698  mxCkbEvaluateFormulas->get_active(), meCall );
699 }
700 
702 {
703  if (cSep)
704  {
705  // Exclusively set a separator, maFieldSeparators needs not be
706  // modified, it's obtained by GetSeparators() after this call.
707  constexpr sal_Unicode aSeps[] = { '\t', ';', ',', ' ' };
708  for (const sal_Unicode c : aSeps)
709  {
710  const bool bSet = (c == cSep);
711  switch (c)
712  {
713  case '\t': mxCkbTab->set_active(bSet); break;
714  case ';': mxCkbSemicolon->set_active(bSet); break;
715  case ',': mxCkbComma->set_active(bSet); break;
716  case ' ': mxCkbSpace->set_active(bSet); break;
717  }
718  if (bSet)
719  cSep = 0;
720  }
721  if (cSep)
722  {
723  mxCkbOther->set_active(true);
724  mxEdOther->set_text(OUStringChar(cSep));
725  }
726  }
727  else
728  {
729  for (sal_Int32 i = 0; i < maFieldSeparators.getLength(); ++i)
730  {
731  switch (maFieldSeparators[i])
732  {
733  case '\t': mxCkbTab->set_active(true); break;
734  case ';': mxCkbSemicolon->set_active(true); break;
735  case ',': mxCkbComma->set_active(true); break;
736  case ' ': mxCkbSpace->set_active(true); break;
737  default:
738  mxCkbOther->set_active(true);
739  mxEdOther->set_text(mxEdOther->get_text() + OUStringChar(maFieldSeparators[i]));
740  }
741  }
742  }
743 }
744 
746 {
747  meCharSet = mxLbCharSet->GetSelectTextEncoding();
748  mbCharSetSystem = (meCharSet == RTL_TEXTENCODING_DONTKNOW);
749  if( mbCharSetSystem )
750  meCharSet = osl_getThreadTextEncoding();
751 }
752 
754 {
755  OUString aSepChars;
756  if( mxCkbTab->get_active() )
757  aSepChars += "\t";
758  if( mxCkbSemicolon->get_active() )
759  aSepChars += ";";
760  if( mxCkbComma->get_active() )
761  aSepChars += ",";
762  if( mxCkbSpace->get_active() )
763  aSepChars += " ";
764  if( mxCkbOther->get_active() )
765  aSepChars += mxEdOther->get_text();
766  return aSepChars;
767 }
768 
770 {
771  bool bEnable = mxRbSeparated->get_active();
772  mxCkbTab->set_sensitive( bEnable );
773  mxCkbSemicolon->set_sensitive( bEnable );
774  mxCkbComma->set_sensitive( bEnable );
775  mxCkbSpace->set_sensitive( bEnable );
776  mxCkbRemoveSpace->set_sensitive( bEnable );
777  mxCkbOther->set_sensitive( bEnable );
778  mxEdOther->set_sensitive( bEnable );
779  mxCkbAsOnce->set_sensitive( bEnable );
780  mxFtTextSep->set_sensitive( bEnable );
781  mxCbTextSep->set_sensitive( bEnable );
782 }
783 
785 {
786  mnRowPosCount = 0;
787  if (mpDatStream)
789 }
790 
792 {
793  weld::WaitObject aWaitObj(m_xDialog.get());
794  if( mxRbFixed->get_active() )
795  mxTableBox->SetFixedWidthMode();
796  else
797  mxTableBox->SetSeparatorsMode();
799 }
800 
801 IMPL_LINK(ScImportAsciiDlg, RbSepFixHdl, weld::Toggleable&, rButton, void)
802 {
803  if (!rButton.get_active())
804  return;
805  RbSepFix();
806 }
807 
808 IMPL_LINK(ScImportAsciiDlg, SeparatorClickHdl, weld::Toggleable&, rCtrl, void)
809 {
810  SeparatorHdl(&rCtrl);
811 }
812 
813 IMPL_LINK( ScImportAsciiDlg, SeparatorComboBoxHdl, weld::ComboBox&, rCtrl, void )
814 {
815  SeparatorHdl(&rCtrl);
816 }
817 
818 IMPL_LINK( ScImportAsciiDlg, SeparatorEditHdl, weld::Entry&, rEdit, void )
819 {
820  SeparatorHdl(&rEdit);
821 }
822 
824 {
825  OSL_ENSURE( pCtrl, "ScImportAsciiDlg::SeparatorHdl - missing sender" );
826  OSL_ENSURE( !mxRbFixed->get_active(), "ScImportAsciiDlg::SeparatorHdl - not allowed in fixed width" );
827 
828  /* #i41550# First update state of the controls. The GetSeparators()
829  function needs final state of the check boxes. */
830  if (pCtrl == mxCkbOther.get() && mxCkbOther->get_active())
831  mxEdOther->grab_focus();
832  else if (pCtrl == mxEdOther.get())
833  mxCkbOther->set_active(!mxEdOther->get_text().isEmpty());
834 
835  OUString aOldFldSeps( maFieldSeparators);
837  sal_Unicode cOldSep = mcTextSep;
839  // Any separator changed may result in completely different lines due to
840  // embedded line breaks.
841  if (cOldSep != mcTextSep || aOldFldSeps != maFieldSeparators)
842  UpdateVertical();
843 
844  mxTableBox->GetGrid().Execute( CSVCMD_NEWCELLTEXTS );
845 }
846 
848 {
849  if (mxLbCharSet->get_active() != -1)
850  {
851  weld::WaitObject aWaitObj(m_xDialog.get());
852  rtl_TextEncoding eOldCharSet = meCharSet;
853  SetSelectedCharSet();
854  // switching char-set invalidates 8bit -> String conversions
855  if (eOldCharSet != meCharSet)
856  UpdateVertical();
857 
858  mxTableBox->GetGrid().Execute( CSVCMD_NEWCELLTEXTS );
859  }
860 }
861 
862 IMPL_LINK(ScImportAsciiDlg, FirstRowHdl, weld::SpinButton&, rNumField, void)
863 {
864  mxTableBox->GetGrid().Execute( CSVCMD_SETFIRSTIMPORTLINE, rNumField.get_value() - 1);
865 }
866 
867 IMPL_LINK(ScImportAsciiDlg, LbColTypeHdl, weld::ComboBox&, rListBox, void)
868 {
869  if (&rListBox == mxLbType.get())
870  mxTableBox->GetGrid().Execute(CSVCMD_SETCOLUMNTYPE, rListBox.get_active());
871 }
872 
874 {
875  // Checking the separator can only be done once for the very first time
876  // when the dialog wasn't already presented to the user.
877  // As a side effect this has the benefit that the check is only done on the
878  // first set of visible lines.
879  mbDetectSep = (mbDetectSep && !mxRbFixed->get_active()
880  && (!mxCkbTab->get_active() || !mxCkbSemicolon->get_active()
881  || !mxCkbComma->get_active() || !mxCkbSpace->get_active()));
882  sal_Unicode cDetectSep = (mbDetectSep ? 0 : 0xffff);
883 
884  sal_Int32 nBaseLine = mxTableBox->GetGrid().GetFirstVisLine();
885  sal_Int32 nRead = mxTableBox->GetGrid().GetVisLineCount();
886  // If mnRowPosCount==0, this is an initializing call, read ahead for row
887  // count and resulting scroll bar size and position to be able to scroll at
888  // all. When adding lines, read only the amount of next lines to be
889  // displayed.
890  if (!mnRowPosCount || nRead > CSV_PREVIEW_LINES)
891  nRead = CSV_PREVIEW_LINES;
892 
893  sal_Int32 i;
894  for (i = 0; i < nRead; i++)
895  {
896  if (!GetLine( nBaseLine + i, maPreviewLine[i], cDetectSep))
897  break;
898  }
899  for (; i < CSV_PREVIEW_LINES; i++)
900  maPreviewLine[i].clear();
901 
902  if (mbDetectSep)
903  {
904  mbDetectSep = false;
905  if (cDetectSep)
906  {
907  // Expect separator to be appended by now so all subsequent
908  // GetLine()/ReadCsvLine() actually used it.
909  assert(maFieldSeparators.endsWith(OUStringChar(cDetectSep)));
910  // Preselect separator in UI.
911  switch (cDetectSep)
912  {
913  case '\t': mxCkbTab->set_active(true); break;
914  case ';': mxCkbSemicolon->set_active(true); break;
915  case ',': mxCkbComma->set_active(true); break;
916  case ' ': mxCkbSpace->set_active(true); break;
917  }
918  }
919  }
920 
921  mxTableBox->GetGrid().Execute( CSVCMD_SETLINECOUNT, mnRowPosCount);
922  bool bMergeSep = mxCkbAsOnce->get_active();
923  bool bRemoveSpace = mxCkbRemoveSpace->get_active();
924  mxTableBox->SetUniStrings( maPreviewLine, maFieldSeparators, mcTextSep, bMergeSep, bRemoveSpace );
925 }
926 
927 IMPL_LINK( ScImportAsciiDlg, ColTypeHdl, ScCsvTableBox&, rTableBox, void )
928 {
929  sal_Int32 nType = rTableBox.GetSelColumnType();
930  sal_Int32 nTypeCount = mxLbType->get_count();
931  bool bEmpty = (nType == CSV_TYPE_MULTI);
932  bool bEnable = ((0 <= nType) && (nType < nTypeCount)) || bEmpty;
933 
934  mxFtType->set_sensitive( bEnable );
935  mxLbType->set_sensitive( bEnable );
936 
937  if (bEmpty)
938  mxLbType->set_active(-1);
939  else if (bEnable)
940  mxLbType->set_active(nType);
941 }
942 
943 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::shared_ptr< weld::Dialog > m_xDialog
static sal_Unicode lcl_CharFromCombo(const weld::ComboBox &rCombo, std::u16string_view rList)
std::unique_ptr< weld::ComboBox > mxLbType
OUString maFieldSeparators
virtual ~ScImportAsciiDlg() override
std::unique_ptr< weld::RadioButton > mxRbFixed
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
std::unique_ptr< weld::CheckButton > mxCkbOther
void SeparatorHdl(const weld::Widget *)
sal_Int32 nProperties
const ::std::vector< OUString > CSVImportOptionNames
bool ReadUniOrByteStringLine(OUString &rStr, rtl_TextEncoding eSrcCharSet, sal_Int32 nMaxCodepointsToRead=0xFFFE)
std::unique_ptr< weld::ComboBox > mxCbTextSep
signed char sal_Int8
sal_Unicode mcTextSep
std::vector< sal_uInt8 > bytes
IMPL_LINK_NOARG(ScImportAsciiDlg, CharSetHdl, weld::ComboBox &, void)
bool Seek(sal_uLong nPos)
sal_uIntPtr sal_uLong
Update cell texts with current split settings. [-].
Definition: csvcontrol.hxx:184
void SetCharSetSystem(bool bSet)
Definition: asciiopt.hxx:73
sal_uInt64 Seek(sal_uInt64 nPos)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
std::unique_ptr< weld::SpinButton > mxNfRow
static void lcl_CreatePropertiesNames(OUString &rSepPath, Sequence< OUString > &rNames, ScImportAsciiCall eCall)
void SetupSeparatorCtrls()
Enables or disables all separator checkboxes and edit fields.
bool GetLine(sal_uLong nLine, OUString &rText, sal_Unicode &rcDetectSep)
void SetSkipEmptyCells(bool bSet)
Definition: asciiopt.hxx:81
std::unique_ptr< weld::CheckButton > mxCkbQuotedAsText
std::unique_ptr< weld::RadioButton > mxRbSeparated
sal_uLong mnStreamPos
SvStream * mpDatStream
#define ERRCODE_IO_CANTSEEK
void SetStartRow(sal_Int32 nRow)
Definition: asciiopt.hxx:83
constexpr OUStringLiteral aSep_Path_Clpbrd
void SetSeparators(sal_Unicode cSep)
Set separators in ui from maFieldSeparators or an optionally defined separator.
std::unique_ptr< weld::CheckButton > mxCkbSpace
bool match(const sal_Unicode *pWild, const sal_Unicode *pStr, const sal_Unicode cEscape)
void SetCharSet(rtl_TextEncoding eNew)
Definition: asciiopt.hxx:72
sal_uInt16 sal_Unicode
std::unique_ptr< weld::CheckButton > mxCkbEvaluateFormulas
void SetDetectSpecialNumber(bool bSet)
Definition: asciiopt.hxx:79
ErrCode GetError() const
bool eof() const
void StartReadingUnicodeText(rtl_TextEncoding eReadBomCharSet)
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
IMPL_STATIC_LINK_NOARG(ScImportAsciiDlg, InstallLOKNotifierHdl, void *, vcl::ILibreOfficeKitNotifier *)
const SCSIZE ASCIIDLG_MAXROWS
TODO make dynamic.
Application * GetpApp()
std::unique_ptr< weld::CheckButton > mxCkbSkipEmptyCells
const SCROW MAXROWCOUNT
Definition: address.hxx:62
std::unique_ptr< weld::CheckButton > mxCkbSemicolon
constexpr OUStringLiteral aSep_Path_Text2Col
std::unique_ptr< weld::CheckButton > mxCkbComma
OUString GetSeparators() const
Returns all separator characters in a string.
void SetEvaluateFormulas(bool bSet)
Definition: asciiopt.hxx:80
Send selected column type to external controls. [-].
Definition: csvcontrol.hxx:186
std::unique_ptr< weld::Label > mxFtCharSet
Whether to detect a possible separator.
std::unique_ptr< weld::Label > mxFtRow
void SetQuotedAsText(bool bSet)
Definition: asciiopt.hxx:78
rtl_TextEncoding meCharSet
int i
static void lcl_SaveSeparators(const OUString &sFieldSeparators, const OUString &sTextSeparators, bool bMergeDelimiters, bool bQuotedAsText, bool bDetectSpecialNum, bool bFixedWidth, sal_Int32 nFromRow, sal_Int32 nCharSet, sal_Int32 nLanguage, bool bSkipEmptyCells, bool bRemoveSpace, bool bEvaluateFormulas, ScImportAsciiCall eCall)
std::unique_ptr< ScCsvTableBox > mxTableBox
void SetLanguage(LanguageType e)
Definition: asciiopt.hxx:84
#define LANGUAGE_SYSTEM
void SetRemoveSpace(bool bSet)
Definition: asciiopt.hxx:77
void SetSelectedCharSet()
Sets the selected char set data to meCharSet and mbCharSetSystem.
std::unique_ptr< weld::CheckButton > mxCkbTab
bool mbCharSetSystem
Selected char set.
float u
std::unique_ptr< weld::CheckButton > mxCkbDetectNumber
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::unique_ptr< SvxTextEncodingBox > mxLbCharSet
void SetFixedLen(bool bSet)
Definition: asciiopt.hxx:74
void SetFieldSeps(const OUString &rStr)
Definition: asciiopt.hxx:75
void GetOptions(ScAsciiOptions &rOpt)
void PutProperties(const css::uno::Sequence< OUString > &rNames, const css::uno::Sequence< css::uno::Any > &rValues)
Definition: optutil.hxx:55
OUString ReadCsvLine(SvStream &rStream, bool bEmbeddedLineBreak, OUString &rFieldSeparators, sal_Unicode cFieldQuote, sal_Unicode &rcDetectSep, sal_uInt32 nMaxSourceLines)
Read a CSV (comma separated values) data line using ReadUniOrByteStringLine().
Definition: impex.cxx:2676
The control in the CSV import dialog that contains a ruler and a data grid to visualize and modify th...
Definition: csvtablebox.hxx:43
std::size_t ReadBytes(void *pData, std::size_t nSize)
static void EmbeddedNullTreatment(OUString &rStr)
Definition: impex.cxx:1794
Move to make passed position visible (for mouse tracking). [position].
Definition: csvcontrol.hxx:182
std::unique_ptr< weld::Label > mxFtTextSep
static void lcl_LoadSeparators(OUString &rFieldSeparators, OUString &rTextSeparators, bool &rMergeDelimiters, bool &rQuotedAsText, bool &rDetectSpecialNum, bool &rFixedWidth, sal_Int32 &rFromRow, sal_Int32 &rCharSet, sal_Int32 &rLanguage, bool &rSkipEmptyCells, bool &rRemoveSpace, bool &rEvaluateFormulas, ScImportAsciiCall eCall)
std::unique_ptr< sal_uLong[]> mpRowPosArray
weld::Entry & rEdit
std::unique_ptr< weld::Entry > mxEdOther
const sal_Int32 CSV_TYPE_MULTI
Multi selection with different types.
Definition: csvcontrol.hxx:49
void SetEndian(SvStreamEndian SvStreamEndian)
OUString aName
std::unique_ptr< weld::Label > mxAltTitle
ScImportAsciiCall
How ScImportAsciiDlg is called.
Definition: asciiopt.hxx:103
void SetStreamCharSet(rtl_TextEncoding eCharSet)
rtl_TextEncoding GetStreamCharSet() const
Reference< XExecutableDialog > m_xDialog
std::unique_ptr< weld::CheckButton > mxCkbAsOnce
sal_uLong mnRowPosCount
sal_uInt64 Tell() const
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
IMPL_LINK(ScImportAsciiDlg, RbSepFixHdl, weld::Toggleable &, rButton, void)
Change character pixel width. [width in pixel].
Definition: csvcontrol.hxx:171
static void lcl_FillCombo(weld::ComboBox &rCombo, std::u16string_view rList, sal_Unicode cSelect)
bool good() const
constexpr sal_uInt32 kMaxEmbeddedLinefeeds
ScImportAsciiCall meCall
Is System char set selected?
void append_text(const OUString &rStr)
constexpr OUStringLiteral aSep_Path
virtual void ResetError()
std::unique_ptr< weld::CheckButton > mxCkbRemoveSpace
void SetMergeSeps(bool bSet)
Definition: asciiopt.hxx:76
static bool GetBoolFromAny(const css::uno::Any &aAny)
Definition: miscuno.cxx:138
static SC_DLLPUBLIC::utl::TransliterationWrapper & GetTransliteration()
Definition: global.cxx:986
std::unique_ptr< SvxLanguageBox > mxLbCustomLang
css::uno::Sequence< css::uno::Any > GetProperties(const css::uno::Sequence< OUString > &rNames)
Definition: optutil.hxx:53
ScImportAsciiDlg(weld::Window *pParent, const OUString &aDatName, SvStream *pInStream, ScImportAsciiCall eCall)
aStr
virtual void set_entry_text(const OUString &rStr)=0
void SetTextSep(sal_Unicode c)
Definition: asciiopt.hxx:82
std::unique_ptr< weld::Label > mxFtCustomLang
const sal_Int32 CSV_PREVIEW_LINES
TODO make string array dynamic.
Definition: csvcontrol.hxx:42
constexpr OUStringLiteral SCSTR_TEXTSEP
Definition: strings.hxx:15
virtual OUString get_active_text() const =0
CSVImportOptionsIndex
std::unique_ptr< weld::Label > mxFtType