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