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  bEvaluateFormulas = rString.getToken(0, ',', nPos) == "true";
190  }
191  else
192  bEvaluateFormulas = true; // default of versions that didn't add the parameter
193 }
194 
196 {
197  OUStringBuffer aOutStr;
198 
199  // Token 0: Field separator.
200  if ( bFixedLen )
201  aOutStr.append(pStrFix);
202  else if ( aFieldSeps.isEmpty() )
203  aOutStr.append("0");
204  else
205  {
206  sal_Int32 nLen = aFieldSeps.getLength();
207  for (sal_Int32 i=0; i<nLen; i++)
208  {
209  if (i)
210  aOutStr.append("/");
211  aOutStr.append(OUString::number(aFieldSeps[i]));
212  }
213  if ( bMergeFieldSeps )
214  {
215  aOutStr.append("/");
216  aOutStr.append(pStrMrg);
217  }
218  }
219 
220  // Token 1: Text Quote character.
221  aOutStr.append("," + OUString::number(cTextSep) + ",");
222 
223  //Token 2: Text encoding.
224  if ( bCharSetSystem ) // force "SYSTEM"
225  aOutStr.append(ScGlobal::GetCharsetString( RTL_TEXTENCODING_DONTKNOW ));
226  else
227  aOutStr.append(ScGlobal::GetCharsetString( eCharSet ));
228 
229  //Token 3: Number of start row.
230  aOutStr.append("," + OUString::number(nStartRow) + ",");
231 
232  //Token 4: Column info.
233  for (size_t nInfo=0; nInfo<mvColStart.size(); nInfo++)
234  {
235  if (nInfo)
236  aOutStr.append("/");
237  aOutStr.append(OUString::number(mvColStart[nInfo]) +
238  "/" +
239  OUString::number(mvColFormat[nInfo]));
240  }
241 
242  // #i112025# the options string is used in macros and linked sheets,
243  // so new options must be added at the end, to remain compatible
244  // Always keep in sync with ScImportOptions.
245 
246  aOutStr.append("," +
247  // Token 5: Language
248  OUString::number(static_cast<sal_uInt16>(eLang)) + "," +
249  // Token 6: Import quoted field as text.
250  OUString::boolean( bQuotedFieldAsText ) + "," +
251  // Token 7: Detect special numbers.
252  OUString::boolean( bDetectSpecialNumber ) + "," +
253  // Token 8: used for "Save as shown" in export options
254  OUString::boolean( bSaveAsShown ) +"," +
255  // Token 9: used for "Save cell formulas" in export options
256  OUString::boolean( bSaveFormulas ) + "," +
257  // Token 10: Trim Space
258  OUString::boolean( bRemoveSpace ) +
259  // Token 11: sheet to export, always 0 for current sheet
260  ",0," +
261  // Token 12: evaluate formulas in import
262  OUString::boolean( bEvaluateFormulas )
263  );
264  return aOutStr.makeStringAndClear();
265 }
266 
267 // static
268 sal_Unicode ScAsciiOptions::GetWeightedFieldSep( const OUString & rFieldSeps, bool bDecodeNumbers )
269 {
270  bool bMergeFieldSeps = false;
271  OUString aFieldSeps( bDecodeNumbers ? lcl_decodeSepString( rFieldSeps, bMergeFieldSeps) : rFieldSeps);
272  if (aFieldSeps.isEmpty())
273  {
274  return 0;
275  }
276  else if (aFieldSeps.getLength() == 1)
277  return aFieldSeps[0];
278  else
279  {
280  // There can be only one separator for output. See also fdo#53449
281  if (aFieldSeps.indexOf(',') != -1)
282  return ',';
283  else if (aFieldSeps.indexOf('\t') != -1)
284  return '\t';
285  else if (aFieldSeps.indexOf(';') != -1)
286  return ';';
287  else if (aFieldSeps.indexOf(' ') != -1)
288  return ' ';
289  else
290  return aFieldSeps[0];
291  }
292 }
293 
294 /* 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:584
OUString WriteToString() const
Definition: asciiopt.cxx:195
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:268
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:556
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