/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/


// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbui.hxx"
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif

#ifndef DBAUI_TEXTCONNECTIONHELPER_HXX
#include "TextConnectionHelper.hxx"
#endif

#ifndef _DBAUI_SQLMESSAGE_HXX_
#include "sqlmessage.hxx"
#endif
#ifndef _DBU_DLG_HRC_
#include "dbu_dlg.hrc"
#endif
#ifndef _DBU_RESOURCE_HRC_
#include "dbu_resource.hrc"
#endif
#include "AutoControlsDef.hrc"

#ifndef _SFXITEMSET_HXX
#include <svl/itemset.hxx>
#endif
#ifndef _SFXSTRITEM_HXX
#include <svl/stritem.hxx>
#endif
#ifndef _SFXENUMITEM_HXX
#include <svl/eitem.hxx>
#endif
#ifndef _SFXINTITEM_HXX
#include <svl/intitem.hxx>
#endif
#ifndef _DBAUI_DATASOURCEITEMS_HXX_
#include "dsitems.hxx"
#endif
#ifndef _DBAUI_DBFINDEX_HXX_
#include "dbfindex.hxx"
#endif
#ifndef _DBA_DBACCESS_HELPID_HRC_
#include "dbaccess_helpid.hrc"
#endif
#ifndef _DBAUI_LOCALRESACCESS_HXX_
#include "localresaccess.hxx"
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _SV_MNEMONIC_HXX
#include <vcl/mnemonic.hxx>
#endif
#ifndef _SVTOOLS_CJKOPTIONS_HXX
#include <svl/cjkoptions.hxx>
#endif
#include <jvmaccess/virtualmachine.hxx>
#ifndef _DBAUI_ADASTAT_HXX_
#include "AdabasStat.hxx"
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include <connectivity/CommonTools.hxx>
#endif
#ifndef DBAUI_DRIVERSETTINGS_HXX
#include "DriverSettings.hxx"
#endif
#ifndef _DBAUI_DBADMIN_HXX_
#include "dbadmin.hxx"
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif

#ifndef _COM_SUN_STAR_UI_DIALOGS_XFOLDERPICKER_HPP_
#include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
#endif
// #106016# ------------------------------------
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
#include <com/sun/star/task/XInteractionHandler.hpp>
#endif

#ifndef SVTOOLS_FILENOTATION_HXX_
#include <svl/filenotation.hxx>
#endif

#ifndef _UNOTOOLS_LOCALFILEHELPER_HXX
#include <unotools/localfilehelper.hxx>
#endif
#ifndef _UNOTOOLS_UCBHELPER_HXX
#include <unotools/ucbhelper.hxx>
#endif
#ifndef _UCBHELPER_COMMANDENVIRONMENT_HXX
#include <ucbhelper/commandenvironment.hxx>
#endif
#ifndef DBAUI_FILEPICKER_INTERACTION_HXX
#include "finteraction.hxx"
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include <connectivity/CommonTools.hxx>
#endif

#ifndef DBAUI_DBSETUPCONNECTIONPAGES_HXX
#include "DBSetupConnectionPages.hxx"
#endif

#ifndef _DBU_DLG_HRC_
#include "dbu_dlg.hrc"
#endif

#ifndef _DBA_DBACCESS_HELPID_HRC_
#include "dbaccess_helpid.hrc"
#endif

#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <unotools/pathoptions.hxx>
#endif

#ifndef SVTOOLS_INC_ROADMAPWIZARD_HXX
#include <svtools/roadmapwizard.hxx>
#endif


namespace dbaui
{

    //========================================================================
	//= OTextConnectionPageSetup
	//========================================================================
DBG_NAME(OTextConnectionHelper)
//------------------------------------------------------------------------
	OTextConnectionHelper::OTextConnectionHelper( Window* pParent, const short _nAvailableSections )
		:Control( pParent, WB_DIALOGCONTROL )
        ,m_aFTExtensionHeader       (this, ModuleRes(FT_AUTOEXTENSIONHEADER))
        ,m_aRBAccessTextFiles       (this, ModuleRes(RB_AUTOACCESSCTEXTFILES))
        ,m_aRBAccessCSVFiles        (this, ModuleRes(RB_AUTOACCESSCCSVFILES))
        ,m_aRBAccessOtherFiles      (this, ModuleRes(RB_AUTOACCESSOTHERS))
        ,m_aETOwnExtension          (this, ModuleRes(ET_AUTOOWNEXTENSION))
        ,m_aFTExtensionExample      (this, ModuleRes(FT_AUTOOWNEXTENSIONAPPENDIX))
        ,m_aLineFormat				(this, ModuleRes(FL_AUTOSEPARATOR2))
        ,m_aFieldSeparatorLabel		(this, ModuleRes(FT_AUTOFIELDSEPARATOR))
		,m_aFieldSeparator			(this, ModuleRes(CM_AUTOFIELDSEPARATOR))
		,m_aTextSeparatorLabel		(this, ModuleRes(FT_AUTOTEXTSEPARATOR))
		,m_aTextSeparator			(this, ModuleRes(CM_AUTOTEXTSEPARATOR))
		,m_aDecimalSeparatorLabel	(this, ModuleRes(FT_AUTODECIMALSEPARATOR))
		,m_aDecimalSeparator		(this, ModuleRes(CM_AUTODECIMALSEPARATOR))
		,m_aThousandsSeparatorLabel	(this, ModuleRes(FT_AUTOTHOUSANDSSEPARATOR))
		,m_aThousandsSeparator		(this, ModuleRes(CM_AUTOTHOUSANDSSEPARATOR))
        ,m_aRowHeader               (this, ModuleRes(CB_AUTOHEADER))
        ,m_aCharSetHeader           (this, ModuleRes(FL_DATACONVERT))
        ,m_aCharSetLabel            (this, ModuleRes(FT_CHARSET))
        ,m_aCharSet                 (this, ModuleRes(LB_CHARSET))
		,m_aFieldSeparatorList		(ModuleRes(STR_AUTOFIELDSEPARATORLIST))
		,m_aTextSeparatorList		(ModuleRes(STR_AUTOTEXTSEPARATORLIST))
		,m_aTextNone				(ModuleRes(STR_AUTOTEXT_FIELD_SEP_NONE))
        ,m_nAvailableSections( _nAvailableSections )
    {
        DBG_CTOR(OTextConnectionHelper,NULL);

        xub_StrLen nCnt = m_aFieldSeparatorList.GetTokenCount( '\t' );
		xub_StrLen i;

		for( i = 0 ; i < nCnt ; i += 2 )
			m_aFieldSeparator.InsertEntry( m_aFieldSeparatorList.GetToken( i, '\t' ) );

		nCnt = m_aTextSeparatorList.GetTokenCount( '\t' );
		for( i=0 ; i<nCnt ; i+=2 )
			m_aTextSeparator.InsertEntry( m_aTextSeparatorList.GetToken( i, '\t' ) );
		m_aTextSeparator.InsertEntry(m_aTextNone);

		// set the modify handlers
		m_aFieldSeparator.SetUpdateDataHdl(getControlModifiedLink());
		m_aFieldSeparator.SetSelectHdl(getControlModifiedLink());
		m_aTextSeparator.SetUpdateDataHdl(getControlModifiedLink());
		m_aTextSeparator.SetSelectHdl(getControlModifiedLink());
		m_aCharSet.SetSelectHdl(getControlModifiedLink());

		m_aFieldSeparator.SetModifyHdl(getControlModifiedLink());
		m_aTextSeparator.SetModifyHdl(getControlModifiedLink());
		m_aDecimalSeparator.SetModifyHdl(getControlModifiedLink());
		m_aThousandsSeparator.SetModifyHdl(getControlModifiedLink());
        m_aETOwnExtension.SetModifyHdl(LINK(this, OTextConnectionHelper, OnEditModified));
   		m_aRBAccessTextFiles.SetToggleHdl(LINK(this, OTextConnectionHelper, OnSetExtensionHdl));
   		m_aRBAccessCSVFiles.SetToggleHdl(LINK(this, OTextConnectionHelper, OnSetExtensionHdl));
        m_aRBAccessOtherFiles.SetToggleHdl(LINK(this, OTextConnectionHelper, OnSetExtensionHdl));
        m_aRBAccessCSVFiles.Check(sal_True);

        struct SectionDescriptor
        {
            short   nFlag;
            Window* pFirstControl;
        } aSections[] = {
            { TC_EXTENSION,     &m_aFTExtensionHeader },
            { TC_SEPARATORS,    &m_aLineFormat },
            { TC_HEADER,        &m_aRowHeader },
            { TC_CHARSET,       &m_aCharSetHeader },
            { 0, NULL }
        };

        for ( size_t section=0; section < sizeof( aSections ) / sizeof( aSections[0] ) - 1; ++section )
        {
            if ( ( m_nAvailableSections & aSections[section].nFlag ) != 0 )
            {
                // the section is visible, no need to do anything here
                continue;
            }

            Window* pThisSection = aSections[section].pFirstControl;
            Window* pNextSection = aSections[section+1].pFirstControl;

            // hide all elements from this section
            Window* pControl = pThisSection;
            while ( ( pControl != pNextSection ) && pControl )
            {
                Window* pRealWindow = pControl->GetWindow( WINDOW_CLIENT );
            #if OSL_DEBUG_LEVEL > 0
                String sWindowText( pRealWindow->GetText() );
                (void)sWindowText;
            #endif
                pRealWindow->Hide();
                pControl = pControl->GetWindow( WINDOW_NEXT );
            }

            // move all controls in following sections up
            if ( !pNextSection )
                continue;
            const long nThisSectionStart = pThisSection->GetPosPixel().Y();
            const long nNextSectionStart = pNextSection->GetPosPixel().Y();
            const long nMoveOffset( nThisSectionStart - nNextSectionStart );
            while ( pControl )
            {
                Point aPos = pControl->GetPosPixel();
                aPos.Move( 0, nMoveOffset );
                pControl->SetPosPixel( aPos );
                pControl = pControl->GetWindow( WINDOW_NEXT );
            }
        }

        Rectangle aControlRectUnion;
        for (   Window* pControl = aSections[0].pFirstControl;
                pControl != NULL;
                pControl = pControl->GetWindow( WINDOW_NEXT )
            )
        {
            aControlRectUnion = aControlRectUnion.Union( Rectangle( pControl->GetPosPixel(), pControl->GetSizePixel() ) );
        }

        // need some adjustments to the positions, since the resource-specified
        // positions for the control were relative to *our* parent, while by now
        // the controls have |this| as parent.

        // first, move ourself to the upper left of the area occupied by all controls
        SetPosPixel( aControlRectUnion.TopLeft() );

        // then, compensate in the control positions, by moving them the up/left
        for (   Window* pControl = aSections[0].pFirstControl;
                pControl != NULL;
                pControl = pControl->GetWindow( WINDOW_NEXT )
            )
        {
            Point aPos( pControl->GetPosPixel() );
            aPos.Move( -aControlRectUnion.Left(), -aControlRectUnion.Top() );
            pControl->SetPosPixel( aPos );

            // while we are here ... the controls should not have an own background
            // (this would not be needed when our outer dialog were also the parent
            // of the controls)
            pControl->SetBackground();
        }

        // now, change our own size so all controls fit
        SetSizePixel( aControlRectUnion.GetSize() );

        SetBackground();
        Show();
	}

	// -----------------------------------------------------------------------
	OTextConnectionHelper::~OTextConnectionHelper()
	{

        DBG_DTOR(OTextConnectionHelper,NULL);
    }


	// -----------------------------------------------------------------------
	IMPL_LINK(OTextConnectionHelper, OnControlModified, Control*, /*EMPTYARG*/)
	{
		callModifiedHdl();
		return 0L;
	}

    // -----------------------------------------------------------------------
	IMPL_LINK(OTextConnectionHelper, OnEditModified, Edit*, /*_pEdit*/)
	{
		m_aGetExtensionHandler.Call(this);
		return 0L;
	}


    IMPL_LINK(OTextConnectionHelper, OnSetExtensionHdl, RadioButton*, /*_pRadioButton*/)
    {
        sal_Bool bDoEnable = m_aRBAccessOtherFiles.IsChecked();
        m_aETOwnExtension.Enable(bDoEnable);
        m_aFTExtensionExample.Enable(bDoEnable);
        m_aGetExtensionHandler.Call(this);
        return 0L;
    }


    // -----------------------------------------------------------------------
	void OTextConnectionHelper::fillControls(::std::vector< ISaveValueWrapper* >& _rControlList)
	{
		_rControlList.push_back(new OSaveValueWrapper<ComboBox>(&m_aFieldSeparator));
		_rControlList.push_back(new OSaveValueWrapper<ComboBox>(&m_aTextSeparator));
		_rControlList.push_back(new OSaveValueWrapper<ComboBox>(&m_aDecimalSeparator));
		_rControlList.push_back(new OSaveValueWrapper<ComboBox>(&m_aThousandsSeparator));
        _rControlList.push_back(new OSaveValueWrapper<CheckBox>(&m_aRowHeader));
        _rControlList.push_back(new OSaveValueWrapper<ListBox>(&m_aCharSet));
	}
	// -----------------------------------------------------------------------
	void OTextConnectionHelper::fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList)
	{
		_rControlList.push_back(new ODisableWrapper<FixedText>(&m_aFieldSeparatorLabel));
		_rControlList.push_back(new ODisableWrapper<FixedText>(&m_aTextSeparatorLabel));
		_rControlList.push_back(new ODisableWrapper<FixedText>(&m_aDecimalSeparatorLabel));
		_rControlList.push_back(new ODisableWrapper<FixedText>(&m_aThousandsSeparatorLabel));
        _rControlList.push_back(new ODisableWrapper<FixedLine>(&m_aCharSetHeader));
        _rControlList.push_back(new ODisableWrapper<FixedText>(&m_aCharSetLabel));
        _rControlList.push_back(new ODisableWrapper<ListBox>(&m_aCharSet));
	}

    // -----------------------------------------------------------------------
	void OTextConnectionHelper::implInitControls(const SfxItemSet& _rSet, sal_Bool _bValid)
	{
        if ( !_bValid )
            return;

		SFX_ITEMSET_GET( _rSet, pDelItem, SfxStringItem, DSID_FIELDDELIMITER, sal_True );
		SFX_ITEMSET_GET( _rSet, pStrItem, SfxStringItem, DSID_TEXTDELIMITER, sal_True );
		SFX_ITEMSET_GET( _rSet, pDecdelItem, SfxStringItem, DSID_DECIMALDELIMITER, sal_True );
		SFX_ITEMSET_GET( _rSet, pThodelItem, SfxStringItem, DSID_THOUSANDSDELIMITER, sal_True );
		SFX_ITEMSET_GET( _rSet, pExtensionItem, SfxStringItem, DSID_TEXTFILEEXTENSION, sal_True );
		SFX_ITEMSET_GET( _rSet, pCharsetItem, SfxStringItem, DSID_CHARSET, sal_True );

        if ( ( m_nAvailableSections & TC_EXTENSION ) != 0 )
        {
            m_aOldExtension = pExtensionItem->GetValue();
            SetExtension( m_aOldExtension );
        }

        if ( ( m_nAvailableSections & TC_HEADER ) != 0 )
        {
        	SFX_ITEMSET_GET( _rSet, pHdrItem, SfxBoolItem, DSID_TEXTFILEHEADER, sal_True );
			m_aRowHeader.Check( pHdrItem->GetValue() );
        }

        if ( ( m_nAvailableSections & TC_SEPARATORS ) != 0 )
        {
		    SetSeparator( m_aFieldSeparator, m_aFieldSeparatorList, pDelItem->GetValue() );
		    SetSeparator( m_aTextSeparator, m_aTextSeparatorList, pStrItem->GetValue() );
		    m_aDecimalSeparator.SetText( pDecdelItem->GetValue() );
		    m_aThousandsSeparator.SetText( pThodelItem->GetValue() );
        }

        if ( ( m_nAvailableSections & TC_CHARSET ) != 0 )
        {
            m_aCharSet.SelectEntryByIanaName( pCharsetItem->GetValue() );
        }
	}



	// -----------------------------------------------------------------------
	sal_Bool OTextConnectionHelper::prepareLeave()
	{
		LocalResourceAccess aStringResAccess(PAGE_TEXT, RSC_TABPAGE);
			// for accessing the strings which are local to our own resource block
        String sExtension = GetExtension();
		String aErrorText;
		Control* pErrorWin = NULL;
		//	if (!m_aFieldSeparator.GetText().Len())
			// bug (#42168) if this line is compiled under OS2 (in a product environent)
			// -> use a temporary variable
		String aDelText(m_aFieldSeparator.GetText());
		if(!aDelText.Len())
		{	// Kein FeldTrenner
			aErrorText = String(ModuleRes(STR_AUTODELIMITER_MISSING));
			aErrorText.SearchAndReplaceAscii("#1",m_aFieldSeparatorLabel.GetText());
			pErrorWin = &m_aFieldSeparator;
		}
		else if (!m_aDecimalSeparator.GetText().Len())
		{	// kein Decimaltrenner
			aErrorText = String(ModuleRes(STR_AUTODELIMITER_MISSING));
			aErrorText.SearchAndReplaceAscii("#1",m_aDecimalSeparatorLabel.GetText());
			pErrorWin = &m_aDecimalSeparator;
		}
		else if (m_aTextSeparator.GetText() == m_aFieldSeparator.GetText())
		{	// Feld und TextTrenner duerfen nicht gleich sein
			aErrorText = String(ModuleRes(STR_AUTODELIMITER_MUST_DIFFER));
			aErrorText.SearchAndReplaceAscii("#1",m_aTextSeparatorLabel.GetText());
			aErrorText.SearchAndReplaceAscii("#2",m_aFieldSeparatorLabel.GetText());
			pErrorWin = &m_aTextSeparator;
		}
		else if (m_aDecimalSeparator.GetText() == m_aThousandsSeparator.GetText())
		{	// Tausender und DecimalTrenner duerfen nicht gleich sein
			aErrorText = String(ModuleRes(STR_AUTODELIMITER_MUST_DIFFER));
			aErrorText.SearchAndReplaceAscii("#1",m_aDecimalSeparatorLabel.GetText());
			aErrorText.SearchAndReplaceAscii("#2",m_aThousandsSeparatorLabel.GetText());
			pErrorWin = &m_aDecimalSeparator;
		}
		else if (m_aFieldSeparator.GetText() == m_aThousandsSeparator.GetText())
		{	// Tausender und FeldTrenner duerfen nicht gleich sein
			aErrorText = String(ModuleRes(STR_AUTODELIMITER_MUST_DIFFER));
			aErrorText.SearchAndReplaceAscii("#1",m_aFieldSeparatorLabel.GetText());
			aErrorText.SearchAndReplaceAscii("#2",m_aThousandsSeparatorLabel.GetText());
			pErrorWin = &m_aFieldSeparator;
		}
		else if (m_aFieldSeparator.GetText() == m_aDecimalSeparator.GetText())
		{	// Zehner und FeldTrenner duerfen nicht gleich sein
			aErrorText = String(ModuleRes(STR_AUTODELIMITER_MUST_DIFFER));
			aErrorText.SearchAndReplaceAscii("#1",m_aFieldSeparatorLabel.GetText());
			aErrorText.SearchAndReplaceAscii("#2",m_aDecimalSeparatorLabel.GetText());
			pErrorWin = &m_aFieldSeparator;
		}
		else if (m_aTextSeparator.GetText() == m_aThousandsSeparator.GetText())
		{	// Tausender und TextTrenner duerfen nicht gleich sein
			aErrorText = String(ModuleRes(STR_AUTODELIMITER_MUST_DIFFER));
			aErrorText.SearchAndReplaceAscii("#1",m_aTextSeparatorLabel.GetText());
			aErrorText.SearchAndReplaceAscii("#2",m_aThousandsSeparatorLabel.GetText());
			pErrorWin = &m_aTextSeparator;
		}
		else if (m_aTextSeparator.GetText() == m_aDecimalSeparator.GetText())
		{	// Zehner und TextTrenner duerfen nicht gleich sein
			aErrorText = String(ModuleRes(STR_AUTODELIMITER_MUST_DIFFER));
			aErrorText.SearchAndReplaceAscii("#1",m_aTextSeparatorLabel.GetText());
			aErrorText.SearchAndReplaceAscii("#2",m_aDecimalSeparatorLabel.GetText());
			pErrorWin = &m_aTextSeparator;
		}
		else if ((sExtension.Search('*') != STRING_NOTFOUND) || (sExtension.Search('?') != STRING_NOTFOUND))
		{
			aErrorText = String(ModuleRes(STR_AUTONO_WILDCARDS));
			aErrorText.SearchAndReplaceAscii("#1",sExtension);
			pErrorWin = &m_aETOwnExtension;
		}
		else
			return sal_True;
		ErrorBox(NULL, WB_OK, MnemonicGenerator::EraseAllMnemonicChars( aErrorText)).Execute();
		pErrorWin->GrabFocus();
		return 0;
	}


	// -----------------------------------------------------------------------
	sal_Bool OTextConnectionHelper::FillItemSet( SfxItemSet& rSet, const sal_Bool _bChangedSomething )
	{
        sal_Bool bChangedSomething = _bChangedSomething;

        if ( ( m_nAvailableSections & TC_EXTENSION ) != 0 )
        {
            String sExtension = GetExtension();
		    if( !m_aOldExtension.Equals( sExtension ) )
		    {
			    rSet.Put( SfxStringItem( DSID_TEXTFILEEXTENSION, sExtension ) );
			    bChangedSomething = sal_True;
		    }
        }

        if ( ( m_nAvailableSections & TC_HEADER ) != 0 )
        {
		    if( (m_aRowHeader.GetState() != m_aRowHeader.GetSavedValue()) )
		    {
			    rSet.Put(SfxBoolItem(DSID_TEXTFILEHEADER, m_aRowHeader.IsChecked()));
			    bChangedSomething = sal_True;
		    }
        }

        if ( ( m_nAvailableSections & TC_SEPARATORS ) != 0 )
        {
		    if( m_aFieldSeparator.GetText() != m_aFieldSeparator.GetSavedValue() )
		    {
			    rSet.Put( SfxStringItem(DSID_FIELDDELIMITER, GetSeparator( m_aFieldSeparator, m_aFieldSeparatorList) ) );
			    bChangedSomething = sal_True;
		    }
		    if( m_aTextSeparator.GetText() != m_aTextSeparator.GetSavedValue() )
		    {
			    rSet.Put( SfxStringItem(DSID_TEXTDELIMITER, GetSeparator( m_aTextSeparator, m_aTextSeparatorList) ) );
			    bChangedSomething = sal_True;
		    }

		    if( m_aDecimalSeparator.GetText() != m_aDecimalSeparator.GetSavedValue() )
		    {
			    rSet.Put( SfxStringItem(DSID_DECIMALDELIMITER, m_aDecimalSeparator.GetText().Copy(0, 1) ) );
			    bChangedSomething = sal_True;
		    }
		    if( m_aThousandsSeparator.GetText() != m_aThousandsSeparator.GetSavedValue() )
		    {
			    rSet.Put( SfxStringItem(DSID_THOUSANDSDELIMITER, m_aThousandsSeparator.GetText().Copy(0,1) ) );
			    bChangedSomething = sal_True;
		    }
        }

        if ( ( m_nAvailableSections & TC_CHARSET ) != 0 )
        {
            if ( m_aCharSet.StoreSelectedCharSet( rSet, DSID_CHARSET ) )
                bChangedSomething = sal_True;
        }

		return bChangedSomething;
	}


    void OTextConnectionHelper::SetExtension(const String& _rVal)
    {
        if (_rVal.EqualsAscii("txt"))
            m_aRBAccessTextFiles.Check(sal_True);
        else if (_rVal.EqualsAscii( "csv" ))
            m_aRBAccessCSVFiles.Check(sal_True);
        else
        {
            m_aRBAccessOtherFiles.Check(sal_True);
            m_aFTExtensionExample.SetText(_rVal);
        }
    }


    String OTextConnectionHelper::GetExtension()
    {
        String sExtension;
        if (m_aRBAccessTextFiles.IsChecked())
            sExtension = String::CreateFromAscii("txt");
        else if (m_aRBAccessCSVFiles.IsChecked())
            sExtension = String::CreateFromAscii("csv");
        else
        {
            sExtension = m_aETOwnExtension.GetText();
            if ( sExtension.GetToken(0,'.').Equals('*') )
                sExtension.Erase(0,2);
        }
        return sExtension;
    }


	//------------------------------------------------------------------------
	String OTextConnectionHelper::GetSeparator( const ComboBox& rBox, const String& rList )
	{
		sal_Unicode	nTok = '\t';
		xub_StrLen	nPos(rBox.GetEntryPos( rBox.GetText() ));

		if( nPos == COMBOBOX_ENTRY_NOTFOUND )
			return rBox.GetText().Copy(0);

		if ( !( &m_aTextSeparator == &rBox && nPos == (rBox.GetEntryCount()-1) ) )
			return String(
                static_cast< sal_Unicode >(
                    rList.GetToken(((nPos*2)+1), nTok ).ToInt32()));
		// somewhat strange ... translates for instance an "32" into " "
		return String();
	}

	//------------------------------------------------------------------------
	void OTextConnectionHelper::SetSeparator( ComboBox& rBox, const String& rList, const String& rVal )
	{
		char	nTok = '\t';
		xub_StrLen	nCnt(rList.GetTokenCount( nTok ));
		xub_StrLen	i;

		for( i=0 ; i<nCnt ; i+=2 )
		{
			String	sTVal(
                static_cast< sal_Unicode >(
                    rList.GetToken( (i+1), nTok ).ToInt32()));

			if( sTVal == rVal )
			{
				rBox.SetText( rList.GetToken( i, nTok ) );
				break;
			}
		}

		if ( i >= nCnt )
		{
			if ( &m_aTextSeparator == &rBox && !rVal.Len() )
				rBox.SetText(m_aTextNone);
			else
				rBox.SetText( rVal.Copy(0, 1) );
		}
	}

//.........................................................................
}	// namespace dbaui
//.........................................................................
