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