xref: /trunk/main/sc/source/ui/dbgui/scuiasciiopt.cxx (revision b77af630)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scui.hxx"
26 
27 #undef SC_DLLIMPLEMENTATION
28 
29 #include "global.hxx"
30 #include "scresid.hxx"
31 #include "impex.hxx"
32 #include "scuiasciiopt.hxx"
33 #include "asciiopt.hrc"
34 #include <tools/debug.hxx>
35 #include <rtl/tencinfo.h>
36 #include <unotools/transliterationwrapper.hxx>
37 // ause
38 #include "editutil.hxx"
39 
40 #include <optutil.hxx>
41 #include <com/sun/star/uno/Any.hxx>
42 #include <com/sun/star/uno/Sequence.hxx>
43 #include "miscuno.hxx"
44 
45 //! TODO make dynamic
46 const SCSIZE ASCIIDLG_MAXROWS                = MAXROWCOUNT;
47 
48 
49 using namespace rtl;
50 using namespace com::sun::star::uno;
51 
52 // Defines - CSV Import Preserve Options
53 #define FIXED_WIDTH         "FixedWidth"
54 #define FROM_ROW            "FromRow"
55 #define CHAR_SET            "CharSet"
56 #define SEPARATORS          "Separators"
57 #define TEXT_SEPARATORS     "TextSeparators"
58 #define MERGE_DELIMITERS    "MergeDelimiters"
59 #define QUOTED_AS_TEXT      "QuotedFieldAsText"
60 #define DETECT_SPECIAL_NUM  "DetectSpecialNumbers"
61 #define LANGUAGE            "Language"
62 #define SEP_PATH            "Office.Calc/Dialogs/CSVImport"
63 
64 // ============================================================================
65 
66 void lcl_FillCombo( ComboBox& rCombo, const String& rList, sal_Unicode cSelect )
67 {
68 	xub_StrLen i;
69 	xub_StrLen nCount = rList.GetTokenCount('\t');
70 	for ( i=0; i<nCount; i+=2 )
71 		rCombo.InsertEntry( rList.GetToken(i,'\t') );
72 
73 	if ( cSelect )
74 	{
75 		String aStr;
76 		for ( i=0; i<nCount; i+=2 )
77 			if ( (sal_Unicode)rList.GetToken(i+1,'\t').ToInt32() == cSelect )
78 				aStr = rList.GetToken(i,'\t');
79 		if (!aStr.Len())
80 			aStr = cSelect;			// Ascii
81 
82 		rCombo.SetText(aStr);
83 	}
84 }
85 
86 sal_Unicode lcl_CharFromCombo( ComboBox& rCombo, const String& rList )
87 {
88 	sal_Unicode c = 0;
89 	String aStr = rCombo.GetText();
90 	if ( aStr.Len() )
91 	{
92 		xub_StrLen nCount = rList.GetTokenCount('\t');
93 		for ( xub_StrLen i=0; i<nCount; i+=2 )
94         {
95             if ( ScGlobal::GetpTransliteration()->isEqual( aStr, rList.GetToken(i,'\t') ) )//CHINA001 if ( ScGlobal::GetpTransliteration()->isEqual( aStr, rList.GetToken(i,'\t') ) )
96 				c = (sal_Unicode)rList.GetToken(i+1,'\t').ToInt32();
97         }
98         if (!c && aStr.Len())
99         {
100             sal_Unicode cFirst = aStr.GetChar( 0 );
101             // #i24235# first try the first character of the string directly
102             if( (aStr.Len() == 1) || (cFirst < '0') || (cFirst > '9') )
103                 c = cFirst;
104             else    // keep old behaviour for compatibility (i.e. "39" -> "'")
105                 c = (sal_Unicode) aStr.ToInt32();       // Ascii
106         }
107 	}
108 	return c;
109 }
110 
111 static void load_Separators( OUString &sFieldSeparators, OUString &sTextSeparators,
112                              bool &bMergeDelimiters, bool& bQuotedAsText, bool& bDetectSpecialNum,
113                              bool &bFixedWidth, sal_Int32 &nFromRow, sal_Int32 &nCharSet,
114                              sal_Int32& nLanguage )
115 {
116     Sequence<Any>aValues;
117     const Any *pProperties;
118     Sequence<OUString> aNames(9);
119     OUString* pNames = aNames.getArray();
120     ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) );
121 
122     pNames[0] = OUString::createFromAscii( MERGE_DELIMITERS );
123     pNames[1] = OUString::createFromAscii( SEPARATORS );
124     pNames[2] = OUString::createFromAscii( TEXT_SEPARATORS );
125     pNames[3] = OUString::createFromAscii( FIXED_WIDTH );
126     pNames[4] = OUString::createFromAscii( FROM_ROW );
127     pNames[5] = OUString::createFromAscii( CHAR_SET );
128     pNames[6] = OUString::createFromAscii( QUOTED_AS_TEXT );
129     pNames[7] = OUString::createFromAscii( DETECT_SPECIAL_NUM );
130     pNames[8] = OUString::createFromAscii( LANGUAGE );
131     aValues = aItem.GetProperties( aNames );
132     pProperties = aValues.getConstArray();
133     if( pProperties[1].hasValue() )
134         pProperties[1] >>= sFieldSeparators;
135 
136     if( pProperties[2].hasValue() )
137         pProperties[2] >>= sTextSeparators;
138 
139     if( pProperties[0].hasValue() )
140         bMergeDelimiters = ScUnoHelpFunctions::GetBoolFromAny( pProperties[0] );
141 
142     if( pProperties[3].hasValue() )
143         bFixedWidth = ScUnoHelpFunctions::GetBoolFromAny( pProperties[3] );
144 
145     if( pProperties[4].hasValue() )
146         pProperties[4] >>= nFromRow;
147 
148     if( pProperties[5].hasValue() )
149         pProperties[5] >>= nCharSet;
150 
151     if ( pProperties[6].hasValue() )
152         pProperties[6] >>= bQuotedAsText;
153 
154     if ( pProperties[7].hasValue() )
155         pProperties[7] >>= bDetectSpecialNum;
156 
157     if ( pProperties[8].hasValue() )
158         pProperties[8] >>= nLanguage;
159 }
160 
161 static void save_Separators(
162     String maSeparators, String maTxtSep, bool bMergeDelimiters, bool bQuotedAsText,
163     bool bDetectSpecialNum, bool bFixedWidth, sal_Int32 nFromRow, sal_Int32 nCharSet, sal_Int32 nLanguage )
164 {
165     OUString sFieldSeparators = OUString( maSeparators );
166     OUString sTextSeparators = OUString( maTxtSep );
167     Sequence<Any> aValues;
168     Any *pProperties;
169     Sequence<OUString> aNames(9);
170     OUString* pNames = aNames.getArray();
171     ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) );
172 
173     pNames[0] = OUString::createFromAscii( MERGE_DELIMITERS );
174     pNames[1] = OUString::createFromAscii( SEPARATORS );
175     pNames[2] = OUString::createFromAscii( TEXT_SEPARATORS );
176     pNames[3] = OUString::createFromAscii( FIXED_WIDTH );
177     pNames[4] = OUString::createFromAscii( FROM_ROW );
178     pNames[5] = OUString::createFromAscii( CHAR_SET );
179     pNames[6] = OUString::createFromAscii( QUOTED_AS_TEXT );
180     pNames[7] = OUString::createFromAscii( DETECT_SPECIAL_NUM );
181     pNames[8] = OUString::createFromAscii( LANGUAGE );
182     aValues = aItem.GetProperties( aNames );
183     pProperties = aValues.getArray();
184     pProperties[1] <<= sFieldSeparators;
185     pProperties[2] <<= sTextSeparators;
186     ScUnoHelpFunctions::SetBoolInAny( pProperties[0], bMergeDelimiters );
187     ScUnoHelpFunctions::SetBoolInAny( pProperties[3], bFixedWidth );
188     pProperties[4] <<= nFromRow;
189     pProperties[5] <<= nCharSet;
190     pProperties[6] <<= static_cast<sal_Bool>(bQuotedAsText);
191     pProperties[7] <<= static_cast<sal_Bool>(bDetectSpecialNum);
192     pProperties[8] <<= nLanguage;
193 
194     aItem.PutProperties(aNames, aValues);
195 }
196 
197 // ----------------------------------------------------------------------------
198 
199 ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName,
200                                     SvStream* pInStream, sal_Unicode cSep ) :
201 		ModalDialog	( pParent, ScResId( RID_SCDLG_ASCII ) ),
202         mpDatStream  ( pInStream ),
203         mnStreamPos( pInStream ? pInStream->Tell() : 0 ),
204 
205 		mpRowPosArray( NULL ),
206 		mnRowPosCount(0),
207 
208         aFlFieldOpt ( this, ScResId( FL_FIELDOPT ) ),
209 		aFtCharSet	( this, ScResId( FT_CHARSET ) ),
210 		aLbCharSet	( this, ScResId( LB_CHARSET ) ),
211         aFtCustomLang( this, ScResId( FT_CUSTOMLANG ) ),
212         aLbCustomLang( this, ScResId( LB_CUSTOMLANG ) ),
213 
214 		aFtRow		( this, ScResId( FT_AT_ROW	) ),
215 		aNfRow		( this,	ScResId( NF_AT_ROW	) ),
216 
217         aFlSepOpt   ( this, ScResId( FL_SEPOPT ) ),
218 		aRbFixed	( this, ScResId( RB_FIXED ) ),
219 		aRbSeparated( this, ScResId( RB_SEPARATED ) ),
220 
221 		aCkbTab		( this, ScResId( CKB_TAB ) ),
222 		aCkbSemicolon(this, ScResId( CKB_SEMICOLON ) ),
223 		aCkbComma	( this, ScResId( CKB_COMMA	) ),
224 		aCkbSpace	( this,	ScResId( CKB_SPACE	 ) ),
225 		aCkbOther	( this, ScResId( CKB_OTHER ) ),
226 		aEdOther	( this, ScResId( ED_OTHER ) ),
227 		aCkbAsOnce	( this, ScResId( CB_ASONCE) ),
228         aFlOtherOpt ( this, ScResId( FL_OTHER_OPTIONS ) ),
229 
230 		aFtTextSep	( this, ScResId( FT_TEXTSEP ) ),
231 		aCbTextSep	( this, ScResId( CB_TEXTSEP ) ),
232 
233         aCkbQuotedAsText( this, ScResId(CB_QUOTED_AS_TEXT) ),
234         aCkbDetectNumber( this, ScResId(CB_DETECT_SPECIAL_NUMBER) ),
235 
236         aFlWidth    ( this, ScResId( FL_WIDTH ) ),
237 		aFtType		( this, ScResId( FT_TYPE ) ),
238 		aLbType		( this, ScResId( LB_TYPE1 ) ),
239 
240         maTableBox  ( this, ScResId( CTR_TABLEBOX ) ),
241 
242 		aBtnOk		( this, ScResId( BTN_OK ) ),
243 		aBtnCancel	( this, ScResId( BTN_CANCEL ) ),
244 		aBtnHelp	( this, ScResId( BTN_HELP ) ),
245 
246 		aCharSetUser( ScResId( SCSTR_CHARSET_USER ) ),
247 		aColumnUser	( ScResId( SCSTR_COLUMN_USER ) ),
248 		aTextSepList( ScResId( SCSTR_TEXTSEP ) ),
249         mcTextSep   ( ScAsciiOptions::cDefaultTextSep ),
250         maStrTextToColumns( ScResId( STR_TEXTTOCOLUMNS ) ),
251         mbFileImport(true)
252 {
253 	FreeResource();
254     mbFileImport = aDatName.Len() > 0;
255 
256 	String aName = GetText();
257     // aDatName is empty if invoked during paste from clipboard.
258     if (mbFileImport)
259     {
260         aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" - ["));
261         aName += aDatName;
262         aName += ']';
263     }
264 	SetText( aName );
265 
266     OUString sFieldSeparators;
267     OUString sTextSeparators;
268     bool bMergeDelimiters = false;
269     bool bFixedWidth = false;
270     bool bQuotedFieldAsText = false;
271     bool bDetectSpecialNum = false;
272     sal_Int32 nFromRow = 1;
273     sal_Int32 nCharSet = -1;
274     sal_Int32 nLanguage = 0;
275     if (mbFileImport)
276         // load separators only when importing csv files.
277         load_Separators (sFieldSeparators, sTextSeparators, bMergeDelimiters,
278                          bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow, nCharSet, nLanguage);
279     else
280     {
281         // #i115474# otherwise use sensible defaults
282         sFieldSeparators = OUString( cSep );
283         sTextSeparators = OUString( ScAsciiOptions::cDefaultTextSep );
284     }
285     maFieldSeparators = String(sFieldSeparators);
286 
287     if( bMergeDelimiters )
288         aCkbAsOnce.Check();
289     if (bQuotedFieldAsText)
290         aCkbQuotedAsText.Check();
291     if (bDetectSpecialNum)
292         aCkbDetectNumber.Check();
293     if( bFixedWidth )
294         aRbFixed.Check();
295     if( nFromRow != 1 )
296         aNfRow.SetValue( nFromRow );
297 
298     ByteString bString(maFieldSeparators,RTL_TEXTENCODING_MS_1252);
299     const sal_Char *aSep = bString.GetBuffer();
300     int len = maFieldSeparators.Len();
301     for (int i = 0; i < len; ++i)
302     {
303         switch( aSep[i] )
304         {
305             case '\t':  aCkbTab.Check();        break;
306             case ';':   aCkbSemicolon.Check();  break;
307             case ',':   aCkbComma.Check();      break;
308             case ' ':   aCkbSpace.Check();      break;
309             default:
310                 aCkbOther.Check();
311                 aEdOther.SetText( aEdOther.GetText() + OUString( aSep[i] ) );
312         }
313     }
314 
315     // Get Separators from the dialog
316     maFieldSeparators = GetSeparators();
317 
318     // Clipboard is always Unicode, else detect.
319     rtl_TextEncoding ePreselectUnicode = (mbFileImport ?
320             RTL_TEXTENCODING_DONTKNOW : RTL_TEXTENCODING_UNICODE);
321 	// Sniff for Unicode / not
322     if( ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW && mpDatStream )
323 	{
324 		Seek( 0 );
325 		mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_DONTKNOW );
326 		sal_uLong nUniPos = mpDatStream->Tell();
327         switch (nUniPos)
328         {
329             case 2:
330                 ePreselectUnicode = RTL_TEXTENCODING_UNICODE;   // UTF-16
331                 break;
332             case 3:
333                 ePreselectUnicode = RTL_TEXTENCODING_UTF8;      // UTF-8
334                 break;
335             case 0:
336                 {
337                     sal_uInt16 n;
338                     *mpDatStream >> n;
339                     // Assume that normal ASCII/ANSI/ISO/etc. text doesn't start with
340                     // control characters except CR,LF,TAB
341                     if ( (n & 0xff00) < 0x2000 )
342                     {
343                         switch ( n & 0xff00 )
344                         {
345                             case 0x0900 :
346                             case 0x0a00 :
347                             case 0x0d00 :
348                                 break;
349                             default:
350                                 ePreselectUnicode = RTL_TEXTENCODING_UNICODE;   // UTF-16
351                         }
352                     }
353                     mpDatStream->Seek(0);
354                 }
355                 break;
356             default:
357                 ;   // nothing
358         }
359 		mnStreamPos = mpDatStream->Tell();
360 	}
361 
362     aNfRow.SetModifyHdl( LINK( this, ScImportAsciiDlg, FirstRowHdl ) );
363 
364     // *** Separator characters ***
365     lcl_FillCombo( aCbTextSep, aTextSepList, mcTextSep );
366     aCbTextSep.SetText( sTextSeparators );
367 
368     Link aSeparatorHdl =LINK( this, ScImportAsciiDlg, SeparatorHdl );
369     aCbTextSep.SetSelectHdl( aSeparatorHdl );
370     aCbTextSep.SetModifyHdl( aSeparatorHdl );
371     aCkbTab.SetClickHdl( aSeparatorHdl );
372     aCkbSemicolon.SetClickHdl( aSeparatorHdl );
373     aCkbComma.SetClickHdl( aSeparatorHdl );
374     aCkbAsOnce.SetClickHdl( aSeparatorHdl );
375     aCkbQuotedAsText.SetClickHdl( aSeparatorHdl );
376     aCkbDetectNumber.SetClickHdl( aSeparatorHdl );
377     aCkbSpace.SetClickHdl( aSeparatorHdl );
378     aCkbOther.SetClickHdl( aSeparatorHdl );
379     aEdOther.SetModifyHdl( aSeparatorHdl );
380 
381     // *** text encoding ListBox ***
382 	// all encodings allowed, including Unicode, but subsets are excluded
383 	aLbCharSet.FillFromTextEncodingTable( sal_True );
384 	// Insert one "SYSTEM" entry for compatibility in AsciiOptions and system
385 	// independent document linkage.
386 	aLbCharSet.InsertTextEncoding( RTL_TEXTENCODING_DONTKNOW, aCharSetUser );
387 	aLbCharSet.SelectTextEncoding( ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW ?
388             gsl_getSystemTextEncoding() : ePreselectUnicode );
389 
390     if( nCharSet >= 0 && ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW )
391         aLbCharSet.SelectEntryPos( static_cast<sal_uInt16>(nCharSet) );
392 
393     SetSelectedCharSet();
394 	aLbCharSet.SetSelectHdl( LINK( this, ScImportAsciiDlg, CharSetHdl ) );
395 
396     aLbCustomLang.SetLanguageList(
397         LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, false, false);
398     aLbCustomLang.InsertLanguage(LANGUAGE_SYSTEM);
399     aLbCustomLang.SelectLanguage(static_cast<LanguageType>(nLanguage), true);
400 
401     // *** column type ListBox ***
402 	xub_StrLen nCount = aColumnUser.GetTokenCount();
403 	for (xub_StrLen i=0; i<nCount; i++)
404         aLbType.InsertEntry( aColumnUser.GetToken( i ) );
405 
406     aLbType.SetSelectHdl( LINK( this, ScImportAsciiDlg, LbColTypeHdl ) );
407     aFtType.Disable();
408     aLbType.Disable();
409 
410     // *** table box preview ***
411     maTableBox.SetUpdateTextHdl( LINK( this, ScImportAsciiDlg, UpdateTextHdl ) );
412     maTableBox.InitTypes( aLbType );
413     maTableBox.SetColTypeHdl( LINK( this, ScImportAsciiDlg, ColTypeHdl ) );
414 
415     aRbSeparated.SetClickHdl( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
416     aRbFixed.SetClickHdl( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
417 
418     SetupSeparatorCtrls();
419     RbSepFixHdl( &aRbFixed );
420 
421 	UpdateVertical();
422 
423     maTableBox.Execute( CSVCMD_NEWCELLTEXTS );
424 
425 	aEdOther.SetAccessibleName(aCkbOther.GetText());
426 	aEdOther.SetAccessibleRelationLabeledBy(&aCkbOther);
427 }
428 
429 
430 ScImportAsciiDlg::~ScImportAsciiDlg()
431 {
432 	delete[] mpRowPosArray;
433 }
434 
435 
436 // ----------------------------------------------------------------------------
437 
438 bool ScImportAsciiDlg::GetLine( sal_uLong nLine, String &rText )
439 {
440     if (nLine >= ASCIIDLG_MAXROWS || !mpDatStream)
441         return false;
442 
443     bool bRet = true;
444     bool bFixed = aRbFixed.IsChecked();
445 
446     if (!mpRowPosArray)
447         mpRowPosArray = new sal_uLong[ASCIIDLG_MAXROWS + 2];
448 
449     if (!mnRowPosCount) // complete re-fresh
450     {
451         memset( mpRowPosArray, 0, sizeof(mpRowPosArray[0]) * (ASCIIDLG_MAXROWS+2));
452 
453         Seek(0);
454         mpDatStream->StartReadingUnicodeText( mpDatStream->GetStreamCharSet() );
455 
456         mnStreamPos = mpDatStream->Tell();
457         mpRowPosArray[mnRowPosCount] = mnStreamPos;
458     }
459 
460     if (nLine >= mnRowPosCount)
461     {
462         // need to work out some more line information
463         do
464         {
465             if (!Seek( mpRowPosArray[mnRowPosCount]) ||
466                     mpDatStream->GetError() != ERRCODE_NONE ||
467                     mpDatStream->IsEof())
468             {
469                 bRet = false;
470                 break;
471             }
472             mpDatStream->ReadCsvLine( rText, !bFixed, maFieldSeparators,
473                     mcTextSep);
474             mnStreamPos = mpDatStream->Tell();
475             mpRowPosArray[++mnRowPosCount] = mnStreamPos;
476         } while (nLine >= mnRowPosCount &&
477                 mpDatStream->GetError() == ERRCODE_NONE &&
478                 !mpDatStream->IsEof());
479         if (mpDatStream->IsEof() &&
480                 mnStreamPos == mpRowPosArray[mnRowPosCount-1])
481         {
482             // the very end, not even an empty line read
483             bRet = false;
484             --mnRowPosCount;
485         }
486     }
487     else
488     {
489         Seek( mpRowPosArray[nLine]);
490         mpDatStream->ReadCsvLine( rText, !bFixed, maFieldSeparators, mcTextSep);
491         mnStreamPos = mpDatStream->Tell();
492     }
493 
494     //	#107455# If the file content isn't unicode, ReadUniStringLine
495     //	may try to seek beyond the file's end and cause a CANTSEEK error
496     //	(depending on the stream type). The error code has to be cleared,
497     //	or further read operations (including non-unicode) will fail.
498     if ( mpDatStream->GetError() == ERRCODE_IO_CANTSEEK )
499         mpDatStream->ResetError();
500 
501     return bRet;
502 }
503 
504 
505 void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt )
506 {
507     rOpt.SetCharSet( meCharSet );
508     rOpt.SetCharSetSystem( mbCharSetSystem );
509     rOpt.SetLanguage(aLbCustomLang.GetSelectLanguage());
510     rOpt.SetFixedLen( aRbFixed.IsChecked() );
511     rOpt.SetStartRow( (long)aNfRow.GetValue() );
512     maTableBox.FillColumnData( rOpt );
513     if( aRbSeparated.IsChecked() )
514     {
515         rOpt.SetFieldSeps( GetSeparators() );
516         rOpt.SetMergeSeps( aCkbAsOnce.IsChecked() );
517         rOpt.SetTextSep( lcl_CharFromCombo( aCbTextSep, aTextSepList ) );
518     }
519 
520     rOpt.SetQuotedAsText(aCkbQuotedAsText.IsChecked());
521     rOpt.SetDetectSpecialNumber(aCkbDetectNumber.IsChecked());
522 }
523 
524 void ScImportAsciiDlg::SetTextToColumnsMode()
525 {
526     SetText( maStrTextToColumns );
527     aFtCharSet.Disable();
528     aLbCharSet.Disable();
529     aFtCustomLang.Disable();
530     aLbCustomLang.SelectLanguage(LANGUAGE_SYSTEM);
531     aLbCustomLang.Disable();
532     aFtRow.Disable();
533     aNfRow.Disable();
534 
535     // Quoted field as text option is not used for text-to-columns mode.
536     aCkbQuotedAsText.Check(false);
537     aCkbQuotedAsText.Disable();
538 
539     // Always detect special numbers for text-to-columns mode.
540     aCkbDetectNumber.Check();
541     aCkbDetectNumber.Disable();
542 }
543 
544 void ScImportAsciiDlg::SaveParameters()
545 {
546     if (!mbFileImport)
547         // We save parameters only for file import.
548         return;
549 
550     save_Separators( maFieldSeparators, aCbTextSep.GetText(), aCkbAsOnce.IsChecked(),
551                      aCkbQuotedAsText.IsChecked(), aCkbDetectNumber.IsChecked(),
552                      aRbFixed.IsChecked(),
553                      static_cast<sal_Int32>(aNfRow.GetValue()),
554                      static_cast<sal_Int32>(aLbCharSet.GetSelectEntryPos()),
555                      static_cast<sal_Int32>(aLbCustomLang.GetSelectLanguage()) );
556 }
557 
558 void ScImportAsciiDlg::SetSelectedCharSet()
559 {
560     meCharSet = aLbCharSet.GetSelectTextEncoding();
561     mbCharSetSystem = (meCharSet == RTL_TEXTENCODING_DONTKNOW);
562     if( mbCharSetSystem )
563         meCharSet = gsl_getSystemTextEncoding();
564 }
565 
566 String ScImportAsciiDlg::GetSeparators() const
567 {
568     String aSepChars;
569     if( aCkbTab.IsChecked() )
570         aSepChars += '\t';
571     if( aCkbSemicolon.IsChecked() )
572         aSepChars += ';';
573     if( aCkbComma.IsChecked() )
574         aSepChars += ',';
575     if( aCkbSpace.IsChecked() )
576         aSepChars += ' ';
577     if( aCkbOther.IsChecked() )
578         aSepChars += aEdOther.GetText();
579     return aSepChars;
580 }
581 
582 void ScImportAsciiDlg::SetupSeparatorCtrls()
583 {
584     sal_Bool bEnable = aRbSeparated.IsChecked();
585     aCkbTab.Enable( bEnable );
586     aCkbSemicolon.Enable( bEnable );
587     aCkbComma.Enable( bEnable );
588     aCkbSpace.Enable( bEnable );
589     aCkbOther.Enable( bEnable );
590     aEdOther.Enable( bEnable );
591     aCkbAsOnce.Enable( bEnable );
592     aFtTextSep.Enable( bEnable );
593     aCbTextSep.Enable( bEnable );
594 }
595 
596 void ScImportAsciiDlg::UpdateVertical()
597 {
598     mnRowPosCount = 0;
599     if (mpDatStream)
600         mpDatStream->SetStreamCharSet(meCharSet);
601 }
602 
603 
604 // ----------------------------------------------------------------------------
605 
606 IMPL_LINK( ScImportAsciiDlg, RbSepFixHdl, RadioButton*, pButton )
607 {
608     DBG_ASSERT( pButton, "ScImportAsciiDlg::RbSepFixHdl - missing sender" );
609 
610     if( (pButton == &aRbFixed) || (pButton == &aRbSeparated) )
611 	{
612         SetPointer( Pointer( POINTER_WAIT ) );
613         if( aRbFixed.IsChecked() )
614             maTableBox.SetFixedWidthMode();
615         else
616             maTableBox.SetSeparatorsMode();
617         SetPointer( Pointer( POINTER_ARROW ) );
618 
619         SetupSeparatorCtrls();
620 	}
621 	return 0;
622 }
623 
624 IMPL_LINK( ScImportAsciiDlg, SeparatorHdl, Control*, pCtrl )
625 {
626     DBG_ASSERT( pCtrl, "ScImportAsciiDlg::SeparatorHdl - missing sender" );
627     DBG_ASSERT( !aRbFixed.IsChecked(), "ScImportAsciiDlg::SeparatorHdl - not allowed in fixed width" );
628 
629     /*  #i41550# First update state of the controls. The GetSeparators()
630         function needs final state of the check boxes. */
631     if( (pCtrl == &aCkbOther) && aCkbOther.IsChecked() )
632         aEdOther.GrabFocus();
633     else if( pCtrl == &aEdOther )
634         aCkbOther.Check( aEdOther.GetText().Len() > 0 );
635 
636     String aOldFldSeps( maFieldSeparators);
637     maFieldSeparators = GetSeparators();
638     sal_Unicode cOldSep = mcTextSep;
639     mcTextSep = lcl_CharFromCombo( aCbTextSep, aTextSepList );
640     // Any separator changed may result in completely different lines due to
641     // embedded line breaks.
642     if (cOldSep != mcTextSep || aOldFldSeps != maFieldSeparators)
643         UpdateVertical();
644 
645     maTableBox.Execute( CSVCMD_NEWCELLTEXTS );
646 	return 0;
647 }
648 
649 IMPL_LINK( ScImportAsciiDlg, CharSetHdl, SvxTextEncodingBox*, pCharSetBox )
650 {
651     DBG_ASSERT( pCharSetBox, "ScImportAsciiDlg::CharSetHdl - missing sender" );
652 
653     if( (pCharSetBox == &aLbCharSet) && (pCharSetBox->GetSelectEntryCount() == 1) )
654     {
655         SetPointer( Pointer( POINTER_WAIT ) );
656         CharSet eOldCharSet = meCharSet;
657         SetSelectedCharSet();
658         // switching char-set invalidates 8bit -> String conversions
659         if (eOldCharSet != meCharSet)
660             UpdateVertical();
661 
662         maTableBox.Execute( CSVCMD_NEWCELLTEXTS );
663         SetPointer( Pointer( POINTER_ARROW ) );
664     }
665 	return 0;
666 }
667 
668 IMPL_LINK( ScImportAsciiDlg, FirstRowHdl, NumericField*, pNumField )
669 {
670     DBG_ASSERT( pNumField, "ScImportAsciiDlg::FirstRowHdl - missing sender" );
671     maTableBox.Execute( CSVCMD_SETFIRSTIMPORTLINE, sal::static_int_cast<sal_Int32>( pNumField->GetValue() - 1 ) );
672     return 0;
673 }
674 
675 IMPL_LINK( ScImportAsciiDlg, LbColTypeHdl, ListBox*, pListBox )
676 {
677     DBG_ASSERT( pListBox, "ScImportAsciiDlg::LbColTypeHdl - missing sender" );
678     if( pListBox == &aLbType )
679         maTableBox.Execute( CSVCMD_SETCOLUMNTYPE, pListBox->GetSelectEntryPos() );
680 	return 0;
681 }
682 
683 IMPL_LINK( ScImportAsciiDlg, UpdateTextHdl, ScCsvTableBox*, EMPTYARG )
684 {
685     sal_Int32 nBaseLine = maTableBox.GetFirstVisLine();
686     sal_Int32 nRead = maTableBox.GetVisLineCount();
687     // If mnRowPosCount==0, this is an initializing call, read ahead for row
688     // count and resulting scroll bar size and position to be able to scroll at
689     // all. When adding lines, read only the amount of next lines to be
690     // displayed.
691     if (!mnRowPosCount || nRead > CSV_PREVIEW_LINES)
692         nRead = CSV_PREVIEW_LINES;
693 
694     sal_Int32 i;
695     for (i = 0; i < nRead; i++)
696     {
697         if (!GetLine( nBaseLine + i, maPreviewLine[i]))
698             break;
699     }
700     for (; i < CSV_PREVIEW_LINES; i++)
701         maPreviewLine[i].Erase();
702 
703     maTableBox.Execute( CSVCMD_SETLINECOUNT, mnRowPosCount);
704     bool bMergeSep = (aCkbAsOnce.IsChecked() == sal_True);
705     maTableBox.SetUniStrings( maPreviewLine, maFieldSeparators, mcTextSep, bMergeSep);
706 
707     return 0;
708 }
709 
710 IMPL_LINK( ScImportAsciiDlg, ColTypeHdl, ScCsvTableBox*, pTableBox )
711 {
712     DBG_ASSERT( pTableBox, "ScImportAsciiDlg::ColTypeHdl - missing sender" );
713 
714     sal_Int32 nType = pTableBox->GetSelColumnType();
715     sal_Int32 nTypeCount = aLbType.GetEntryCount();
716     bool bEmpty = (nType == CSV_TYPE_MULTI);
717     bool bEnable = ((0 <= nType) && (nType < nTypeCount)) || bEmpty;
718 
719     aFtType.Enable( bEnable );
720     aLbType.Enable( bEnable );
721 
722     Link aSelHdl = aLbType.GetSelectHdl();
723     aLbType.SetSelectHdl( Link() );
724     if( bEmpty )
725         aLbType.SetNoSelection();
726     else if( bEnable )
727         aLbType.SelectEntryPos( static_cast< sal_uInt16 >( nType ) );
728     aLbType.SetSelectHdl( aSelHdl );
729 
730     return 0;
731 }
732