1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "scresid.hxx"
23 #include "asciiopt.hxx"
24 #include "asciiopt.hrc"
25 #include <comphelper/string.hxx>
26 #include <osl/thread.h>
27 #include <rtl/tencinfo.h>
28 #include <unotools/transliterationwrapper.hxx>
29 #include "editutil.hxx"
31 static const sal_Char pStrFix
[] = "FIX";
32 static const sal_Char pStrMrg
[] = "MRG";
34 ScAsciiOptions::ScAsciiOptions() :
36 aFieldSeps ( OUString(';') ),
37 bMergeFieldSeps ( false ),
38 bQuotedFieldAsText(false),
39 bDetectSpecialNumber(false),
40 cTextSep ( cDefaultTextSep
),
41 eCharSet ( osl_getThreadTextEncoding() ),
42 eLang ( LANGUAGE_SYSTEM
),
43 bCharSetSystem ( false ),
51 ScAsciiOptions::ScAsciiOptions(const ScAsciiOptions
& rOpt
) :
52 bFixedLen ( rOpt
.bFixedLen
),
53 aFieldSeps ( rOpt
.aFieldSeps
),
54 bMergeFieldSeps ( rOpt
.bMergeFieldSeps
),
55 bQuotedFieldAsText(rOpt
.bQuotedFieldAsText
),
56 bDetectSpecialNumber(rOpt
.bDetectSpecialNumber
),
57 cTextSep ( rOpt
.cTextSep
),
58 eCharSet ( rOpt
.eCharSet
),
60 bCharSetSystem ( rOpt
.bCharSetSystem
),
61 nStartRow ( rOpt
.nStartRow
),
62 nInfoCount ( rOpt
.nInfoCount
)
66 pColStart
= new sal_Int32
[nInfoCount
];
67 pColFormat
= new sal_uInt8
[nInfoCount
];
68 for (sal_uInt16 i
=0; i
<nInfoCount
; i
++)
70 pColStart
[i
] = rOpt
.pColStart
[i
];
71 pColFormat
[i
] = rOpt
.pColFormat
[i
];
81 ScAsciiOptions::~ScAsciiOptions()
87 void ScAsciiOptions::SetColInfo( sal_uInt16 nCount
, const sal_Int32
* pStart
, const sal_uInt8
* pFormat
)
96 pColStart
= new sal_Int32
[nInfoCount
];
97 pColFormat
= new sal_uInt8
[nInfoCount
];
98 for (sal_uInt16 i
=0; i
<nInfoCount
; i
++)
100 pColStart
[i
] = pStart
[i
];
101 pColFormat
[i
] = pFormat
[i
];
111 void ScAsciiOptions::SetColumnInfo( const ScCsvExpDataVec
& rDataVec
)
118 nInfoCount
= static_cast< sal_uInt16
>( rDataVec
.size() );
121 pColStart
= new sal_Int32
[ nInfoCount
];
122 pColFormat
= new sal_uInt8
[ nInfoCount
];
123 for( sal_uInt16 nIx
= 0; nIx
< nInfoCount
; ++nIx
)
125 pColStart
[ nIx
] = rDataVec
[ nIx
].mnIndex
;
126 pColFormat
[ nIx
] = rDataVec
[ nIx
].mnType
;
131 ScAsciiOptions
& ScAsciiOptions::operator=( const ScAsciiOptions
& rCpy
)
133 SetColInfo( rCpy
.nInfoCount
, rCpy
.pColStart
, rCpy
.pColFormat
);
135 bFixedLen
= rCpy
.bFixedLen
;
136 aFieldSeps
= rCpy
.aFieldSeps
;
137 bMergeFieldSeps
= rCpy
.bMergeFieldSeps
;
138 bQuotedFieldAsText
= rCpy
.bQuotedFieldAsText
;
139 cTextSep
= rCpy
.cTextSep
;
140 eCharSet
= rCpy
.eCharSet
;
141 bCharSetSystem
= rCpy
.bCharSetSystem
;
142 nStartRow
= rCpy
.nStartRow
;
147 bool ScAsciiOptions::operator==( const ScAsciiOptions
& rCmp
) const
149 if ( bFixedLen
== rCmp
.bFixedLen
&&
150 aFieldSeps
== rCmp
.aFieldSeps
&&
151 bMergeFieldSeps
== rCmp
.bMergeFieldSeps
&&
152 bQuotedFieldAsText
== rCmp
.bQuotedFieldAsText
&&
153 cTextSep
== rCmp
.cTextSep
&&
154 eCharSet
== rCmp
.eCharSet
&&
155 bCharSetSystem
== rCmp
.bCharSetSystem
&&
156 nStartRow
== rCmp
.nStartRow
&&
157 nInfoCount
== rCmp
.nInfoCount
)
159 OSL_ENSURE( !nInfoCount
|| (pColStart
&& pColFormat
&& rCmp
.pColStart
&& rCmp
.pColFormat
),
160 "NULL pointer in ScAsciiOptions::operator==() column info" );
161 for (sal_uInt16 i
=0; i
<nInfoCount
; i
++)
162 if ( pColStart
[i
] != rCmp
.pColStart
[i
] ||
163 pColFormat
[i
] != rCmp
.pColFormat
[i
] )
171 static OUString
lcl_decodeSepString( const OUString
& rSepNums
, bool & o_bMergeFieldSeps
)
174 sal_Int32 nSub
= comphelper::string::getTokenCount( rSepNums
, '/');
175 for (sal_Int32 i
=0; i
<nSub
; ++i
)
177 OUString aCode
= rSepNums
.getToken( i
, '/' );
178 if ( aCode
== pStrMrg
)
179 o_bMergeFieldSeps
= true;
182 sal_Int32 nVal
= aCode
.toInt32();
184 aFieldSeps
+= OUString((sal_Unicode
) nVal
);
190 // The options string must not contain semicolons (because of the pick list),
191 // use comma as separator.
193 void ScAsciiOptions::ReadFromString( const OUString
& rString
)
195 sal_Int32 nCount
= comphelper::string::getTokenCount(rString
, ',');
201 bFixedLen
= bMergeFieldSeps
= false;
203 aToken
= rString
.getToken(0,',');
204 if ( aToken
== pStrFix
)
206 aFieldSeps
= lcl_decodeSepString( aToken
, bMergeFieldSeps
);
212 aToken
= rString
.getToken(1,',');
213 sal_Int32 nVal
= aToken
.toInt32();
214 cTextSep
= (sal_Unicode
) nVal
;
220 aToken
= rString
.getToken(2,',');
221 eCharSet
= ScGlobal::GetCharsetValue( aToken
);
224 // Number of start row.
227 aToken
= rString
.getToken(3,',');
228 nStartRow
= aToken
.toInt32();
237 aToken
= rString
.getToken(4,',');
238 sal_Int32 nSub
= comphelper::string::getTokenCount(aToken
, '/');
239 nInfoCount
= nSub
/ 2;
242 pColStart
= new sal_Int32
[nInfoCount
];
243 pColFormat
= new sal_uInt8
[nInfoCount
];
244 for (sal_uInt16 nInfo
=0; nInfo
<nInfoCount
; nInfo
++)
246 pColStart
[nInfo
] = (sal_Int32
) aToken
.getToken( 2*nInfo
, '/' ).toInt32();
247 pColFormat
[nInfo
] = (sal_uInt8
) aToken
.getToken( 2*nInfo
+1, '/' ).toInt32();
260 aToken
= rString
.getToken(5, ',');
261 eLang
= static_cast<LanguageType
>(aToken
.toInt32());
264 // Import quoted field as text.
267 aToken
= rString
.getToken(6, ',');
268 bQuotedFieldAsText
= aToken
== "true";
271 // Detect special numbers.
274 aToken
= rString
.getToken(7, ',');
275 bDetectSpecialNumber
= aToken
== "true";
278 bDetectSpecialNumber
= true; // default of versions that didn't add the parameter
280 // 9th token is used for "Save as shown" in export options
281 // 10th token is used for "Save cell formulas" in export options
284 OUString
ScAsciiOptions::WriteToString() const
291 else if ( aFieldSeps
.isEmpty() )
295 sal_Int32 nLen
= aFieldSeps
.getLength();
296 for (sal_Int32 i
=0; i
<nLen
; i
++)
300 aOutStr
+= OUString::number(aFieldSeps
[i
]);
302 if ( bMergeFieldSeps
)
310 aOutStr
+= "," + OUString::number(cTextSep
) + ",";
313 if ( bCharSetSystem
) // force "SYSTEM"
314 aOutStr
+= ScGlobal::GetCharsetString( RTL_TEXTENCODING_DONTKNOW
);
316 aOutStr
+= ScGlobal::GetCharsetString( eCharSet
);
318 // Number of start row.
319 aOutStr
+= "," + OUString::number(nStartRow
) + ",";
322 OSL_ENSURE( !nInfoCount
|| (pColStart
&& pColFormat
), "NULL pointer in ScAsciiOptions column info" );
323 for (sal_uInt16 nInfo
=0; nInfo
<nInfoCount
; nInfo
++)
327 aOutStr
+= OUString::number(pColStart
[nInfo
]) +
329 OUString::number(pColFormat
[nInfo
]);
332 // #i112025# the options string is used in macros and linked sheets,
333 // so new options must be added at the end, to remain compatible
337 OUString::number(eLang
) + "," +
338 // Import quoted field as text.
339 OUString::boolean( bQuotedFieldAsText
) + "," +
340 // Detect special numbers.
341 OUString::boolean( bDetectSpecialNumber
);
343 // 9th token is used for "Save as shown" in export options
344 // 10th token is used for "Save cell formulas" in export options
350 sal_Unicode
ScAsciiOptions::GetWeightedFieldSep( const OUString
& rFieldSeps
, bool bDecodeNumbers
)
352 bool bMergeFieldSeps
= false;
353 OUString
aFieldSeps( bDecodeNumbers
? lcl_decodeSepString( rFieldSeps
, bMergeFieldSeps
) : rFieldSeps
);
354 if (aFieldSeps
.isEmpty())
358 else if (aFieldSeps
.getLength() == 1)
359 return aFieldSeps
[0];
362 // There can be only one separator for output. See also fdo#53449
363 if (aFieldSeps
.indexOf(',') != -1)
365 else if (aFieldSeps
.indexOf('\t') != -1)
367 else if (aFieldSeps
.indexOf(';') != -1)
369 else if (aFieldSeps
.indexOf(' ') != -1)
372 return aFieldSeps
[0];
376 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */