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