/***************************************************************************
                          kbearsitemanager.cpp  -  description
                             -------------------
    begin                : fre mar 15 2002
    copyright            : (C) 2003 by Björn Sahlström
    email                : kbjorn@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

//////////////////////////////////////////////////////////////////////
// Qt specific include files
#include <qtimer.h>
#include <qdom.h>
#include <qcolor.h>
#include <qfile.h>
#include <qtabbar.h>
#include <qtextedit.h>
#include <qcheckbox.h>
#include <qpopupmenu.h>
#include <qradiobutton.h>
#include <qbuttongroup.h>
#include <qvbuttongroup.h>
#include <qhbuttongroup.h>
#include <qgroupbox.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qlayout.h>
#include <qvbox.h>
#include <qlabel.h>
///////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <kprotocolinfo.h>
#include <kparts/plugin.h>
#include <kpassdlg.h>
#include <kmessagebox.h>
#include <ktextedit.h>
#include <klineedit.h>
#include <klineeditdlg.h>
#include <kcombobox.h>
#include <kpushbutton.h>
#include <kprogress.h>
#include <kmdcodec.h>
#include <kcharsets.h>
#include <kstandarddirs.h>
#include <knuminput.h>
#include <ktabctl.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kglobal.h>
#include <kdebug.h>
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "kbearsitemanager.h"
#include "kbearsitemanagertreeview.h"
#include "siteimportwidget.h"
#include "misc.h"
#include <netdb.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <string.h>

using namespace KBear;
//-----------------------------------------------
KBearSiteManager::KBearSiteManager(QWidget *parent, const char *name )
		: KDialogBase( Tabbed, i18n("KBear Sitemanager" ), Close|User1, (ButtonCode)-1, parent, name ),
		m_hasKBearFTP(false), m_pendingConnect( false ),
		m_isModified( false )
{
	setupGUI();
	setupProtocolCombo();
	QStringList lst = KGlobal::charsets()->descriptiveEncodingNames();
	m_encodingComboBox->insertStringList( lst );
	m_advEncodingComboBox->insertStringList( lst );
	setupConnections();
}
//-----------------------------------------------
KBearSiteManager::~KBearSiteManager(){
}
//-----------------------------------------------
void KBearSiteManager::setupGUI() {
	QVBox* vbox = addVBoxPage( i18n( "General" ));
	QWidget *m_generalWidget = new QWidget( vbox );
	vbox = addVBoxPage( i18n( "Advanced Settings" ));
	m_advancedWidget = new QWidget( vbox );
	vbox = addVBoxPage( i18n( "Import" ));
	m_importWidget = new KBearSiteImportWidget( vbox );
	
	// General Widget
	QGridLayout *m_generalLayout = new QGridLayout( m_generalWidget, 0, 0, 11, 6 );
	QGridLayout *m_buttonLayout = new QGridLayout( m_generalWidget, 0, 0, 6 );

	m_groupBox = new QGroupBox( m_generalWidget );
	m_groupBox->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ) );
	m_groupBox->setColumnLayout(0, Qt::Vertical );
	m_groupBox->layout()->setSpacing( 6 );
	m_groupBox->layout()->setMargin( 11 );
	QGridLayout *m_groupBoxLayout = new QGridLayout( m_groupBox->layout() );
	QVBoxLayout *m_descriptionLayout = new QVBoxLayout( m_groupBox, 0, 6 );
	QHBoxLayout *m_checkboxLayout = new QHBoxLayout( m_generalWidget, 6 );

/*
	m_systemtrayCheckBox = new QCheckBox( i18n( "Show system tray icon for database daemon" ), m_generalWidget );
	m_systemtrayCheckBox->setChecked( true );
	QString tmp = i18n( "Check this if you want the system tray icon for the database daemon to be visible. " );
	QToolTip::add( m_systemtrayCheckBox, tmp );
	QWhatsThis::add( m_systemtrayCheckBox, tmp );
*/
	m_plugkonqCheckBox = new QCheckBox( i18n( "Plug into Konqueror" ), m_generalWidget );
	m_plugkonqCheckBox->setChecked( true );
	QString tmp = i18n( "Check this if you want the Sitemanager to plug into Konqueror." );
	QToolTip::add( m_plugkonqCheckBox, tmp );
	QWhatsThis::add( m_plugkonqCheckBox, tmp );

	siteTreeView = new KBearSiteManagerTreeView( m_generalWidget );
	siteTreeView->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ) );
	tmp = i18n( "Treeview over all sites in site list. Here you can rename or remove the sites, you can also move them with drag and drop." );
	QToolTip::add( siteTreeView, tmp );
	QWhatsThis::add( siteTreeView, tmp );

	m_reloadButton = new KPushButton( "reload", m_generalWidget );
	m_reloadButton->setPixmap( BarIcon("reload") );
	QToolTip::add( m_reloadButton, i18n( "Push this button to update the treeview." ) );
	QWhatsThis::add( m_reloadButton, i18n( "Push this button to update the treeview. This will call the database and retreive a new content" ) );
	QLabel *m_encodingLabel = new QLabel( i18n( "Set encoding for database:" ), m_generalWidget );

	m_newgroupButton = new KPushButton( i18n( "&New group" ), m_generalWidget );
	tmp = i18n( "Adds a new group to the site list" );
	QToolTip::add( m_newgroupButton, tmp );
	QWhatsThis::add( m_newgroupButton, tmp );

	m_removeButton = new KPushButton( i18n( "&Remove" ), m_generalWidget );
	m_removeButton->setEnabled( false );
	tmp = i18n( "Remove selected site from site list" );
	QToolTip::add( m_removeButton, tmp );
	QWhatsThis::add( m_removeButton, tmp );

	m_connectButton = new KPushButton( i18n( "C&onnect" ), m_generalWidget );
	m_connectButton->setFont( QFont( m_connectButton->font().family(), 24, QFont::Bold ) );
	m_connectButton->setDefault( true );
	m_connectButton->setEnabled( false );
	tmp = i18n( "Connect to selected site" );
	QToolTip::add( m_connectButton, tmp );
	QWhatsThis::add( m_connectButton, tmp );

	QLabel *m_siteLabel = new QLabel( i18n( "Site Label:" ), m_groupBox );

	m_siteEdit = new KLineEdit( m_groupBox );
	QToolTip::add( m_siteEdit, i18n( "Enter your label for the site here. This name has to be unique within the group." ) );
	QWhatsThis::add( m_siteEdit, i18n( "Enter your label for the site here. This name has to be unique within the group. If it's not unique it will be renamed automatically." ) );
	QLabel *m_hostnameLabel = new QLabel( i18n( "Hostname:" ), m_groupBox );

	m_hostnameEdit = new KLineEdit( m_groupBox );
	tmp = i18n( "Enter the address for the site here. Something like 'ftp.kde.org' or '127.0.0.1" );
	QToolTip::add( m_hostnameEdit, tmp );
	QWhatsThis::add( m_hostnameEdit, tmp );

	QLabel *m_portLabel = new QLabel( i18n( "Port:" ), m_groupBox );

	m_portSpinBox = new KIntSpinBox( 0, 65535, 1, 23, 10, m_groupBox );
	tmp = i18n( "Select port number here. Standard port for FTP is 21." );
	QToolTip::add( m_portSpinBox, tmp );
	QWhatsThis::add( m_portSpinBox, tmp );

	QLabel *m_protocolLabel = new QLabel( i18n( "Protocol:" ), m_groupBox );

	m_protocolComboBox = new KComboBox( m_groupBox );

	m_anonymousCheckBox = new QCheckBox( i18n( "Anonymous Login" ), m_groupBox );
	tmp = i18n( "Check this if you want anonymous login" );
	QToolTip::add( m_anonymousCheckBox, tmp );
	QWhatsThis::add( m_anonymousCheckBox, tmp );

	QLabel *m_usernameLabel = new QLabel( i18n( "User name:" ), m_groupBox );

	m_usernameComboBox = new KComboBox( m_groupBox );
	m_usernameComboBox->setEditable( true );
	tmp = i18n( "Enter your username here or select anonymous" );
	QToolTip::add( m_usernameComboBox, tmp );
	QWhatsThis::add( m_usernameComboBox, tmp );

	QLabel *m_passwordLabel = new QLabel( i18n( "Password:" ), m_groupBox );

	m_passwordEdit = new KLineEdit( m_groupBox );
	m_passwordEdit->setEchoMode( KLineEdit::Password );
	tmp = i18n( "Enter your password here" );
	QToolTip::add( m_passwordEdit, tmp );
	QWhatsThis::add( m_passwordEdit, tmp );

	QLabel *m_localdirLabel = new QLabel( i18n( "Local Directory:" ), m_groupBox );

	m_localdirEdit = new KLineEdit( m_groupBox );
	tmp = i18n( "Enter the default directory for your local filesystem here" );
	QToolTip::add( m_localdirEdit, tmp );
	QWhatsThis::add( m_localdirEdit, tmp );

	QLabel *m_remotedirLabel = new QLabel( i18n( "Remote Directory:" ), m_groupBox );

	m_remotedirEdit = new KLineEdit( m_groupBox );
	tmp = i18n( "Enter the default directory for the remote host here" );
	QToolTip::add( m_remotedirEdit, tmp );
	QWhatsThis::add( m_remotedirEdit, tmp );

	QLabel *m_descriptionLabel = new QLabel( i18n( "Description:" ), m_groupBox );
	m_descriptionLabel->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed, 0, 0, m_descriptionLabel->sizePolicy().hasHeightForWidth() ) );

	m_encodingComboBox = new KComboBox( false, m_generalWidget );
	m_encodingComboBox->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ) );
	tmp = i18n( "Use this to select the encoding for the Sitemanagerdatabase. Can be important for some languages in order to save certain characters." );
	QToolTip::add( m_encodingComboBox, tmp );
	QWhatsThis::add( m_encodingComboBox, tmp );

	m_descriptionEdit = new KTextEdit( m_groupBox );
	m_descriptionEdit->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding, 0, 0, m_descriptionEdit->sizePolicy().hasHeightForWidth() ) );
	tmp = i18n( "Enter a short descripton of the site" );
	QToolTip::add( m_descriptionEdit, tmp );
	QWhatsThis::add( m_descriptionEdit, tmp );
		
	m_descriptionLayout->addWidget( m_descriptionLabel );
	m_descriptionLayout->addWidget( m_descriptionEdit );
	m_groupBoxLayout->addWidget( m_siteLabel, 0, 0 );
	m_groupBoxLayout->addWidget( m_siteEdit, 0, 1 );
	m_groupBoxLayout->addWidget( m_hostnameLabel, 1, 0 );
	m_groupBoxLayout->addWidget( m_hostnameEdit, 1, 1 );
	m_groupBoxLayout->addWidget( m_portLabel, 2, 0 );
	m_groupBoxLayout->addWidget( m_portSpinBox, 2, 1 );
	m_groupBoxLayout->addWidget( m_protocolLabel, 3, 0 );
	m_groupBoxLayout->addWidget( m_protocolComboBox, 3, 1 );
	m_groupBoxLayout->addWidget( m_anonymousCheckBox, 4, 0 );
	m_groupBoxLayout->addWidget( m_usernameLabel, 5, 0 );
 	m_groupBoxLayout->addWidget( m_usernameComboBox, 5, 1 );
	m_groupBoxLayout->addWidget( m_passwordLabel, 6, 0 );
  	m_groupBoxLayout->addWidget( m_passwordEdit, 6, 1 );
	m_groupBoxLayout->addWidget( m_localdirLabel, 7, 0 );
 	m_groupBoxLayout->addWidget( m_localdirEdit, 7, 1 );
	m_groupBoxLayout->addWidget( m_remotedirLabel, 8, 0 );
 	m_groupBoxLayout->addWidget( m_remotedirEdit, 8, 1 );
 	m_groupBoxLayout->addMultiCellLayout( m_descriptionLayout, 9, 9, 0, 1 );
	m_buttonLayout->addWidget( m_newgroupButton, 0, 0 );
	m_buttonLayout->addWidget( m_removeButton, 0, 1 );
	m_buttonLayout->addMultiCellWidget( m_connectButton, 1, 2, 0, 1 );
//	m_checkboxLayout->addWidget( m_systemtrayCheckBox );
 	m_checkboxLayout->addWidget( m_plugkonqCheckBox );
 	m_generalLayout->addMultiCellLayout( m_checkboxLayout, 0, 0, 0, 1 );
	m_generalLayout->addWidget( siteTreeView, 1, 0 );
	m_generalLayout->addWidget( m_groupBox, 1, 1 );
	m_generalLayout->addWidget( m_reloadButton, 2, 0 );
	m_generalLayout->addMultiCellLayout( m_buttonLayout, 2, 4, 1, 1 );
	m_generalLayout->addWidget( m_encodingLabel, 3, 0 );
	m_generalLayout->addWidget( m_encodingComboBox, 4, 0 );
	m_generalLayout->activate();

	// Advanced settings widget
	QVBoxLayout *m_advancedLayout = new QVBoxLayout( m_advancedWidget, 6, 6 );
	QLabel* infoLabel = new QLabel( m_advancedWidget );
	infoLabel->setText( i18n( "<p>This page let you set up some more advanced settings for the selected site.<br>"
															"<b>If you are uncertain we suggest that you leave this settings to default</b><br>"
															"But you should know that the settings on this page can solve problems "
															"that can occur when working against a site</p>" ) );
	infoLabel->setAlignment( int( QLabel::WordBreak | QLabel::AlignTop ) );

	QVButtonGroup* groupBox = new QVButtonGroup( m_advancedWidget );
	groupBox->setExclusive( false );
	m_advPasvCheckBox = new QCheckBox( i18n( "Disable passive mode (PASV)" ), groupBox );
	tmp = i18n( "Check this option if you want to disable passive mode (PASV)." );
	QToolTip::add( m_advPasvCheckBox, tmp );
	QWhatsThis::add( m_advPasvCheckBox, tmp );
	m_advPasvCheckBox->setChecked( true );

	m_advEpsvCheckBox = new QCheckBox( i18n( "Disable extended passive mode (EPSV)" ), groupBox );
	tmp = i18n( "Check this option if you want to disable extended passive mode (EPSV)." );
	QToolTip::add( m_advEpsvCheckBox, tmp );
	QWhatsThis::add( m_advEpsvCheckBox, tmp );
	m_advEpsvCheckBox->setChecked( true );

	m_advPartCheckBox = new QCheckBox( i18n( "Use .part extension" ), groupBox );
	tmp = i18n( "Uncheck this option if you don't want the '.part' extension to be used during transfers.\nThis can solve the 'rename problem' on anonymous servers." );
	QToolTip::add( m_advPartCheckBox, tmp );
	QWhatsThis::add( m_advPartCheckBox, tmp );

	m_advLogCheckBox = new QCheckBox( i18n( "Disable logging" ), groupBox );
	QToolTip::add( m_advLogCheckBox, i18n("Check this option if you don't want KBear to produce log information.") );
	QWhatsThis::add( m_advLogCheckBox, i18n("Check this option if you don't want KBear to produce log information.\n"
													"If you notice reduced transfer speed, you can try to check this, since log information can reduce transfer speed a bit.") );
/* Removed since this is now a globally option
	m_advQueueCheckBox = new QCheckBox( i18n( "Queue transfers" ), groupBox );
	QToolTip::add( m_advQueueCheckBox, i18n( "Check this option if you want to queue transfers to or from this site." ) );
	QWhatsThis::add( m_advQueueCheckBox, i18n( "Check this option if you want to queue transfers to or from this site.\nThis will override the global queue option if checked." ) );
*/
	m_advSingleCheckBox = new QCheckBox( i18n( "Use a single connection" ), groupBox );
	QToolTip::add( m_advSingleCheckBox, i18n("Check this if you want all filesystem operations to use the same connection.") );
	QWhatsThis::add( m_advSingleCheckBox, i18n("Check this if you want all filesystem operations to use the same connection. "
												"This will cause, for example, a listing operation to be blocked until a delete operation is finished. "
												"Default is to use several connections, but some systems don't allow this so if you have trouble with this, try to check this option.") );

	groupBox->insert( m_advPasvCheckBox );
	groupBox->insert( m_advEpsvCheckBox );
	groupBox->insert( m_advPartCheckBox );
	groupBox->insert( m_advLogCheckBox );
	groupBox->insert( m_advSingleCheckBox );
	m_advancedLayout->addWidget( infoLabel );
	m_advancedLayout->addWidget( groupBox );

	QFrame *m_advListGroup = new QFrame( m_advancedWidget, "m_advListGroup" );
	m_advListGroup->setFrameShape( QFrame::Box );
	m_advListGroup->setFrameShadow( QFrame::Raised );
	QHBoxLayout *m_advListGroupLayout = new QHBoxLayout( m_advListGroup, 11, 6 );
	QLabel *m_advListCmdLabel = new QLabel( i18n( "Command to list directories:" ), m_advListGroup );
	m_advListCmdCheckBox = new QCheckBox( i18n( "Default" ), m_advListGroup );
	QToolTip::add( m_advListCmdCheckBox, i18n( "Uncheck this option if you don't want to use the standard list command." ) );
	QWhatsThis::add( m_advListCmdCheckBox, i18n( "Uncheck this option if you don't want to use the standard list command.. "
																					"This can be necessary if the server doesn't understand the standard 'list -a' command.\n"
																					"If you uncheck this you also need to enter the new command to use." ) );
	m_advListCmdEdit = new KLineEdit( m_advListGroup );
	QToolTip::add( m_advListCmdEdit, i18n( "Here you can enter the command to use to list directories." ) );
	QWhatsThis::add( m_advListCmdEdit, i18n( "Here you can enter the command to use to list directories. "
																					"This can be necessary if the server doesn't understand the standard 'list -a' command." ) );
	m_advListGroupLayout->addWidget( m_advListCmdLabel );
	m_advListGroupLayout->addWidget( m_advListCmdCheckBox );
	m_advListGroupLayout->addWidget( m_advListCmdEdit );
	
	m_advancedLayout->addWidget( m_advListGroup );
	
/* Removed since this is now a globally option

	m_advTransferGroup = new QHButtonGroup( i18n( "File transfer mode" ), m_advancedWidget );
	m_advTransferGroup->setRadioButtonExclusive( true );
	m_advBinaryRadio = new QRadioButton( i18n( "Binary (I)" ), m_advTransferGroup );
	m_advAsciiRadio = new QRadioButton( i18n( "ASCII (A)" ), m_advTransferGroup );
	m_advTransferGroup->insert( m_advBinaryRadio );
	m_advTransferGroup->insert( m_advAsciiRadio );

	m_advancedLayout->addWidget( m_advTransferGroup );
*/
	QFrame* m_advGroup = new QFrame( m_advancedWidget, "m_advGroup" );
	m_advGroup->setFrameShape( QFrame::Box );
	m_advGroup->setFrameShadow( QFrame::Raised );
	QGridLayout *m_advGroupLayout = new QGridLayout( m_advGroup, 1, 1, 11, 6 );

	m_advReconnectCheckBox = new QCheckBox( i18n( "Reconnect automatically." ), m_advGroup );
	tmp = i18n( "Check this if you want KBear to automatically try to reconnect on connection failure." );
	QToolTip::add( m_advReconnectCheckBox, tmp );
	QWhatsThis::add( m_advReconnectCheckBox, tmp );

	QLabel *m_advWaitLabel = new QLabel( i18n( "Wait number of seconds:" ), m_advGroup );
	m_advWaitLabel->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)3, 0, 0, m_advWaitLabel->sizePolicy().hasHeightForWidth() ) );

	QLabel *m_advRetriesLabel = new QLabel( i18n( "Number of retries:" ), m_advGroup );
	m_advRetriesLabel->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)3, 0, 0, m_advRetriesLabel->sizePolicy().hasHeightForWidth() ) );

	m_advWaitSpinBox = new KIntSpinBox( 1, 600, 1, 30, 10, m_advGroup );
	tmp = i18n( "Set number of seconds to wait before trying to reconnect. Only valid if 'Reconnect automatically' is selected." );
	QToolTip::add( m_advWaitSpinBox, tmp );
	QWhatsThis::add( m_advWaitSpinBox, tmp );
	m_advWaitSpinBox->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, m_advWaitSpinBox->sizePolicy().hasHeightForWidth() ) );

	m_advRetriesSpinBox = new KIntSpinBox( 0, 100, 1, 10, 10, m_advGroup );
	tmp = i18n( "Set number of attempts to reconnect. Only valid if 'Reconnect automatically' is selected." );
	QToolTip::add( m_advRetriesSpinBox, tmp );
	QWhatsThis::add( m_advRetriesSpinBox, tmp );
	m_advRetriesSpinBox->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, m_advRetriesSpinBox->sizePolicy().hasHeightForWidth() ) );
	
	m_advancedLayout->addWidget( m_advGroup );

	QLabel *m_advEncodingLabel = new QLabel( i18n( "Select encoding for this site:" ), m_advancedWidget );

	m_advEncodingComboBox = new KComboBox( m_advancedWidget );
	QToolTip::add( m_advEncodingComboBox, i18n("Select the encoding used by this site.") );
	QWhatsThis::add( m_advEncodingComboBox, i18n("Select the encoding used by this site.\nNormally you shouldn't need to do this. "
																					"Some sites, like sites using, for example, chinese file names, this can be necessary if you want the file names to be displayed correctly.") );

	m_advGroupLayout->addWidget( m_advReconnectCheckBox, 0, 0 );
	m_advGroupLayout->addWidget( m_advWaitLabel, 1, 0 );
	m_advGroupLayout->addWidget( m_advWaitSpinBox, 1, 1 );
	m_advGroupLayout->addWidget( m_advRetriesLabel, 2, 0 );
	m_advGroupLayout->addWidget( m_advRetriesSpinBox, 2, 1 );
	
	m_advancedLayout->addWidget( m_advEncodingLabel );
	m_advancedLayout->addWidget( m_advEncodingComboBox );
	m_advancedLayout->addStretch( 10 );
	m_advancedLayout->activate();

	setButtonText( User1, i18n( "&Save" ) );
	setButtonTip( User1, i18n( "Save the edited site. This will overwrite the old information unless you change the label." ) );
	setButtonWhatsThis( User1, i18n( "Save the edited site. This will overwrite the old information. If you change the label it will be saved as a new site." ) );
	enableButton( User1, false );
	m_advancedWidget->setEnabled( false );

}
//-----------------------------------------------
void KBearSiteManager::setPlugIntoKonq( bool plug ) {
	m_plugkonqCheckBox->setChecked( plug );
}
//-----------------------------------------------
void KBearSiteManager::setupConnections() {
	// connections
 	connect( m_plugkonqCheckBox, SIGNAL( toggled( bool ) ), SIGNAL( plugInKonq( bool ) ) );
	connect( m_reloadButton, SIGNAL( clicked() ), SIGNAL( update() ) );
	connect( m_anonymousCheckBox, 	SIGNAL( clicked() ), this, SLOT( slotSetEdited() ) );
	connect( m_siteEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( slotSetEdited() ) );
	connect( m_siteEdit, SIGNAL( textChanged( const QString&) ), 
			this, SLOT( slotSiteLabelChanged() ) );
	connect( m_hostnameEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( slotSetHostEdited() ) );
	connect( m_passwordEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( slotSetEdited() ) );
	connect( m_localdirEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( slotSetEdited() ) );
	connect( m_remotedirEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( slotSetEdited() ) );
	connect( m_descriptionEdit, SIGNAL( textChanged() ), this, SLOT( slotSetEdited() ) );
	connect( m_newgroupButton, SIGNAL( clicked() ), this, SLOT( slotNewGroup() ) );
	connect( m_removeButton, SIGNAL( clicked() ), this, SLOT( slotRemove() ) );
	connect( this, SIGNAL( user1Clicked() ), this, SLOT( slotSave() ) );
	connect( m_connectButton, SIGNAL( clicked() ), this, SLOT( slotConnect() ) );
	connect( m_portSpinBox, SIGNAL( valueChanged(int) ), this, SLOT( slotSetEdited() ) );
	connect( m_encodingComboBox, SIGNAL( activated(const QString&) ), this, SLOT( slotSetEncoding(const QString&) ) );
	connect( m_protocolComboBox, SIGNAL( activated(const QString&) ), this, SLOT( slotSelectedProtocol(const QString&) ) );
	connect( m_protocolComboBox, SIGNAL( activated(int) ), this, SLOT( slotSetEdited() ) );
	connect( m_usernameComboBox, SIGNAL( activated(int) ), this, SLOT( slotSetEdited() ) );
	connect( siteTreeView, SIGNAL( moved( const QString&, const QString&, QListViewItem*,bool) ), this, SLOT( slotMoved(const QString&,const QString&,QListViewItem*,bool) ) );
	connect( siteTreeView, SIGNAL( doubleClicked(QListViewItem*) ), this, SLOT( slotDoubleClicked(QListViewItem*) ) );
    connect( siteTreeView, SIGNAL( selectionChanged(QListViewItem*) ), this, SLOT( slotSelectedSite(QListViewItem*) ) );
    connect( siteTreeView, SIGNAL( pressed(QListViewItem*) ), this, SLOT( slotPressed(QListViewItem*) ) );
	connect( siteTreeView, SIGNAL( itemRenamed (QListViewItem*, const QString&, int) ), this, SLOT( slotItemRenamed(QListViewItem*,const QString&,int) ) );
    connect( siteTreeView, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ), this, SLOT( slotContextMenu( KListView*, QListViewItem*, const QPoint& ) ) );
	connect( m_advPasvCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( slotSetEdited() ) );
	connect( m_advEpsvCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( slotSetEdited() ) );
	connect( m_advListCmdCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( slotSetEdited() ) );
	connect( m_advPartCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( slotSetEdited() ) );
	connect( m_advLogCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( slotSetEdited() ) );
	connect( m_advSingleCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( slotSetEdited() ) );
/* Removed since this is now a globally option
	connect( m_advTransferGroup, SIGNAL( clicked( int ) ), this, SLOT( slotSetEdited() ) );
*/
	connect( m_advReconnectCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( slotSetEdited() ) );
	connect( m_advWaitSpinBox, SIGNAL( valueChanged( int ) ), this, SLOT( slotSetEdited() ) );
	connect( m_advRetriesSpinBox, SIGNAL( valueChanged( int ) ), this, SLOT( slotSetEdited() ) );
	connect( m_advEncodingComboBox, SIGNAL( activated( int ) ), this, SLOT( slotSetEdited() ) );
	connect( m_advListCmdEdit, SIGNAL( textChanged( const QString& ) ),
			this, SLOT( slotListCmdEditChanged( const QString& ) ) );
	connect( m_advListCmdEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotSetEdited() ) );
	connect( this, SIGNAL( aboutToShowPage( QWidget* ) ), this, SLOT( slotAboutToShowPage( QWidget* ) ) );
	connect( m_importWidget, SIGNAL( importSites( const QString& ) ), this, SIGNAL( importSites( const QString& ) ) );
}
//-----------------------------------------------
void KBearSiteManager::slotSetEdited() {
	enableButton( User1, true);
	m_isModified = true;
	slotUpdateAdv();
}
//-----------------------------------------------
void KBearSiteManager::slotSetHostEdited() {
	slotSetEdited();
	m_connectButton->setEnabled(true);
}
//-----------------------------------------------
SiteInfo KBearSiteManager::getCurrentSite() {
kdDebug()<<"KBearSiteManager::getCurrentSite()="<<m_siteEdit->text()<<endl;
	SiteInfo s;
	QListViewItem* item = siteTreeView->selectedItem();
	QString parentStr = QString::null;
	if( item ) {
		if( item->isExpandable() )
			parentStr = siteTreeView->getFullPath( item );
		else
			parentStr = siteTreeView->getParentString( item );
	}				
	s.setParent( parentStr );
	s.setDescription( m_descriptionEdit->text() );
	s.setLabel( m_siteEdit->text() );
	s.setHost( m_hostnameEdit->text() );
	if( m_protocolComboBox->currentText() == "ftp" /*&& m_hasKBearFTP */)
		s.setProtocol( "kbearftp" );
	else
		s.setProtocol( m_protocolComboBox->currentText() );

	s.setAnonym( !m_anonymousCheckBox->isChecked() );
	s.setUser( m_usernameComboBox->currentText() );
	s.setPass( encodePassword( m_passwordEdit->text() ) );

	if( m_localdirEdit->text() == "" )
		s.setLocalPath( "/" );
	else
		s.setLocalPath( m_localdirEdit->text() );
	if( m_remotedirEdit->text() == "" )
		s.setRemotePath( "/" );
	else
		s.setRemotePath( m_remotedirEdit->text() );

	s.setPort( m_portSpinBox->value() );
	
	// Advanced settings
	s.setAutoReconnect( m_advReconnectCheckBox->isChecked() );
	s.setReconnectTime( m_advWaitSpinBox->value() );
	s.setNumOfRetries( m_advRetriesSpinBox->value() );
/* Removed since this is now a globally option
	s.setBinaryMode( m_advBinaryRadio->isChecked() );
*/
	s.setEnableLog( m_advLogCheckBox->isChecked() );
	s.setMarkPartial( m_advPartCheckBox->isChecked() );
	s.setPassiveMode( !m_advPasvCheckBox->isChecked() );
	s.setListCommand( m_advListCmdEdit->text() );
/* Removed since this is now a globally option
	s.setQueue( m_advQueueCheckBox->isChecked() );
*/
	s.setSingleConnection( m_advSingleCheckBox->isChecked() );
	if( m_advEpsvCheckBox->isEnabled() )
		s.setExtendedPassiveMode( ! m_advEpsvCheckBox->isChecked() );
	else
		s.setExtendedPassiveMode( false );
	
	QString tmp = KGlobal::charsets()->encodingForName( m_advEncodingComboBox->currentText() );
	s.setFileSysEncoding( tmp );

	return s;
}
//-----------------------------------------------
void KBearSiteManager::slotConnect() {
	slotClose();
	SiteInfo site = getCurrentSite();
	site.setPass( decodePassword( site.pass() ) );
	emit openConnection( site );
}
//-----------------------------------------------
void KBearSiteManager::slotDoubleClicked(QListViewItem* item) {
	if( ! item || item->isExpandable() ) // no item or a group was selected so ignore it
		return;
kdDebug()<<"KBearSiteManager::slotDoubleClicked"<<endl;
	m_pendingConnect = true;
	slotSelectedSite( item );
}
//-----------------------------------------------
void KBearSiteManager::slotMoved(const QString& oldParent, const QString& name, QListViewItem* newParent, bool isGroup) {
	m_movedItem.setLabel( name );
	m_movedItem.setParent( oldParent );

	QString newParentPath = siteTreeView->getFullPath(newParent);		

	if( isGroup )
		emit moveGroup( m_movedItem, newParentPath );
	else {
		SiteInfo site;
		site.setLabel( name );
		site.setParent( oldParent );
		emit moveSite( site, newParentPath );
	}
}
//-----------------------------------------------
void KBearSiteManager::slotNewGroup() {
	QString name = promptForGroupName();
	if( name.isNull() )
		return;
	QListViewItem* selectedItem =  siteTreeView->selectedItem();
	QString parentName = QString::null;
	if( selectedItem ) {
		if( selectedItem->isExpandable() ) {
			parentName = siteTreeView->getFullPath( selectedItem );
		}
		else {
			parentName = siteTreeView->getFullPath( selectedItem->parent() );
		}
	}
	Group group;
	group.setLabel( name );
	group.setParent( parentName );
	emit newGroup( group );
}
//-----------------------------------------------
void KBearSiteManager::slotRemove() {
	if( ! siteTreeView->selectedItem() )
		return;
	QString tmp1, tmp2;
	if( siteTreeView->selectedItem()->isExpandable() ) {
		tmp1 = i18n("group");
		tmp2 = i18n("\nIf you do all sub groups/sites will be removed as well.");
	}
	else {
		tmp1 = i18n("site");
		tmp2 = i18n("\nIf you do the site will be removed permanently.");
	}
	int answer = KMessageBox::questionYesNo( this, i18n( "Do you really want to remove the %1:\n%2"
							"%3" ).arg(tmp1).arg(siteTreeView->selectedItem()->text(0)).arg(tmp2),
							i18n("Remove...") );
	if( answer == KMessageBox::No )
		return;
	if( siteTreeView->selectedItem()->isExpandable() ) {
		Group group;
		QListViewItem *item = siteTreeView->selectedItem()->parent();
		QString path;
		if( !item )
			 path = "/";
		else
			path = siteTreeView->getFullPath( siteTreeView->selectedItem()->parent() );
		group.setParent( path );
		QListViewItem* labelItem = siteTreeView->selectedItem();
		QString label;
		if( !labelItem )
			label = "";
		else
			label = labelItem->text( 0 );
		group.setLabel( label );
		emit removeGroup( group );
	}
	else {
		SiteInfo site = getCurrentSite();
		emit removeSite( site );
	}	
	clear();
}
//-----------------------------------------------
void KBearSiteManager::slotSave() {
	SiteInfo site = getCurrentSite();
	m_isModified = false;
	enableButton( User1, false );
	if( site.label() == m_selectedItem.label() ) {
		emit changeSite( site, m_selectedItem.label() );
	}
	else {
		emit saveSite( site );
	}
	m_selectedItem = site;
}
//-----------------------------------------------
void KBearSiteManager::slotContextMenu( KListView*, QListViewItem* item, const QPoint& pos) {
	if( ! item )
		return;
	QPopupMenu menu( this );
	menu.insertItem( i18n("&Remove"), this, SLOT( slotRemove() ) );
	menu.insertSeparator();
	const int RENAME = menu.insertItem( i18n("Rename") );
	menu.setMouseTracking( true );
	if( RENAME == menu.exec( pos ) ) {
		siteTreeView->rename( item, 0 );
	}
}
//-----------------------------------------------
void KBearSiteManager::slotItemRenamed(QListViewItem* item, const QString& newName, int) {
kdDebug()<<"KBearSiteManager::slotItemRenamed"<<endl;
	if( ! item || m_selectedItem.label() == newName )
		return;
kdDebug()<<"KBearSiteManager::slotItemRenamed selected="<<m_selectedItem.label()<<" new name="<<newName<<endl;
	if( item->isExpandable() ) {// group renamed
		Group group;
		group.setParent( m_selectedItem.parent() );
		group.setLabel( newName );
		emit changeGroup( group, m_selectedItem.label() );
	}
	else {
		m_siteEdit->blockSignals( true ); // we need to block signals so we don't think it's user changed
		m_siteEdit->setText( newName );
		QString oldName = m_selectedItem.label();
		m_selectedItem.setLabel( newName );
		emit changeSite( m_selectedItem, oldName );
		m_siteEdit->blockSignals( false );
	}
}
//-----------------------------------------------
void KBearSiteManager::slotPressed(QListViewItem* item) {
	if( ! item )
		slotSelectedSite( 0L );
		return;
	if( item->isExpandable() ) {
		m_advancedWidget->setEnabled( false );
	} else {
		m_advancedWidget->setEnabled( true );
	}
}
//-----------------------------------------------
void KBearSiteManager::slotSelectedSite( QListViewItem* item ) {
kdDebug()<<"KBearSiteManager::slotSelectedSite item="<<(item?item->text(0):QString::null)<<endl;

	if( item && item->isSelected() ) {
 		//checkModified();
		QString parent = siteTreeView->getParentString( item );
		QString label = item->text( 0 );
		m_removeButton->setEnabled( true );
		
		bool b = item->isExpandable();
		// Enable/Disable the groupBox items depending on the item (group or not)	
		m_siteEdit->setEnabled( true );
		m_hostnameEdit->setEnabled( !b );
		m_portSpinBox->setEnabled( !b );
		m_protocolComboBox->setEnabled( !b );
		m_anonymousCheckBox->setEnabled( !b );
		m_usernameComboBox->setEnabled( !b );
		m_passwordEdit->setEnabled( !b );
		m_localdirEdit->setEnabled( !b );
		m_remotedirEdit->setEnabled( !b );
		m_advancedWidget->setEnabled( !b );
		
		if( item->isExpandable() ) {// a group was selected
			clear();
			m_selectedItem.setParent( parent );
			m_selectedItem.setLabel( label );
			emit selectionCleared();
			m_groupSelected = true;
			return;
		}
		m_selectedItem.setParent( parent );
		m_selectedItem.setLabel( label );
		m_groupSelected = false;
	}
	else {
		m_selectedItem.setParent( QString::null );
		m_selectedItem.setLabel( QString::null );
		m_removeButton->setEnabled( false );
		m_groupBox->setEnabled( false );
		clear();
		emit selectionCleared();
		kdDebug()<<"KBearSiteManager::slotSelectedSite item==NULL"<<endl;
		return;
	}
	m_groupBox->setEnabled( true );
	emit siteSelected( m_selectedItem );
}
//-----------------------------------------------
void KBearSiteManager::setSite( const SiteInfo& site ) {
	m_siteEdit->setText( site.label() );
	m_hostnameEdit->setText( site.host() );
	QString prot = (site.protocol()=="kbearftp"?QString::fromLatin1("ftp"):site.protocol());
	m_protocolComboBox->setCurrentItem( prot );
	m_anonymousCheckBox->setChecked( site.anonym() );
	m_usernameComboBox->setCurrentText( site.user() );
	m_passwordEdit->setText( decodePassword( site.pass() ) );
	m_localdirEdit->setText( site.localPath() );
	m_remotedirEdit->setText( site.remotePath() );
	m_portSpinBox->setValue( site.port() );
	m_descriptionEdit->setText( site.description() );
	// Advanced settings
	m_advReconnectCheckBox->setChecked( site.autoReconnect() );
	m_advWaitSpinBox->setValue( site.reconnectTime() );
	m_advRetriesSpinBox->setValue( site.numOfRetries() );
/* Removed since this is now a globally option
	if( site.binaryMode() )
		m_advBinaryRadio->setChecked( true );
	else
		m_advAsciiRadio->setChecked( true );
*/
	m_advLogCheckBox->setChecked( ! site.enableLog() );
	m_advPartCheckBox->setChecked( site.markPartial() );
	m_advPasvCheckBox->setChecked( ! site.passiveMode() );
	m_advEpsvCheckBox->setChecked( ! site.extendedPassiveMode() );
	if( site.listCommand() == "list -a" )
		m_advListCmdCheckBox->setChecked( true );
	else {
		m_advListCmdCheckBox->setChecked( false );
	}
	// we should always display the list command (kbjorn)
	m_advListCmdEdit->setText( site.listCommand() );

//	m_advListCheckBox->setChecked( ! site.listA() );
/* Removed since this is now a globally option
	m_advQueueCheckBox->setChecked( site.queue() );
*/
	m_advSingleCheckBox->setChecked( site.singleConnection() );
	QString fileSysEncoding = site.fileSysEncoding();
	 for( int i = 0; i < m_advEncodingComboBox->count(); i++ ) {
		QString tmp = KGlobal::charsets()->encodingForName( m_advEncodingComboBox->text( i ) );
		if( tmp == fileSysEncoding ) {
			m_advEncodingComboBox->setCurrentItem( i );
			break;
		}
	}

	slotUpdateAdv();

	m_isModified = false;
	m_selectedItem = site;
	m_connectButton->setEnabled( true );
	enableButton( User1, false );
//	m_saveButton->setEnabled( false );
	QListViewItem* parentItem = siteTreeView->findParentByFullName( site.parent() );
	if( parentItem ) {
		QListViewItem* item = siteTreeView->findItemByName( parentItem, site.label() );
		if( item ) {
			siteTreeView->ensureItemVisible( item );
			siteTreeView->blockSignals( true );
			siteTreeView->setSelected( item, true );		
			siteTreeView->blockSignals( false );
		}
	}
	if( m_pendingConnect ) {
		slotConnect();
		m_pendingConnect = false;
	}
}
//-----------------------------------------------
void KBearSiteManager::slotSetEncoding(const QString& encoding) {
	emit newEncoding( KGlobal::charsets()->encodingForName( encoding ) );
}
//-----------------------------------------------
void KBearSiteManager::slotSelectedProtocol( const QString& protocol ) {
	int port = KBear::getPortForProtocol( protocol );
	if( port > 0 ) {
		m_portSpinBox->setValue( port );
	}
}
//-----------------------------------------------
void KBearSiteManager::setupProtocolCombo() {
	bool hasFTP = false;
	QStringList protList = KProtocolInfo::protocols();
	for( QStringList::Iterator it = protList.begin(); it != protList.end(); ++it ) {
		if( ( KProtocolInfo::outputType( *it ) == KProtocolInfo::T_FILESYSTEM )
			&& KProtocolInfo::supportsListing( *it )
			&& KProtocolInfo::supportsReading( *it )
			&& KProtocolInfo::supportsWriting( *it )
			&& KProtocolInfo::supportsMakeDir( *it )
			&& KProtocolInfo::supportsDeleting( *it ) ) {
							
			if( *it == "ftp" )
				hasFTP = true;
			else if( *it == "kbearftp" )
				m_hasKBearFTP = true;
			if( (*it != "floppy") && (*it != "file") && ( (*it).left(6) != "webdav") )
				m_protocolComboBox->insertItem( *it );
			
		}
	}		
	if( hasFTP ) {
		if( m_hasKBearFTP ) {
			m_protocolComboBox->setCurrentText( "kbearftp" );
			m_protocolComboBox->removeItem( m_protocolComboBox->currentItem() );
		}
		m_protocolComboBox->setCurrentText( "ftp" );
	}
	slotSelectedProtocol( m_protocolComboBox->currentText() );
}
//-----------------------------------------------
void KBearSiteManager::clear(){
	SiteInfo site;  // We use a site here in order to get the correct default values
	setSite( site );	
	m_connectButton->setEnabled( false );
}
//-----------------------------------------------
QString KBearSiteManager::promptForGroupName() {
	bool ok;
	QString name = KLineEditDlg::getText( i18n("Enter name for the group:"),  i18n("New Group"), &ok, this );
	if( ok )
		return name;
	
	return QString::null;
}
//-----------------------------------------------
void KBearSiteManager::slotClose() {
	if( ! checkModified() ) {
		return;
	}
	KDialogBase::slotClose();
//	close();
}
//-----------------------------------------------
bool KBearSiteManager::checkModified() {
	if( m_isModified ) {
		int answer = KMessageBox::warningYesNoCancel( this, i18n( "You have unsaved changes.\n"
							"Do you want to save these changes ?" ), i18n("Unsaved changes...") );

		switch( answer ) {
			case KMessageBox::Yes:
				slotSave();
				break;
			case KMessageBox::Cancel:
				//m_saveButton->setEnabled(false);
				enableButton( User1, false );
				m_isModified = false;
				return false;
			default:
					enableButton( User1, false );
				//m_saveButton->setEnabled(false);
				m_isModified = false;
				break;
		}
	}
	return true;
}
//-----------------------------------------------
void KBearSiteManager::slotAboutToShowPage( QWidget* w ) {
	kdDebug()<<k_funcinfo<<endl;
	if( w == m_advancedWidget )  slotUpdateAdv();	// Update Advanced Settings
}
//-----------------------------------------------
void KBearSiteManager::slotUpdateAdv() {
	bool enabled = (m_protocolComboBox->currentText() == "ftp");
	bool tmp = actionButton( User1 )->isEnabled(); // store the original state because it will be changed when we change the widgets
/* Removed since this is now a globally option
	m_advBinaryRadio->setEnabled( enabled );
	m_advAsciiRadio->setEnabled( enabled );
*/

	if( m_advPasvCheckBox->isChecked() ) {
		m_advEpsvCheckBox->setChecked( false );
		m_advEpsvCheckBox->setEnabled( false );
	} else {
		m_advEpsvCheckBox->setEnabled( true );
	}
	if( !m_advListCmdCheckBox->isChecked() ) {
		m_advListCmdEdit->setEnabled( true );
		if( m_advListCmdEdit->text().isEmpty() )
			m_advListCmdEdit->setText( QString::fromLatin1("list -a") );
	} else {
		m_advListCmdEdit->setEnabled( false );
		m_advListCmdEdit->setText( QString::fromLatin1("list -a") );
	}
	m_advWaitSpinBox->setEnabled( enabled && m_advReconnectCheckBox->isChecked() );
	m_advRetriesSpinBox->setEnabled( enabled && m_advReconnectCheckBox->isChecked() );

	// These settings only apply to ftp protocol, so we disable them
	// for all others. Also disable the encoding for now since we don't know
	// how to handle it yet. I would like to handle it in the ftp implementation
	// and if so it also only apply to ftp.
	m_advPasvCheckBox->setEnabled( enabled );
	m_advEpsvCheckBox->setEnabled( enabled && m_advEpsvCheckBox->isEnabled() );
	m_advListCmdCheckBox->setEnabled( enabled );
	m_advListCmdEdit->setEnabled( enabled && m_advListCmdEdit->isEnabled() );
	m_advEncodingComboBox->setEnabled( enabled );

	enableButton( User1, tmp );
	m_isModified = tmp;
}
//-----------------------------------------------
void KBearSiteManager::slotSiteLabelChanged() {
	if( m_groupSelected ) {
		m_hostnameEdit->setEnabled( true );
		m_portSpinBox->setEnabled( true );
		m_protocolComboBox->setEnabled( true );
		m_anonymousCheckBox->setEnabled( true );
		m_usernameComboBox->setEnabled( true );
		m_passwordEdit->setEnabled( true );
		m_localdirEdit->setEnabled( true );
		m_remotedirEdit->setEnabled( true );
		m_advancedWidget->setEnabled( true );
	}
}
//-----------------------------------------------
void KBearSiteManager::slotListCmdEditChanged( const QString & text ) {
	if( text == QString::fromLatin1("list -a") ) {
		// we should always display the list command (kbjorn)
		//m_advListCmdEdit->setText("");
		m_advListCmdEdit->setEnabled( false );
		m_advListCmdCheckBox->setChecked( true );
	}
}

#ifndef NO_INCLUDE_MOCFILES
#include "kbearsitemanager.moc"
#endif
