1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include "moduledbu.hxx"
23 #include "TextConnectionHelper.hxx"
24 #include "sqlmessage.hxx"
25 #include "dbu_dlg.hrc"
26 #include "dbu_resource.hrc"
27 #include <svl/itemset.hxx>
28 #include <svl/stritem.hxx>
29 #include <svl/eitem.hxx>
30 #include <svl/intitem.hxx>
31 #include "dsitems.hxx"
32 #include "dbfindex.hxx"
33 #include "dbaccess_helpid.hrc"
34 #include "localresaccess.hxx"
35 #include <vcl/layout.hxx>
36 #include <vcl/mnemonic.hxx>
37 #include <svl/cjkoptions.hxx>
39 #include <jvmaccess/virtualmachine.hxx>
41 #include <connectivity/CommonTools.hxx>
42 #include "DriverSettings.hxx"
43 #include "dbadmin.hxx"
44 #include <comphelper/string.hxx>
45 #include <comphelper/types.hxx>
46 #include <com/sun/star/task/XInteractionHandler.hpp>
47 #include <svl/filenotation.hxx>
48 #include <unotools/localfilehelper.hxx>
49 #include <unotools/ucbhelper.hxx>
50 #include <ucbhelper/commandenvironment.hxx>
51 #include "finteraction.hxx"
52 #include "DBSetupConnectionPages.hxx"
53 #include <unotools/pathoptions.hxx>
54 #include <svtools/roadmapwizard.hxx>
59 OTextConnectionHelper::OTextConnectionHelper( vcl::Window
* pParent
, const short _nAvailableSections
)
60 :TabPage(pParent
, "TextPage", "dbaccess/ui/textpage.ui")
61 ,m_aFieldSeparatorList (ModuleRes(STR_AUTOFIELDSEPARATORLIST
))
62 ,m_aTextSeparatorList (ModuleRes(STR_AUTOTEXTSEPARATORLIST
))
63 ,m_aTextNone (ModuleRes(STR_AUTOTEXT_FIELD_SEP_NONE
))
64 ,m_nAvailableSections( _nAvailableSections
)
66 get(m_pExtensionHeader
, "extensionheader");
67 get(m_pAccessTextFiles
, "textfile");
68 get(m_pAccessCSVFiles
, "csvfile");
69 get(m_pAccessOtherFiles
, "custom");
70 get(m_pOwnExtension
, "extension");
71 get(m_pExtensionExample
, "example");
72 get(m_pFormatHeader
, "formatlabel");
73 get(m_pFieldSeparatorLabel
, "fieldlabel");
74 get(m_pFieldSeparator
, "fieldseparator");
75 get(m_pTextSeparatorLabel
, "textlabel");
76 get(m_pTextSeparator
, "textseparator");
77 get(m_pDecimalSeparatorLabel
, "decimallabel");
78 get(m_pDecimalSeparator
, "decimalseparator");
79 get(m_pThousandsSeparatorLabel
, "thousandslabel");
80 get(m_pThousandsSeparator
, "thousandsseparator");
81 get(m_pRowHeader
, "containsheaders");
82 get(m_pCharSetHeader
, "charsetheader");
83 get(m_pCharSetLabel
, "charsetlabel");
84 get(m_pCharSet
, "charset");
86 sal_Int32 nCnt
= comphelper::string::getTokenCount(m_aFieldSeparatorList
, '\t');
89 for( i
= 0 ; i
< nCnt
; i
+= 2 )
90 m_pFieldSeparator
->InsertEntry( m_aFieldSeparatorList
.getToken( i
, '\t' ) );
92 nCnt
= comphelper::string::getTokenCount(m_aTextSeparatorList
, '\t');
93 for( i
=0 ; i
<nCnt
; i
+=2 )
94 m_pTextSeparator
->InsertEntry( m_aTextSeparatorList
.getToken( i
, '\t' ) );
95 m_pTextSeparator
->InsertEntry(m_aTextNone
);
97 // set the modify handlers
98 m_pFieldSeparator
->SetUpdateDataHdl(getControlModifiedLink());
99 m_pFieldSeparator
->SetSelectHdl(getControlModifiedLink());
100 m_pTextSeparator
->SetUpdateDataHdl(getControlModifiedLink());
101 m_pTextSeparator
->SetSelectHdl(getControlModifiedLink());
102 m_pCharSet
->SetSelectHdl(getControlModifiedLink());
104 m_pFieldSeparator
->SetModifyHdl(getControlModifiedLink());
105 m_pTextSeparator
->SetModifyHdl(getControlModifiedLink());
106 m_pDecimalSeparator
->SetModifyHdl(getControlModifiedLink());
107 m_pThousandsSeparator
->SetModifyHdl(getControlModifiedLink());
108 m_pOwnExtension
->SetModifyHdl(LINK(this, OTextConnectionHelper
, OnEditModified
));
109 m_pAccessTextFiles
->SetToggleHdl(LINK(this, OTextConnectionHelper
, OnSetExtensionHdl
));
110 m_pAccessCSVFiles
->SetToggleHdl(LINK(this, OTextConnectionHelper
, OnSetExtensionHdl
));
111 m_pAccessOtherFiles
->SetToggleHdl(LINK(this, OTextConnectionHelper
, OnSetExtensionHdl
));
112 m_pAccessCSVFiles
->Check(true);
114 struct SectionDescriptor
117 VclPtr
<vcl::Window
> pFirstControl
;
119 { TC_EXTENSION
, m_pExtensionHeader
},
120 { TC_SEPARATORS
, m_pFormatHeader
},
121 { TC_HEADER
, m_pRowHeader
},
122 { TC_CHARSET
, m_pCharSetHeader
},
126 for ( size_t section
=0; section
< sizeof( aSections
) / sizeof( aSections
[0] ) - 1; ++section
)
128 if ( ( m_nAvailableSections
& aSections
[section
].nFlag
) != 0 )
130 // the section is visible, no need to do anything here
134 vcl::Window
* pThisSection
= aSections
[section
].pFirstControl
;
135 vcl::Window
* pNextSection
= aSections
[section
+1].pFirstControl
;
137 // hide all elements from this section
138 vcl::Window
* pControl
= pThisSection
;
139 while ( ( pControl
!= pNextSection
) && pControl
)
141 vcl::Window
* pRealWindow
= pControl
->GetWindow( GetWindowType::Client
);
142 #if OSL_DEBUG_LEVEL > 0
143 OUString
sWindowText( pRealWindow
->GetText() );
147 pControl
= pControl
->GetWindow( GetWindowType::Next
);
154 OTextConnectionHelper::~OTextConnectionHelper()
159 void OTextConnectionHelper::dispose()
161 m_pExtensionHeader
.clear();
162 m_pAccessTextFiles
.clear();
163 m_pAccessCSVFiles
.clear();
164 m_pAccessOtherFiles
.clear();
165 m_pOwnExtension
.clear();
166 m_pExtensionExample
.clear();
167 m_pFormatHeader
.clear();
168 m_pFieldSeparatorLabel
.clear();
169 m_pFieldSeparator
.clear();
170 m_pTextSeparatorLabel
.clear();
171 m_pTextSeparator
.clear();
172 m_pDecimalSeparatorLabel
.clear();
173 m_pDecimalSeparator
.clear();
174 m_pThousandsSeparatorLabel
.clear();
175 m_pThousandsSeparator
.clear();
176 m_pRowHeader
.clear();
177 m_pCharSetHeader
.clear();
178 m_pCharSetLabel
.clear();
183 IMPL_LINK(OTextConnectionHelper
, OnControlModified
, Control
*,)
189 IMPL_LINK(OTextConnectionHelper
, OnEditModified
, Edit
*, /*_pEdit*/)
191 m_aGetExtensionHandler
.Call(this);
195 IMPL_LINK(OTextConnectionHelper
, OnSetExtensionHdl
, RadioButton
*, /*_pRadioButton*/)
197 bool bDoEnable
= m_pAccessOtherFiles
->IsChecked();
198 m_pOwnExtension
->Enable(bDoEnable
);
199 m_pExtensionExample
->Enable(bDoEnable
);
200 m_aGetExtensionHandler
.Call(this);
204 void OTextConnectionHelper::fillControls(::std::vector
< ISaveValueWrapper
* >& _rControlList
)
206 _rControlList
.push_back(new OSaveValueWrapper
<ComboBox
>(m_pFieldSeparator
));
207 _rControlList
.push_back(new OSaveValueWrapper
<ComboBox
>(m_pTextSeparator
));
208 _rControlList
.push_back(new OSaveValueWrapper
<ComboBox
>(m_pDecimalSeparator
));
209 _rControlList
.push_back(new OSaveValueWrapper
<ComboBox
>(m_pThousandsSeparator
));
210 _rControlList
.push_back(new OSaveValueWrapper
<CheckBox
>(m_pRowHeader
));
211 _rControlList
.push_back(new OSaveValueWrapper
<ListBox
>(m_pCharSet
));
214 void OTextConnectionHelper::fillWindows(::std::vector
< ISaveValueWrapper
* >& _rControlList
)
216 _rControlList
.push_back(new ODisableWrapper
<FixedText
>(m_pFieldSeparatorLabel
));
217 _rControlList
.push_back(new ODisableWrapper
<FixedText
>(m_pTextSeparatorLabel
));
218 _rControlList
.push_back(new ODisableWrapper
<FixedText
>(m_pDecimalSeparatorLabel
));
219 _rControlList
.push_back(new ODisableWrapper
<FixedText
>(m_pThousandsSeparatorLabel
));
220 _rControlList
.push_back(new ODisableWrapper
<FixedText
>(m_pCharSetHeader
));
221 _rControlList
.push_back(new ODisableWrapper
<FixedText
>(m_pCharSetLabel
));
222 _rControlList
.push_back(new ODisableWrapper
<ListBox
>(m_pCharSet
));
225 void OTextConnectionHelper::implInitControls(const SfxItemSet
& _rSet
, bool _bValid
)
230 SFX_ITEMSET_GET( _rSet
, pDelItem
, SfxStringItem
, DSID_FIELDDELIMITER
, true );
231 SFX_ITEMSET_GET( _rSet
, pStrItem
, SfxStringItem
, DSID_TEXTDELIMITER
, true );
232 SFX_ITEMSET_GET( _rSet
, pDecdelItem
, SfxStringItem
, DSID_DECIMALDELIMITER
, true );
233 SFX_ITEMSET_GET( _rSet
, pThodelItem
, SfxStringItem
, DSID_THOUSANDSDELIMITER
, true );
234 SFX_ITEMSET_GET( _rSet
, pExtensionItem
, SfxStringItem
, DSID_TEXTFILEEXTENSION
, true );
235 SFX_ITEMSET_GET( _rSet
, pCharsetItem
, SfxStringItem
, DSID_CHARSET
, true );
237 if ( ( m_nAvailableSections
& TC_EXTENSION
) != 0 )
239 m_aOldExtension
= pExtensionItem
->GetValue();
240 SetExtension( m_aOldExtension
);
243 if ( ( m_nAvailableSections
& TC_HEADER
) != 0 )
245 SFX_ITEMSET_GET( _rSet
, pHdrItem
, SfxBoolItem
, DSID_TEXTFILEHEADER
, true );
246 m_pRowHeader
->Check( pHdrItem
->GetValue() );
249 if ( ( m_nAvailableSections
& TC_SEPARATORS
) != 0 )
251 SetSeparator( *m_pFieldSeparator
, m_aFieldSeparatorList
, pDelItem
->GetValue() );
252 SetSeparator( *m_pTextSeparator
, m_aTextSeparatorList
, pStrItem
->GetValue() );
253 m_pDecimalSeparator
->SetText( pDecdelItem
->GetValue() );
254 m_pThousandsSeparator
->SetText( pThodelItem
->GetValue() );
257 if ( ( m_nAvailableSections
& TC_CHARSET
) != 0 )
259 m_pCharSet
->SelectEntryByIanaName( pCharsetItem
->GetValue() );
263 bool OTextConnectionHelper::prepareLeave()
265 OUString sExtension
= GetExtension();
267 Control
* pErrorWin
= NULL
;
268 OUString
aDelText(m_pFieldSeparator
->GetText());
269 if(aDelText
.isEmpty())
270 { // No FieldSeparator
271 aErrorText
= ModuleRes(STR_AUTODELIMITER_MISSING
);
272 aErrorText
= aErrorText
.replaceFirst("#1",m_pFieldSeparatorLabel
->GetText());
273 pErrorWin
= m_pFieldSeparator
;
275 else if (m_pDecimalSeparator
->GetText().isEmpty())
276 { // No DecimalSeparator
277 aErrorText
= ModuleRes(STR_AUTODELIMITER_MISSING
);
278 aErrorText
= aErrorText
.replaceFirst("#1",m_pDecimalSeparatorLabel
->GetText());
279 pErrorWin
= m_pDecimalSeparator
;
281 else if (m_pTextSeparator
->GetText() == m_pFieldSeparator
->GetText())
282 { // Field and TextSeparator must not be the same
283 aErrorText
= ModuleRes(STR_AUTODELIMITER_MUST_DIFFER
);
284 aErrorText
= aErrorText
.replaceFirst("#1",m_pTextSeparatorLabel
->GetText());
285 aErrorText
= aErrorText
.replaceFirst("#2",m_pFieldSeparatorLabel
->GetText());
286 pErrorWin
= m_pTextSeparator
;
288 else if (m_pDecimalSeparator
->GetText() == m_pThousandsSeparator
->GetText())
289 { // Thousands and DecimalSeparator must not be the same
290 aErrorText
= ModuleRes(STR_AUTODELIMITER_MUST_DIFFER
);
291 aErrorText
= aErrorText
.replaceFirst("#1",m_pDecimalSeparatorLabel
->GetText());
292 aErrorText
= aErrorText
.replaceFirst("#2",m_pThousandsSeparatorLabel
->GetText());
293 pErrorWin
= m_pDecimalSeparator
;
295 else if (m_pFieldSeparator
->GetText() == m_pThousandsSeparator
->GetText())
296 { // Thousands and FieldSeparator must not be the same
297 aErrorText
= ModuleRes(STR_AUTODELIMITER_MUST_DIFFER
);
298 aErrorText
= aErrorText
.replaceFirst("#1",m_pFieldSeparatorLabel
->GetText());
299 aErrorText
= aErrorText
.replaceFirst("#2",m_pThousandsSeparatorLabel
->GetText());
300 pErrorWin
= m_pFieldSeparator
;
302 else if (m_pFieldSeparator
->GetText() == m_pDecimalSeparator
->GetText())
303 { // Tenner and FieldSeparator must not be the same
304 aErrorText
= ModuleRes(STR_AUTODELIMITER_MUST_DIFFER
);
305 aErrorText
= aErrorText
.replaceFirst("#1",m_pFieldSeparatorLabel
->GetText());
306 aErrorText
= aErrorText
.replaceFirst("#2",m_pDecimalSeparatorLabel
->GetText());
307 pErrorWin
= m_pFieldSeparator
;
309 else if (m_pTextSeparator
->GetText() == m_pThousandsSeparator
->GetText())
310 { // Thousands and TextSeparator must not be the same
311 aErrorText
= ModuleRes(STR_AUTODELIMITER_MUST_DIFFER
);
312 aErrorText
= aErrorText
.replaceFirst("#1",m_pTextSeparatorLabel
->GetText());
313 aErrorText
= aErrorText
.replaceFirst("#2",m_pThousandsSeparatorLabel
->GetText());
314 pErrorWin
= m_pTextSeparator
;
316 else if (m_pTextSeparator
->GetText() == m_pDecimalSeparator
->GetText())
317 { // Tenner and TextSeparator must not be the same
318 aErrorText
= ModuleRes(STR_AUTODELIMITER_MUST_DIFFER
);
319 aErrorText
= aErrorText
.replaceFirst("#1",m_pTextSeparatorLabel
->GetText());
320 aErrorText
= aErrorText
.replaceFirst("#2",m_pDecimalSeparatorLabel
->GetText());
321 pErrorWin
= m_pTextSeparator
;
323 else if ((sExtension
.indexOf('*') != -1) || (sExtension
.indexOf('?') != -1))
325 aErrorText
= ModuleRes(STR_AUTONO_WILDCARDS
);
326 aErrorText
= aErrorText
.replaceFirst("#1",sExtension
);
327 pErrorWin
= m_pOwnExtension
;
331 ScopedVclPtrInstance
<MessageDialog
>::Create(nullptr, MnemonicGenerator::EraseAllMnemonicChars(aErrorText
))->Execute();
332 pErrorWin
->GrabFocus();
336 bool OTextConnectionHelper::FillItemSet( SfxItemSet
& rSet
, const bool _bChangedSomething
)
338 bool bChangedSomething
= _bChangedSomething
;
340 if ( ( m_nAvailableSections
& TC_EXTENSION
) != 0 )
342 OUString sExtension
= GetExtension();
343 if( m_aOldExtension
!= sExtension
)
345 rSet
.Put( SfxStringItem( DSID_TEXTFILEEXTENSION
, sExtension
) );
346 bChangedSomething
= true;
350 if ( ( m_nAvailableSections
& TC_HEADER
) != 0 )
352 if( m_pRowHeader
->IsValueChangedFromSaved() )
354 rSet
.Put(SfxBoolItem(DSID_TEXTFILEHEADER
, m_pRowHeader
->IsChecked()));
355 bChangedSomething
= true;
359 if ( ( m_nAvailableSections
& TC_SEPARATORS
) != 0 )
361 if( m_pFieldSeparator
->IsValueChangedFromSaved() )
363 rSet
.Put( SfxStringItem(DSID_FIELDDELIMITER
, GetSeparator( *m_pFieldSeparator
, m_aFieldSeparatorList
) ) );
364 bChangedSomething
= true;
366 if( m_pTextSeparator
->IsValueChangedFromSaved() )
368 rSet
.Put( SfxStringItem(DSID_TEXTDELIMITER
, GetSeparator( *m_pTextSeparator
, m_aTextSeparatorList
) ) );
369 bChangedSomething
= true;
372 if( m_pDecimalSeparator
->IsValueChangedFromSaved() )
374 rSet
.Put( SfxStringItem(DSID_DECIMALDELIMITER
, m_pDecimalSeparator
->GetText().copy(0, 1) ) );
375 bChangedSomething
= true;
377 if( m_pThousandsSeparator
->IsValueChangedFromSaved() )
379 rSet
.Put( SfxStringItem(DSID_THOUSANDSDELIMITER
, m_pThousandsSeparator
->GetText().copy(0,1) ) );
380 bChangedSomething
= true;
384 if ( ( m_nAvailableSections
& TC_CHARSET
) != 0 )
386 if ( m_pCharSet
->StoreSelectedCharSet( rSet
, DSID_CHARSET
) )
387 bChangedSomething
= true;
390 return bChangedSomething
;
393 void OTextConnectionHelper::SetExtension(const OUString
& _rVal
)
396 m_pAccessTextFiles
->Check(true);
397 else if (_rVal
== "csv")
398 m_pAccessCSVFiles
->Check(true);
401 m_pAccessOtherFiles
->Check(true);
402 m_pExtensionExample
->SetText(_rVal
);
406 OUString
OTextConnectionHelper::GetExtension()
409 if (m_pAccessTextFiles
->IsChecked())
411 else if (m_pAccessCSVFiles
->IsChecked())
415 sExtension
= m_pOwnExtension
->GetText();
416 if ( comphelper::string::equals(sExtension
.getToken(0,'.'), '*') )
417 sExtension
= sExtension
.copy(2);
422 OUString
OTextConnectionHelper::GetSeparator( const ComboBox
& rBox
, const OUString
& rList
)
424 sal_Unicode nTok
= '\t';
425 sal_Int32
nPos(rBox
.GetEntryPos( rBox
.GetText() ));
427 if( nPos
== COMBOBOX_ENTRY_NOTFOUND
)
428 return rBox
.GetText().copy(0);
430 if ( !( m_pTextSeparator
== &rBox
&& nPos
== (rBox
.GetEntryCount()-1) ) )
432 static_cast< sal_Unicode
>( rList
.getToken((nPos
*2)+1, nTok
).toInt32() ));
433 // somewhat strange ... translates for instance an "32" into " "
437 void OTextConnectionHelper::SetSeparator( ComboBox
& rBox
, const OUString
& rList
, const OUString
& rVal
)
440 sal_Int32 nCnt
= comphelper::string::getTokenCount(rList
, nTok
);
443 for( i
=0 ; i
<nCnt
; i
+=2 )
446 static_cast< sal_Unicode
>( rList
.getToken( (i
+1), nTok
).toInt32() ));
448 if( sTVal
.equals(rVal
) )
450 rBox
.SetText( rList
.getToken( i
, nTok
) );
457 if ( m_pTextSeparator
== &rBox
&& rVal
.isEmpty() )
458 rBox
.SetText(m_aTextNone
);
460 rBox
.SetText( rVal
.copy(0, 1) );
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */