| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| |
| |
| |
| #include "global.hxx" |
| #include "scresid.hxx" |
| #include "impex.hxx" |
| #include "asciiopt.hxx" |
| #include "asciiopt.hrc" |
| #include <tools/debug.hxx> |
| #include <rtl/tencinfo.h> |
| #include <unotools/transliterationwrapper.hxx> |
| // ause |
| #include "editutil.hxx" |
| |
| // ============================================================================ |
| |
| static const sal_Char __FAR_DATA pStrFix[] = "FIX"; |
| static const sal_Char __FAR_DATA pStrMrg[] = "MRG"; |
| |
| |
| // ============================================================================ |
| |
| ScAsciiOptions::ScAsciiOptions() : |
| bFixedLen ( sal_False ), |
| aFieldSeps ( ';' ), |
| bMergeFieldSeps ( sal_False ), |
| bQuotedFieldAsText(false), |
| bDetectSpecialNumber(false), |
| cTextSep ( cDefaultTextSep ), |
| eCharSet ( gsl_getSystemTextEncoding() ), |
| eLang ( LANGUAGE_SYSTEM ), |
| bCharSetSystem ( sal_False ), |
| nStartRow ( 1 ), |
| nInfoCount ( 0 ), |
| pColStart ( NULL ), |
| pColFormat ( NULL ) |
| { |
| } |
| |
| |
| ScAsciiOptions::ScAsciiOptions(const ScAsciiOptions& rOpt) : |
| bFixedLen ( rOpt.bFixedLen ), |
| aFieldSeps ( rOpt.aFieldSeps ), |
| bMergeFieldSeps ( rOpt.bMergeFieldSeps ), |
| bQuotedFieldAsText(rOpt.bQuotedFieldAsText), |
| bDetectSpecialNumber(rOpt.bDetectSpecialNumber), |
| cTextSep ( rOpt.cTextSep ), |
| eCharSet ( rOpt.eCharSet ), |
| eLang ( rOpt.eLang ), |
| bCharSetSystem ( rOpt.bCharSetSystem ), |
| nStartRow ( rOpt.nStartRow ), |
| nInfoCount ( rOpt.nInfoCount ) |
| { |
| if (nInfoCount) |
| { |
| pColStart = new xub_StrLen[nInfoCount]; |
| pColFormat = new sal_uInt8[nInfoCount]; |
| for (sal_uInt16 i=0; i<nInfoCount; i++) |
| { |
| pColStart[i] = rOpt.pColStart[i]; |
| pColFormat[i] = rOpt.pColFormat[i]; |
| } |
| } |
| else |
| { |
| pColStart = NULL; |
| pColFormat = NULL; |
| } |
| } |
| |
| |
| ScAsciiOptions::~ScAsciiOptions() |
| { |
| delete[] pColStart; |
| delete[] pColFormat; |
| } |
| |
| |
| void ScAsciiOptions::SetColInfo( sal_uInt16 nCount, const xub_StrLen* pStart, const sal_uInt8* pFormat ) |
| { |
| delete[] pColStart; |
| delete[] pColFormat; |
| |
| nInfoCount = nCount; |
| |
| if (nInfoCount) |
| { |
| pColStart = new xub_StrLen[nInfoCount]; |
| pColFormat = new sal_uInt8[nInfoCount]; |
| for (sal_uInt16 i=0; i<nInfoCount; i++) |
| { |
| pColStart[i] = pStart[i]; |
| pColFormat[i] = pFormat[i]; |
| } |
| } |
| else |
| { |
| pColStart = NULL; |
| pColFormat = NULL; |
| } |
| } |
| |
| |
| void ScAsciiOptions::SetColumnInfo( const ScCsvExpDataVec& rDataVec ) |
| { |
| delete[] pColStart; |
| pColStart = NULL; |
| delete[] pColFormat; |
| pColFormat = NULL; |
| |
| nInfoCount = static_cast< sal_uInt16 >( rDataVec.size() ); |
| if( nInfoCount ) |
| { |
| pColStart = new xub_StrLen[ nInfoCount ]; |
| pColFormat = new sal_uInt8[ nInfoCount ]; |
| for( sal_uInt16 nIx = 0; nIx < nInfoCount; ++nIx ) |
| { |
| pColStart[ nIx ] = rDataVec[ nIx ].mnIndex; |
| pColFormat[ nIx ] = rDataVec[ nIx ].mnType; |
| } |
| } |
| } |
| |
| |
| ScAsciiOptions& ScAsciiOptions::operator=( const ScAsciiOptions& rCpy ) |
| { |
| SetColInfo( rCpy.nInfoCount, rCpy.pColStart, rCpy.pColFormat ); |
| |
| bFixedLen = rCpy.bFixedLen; |
| aFieldSeps = rCpy.aFieldSeps; |
| bMergeFieldSeps = rCpy.bMergeFieldSeps; |
| bQuotedFieldAsText = rCpy.bQuotedFieldAsText; |
| cTextSep = rCpy.cTextSep; |
| eCharSet = rCpy.eCharSet; |
| bCharSetSystem = rCpy.bCharSetSystem; |
| nStartRow = rCpy.nStartRow; |
| |
| return *this; |
| } |
| |
| |
| sal_Bool ScAsciiOptions::operator==( const ScAsciiOptions& rCmp ) const |
| { |
| if ( bFixedLen == rCmp.bFixedLen && |
| aFieldSeps == rCmp.aFieldSeps && |
| bMergeFieldSeps == rCmp.bMergeFieldSeps && |
| bQuotedFieldAsText == rCmp.bQuotedFieldAsText && |
| cTextSep == rCmp.cTextSep && |
| eCharSet == rCmp.eCharSet && |
| bCharSetSystem == rCmp.bCharSetSystem && |
| nStartRow == rCmp.nStartRow && |
| nInfoCount == rCmp.nInfoCount ) |
| { |
| DBG_ASSERT( !nInfoCount || (pColStart && pColFormat && rCmp.pColStart && rCmp.pColFormat), |
| "0-Zeiger in ScAsciiOptions" ); |
| for (sal_uInt16 i=0; i<nInfoCount; i++) |
| if ( pColStart[i] != rCmp.pColStart[i] || |
| pColFormat[i] != rCmp.pColFormat[i] ) |
| return sal_False; |
| |
| return sal_True; |
| } |
| return sal_False; |
| } |
| |
| // |
| // Der Options-String darf kein Semikolon mehr enthalten (wegen Pickliste) |
| // darum ab Version 336 Komma stattdessen |
| // |
| |
| |
| void ScAsciiOptions::ReadFromString( const String& rString ) |
| { |
| xub_StrLen nCount = rString.GetTokenCount(','); |
| String aToken; |
| xub_StrLen nSub; |
| xub_StrLen i; |
| |
| // |
| // Feld-Trenner |
| // |
| |
| if ( nCount >= 1 ) |
| { |
| bFixedLen = bMergeFieldSeps = sal_False; |
| aFieldSeps.Erase(); |
| |
| aToken = rString.GetToken(0,','); |
| if ( aToken.EqualsAscii(pStrFix) ) |
| bFixedLen = sal_True; |
| nSub = aToken.GetTokenCount('/'); |
| for ( i=0; i<nSub; i++ ) |
| { |
| String aCode = aToken.GetToken( i, '/' ); |
| if ( aCode.EqualsAscii(pStrMrg) ) |
| bMergeFieldSeps = sal_True; |
| else |
| { |
| sal_Int32 nVal = aCode.ToInt32(); |
| if ( nVal ) |
| aFieldSeps += (sal_Unicode) nVal; |
| } |
| } |
| } |
| |
| // |
| // Text-Trenner |
| // |
| |
| if ( nCount >= 2 ) |
| { |
| aToken = rString.GetToken(1,','); |
| sal_Int32 nVal = aToken.ToInt32(); |
| cTextSep = (sal_Unicode) nVal; |
| } |
| |
| // |
| // Zeichensatz |
| // |
| |
| if ( nCount >= 3 ) |
| { |
| aToken = rString.GetToken(2,','); |
| eCharSet = ScGlobal::GetCharsetValue( aToken ); |
| } |
| |
| // |
| // Startzeile |
| // |
| |
| if ( nCount >= 4 ) |
| { |
| aToken = rString.GetToken(3,','); |
| nStartRow = aToken.ToInt32(); |
| } |
| |
| // |
| // Spalten-Infos |
| // |
| |
| if ( nCount >= 5 ) |
| { |
| delete[] pColStart; |
| delete[] pColFormat; |
| |
| aToken = rString.GetToken(4,','); |
| nSub = aToken.GetTokenCount('/'); |
| nInfoCount = nSub / 2; |
| if (nInfoCount) |
| { |
| pColStart = new xub_StrLen[nInfoCount]; |
| pColFormat = new sal_uInt8[nInfoCount]; |
| for (sal_uInt16 nInfo=0; nInfo<nInfoCount; nInfo++) |
| { |
| pColStart[nInfo] = (xub_StrLen) aToken.GetToken( 2*nInfo, '/' ).ToInt32(); |
| pColFormat[nInfo] = (sal_uInt8) aToken.GetToken( 2*nInfo+1, '/' ).ToInt32(); |
| } |
| } |
| else |
| { |
| pColStart = NULL; |
| pColFormat = NULL; |
| } |
| } |
| |
| // Language |
| if (nCount >= 6) |
| { |
| aToken = rString.GetToken(5, ','); |
| eLang = static_cast<LanguageType>(aToken.ToInt32()); |
| } |
| |
| // Import quoted field as text. |
| if (nCount >= 7) |
| { |
| aToken = rString.GetToken(6, ','); |
| bQuotedFieldAsText = aToken.EqualsAscii("true") ? true : false; |
| } |
| |
| // Detect special nubmers. |
| if (nCount >= 8) |
| { |
| aToken = rString.GetToken(7, ','); |
| bDetectSpecialNumber = aToken.EqualsAscii("true") ? true : false; |
| } |
| else |
| bDetectSpecialNumber = sal_True; // default of versions that didn't add the parameter |
| |
| // 9th token is used for "Save as shown" in export options |
| } |
| |
| |
| String ScAsciiOptions::WriteToString() const |
| { |
| String aOutStr; |
| |
| // |
| // Feld-Trenner |
| // |
| |
| if ( bFixedLen ) |
| aOutStr.AppendAscii(pStrFix); |
| else if ( !aFieldSeps.Len() ) |
| aOutStr += '0'; |
| else |
| { |
| xub_StrLen nLen = aFieldSeps.Len(); |
| for (xub_StrLen i=0; i<nLen; i++) |
| { |
| if (i) |
| aOutStr += '/'; |
| aOutStr += String::CreateFromInt32(aFieldSeps.GetChar(i)); |
| } |
| if ( bMergeFieldSeps ) |
| { |
| aOutStr += '/'; |
| aOutStr.AppendAscii(pStrMrg); |
| } |
| } |
| |
| aOutStr += ','; // Token-Ende |
| |
| // |
| // Text-Trenner |
| // |
| |
| aOutStr += String::CreateFromInt32(cTextSep); |
| aOutStr += ','; // Token-Ende |
| |
| // |
| // Zeichensatz |
| // |
| |
| if ( bCharSetSystem ) // force "SYSTEM" |
| aOutStr += ScGlobal::GetCharsetString( RTL_TEXTENCODING_DONTKNOW ); |
| else |
| aOutStr += ScGlobal::GetCharsetString( eCharSet ); |
| aOutStr += ','; // Token-Ende |
| |
| // |
| // Startzeile |
| // |
| |
| aOutStr += String::CreateFromInt32(nStartRow); |
| aOutStr += ','; // Token-Ende |
| |
| // |
| // Spalten-Infos |
| // |
| |
| DBG_ASSERT( !nInfoCount || (pColStart && pColFormat), "0-Zeiger in ScAsciiOptions" ); |
| for (sal_uInt16 nInfo=0; nInfo<nInfoCount; nInfo++) |
| { |
| if (nInfo) |
| aOutStr += '/'; |
| aOutStr += String::CreateFromInt32(pColStart[nInfo]); |
| aOutStr += '/'; |
| aOutStr += String::CreateFromInt32(pColFormat[nInfo]); |
| } |
| |
| // #i112025# the options string is used in macros and linked sheets, |
| // so new options must be added at the end, to remain compatible |
| |
| aOutStr += ','; |
| |
| // Language |
| aOutStr += String::CreateFromInt32(eLang); |
| aOutStr += ','; |
| |
| // Import quoted field as text. |
| aOutStr += String::CreateFromAscii(bQuotedFieldAsText ? "true" : "false"); |
| aOutStr += ','; |
| |
| // Detect special nubmers. |
| aOutStr += String::CreateFromAscii(bDetectSpecialNumber ? "true" : "false"); |
| |
| // 9th token is used for "Save as shown" in export options |
| |
| return aOutStr; |
| } |
| |
| #if 0 |
| // Code, um die Spalten-Liste aus einem Excel-kompatiblen String zu erzeugen: |
| // (im Moment nicht benutzt) |
| |
| void ScAsciiOptions::InterpretColumnList( const String& rString ) |
| { |
| // Eingabe ist 1-basiert, pColStart fuer FixedLen ist 0-basiert |
| |
| // Kommas durch Semikolon ersetzen |
| |
| String aSemiStr = rString; |
| sal_uInt16 nPos = 0; |
| do |
| nPos = aSemiStr.SearchAndReplace( ',', ';', nPos ); |
| while ( nPos != STRING_NOTFOUND ); |
| |
| // Eintraege sortieren |
| |
| sal_uInt16 nCount = aSemiStr.GetTokenCount(); |
| sal_uInt16* pTemp = new sal_uInt16[nCount+1]; |
| pTemp[0] = 1; // erste Spalte faengt immer bei 1 an |
| sal_uInt16 nFound = 1; |
| sal_uInt16 i,j; |
| for (i=0; i<nCount; i++) |
| { |
| sal_uInt16 nVal = (sal_uInt16) aSemiStr.GetToken(i); |
| if (nVal) |
| { |
| sal_Bool bThere = sal_False; |
| nPos = 0; |
| for (j=0; j<nFound; j++) |
| { |
| if ( pTemp[j] == nVal ) |
| bThere = sal_True; |
| else if ( pTemp[j] < nVal ) |
| nPos = j+1; |
| } |
| if ( !bThere ) |
| { |
| if ( nPos < nFound ) |
| memmove( &pTemp[nPos+1], &pTemp[nPos], (nFound-nPos)*sizeof(sal_uInt16) ); |
| pTemp[nPos] = nVal; |
| ++nFound; |
| } |
| } |
| } |
| |
| // Eintraege uebernehmen |
| |
| delete[] pColStart; |
| delete[] pColFormat; |
| nInfoCount = nFound; |
| if (nInfoCount) |
| { |
| pColStart = new sal_uInt16[nInfoCount]; |
| pColFormat = new sal_uInt8[nInfoCount]; |
| for (i=0; i<nInfoCount; i++) |
| { |
| pColStart[i] = pTemp[i] - 1; |
| pColFormat[i] = SC_COL_STANDARD; |
| } |
| } |
| else |
| { |
| pColStart = NULL; |
| pColFormat = NULL; |
| } |
| |
| bFixedLen = sal_True; // sonst macht's keinen Sinn |
| |
| // aufraeumen |
| |
| delete[] pTemp; |
| } |
| #endif |
| |