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