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