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_sc.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 aFldSepList ( ScResId( SCSTR_FIELDSEP ) ), 249 aTextSepList( ScResId( SCSTR_TEXTSEP ) ), 250 mcTextSep ( ScAsciiOptions::cDefaultTextSep ), 251 maStrTextToColumns( ScResId( STR_TEXTTOCOLUMNS ) ), 252 mbFileImport(true) 253 { 254 FreeResource(); 255 mbFileImport = aDatName.Len() > 0; 256 257 String aName = GetText(); 258 // aDatName is empty if invoked during paste from clipboard. 259 if (mbFileImport) 260 { 261 aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" - [")); 262 aName += aDatName; 263 aName += ']'; 264 } 265 SetText( aName ); 266 267 OUString sFieldSeparators; 268 OUString sTextSeparators; 269 bool bMergeDelimiters = false; 270 bool bFixedWidth = false; 271 bool bQuotedFieldAsText = false; 272 bool bDetectSpecialNum = false; 273 sal_Int32 nFromRow = 1; 274 sal_Int32 nCharSet = -1; 275 sal_Int32 nLanguage = 0; 276 if (mbFileImport) 277 // load separators only when importing csv files. 278 load_Separators (sFieldSeparators, sTextSeparators, bMergeDelimiters, 279 bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow, nCharSet, nLanguage); 280 else 281 { 282 // #i115474# otherwise use sensible defaults 283 sFieldSeparators = OUString( cSep ); 284 sTextSeparators = OUString( ScAsciiOptions::cDefaultTextSep ); 285 } 286 maFieldSeparators = String(sFieldSeparators); 287 288 if( bMergeDelimiters ) 289 aCkbAsOnce.Check(); 290 if (bQuotedFieldAsText) 291 aCkbQuotedAsText.Check(); 292 if (bDetectSpecialNum) 293 aCkbDetectNumber.Check(); 294 if( bFixedWidth ) 295 aRbFixed.Check(); 296 if( nFromRow != 1 ) 297 aNfRow.SetValue( nFromRow ); 298 299 ByteString bString(maFieldSeparators,RTL_TEXTENCODING_MS_1252); 300 const sal_Char *aSep = bString.GetBuffer(); 301 int len = maFieldSeparators.Len(); 302 for (int i = 0; i < len; ++i) 303 { 304 switch( aSep[i] ) 305 { 306 case '\t': aCkbTab.Check(); break; 307 case ';': aCkbSemicolon.Check(); break; 308 case ',': aCkbComma.Check(); break; 309 case ' ': aCkbSpace.Check(); break; 310 default: 311 aCkbOther.Check(); 312 aEdOther.SetText( aEdOther.GetText() + OUString( aSep[i] ) ); 313 } 314 } 315 316 // Get Separators from the dialog 317 maFieldSeparators = GetSeparators(); 318 319 // Clipboard is always Unicode, else detect. 320 rtl_TextEncoding ePreselectUnicode = (mbFileImport ? 321 RTL_TEXTENCODING_DONTKNOW : RTL_TEXTENCODING_UNICODE); 322 // Sniff for Unicode / not 323 if( ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW && mpDatStream ) 324 { 325 Seek( 0 ); 326 mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_DONTKNOW ); 327 sal_uLong nUniPos = mpDatStream->Tell(); 328 switch (nUniPos) 329 { 330 case 2: 331 ePreselectUnicode = RTL_TEXTENCODING_UNICODE; // UTF-16 332 break; 333 case 3: 334 ePreselectUnicode = RTL_TEXTENCODING_UTF8; // UTF-8 335 break; 336 case 0: 337 { 338 sal_uInt16 n; 339 *mpDatStream >> n; 340 // Assume that normal ASCII/ANSI/ISO/etc. text doesn't start with 341 // control characters except CR,LF,TAB 342 if ( (n & 0xff00) < 0x2000 ) 343 { 344 switch ( n & 0xff00 ) 345 { 346 case 0x0900 : 347 case 0x0a00 : 348 case 0x0d00 : 349 break; 350 default: 351 ePreselectUnicode = RTL_TEXTENCODING_UNICODE; // UTF-16 352 } 353 } 354 mpDatStream->Seek(0); 355 } 356 break; 357 default: 358 ; // nothing 359 } 360 mnStreamPos = mpDatStream->Tell(); 361 } 362 363 aNfRow.SetModifyHdl( LINK( this, ScImportAsciiDlg, FirstRowHdl ) ); 364 365 // *** Separator characters *** 366 lcl_FillCombo( aCbTextSep, aTextSepList, mcTextSep ); 367 aCbTextSep.SetText( sTextSeparators ); 368 369 Link aSeparatorHdl =LINK( this, ScImportAsciiDlg, SeparatorHdl ); 370 aCbTextSep.SetSelectHdl( aSeparatorHdl ); 371 aCbTextSep.SetModifyHdl( aSeparatorHdl ); 372 aCkbTab.SetClickHdl( aSeparatorHdl ); 373 aCkbSemicolon.SetClickHdl( aSeparatorHdl ); 374 aCkbComma.SetClickHdl( aSeparatorHdl ); 375 aCkbAsOnce.SetClickHdl( aSeparatorHdl ); 376 aCkbQuotedAsText.SetClickHdl( aSeparatorHdl ); 377 aCkbDetectNumber.SetClickHdl( aSeparatorHdl ); 378 aCkbSpace.SetClickHdl( aSeparatorHdl ); 379 aCkbOther.SetClickHdl( aSeparatorHdl ); 380 aEdOther.SetModifyHdl( aSeparatorHdl ); 381 382 // *** text encoding ListBox *** 383 // all encodings allowed, including Unicode, but subsets are excluded 384 aLbCharSet.FillFromTextEncodingTable( sal_True ); 385 // Insert one "SYSTEM" entry for compatibility in AsciiOptions and system 386 // independent document linkage. 387 aLbCharSet.InsertTextEncoding( RTL_TEXTENCODING_DONTKNOW, aCharSetUser ); 388 aLbCharSet.SelectTextEncoding( ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW ? 389 gsl_getSystemTextEncoding() : ePreselectUnicode ); 390 391 if( nCharSet >= 0 && ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW ) 392 aLbCharSet.SelectEntryPos( static_cast<sal_uInt16>(nCharSet) ); 393 394 SetSelectedCharSet(); 395 aLbCharSet.SetSelectHdl( LINK( this, ScImportAsciiDlg, CharSetHdl ) ); 396 397 aLbCustomLang.SetLanguageList( 398 LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, false, false); 399 aLbCustomLang.InsertLanguage(LANGUAGE_SYSTEM); 400 aLbCustomLang.SelectLanguage(static_cast<LanguageType>(nLanguage), true); 401 402 // *** column type ListBox *** 403 xub_StrLen nCount = aColumnUser.GetTokenCount(); 404 for (xub_StrLen i=0; i<nCount; i++) 405 aLbType.InsertEntry( aColumnUser.GetToken( i ) ); 406 407 aLbType.SetSelectHdl( LINK( this, ScImportAsciiDlg, LbColTypeHdl ) ); 408 aFtType.Disable(); 409 aLbType.Disable(); 410 411 // *** table box preview *** 412 maTableBox.SetUpdateTextHdl( LINK( this, ScImportAsciiDlg, UpdateTextHdl ) ); 413 maTableBox.InitTypes( aLbType ); 414 maTableBox.SetColTypeHdl( LINK( this, ScImportAsciiDlg, ColTypeHdl ) ); 415 416 aRbSeparated.SetClickHdl( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) ); 417 aRbFixed.SetClickHdl( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) ); 418 419 SetupSeparatorCtrls(); 420 RbSepFixHdl( &aRbFixed ); 421 422 UpdateVertical(); 423 424 maTableBox.Execute( CSVCMD_NEWCELLTEXTS ); 425 426 aEdOther.SetAccessibleName(aCkbOther.GetText()); 427 aEdOther.SetAccessibleRelationLabeledBy(&aCkbOther); 428 } 429 430 431 ScImportAsciiDlg::~ScImportAsciiDlg() 432 { 433 delete[] mpRowPosArray; 434 } 435 436 437 // ---------------------------------------------------------------------------- 438 439 bool ScImportAsciiDlg::GetLine( sal_uLong nLine, String &rText ) 440 { 441 if (nLine >= ASCIIDLG_MAXROWS || !mpDatStream) 442 return false; 443 444 bool bRet = true; 445 bool bFixed = aRbFixed.IsChecked(); 446 447 if (!mpRowPosArray) 448 mpRowPosArray = new sal_uLong[ASCIIDLG_MAXROWS + 2]; 449 450 if (!mnRowPosCount) // complete re-fresh 451 { 452 memset( mpRowPosArray, 0, sizeof(mpRowPosArray[0]) * (ASCIIDLG_MAXROWS+2)); 453 454 Seek(0); 455 mpDatStream->StartReadingUnicodeText( mpDatStream->GetStreamCharSet() ); 456 457 mnStreamPos = mpDatStream->Tell(); 458 mpRowPosArray[mnRowPosCount] = mnStreamPos; 459 } 460 461 if (nLine >= mnRowPosCount) 462 { 463 // need to work out some more line information 464 do 465 { 466 if (!Seek( mpRowPosArray[mnRowPosCount]) || 467 mpDatStream->GetError() != ERRCODE_NONE || 468 mpDatStream->IsEof()) 469 { 470 bRet = false; 471 break; 472 } 473 mpDatStream->ReadCsvLine( rText, !bFixed, maFieldSeparators, 474 mcTextSep); 475 mnStreamPos = mpDatStream->Tell(); 476 mpRowPosArray[++mnRowPosCount] = mnStreamPos; 477 } while (nLine >= mnRowPosCount && 478 mpDatStream->GetError() == ERRCODE_NONE && 479 !mpDatStream->IsEof()); 480 if (mpDatStream->IsEof() && 481 mnStreamPos == mpRowPosArray[mnRowPosCount-1]) 482 { 483 // the very end, not even an empty line read 484 bRet = false; 485 --mnRowPosCount; 486 } 487 } 488 else 489 { 490 Seek( mpRowPosArray[nLine]); 491 mpDatStream->ReadCsvLine( rText, !bFixed, maFieldSeparators, mcTextSep); 492 mnStreamPos = mpDatStream->Tell(); 493 } 494 495 // #107455# If the file content isn't unicode, ReadUniStringLine 496 // may try to seek beyond the file's end and cause a CANTSEEK error 497 // (depending on the stream type). The error code has to be cleared, 498 // or further read operations (including non-unicode) will fail. 499 if ( mpDatStream->GetError() == ERRCODE_IO_CANTSEEK ) 500 mpDatStream->ResetError(); 501 502 return bRet; 503 } 504 505 506 void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt ) 507 { 508 rOpt.SetCharSet( meCharSet ); 509 rOpt.SetCharSetSystem( mbCharSetSystem ); 510 rOpt.SetLanguage(aLbCustomLang.GetSelectLanguage()); 511 rOpt.SetFixedLen( aRbFixed.IsChecked() ); 512 rOpt.SetStartRow( (long)aNfRow.GetValue() ); 513 maTableBox.FillColumnData( rOpt ); 514 if( aRbSeparated.IsChecked() ) 515 { 516 rOpt.SetFieldSeps( GetSeparators() ); 517 rOpt.SetMergeSeps( aCkbAsOnce.IsChecked() ); 518 rOpt.SetTextSep( lcl_CharFromCombo( aCbTextSep, aTextSepList ) ); 519 } 520 521 rOpt.SetQuotedAsText(aCkbQuotedAsText.IsChecked()); 522 rOpt.SetDetectSpecialNumber(aCkbDetectNumber.IsChecked()); 523 } 524 525 void ScImportAsciiDlg::SetTextToColumnsMode() 526 { 527 SetText( maStrTextToColumns ); 528 aFtCharSet.Disable(); 529 aLbCharSet.Disable(); 530 aFtCustomLang.Disable(); 531 aLbCustomLang.SelectLanguage(LANGUAGE_SYSTEM); 532 aLbCustomLang.Disable(); 533 aFtRow.Disable(); 534 aNfRow.Disable(); 535 536 // Quoted field as text option is not used for text-to-columns mode. 537 aCkbQuotedAsText.Check(false); 538 aCkbQuotedAsText.Disable(); 539 540 // Always detect special numbers for text-to-columns mode. 541 aCkbDetectNumber.Check(); 542 aCkbDetectNumber.Disable(); 543 } 544 545 void ScImportAsciiDlg::SaveParameters() 546 { 547 if (!mbFileImport) 548 // We save parameters only for file import. 549 return; 550 551 save_Separators( maFieldSeparators, aCbTextSep.GetText(), aCkbAsOnce.IsChecked(), 552 aCkbQuotedAsText.IsChecked(), aCkbDetectNumber.IsChecked(), 553 aRbFixed.IsChecked(), 554 static_cast<sal_Int32>(aNfRow.GetValue()), 555 static_cast<sal_Int32>(aLbCharSet.GetSelectEntryPos()), 556 static_cast<sal_Int32>(aLbCustomLang.GetSelectLanguage()) ); 557 } 558 559 void ScImportAsciiDlg::SetSelectedCharSet() 560 { 561 meCharSet = aLbCharSet.GetSelectTextEncoding(); 562 mbCharSetSystem = (meCharSet == RTL_TEXTENCODING_DONTKNOW); 563 if( mbCharSetSystem ) 564 meCharSet = gsl_getSystemTextEncoding(); 565 } 566 567 String ScImportAsciiDlg::GetSeparators() const 568 { 569 String aSepChars; 570 if( aCkbTab.IsChecked() ) 571 aSepChars += '\t'; 572 if( aCkbSemicolon.IsChecked() ) 573 aSepChars += ';'; 574 if( aCkbComma.IsChecked() ) 575 aSepChars += ','; 576 if( aCkbSpace.IsChecked() ) 577 aSepChars += ' '; 578 if( aCkbOther.IsChecked() ) 579 aSepChars += aEdOther.GetText(); 580 return aSepChars; 581 } 582 583 void ScImportAsciiDlg::SetupSeparatorCtrls() 584 { 585 sal_Bool bEnable = aRbSeparated.IsChecked(); 586 aCkbTab.Enable( bEnable ); 587 aCkbSemicolon.Enable( bEnable ); 588 aCkbComma.Enable( bEnable ); 589 aCkbSpace.Enable( bEnable ); 590 aCkbOther.Enable( bEnable ); 591 aEdOther.Enable( bEnable ); 592 aCkbAsOnce.Enable( bEnable ); 593 aFtTextSep.Enable( bEnable ); 594 aCbTextSep.Enable( bEnable ); 595 } 596 597 void ScImportAsciiDlg::UpdateVertical() 598 { 599 mnRowPosCount = 0; 600 if (mpDatStream) 601 mpDatStream->SetStreamCharSet(meCharSet); 602 } 603 604 605 // ---------------------------------------------------------------------------- 606 607 IMPL_LINK( ScImportAsciiDlg, RbSepFixHdl, RadioButton*, pButton ) 608 { 609 DBG_ASSERT( pButton, "ScImportAsciiDlg::RbSepFixHdl - missing sender" ); 610 611 if( (pButton == &aRbFixed) || (pButton == &aRbSeparated) ) 612 { 613 SetPointer( Pointer( POINTER_WAIT ) ); 614 if( aRbFixed.IsChecked() ) 615 maTableBox.SetFixedWidthMode(); 616 else 617 maTableBox.SetSeparatorsMode(); 618 SetPointer( Pointer( POINTER_ARROW ) ); 619 620 SetupSeparatorCtrls(); 621 } 622 return 0; 623 } 624 625 IMPL_LINK( ScImportAsciiDlg, SeparatorHdl, Control*, pCtrl ) 626 { 627 DBG_ASSERT( pCtrl, "ScImportAsciiDlg::SeparatorHdl - missing sender" ); 628 DBG_ASSERT( !aRbFixed.IsChecked(), "ScImportAsciiDlg::SeparatorHdl - not allowed in fixed width" ); 629 630 /* #i41550# First update state of the controls. The GetSeparators() 631 function needs final state of the check boxes. */ 632 if( (pCtrl == &aCkbOther) && aCkbOther.IsChecked() ) 633 aEdOther.GrabFocus(); 634 else if( pCtrl == &aEdOther ) 635 aCkbOther.Check( aEdOther.GetText().Len() > 0 ); 636 637 String aOldFldSeps( maFieldSeparators); 638 maFieldSeparators = GetSeparators(); 639 sal_Unicode cOldSep = mcTextSep; 640 mcTextSep = lcl_CharFromCombo( aCbTextSep, aTextSepList ); 641 // Any separator changed may result in completely different lines due to 642 // embedded line breaks. 643 if (cOldSep != mcTextSep || aOldFldSeps != maFieldSeparators) 644 UpdateVertical(); 645 646 maTableBox.Execute( CSVCMD_NEWCELLTEXTS ); 647 return 0; 648 } 649 650 IMPL_LINK( ScImportAsciiDlg, CharSetHdl, SvxTextEncodingBox*, pCharSetBox ) 651 { 652 DBG_ASSERT( pCharSetBox, "ScImportAsciiDlg::CharSetHdl - missing sender" ); 653 654 if( (pCharSetBox == &aLbCharSet) && (pCharSetBox->GetSelectEntryCount() == 1) ) 655 { 656 SetPointer( Pointer( POINTER_WAIT ) ); 657 CharSet eOldCharSet = meCharSet; 658 SetSelectedCharSet(); 659 // switching char-set invalidates 8bit -> String conversions 660 if (eOldCharSet != meCharSet) 661 UpdateVertical(); 662 663 maTableBox.Execute( CSVCMD_NEWCELLTEXTS ); 664 SetPointer( Pointer( POINTER_ARROW ) ); 665 } 666 return 0; 667 } 668 669 IMPL_LINK( ScImportAsciiDlg, FirstRowHdl, NumericField*, pNumField ) 670 { 671 DBG_ASSERT( pNumField, "ScImportAsciiDlg::FirstRowHdl - missing sender" ); 672 maTableBox.Execute( CSVCMD_SETFIRSTIMPORTLINE, sal::static_int_cast<sal_Int32>( pNumField->GetValue() - 1 ) ); 673 return 0; 674 } 675 676 IMPL_LINK( ScImportAsciiDlg, LbColTypeHdl, ListBox*, pListBox ) 677 { 678 DBG_ASSERT( pListBox, "ScImportAsciiDlg::LbColTypeHdl - missing sender" ); 679 if( pListBox == &aLbType ) 680 maTableBox.Execute( CSVCMD_SETCOLUMNTYPE, pListBox->GetSelectEntryPos() ); 681 return 0; 682 } 683 684 IMPL_LINK( ScImportAsciiDlg, UpdateTextHdl, ScCsvTableBox*, EMPTYARG ) 685 { 686 sal_Int32 nBaseLine = maTableBox.GetFirstVisLine(); 687 sal_Int32 nRead = maTableBox.GetVisLineCount(); 688 // If mnRowPosCount==0, this is an initializing call, read ahead for row 689 // count and resulting scroll bar size and position to be able to scroll at 690 // all. When adding lines, read only the amount of next lines to be 691 // displayed. 692 if (!mnRowPosCount || nRead > CSV_PREVIEW_LINES) 693 nRead = CSV_PREVIEW_LINES; 694 695 sal_Int32 i; 696 for (i = 0; i < nRead; i++) 697 { 698 if (!GetLine( nBaseLine + i, maPreviewLine[i])) 699 break; 700 } 701 for (; i < CSV_PREVIEW_LINES; i++) 702 maPreviewLine[i].Erase(); 703 704 maTableBox.Execute( CSVCMD_SETLINECOUNT, mnRowPosCount); 705 bool bMergeSep = (aCkbAsOnce.IsChecked() == sal_True); 706 maTableBox.SetUniStrings( maPreviewLine, maFieldSeparators, mcTextSep, bMergeSep); 707 708 return 0; 709 } 710 711 IMPL_LINK( ScImportAsciiDlg, ColTypeHdl, ScCsvTableBox*, pTableBox ) 712 { 713 DBG_ASSERT( pTableBox, "ScImportAsciiDlg::ColTypeHdl - missing sender" ); 714 715 sal_Int32 nType = pTableBox->GetSelColumnType(); 716 sal_Int32 nTypeCount = aLbType.GetEntryCount(); 717 bool bEmpty = (nType == CSV_TYPE_MULTI); 718 bool bEnable = ((0 <= nType) && (nType < nTypeCount)) || bEmpty; 719 720 aFtType.Enable( bEnable ); 721 aLbType.Enable( bEnable ); 722 723 Link aSelHdl = aLbType.GetSelectHdl(); 724 aLbType.SetSelectHdl( Link() ); 725 if( bEmpty ) 726 aLbType.SetNoSelection(); 727 else if( bEnable ) 728 aLbType.SelectEntryPos( static_cast< sal_uInt16 >( nType ) ); 729 aLbType.SetSelectHdl( aSelHdl ); 730 731 return 0; 732 } 733