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