LibreOffice Module sc (master)  1
asciiopt.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 #include <global.hxx>
21 #include <asciiopt.hxx>
22 #include <comphelper/string.hxx>
23 #include <osl/thread.h>
24 
25 const char pStrFix[] = "FIX";
26 const char pStrMrg[] = "MRG";
27 
29  bFixedLen ( false ),
30  aFieldSeps ( OUString(';') ),
31  bMergeFieldSeps ( false ),
32  bRemoveSpace ( false ),
33  bQuotedFieldAsText(false),
34  bDetectSpecialNumber(false),
35  bEvaluateFormulas(true),
36  bSkipEmptyCells(false),
37  bSaveAsShown(true),
38  bSaveFormulas(false),
39  cTextSep ( cDefaultTextSep ),
40  eCharSet ( osl_getThreadTextEncoding() ),
41  eLang ( LANGUAGE_SYSTEM ),
42  bCharSetSystem ( false ),
43  nStartRow ( 1 )
44 {
45 }
46 
48 {
49  sal_uInt16 nInfoCount = static_cast< sal_uInt16 >( rDataVec.size() );
50  mvColStart.resize(nInfoCount);
51  mvColFormat.resize(nInfoCount);
52  for( sal_uInt16 nIx = 0; nIx < nInfoCount; ++nIx )
53  {
54  mvColStart[ nIx ] = rDataVec[ nIx ].mnIndex;
55  mvColFormat[ nIx ] = rDataVec[ nIx ].mnType;
56  }
57 }
58 
59 static OUString lcl_decodeSepString( const OUString & rSepNums, bool & o_bMergeFieldSeps )
60 {
61  if ( rSepNums.isEmpty() )
62  return OUString();
63 
64  OUStringBuffer aFieldSeps;
65  sal_Int32 nPos = 0;
66  do
67  {
68  const OUString aCode = rSepNums.getToken( 0, '/', nPos );
69  if ( aCode == pStrMrg )
70  o_bMergeFieldSeps = true;
71  else
72  {
73  sal_Int32 nVal = aCode.toInt32();
74  if ( nVal )
75  aFieldSeps.append(sal_Unicode(nVal));
76  }
77  }
78  while ( nPos >= 0 );
79 
80  return aFieldSeps.makeStringAndClear();
81 }
82 
83 // The options string must not contain semicolons (because of the pick list),
84 // use comma as separator.
85 
86 void ScAsciiOptions::ReadFromString( const OUString& rString )
87 {
88  sal_Int32 nPos = rString.isEmpty() ? -1 : 0;
89 
90  // Token 0: Field separator.
91  if ( nPos >= 0 )
92  {
93  bFixedLen = bMergeFieldSeps = false;
94 
95  const OUString aToken = rString.getToken(0, ',', nPos);
96  if ( aToken == pStrFix )
97  bFixedLen = true;
99  }
100 
101  // Token 1: Text separator.
102  if ( nPos >= 0 )
103  {
104  const sal_Int32 nVal = rString.getToken(0, ',', nPos).toInt32();
105  cTextSep = static_cast<sal_Unicode>(nVal);
106  }
107 
108  // Token 2: Text encoding.
109  if ( nPos >= 0 )
110  {
111  eCharSet = ScGlobal::GetCharsetValue( rString.getToken(0, ',', nPos) );
112  }
113 
114  // Token 3: Number of start row.
115  if ( nPos >= 0 )
116  {
117  nStartRow = rString.getToken(0, ',', nPos).toInt32();
118  }
119 
120  // Token 4: Column info.
121  if ( nPos >= 0 )
122  {
123  const OUString aToken = rString.getToken(0, ',', nPos);
124  const sal_Int32 nInfoCount = comphelper::string::getTokenCount(aToken, '/')/2;
125  mvColStart.resize(nInfoCount);
126  mvColFormat.resize(nInfoCount);
127  sal_Int32 nP = 0;
128  for (sal_Int32 nInfo=0; nInfo<nInfoCount; ++nInfo)
129  {
130  mvColStart[nInfo] = aToken.getToken(0, '/', nP).toInt32();
131  mvColFormat[nInfo] = static_cast<sal_uInt8>(aToken.getToken(0, '/', nP).toInt32());
132  }
133  }
134 
135  // Token 5: Language.
136  if (nPos >= 0)
137  {
138  eLang = static_cast<LanguageType>(rString.getToken(0, ',', nPos).toInt32());
139  }
140 
141  // Token 6: Import quoted field as text.
142  if (nPos >= 0)
143  {
144  bQuotedFieldAsText = rString.getToken(0, ',', nPos) == "true";
145  }
146 
147  // Token 7: Detect special numbers.
148  if (nPos >= 0)
149  {
150  bDetectSpecialNumber = rString.getToken(0, ',', nPos) == "true";
151  }
152  else
153  bDetectSpecialNumber = true; // default of versions that didn't add the parameter
154 
155  // Token 8: used for "Save as shown" in export options
156  if ( nPos >= 0 )
157  {
158  bSaveAsShown = rString.getToken(0, ',', nPos) == "true";
159  }
160  else
161  bSaveAsShown = true; // default value
162 
163  // Token 9: used for "Save cell formulas" in export options
164  if ( nPos >= 0 )
165  {
166  bSaveFormulas = rString.getToken(0, ',', nPos) == "true";
167  }
168  else
169  bSaveFormulas = false;
170 
171  // Token 10: Boolean for Trim spaces.
172  if (nPos >= 0)
173  {
174  bRemoveSpace = rString.getToken(0, ',', nPos) == "true";
175  }
176  else
177  bRemoveSpace = false;
178 
179  // Token 11: sheet to export for --convert-to csv
180  // Does not need to be evaluated here but may be present.
181  if (nPos >= 0)
182  {
183  rString.getToken(0, ',', nPos);
184  }
185 
186  // Token 12: evaluate formulas.
187  if (nPos >= 0)
188  {
189  // If present, defaults to "false".
190  bEvaluateFormulas = rString.getToken(0, ',', nPos) == "true";
191  }
192  else
193  bEvaluateFormulas = true; // default of versions that didn't add the parameter
194 }
195 
197 {
198  OUStringBuffer aOutStr;
199 
200  // Token 0: Field separator.
201  if ( bFixedLen )
202  aOutStr.append(pStrFix);
203  else if ( aFieldSeps.isEmpty() )
204  aOutStr.append("0");
205  else
206  {
207  sal_Int32 nLen = aFieldSeps.getLength();
208  for (sal_Int32 i=0; i<nLen; i++)
209  {
210  if (i)
211  aOutStr.append("/");
212  aOutStr.append(OUString::number(aFieldSeps[i]));
213  }
214  if ( bMergeFieldSeps )
215  {
216  aOutStr.append("/");
217  aOutStr.append(pStrMrg);
218  }
219  }
220 
221  // Token 1: Text Quote character.
222  aOutStr.append("," + OUString::number(cTextSep) + ",");
223 
224  //Token 2: Text encoding.
225  if ( bCharSetSystem ) // force "SYSTEM"
226  aOutStr.append(ScGlobal::GetCharsetString( RTL_TEXTENCODING_DONTKNOW ));
227  else
228  aOutStr.append(ScGlobal::GetCharsetString( eCharSet ));
229 
230  //Token 3: Number of start row.
231  aOutStr.append("," + OUString::number(nStartRow) + ",");
232 
233  //Token 4: Column info.
234  for (size_t nInfo=0; nInfo<mvColStart.size(); nInfo++)
235  {
236  if (nInfo)
237  aOutStr.append("/");
238  aOutStr.append(OUString::number(mvColStart[nInfo]) +
239  "/" +
240  OUString::number(mvColFormat[nInfo]));
241  }
242 
243  // #i112025# the options string is used in macros and linked sheets,
244  // so new options must be added at the end, to remain compatible
245  // Always keep in sync with ScImportOptions.
246 
247  aOutStr.append("," +
248  // Token 5: Language
249  OUString::number(static_cast<sal_uInt16>(eLang)) + "," +
250  // Token 6: Import quoted field as text.
251  OUString::boolean( bQuotedFieldAsText ) + "," +
252  // Token 7: Detect special numbers.
253  OUString::boolean( bDetectSpecialNumber ) + "," +
254  // Token 8: used for "Save as shown" in export options
255  OUString::boolean( bSaveAsShown ) +"," +
256  // Token 9: used for "Save cell formulas" in export options
257  OUString::boolean( bSaveFormulas ) + "," +
258  // Token 10: Trim Space
259  OUString::boolean( bRemoveSpace ) +
260  // Token 11: sheet to export, always 0 for current sheet
261  ",0," +
262  // Token 12: evaluate formulas in import
263  OUString::boolean( bEvaluateFormulas )
264  );
265  return aOutStr.makeStringAndClear();
266 }
267 
268 // static
269 sal_Unicode ScAsciiOptions::GetWeightedFieldSep( const OUString & rFieldSeps, bool bDecodeNumbers )
270 {
271  bool bMergeFieldSeps = false;
272  OUString aFieldSeps( bDecodeNumbers ? lcl_decodeSepString( rFieldSeps, bMergeFieldSeps) : rFieldSeps);
273  if (aFieldSeps.isEmpty())
274  {
275  return 0;
276  }
277  else if (aFieldSeps.getLength() == 1)
278  return aFieldSeps[0];
279  else
280  {
281  // There can be only one separator for output. See also fdo#53449
282  if (aFieldSeps.indexOf(',') != -1)
283  return ',';
284  else if (aFieldSeps.indexOf('\t') != -1)
285  return '\t';
286  else if (aFieldSeps.indexOf(';') != -1)
287  return ';';
288  else if (aFieldSeps.indexOf(' ') != -1)
289  return ' ';
290  else
291  return aFieldSeps[0];
292  }
293 }
294 
295 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const char pStrFix[]
Definition: asciiopt.cxx:25
bool bQuotedFieldAsText
Definition: asciiopt.hxx:34
bool bEvaluateFormulas
Definition: asciiopt.hxx:36
OUString aFieldSeps
Definition: asciiopt.hxx:31
rtl_TextEncoding eCharSet
Definition: asciiopt.hxx:41
void SetColumnInfo(const ScCsvExpDataVec &rDataVec)
Definition: asciiopt.cxx:47
bool bSaveAsShown
Definition: asciiopt.hxx:38
static OUString GetCharsetString(rtl_TextEncoding eVal)
Definition: global.cxx:581
OUString WriteToString() const
Definition: asciiopt.cxx:196
sal_uInt16 sal_Unicode
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:269
static OUString lcl_decodeSepString(const OUString &rSepNums, bool &o_bMergeFieldSeps)
Definition: asciiopt.cxx:59
LanguageType eLang
Definition: asciiopt.hxx:42
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
sal_Int32 nStartRow
Definition: asciiopt.hxx:44
std::vector< sal_Int32 > mvColStart
Definition: asciiopt.hxx:45
int i
#define LANGUAGE_SYSTEM
bool bDetectSpecialNumber
Definition: asciiopt.hxx:35
bool bSaveFormulas
Definition: asciiopt.hxx:39
const char pStrMrg[]
Definition: asciiopt.cxx:26
void ReadFromString(const OUString &rString)
Definition: asciiopt.cxx:86
unsigned char sal_uInt8
bool bMergeFieldSeps
Definition: asciiopt.hxx:32
bool bRemoveSpace
Definition: asciiopt.hxx:33
static rtl_TextEncoding GetCharsetValue(const OUString &rCharSet)
Definition: global.cxx:553
std::vector< sal_uInt8 > mvColFormat
Definition: asciiopt.hxx:46
sal_Unicode cTextSep
Definition: asciiopt.hxx:40
::std::vector< ScCsvExpData > ScCsvExpDataVec
Definition: csvcontrol.hxx:73
sal_uInt16 nPos
bool bCharSetSystem
Definition: asciiopt.hxx:43