/*********************************************************************************
* C++ Implementation: transfermanager.cpp
* Description:
*                              
* Begin : tis jan 15 2003
* Author : Björn Sahlström <kbjorn@users.sourceforge.net> (C) 2003
* Copyright : See COPYING file that comes with this distribution
**********************************************************************************/

//////////////////////////////////////////////////////////////////////
// Qt specific include files
#include <qlcdnumber.h>
#include <qcheckbox.h>
#include <qradiobutton.h>
#include <qlabel.h>
#include <qfont.h>
#include <qmap.h>
#include <qintdict.h>
#include <qstringlist.h>
#include <qvbox.h>
#include <qobjectlist.h>
#include <qpushbutton.h>
#include <qbuttongroup.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <kapplication.h>
#include <keditlistbox.h>
#include <kconfig.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <kurldrag.h>
#include <kconfigbase.h>
#include <klocale.h>
#include <kdebug.h>
#include <kmainwindow.h>
//////////////////////////////////////////////////////////////////////
// System specific include files
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "transfermanager.h"
#include "transfer.h"
#include "transfergroup.h"
#include "kbearcore.h"
#include "kbearmainwiniface.h"
#include "connectionmanager.h"
#include "kbearcopyjob.h"
#include "misc.h"


#include "transfermanager.moc"

using namespace KBear;


///////////////////////////////////////////////////////////
// class KBearQueryExit
///////////////////////////////////////////////////////////
class TransferManager::KBearQueryExit : public KDialogBase {
	public:
		/** */
		KBearQueryExit( QWidget* parent = 0, const char* name = 0 );
		/** */
		virtual ~KBearQueryExit();
	public:
		QLCDNumber* m_activeTransfers;
		QLCDNumber* m_queuedTransfers;
		QCheckBox* m_askAgain;
};
///////////////////////////////////////////////////////////
// class TransferConfigWidget
///////////////////////////////////////////////////////////
class TransferManager::TransferConfigWidget :  public KBear::KBearConfigWidgetIface {
	public:
		/** */
		TransferConfigWidget( QWidget* parent = 0, const char* name = 0 );
		/** */
		virtual ~TransferConfigWidget();
		/** */
		virtual bool helpEnabled() const { return false; }
		/** */
		virtual void readSettings( bool defaultSettings = false );
		/** */
		virtual void saveSettings();
		/** */
		virtual void swallow( QWidget*);
	public:
		QCheckBox* m_confirmCheckBox;
		QCheckBox* m_overWriteCheckBox;
		KEditListBox* m_extensionsListBox;
		QRadioButton* m_asciiModeButton;
		QRadioButton* m_binaryModeButton;
		QRadioButton* m_autoModeButton;
	private:
		QVBoxLayout* m_layout;
		QSpacerItem* m_endSpacer;
};
///////////////////////////////////////////////////////////
// class TransferManager::TransferManagerPrivate
///////////////////////////////////////////////////////////
class TransferManager::TransferManagerPrivate {
	public:
		TransferManagerPrivate()
			:	m_configWidget( 0L ),
				m_startTransfersDirectly( true ),
				m_transferMode( KBear::Binary ),
				m_idCounter( 0 ), m_overWrite( false )
		{
			m_transferGroups.setAutoDelete( true );
		}
	public:
		QGuardedPtr<KBear::KBearConfigWidgetIface> m_configWidget;
		bool m_startTransfersDirectly;
		unsigned int m_transferMode;
		QMap<long, Transfer* > m_transferDict;
		QIntDict<TransferGroup> m_transferGroups;
		long m_idCounter;
		bool m_overWrite;
	};
//-----------------------------------------------
TransferManager* TransferManager::s_instance = 0L;
//-----------------------------------------------
TransferManager::TransferManager()
	:	QObject( KBearMainWindowInterface::getInstance()->core() )
{
	d = new TransferManagerPrivate();
//	connect( KBearMainWindowInterface::getInstance()->core(), SIGNAL(configWidget(KDialogBase*)), this, SLOT(slotConfigWidget(KDialogBase*)) );
//	connect( KBearMainWindowInterface::getInstance()->core(), SIGNAL(configWidget(KWizard*)), this, SLOT(slotConfigWidget(KWizard*)) );
	connect( KBearMainWindowInterface::getInstance()->core(), SIGNAL( shutDownRequested() ), this, SLOT( slotShutDownRequested() ) );
	connect( KBearMainWindowInterface::getInstance()->core(), SIGNAL( metaDataNeeded( KIO::MetaData& ) ),
					this, SLOT( slotMetaDataNeeded( KIO::MetaData& ) ) );

	readSettings();
}
//-----------------------------------------------
TransferManager::~TransferManager() {
	cleanUp();
	delete d;
}
//-----------------------------------------------
void TransferManager::cleanUp() {
	QMap<long, Transfer*>::iterator it = d->m_transferDict.begin();
	for( ; it != d->m_transferDict.end(); ++it ) {
		removeTransfer( (*it), true );
	}
}
//-----------------------------------------------
void TransferManager::slotTransferStatusChanged( long ID, unsigned int status ) {
	switch( status ) {
		case Transfer::Started: {
			break;
		}
		case Transfer::Paused: {
			break;
		}
		case Transfer::Queued: {
			break;
		}
		case Transfer::Finished: {
			emit transferDone( ID );
			removeTransfer( ID );
			break;
		}
		case Transfer::Stopped: { // do we need both Stopped and Canceled ?
		} // fall through
		case Transfer::Canceled: {
			emit transferDone( ID );
			break;
		}
	};
	emit statusChanged( ID, status );
}
//-----------------------------------------------
int TransferManager::numOfActiveTransfers() const {
	return countForStatus( Transfer::Started | Transfer::Paused | Transfer::Uninitialized );
}
//-----------------------------------------------
int TransferManager::numOfQueuedTransfers() const {
	return countForStatus( Transfer::Queued );
}
//-----------------------------------------------
int TransferManager::countForStatus( unsigned int status ) const {
	int count = 0;

	QMap<long, Transfer*>::iterator it = d->m_transferDict.begin();
	for( ; it != d->m_transferDict.end(); ++it ) {
		if( (*it) && ( (*it)->status() & status ) )
			++count;
	}

	return count;
}
//-----------------------------------------------
void TransferManager::setStartTransfersDirectly( bool s ) {
	d->m_startTransfersDirectly = s;
}
//-----------------------------------------------
bool TransferManager::startTransfersDirectly() const {
	return d->m_startTransfersDirectly;
}
//-----------------------------------------------
KBearConfigWidgetIface* TransferManager::configWidget() const {
	return (KBearConfigWidgetIface*)d->m_configWidget;
}
//-----------------------------------------------
TransferGroup* TransferManager::addTransfers( KURLDrag* drag ) {
	Transfer* transfer = 0L;
	TransferGroup* group = 0L;
	KURL::List urls;
	KURL destURL;
	KIO::MetaData metaData;
	KURLDrag::decode( drag, urls, metaData );
	// we are responsible for deleting this
	delete drag;

	int sID = -1;
	int dID = -1;
	if( metaData.contains( "SourceID" ) )
		sID = metaData[ "SourceID" ].toInt();
	if( metaData.contains( "DestID" ) )
		dID = metaData[ "DestID" ].toInt();
	if( metaData.contains( "DestURL" ) ) {
		destURL = metaData[ "DestURL" ];
	}
	else {
		kdError()<<"BUG!!!!!! No destination URL set for transfer in TransferManager::addTransfer( KURLDrag* )"<<endl;
		return group;
	}

	unsigned int type =( ( metaData[ "Action" ] == "move" ) ? Transfer::Move : Transfer::Copy );

	int groupID = getNewGroupID();
	group = new TransferGroup( this, groupID );
	d->m_transferGroups.insert( groupID, group );

	for( unsigned int i = 0; i < urls.count(); i++ ) {
		long ID = getNewID();
		transfer = new Transfer( group, ID, sID, dID, type, metaData[ urls[ i ].url() ] );
		transfer->setSourceURLs( urls[ i ] );
		transfer->setDestURL( destURL );
		transfer->setOverWrite( d->m_overWrite );

		group->addTransfer( transfer );

		d->m_transferDict.insert( ID, transfer );

		kdDebug()<<"TransferManager::addTransfer() Emitting transferAdded() ID="<<ID<<endl;

		connectTransfer( transfer );

		emit transferAdded( ID, transfer );
	}

	emit transferGroupAdded( groupID, group );

	if( d->m_startTransfersDirectly ) {
		QPtrList<Transfer>* transferList = group->transfers();
		for( transfer = transferList->first(); transfer; transfer = transferList->next() ) {
			transfer->setCommand( Transfer::Start );
		}
	}

	return group;
}
//-----------------------------------------------
void TransferManager::connectTransfer( Transfer* transfer ) {
	connect( transfer, SIGNAL( percent( long, unsigned long ) ),
						this, SIGNAL( progress( long, unsigned long ) ) );
	connect( transfer, SIGNAL( totalDirs( long, unsigned long ) ),
						this, SIGNAL( totalDirs( long, unsigned long ) ) );
	connect( transfer, SIGNAL( totalFiles( long, unsigned long ) ),
						this, SIGNAL( totalFiles( long, unsigned long ) ) );
	connect( transfer, SIGNAL( processedFiles( long, unsigned long ) ),
						this, SIGNAL( processedFiles( long, unsigned long ) ) );
	connect( transfer, SIGNAL( processedDirs( long, unsigned long ) ),
						this, SIGNAL( processedDirs( long, unsigned long ) ) );
	connect( transfer, SIGNAL( copying( long, const KURL&, const KURL& ) ),
						this, SIGNAL( copying( long, const KURL&, const KURL& ) ) );
	connect( transfer, SIGNAL( moving( long, const KURL&, const KURL& ) ),
						this, SIGNAL( moving( long, const KURL&, const KURL& ) ) );
	connect( transfer, SIGNAL( creatingDir( long, const KURL& ) ),
						this, SIGNAL( creatingDir( long, const KURL& ) ) );
	connect( transfer, SIGNAL( renamed( long, const KURL&, const KURL& ) ),
						this, SIGNAL( renamed( long, const KURL&, const KURL& ) ) );
	connect( transfer, SIGNAL( totalSize( long, KIO::filesize_t ) ),
						this, SIGNAL( totalSize( long, KIO::filesize_t ) ) );
	connect( transfer, SIGNAL( processedSize( long, KIO::filesize_t ) ),
						this, SIGNAL( processedSize( long, KIO::filesize_t ) ) );
	connect( transfer, SIGNAL( speed( long, unsigned long ) ),
						this, SIGNAL( speed( long, unsigned long ) ) );
	connect( transfer, SIGNAL( statusChanged( long, unsigned int ) ),
						this, SLOT( slotTransferStatusChanged( long, unsigned int ) ) );
}
//-----------------------------------------------
void TransferManager::setTransferCommand( long ID, unsigned int cmd ) {
	Transfer* transfer = d->m_transferDict[ ID ];
	if( transfer ) {
		setTransferCommand( transfer, cmd );
	}
}
//-----------------------------------------------
void TransferManager::setTransferCommand( Transfer* transfer, unsigned int  cmd ) {
	if( transfer )
		transfer->setCommand( cmd );
}
//-----------------------------------------------
void TransferManager::removeTransfer( Transfer* transfer, bool quietly ) {
	if( transfer ) {
		if( ! quietly )
			emit removingTransfer( transfer->transferID() );
		TransferGroup* group = transfer->group();
		group->removeTransfer( transfer );
		if( group->isEmpty() ) {
			if( ! quietly )
				emit removingTransferGroup( group->ID() );
			d->m_transferGroups.remove( group->ID() );
		}
		d->m_transferDict.remove( transfer->transferID() );
		transfer->deleteLater();
	}
}
//-----------------------------------------------
void TransferManager::removeTransfer( long ID ) {
	Transfer* transfer = d->m_transferDict[ ID ];
	if( transfer && transfer->status() != Transfer::Started
							&& transfer->status() != Transfer::Paused )
	{
		removeTransfer( transfer );
	}
}
//-----------------------------------------------
long TransferManager::getNewID() {
	return ++d->m_idCounter;
}
//-----------------------------------------------
int TransferManager::getNewGroupID() {
	int ID = 0;
	while( d->m_transferGroups.find( ID ) )
		++ID;

	return ID;
}
//-----------------------------------------------
void TransferManager::setOverWrite( bool overwrite ) {
	d->m_overWrite = overwrite;
}
//-----------------------------------------------
void TransferManager::setTransferMode( unsigned int mode ) {
	d->m_transferMode = mode;
	KConfig* config = kapp->config();
	KConfigGroupSaver( config, config->group() );
	config->setGroup( QString::fromLatin1("TransferManager" ) );
	config->writeEntry("TransferMode", mode );

	emit transferModeChanged( d->m_transferMode );
}
//-----------------------------------------------
unsigned int TransferManager::transferMode() const {
	return d->m_transferMode;
}
//-----------------------------------------------
void TransferManager::slotMetaDataNeeded(  KIO::MetaData& metaData ) {
	KConfigGroupSaver cs( kapp->config(), kapp->config()->group() );
	kapp->config()->setGroup("TransferManager");
	QStringList lst = kapp->config()->readListEntry( "AutoExtensions" );
	QString tmp = lst.join( "," );
	metaData.insert( "AutoExtensions", tmp );
}
//-----------------------------------------------
void TransferManager::slotShutDownRequested() {
	KConfigGroupSaver cs( kapp->config(), kapp->config()->group() );
	kapp->config()->setGroup("TransferManager");
	bool confirm;
	int accept = QDialog::Accepted;

	int activeTransfers = numOfActiveTransfers();
	int queuedTransfers = numOfQueuedTransfers();

	// do user want to confirm exit on active transfers ?
	if( ( confirm = kapp->config()->readBoolEntry( "ConfirmOnExit", true) )
		&& ( activeTransfers > 0 || queuedTransfers > 0 ) )
	{
		KBearQueryExit queryExitDlg( KBearMainWindowInterface::getInstance()->mainWindow(), "KBearQueryExit" );
		queryExitDlg.m_activeTransfers->display( i18n("%1").arg( activeTransfers ) );
		queryExitDlg.m_queuedTransfers->display( i18n("%1").arg( queuedTransfers ) );
		queryExitDlg.m_askAgain->setChecked( ! confirm );
		accept = queryExitDlg.exec();
		bool confirm = queryExitDlg.m_askAgain->isChecked();
		// set 'ask again'  according to users choice
		if ( accept == QDialog::Accepted ) {
			kapp->config()->writeEntry( "ConfirmOnExit", ! confirm );
		}
	}
	if( accept != QDialog::Accepted ) {
		kdDebug()<<"TransferManager::slotShutDownRequested() ABORTING !!!!!"<<endl;
		KBearMainWindowInterface::getInstance()->core()->abortShutDown();
	}
}
//-----------------------------------------------
void TransferManager::slotConfigWidget( KDialogBase* dlg ) {
	QVBox* vbox = dlg->addVBoxPage( i18n("Transfers"), QString::null,
									KGlobal::iconLoader()->loadIcon("ftp", KIcon::NoGroup, KIcon::SizeMedium) );
	d->m_configWidget = new TransferConfigWidget( vbox, "KBearToolsWidget" );
	connect( dlg, SIGNAL( okClicked() ), this, SLOT( slotSaveConfig() ) );
}
//-----------------------------------------------
void TransferManager::slotConfigWidget( KWizard* wiz ) {
	d->m_configWidget = new TransferConfigWidget( wiz, "KBearToolsWidget" );
	wiz->addPage( d->m_configWidget, i18n("Transfers") );
}
//-----------------------------------------------
void TransferManager::slotSaveConfig() {
	if( d->m_configWidget )
		d->m_configWidget->saveSettings();
}
//-----------------------------------------------
void TransferManager::readSettings() {
	KConfig* config = kapp->config();

	KConfigGroupSaver( config, config->group() );
	config->setGroup( QString::fromLatin1("TransferManager" ) );

	d->m_overWrite = config->readBoolEntry("OverWrite", false );
	d->m_transferMode = config->readUnsignedNumEntry("TransferMode", KBear::Binary );
	emit transferModeChanged( d->m_transferMode );
}
//-----------------------------------------------
void TransferManager::saveSettings() {
	KConfig* config = kapp->config();
	KConfigGroupSaver( config, config->group() );
	config->setGroup( QString::fromLatin1("TransferManager" ) );
	config->writeEntry("TransferMode", d->m_transferMode );
}
//-----------------------------------------------
TransferManager* TransferManager::getInstance() {

	if( ! s_instance )
		s_instance = new TransferManager();
	return s_instance;
}
//-----------------------------------------------
void TransferManager::emitConfigChanged() {
	readSettings();
	emit configChanged();
}
//-----------------------------------------------
// class TransferManager::TransferConfigWidget
//-----------------------------------------------
TransferManager::TransferConfigWidget::TransferConfigWidget( QWidget* parent,  const char* name )
	:	KBearConfigWidgetIface( parent, name )
{
	m_layout = new QVBoxLayout( this, 11, 6 );

	QLabel* infoLabel = new QLabel( this );
	infoLabel->setText( i18n( "<p>The settings on this page all concerns the Transfers in one way or another. "
															"The contents may differ depending on which plugins are loaded.</p>" ) );
	infoLabel->setAlignment( int( QLabel::WordBreak | QLabel::AlignTop ) );

	m_layout->addWidget( infoLabel );

	QButtonGroup* transferModeButtonGroup = new QButtonGroup( this, "transferModeButtonGroup" );
	transferModeButtonGroup->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum, 0, 0, transferModeButtonGroup->sizePolicy().hasHeightForWidth() ) );
	transferModeButtonGroup->setColumnLayout(0, Qt::Vertical );
	transferModeButtonGroup->layout()->setSpacing( 6 );
	transferModeButtonGroup->layout()->setMargin( 11 );
	transferModeButtonGroup->setTitle( i18n( "File transfer mode" ) );
	QGridLayout* transferModeButtonGroupLayout = new QGridLayout( transferModeButtonGroup->layout() );
	transferModeButtonGroupLayout->setAlignment( Qt::AlignTop );

	m_extensionsListBox = new KEditListBox( transferModeButtonGroup, "m_extensionsListBox" );
	m_extensionsListBox->setTitle( i18n( "Set file extensions to automatically transfer in ASCII mode" ) );
	m_extensionsListBox->setEnabled( false );

	transferModeButtonGroupLayout->addMultiCellWidget( m_extensionsListBox, 1, 1, 0, 3 );

	m_asciiModeButton = new QRadioButton( transferModeButtonGroup, "m_asciiModeButton" );
	m_asciiModeButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, m_asciiModeButton->sizePolicy().hasHeightForWidth() ) );
	m_asciiModeButton->setText( i18n( "ASCII (A)" ) );
	QString tmp = i18n( "Check this option if you want files to be transfered in ASCII mode.\n"
						"This can be necessary for some filetypes, for example some perl scripts.\nSee also the Auto option." );
	QToolTip::add( m_asciiModeButton, tmp );
	QWhatsThis::add( m_asciiModeButton, tmp );

	transferModeButtonGroupLayout->addWidget( m_asciiModeButton, 0, 1 );

	m_binaryModeButton = new QRadioButton( transferModeButtonGroup, "m_binaryModeButton" );
	m_binaryModeButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, m_binaryModeButton->sizePolicy().hasHeightForWidth() ) );
	m_binaryModeButton->setText( i18n( "Binary (I)" ) );
	m_binaryModeButton->setChecked( true );
	tmp = i18n( "Check this option if you want files to be transfered in binary mode.\nThis is normally the best option" );
	QToolTip::add( m_binaryModeButton, tmp );
	QWhatsThis::add( m_binaryModeButton, tmp );

	transferModeButtonGroupLayout->addWidget( m_binaryModeButton, 0, 0 );

	m_autoModeButton = new QRadioButton( transferModeButtonGroup, "m_autoModeButton" );
	m_autoModeButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, m_autoModeButton->sizePolicy().hasHeightForWidth() ) );
	m_autoModeButton->setText( i18n( "Auto" ) );
	tmp = i18n( "Check this option if you want all files matching the extensions list below, to be  transfered in ASCII mode (A).\n"
							"This can be necessary for some filetypes, for example some perl scripts.\nAll non matching files will be transfered in Binary mode (I)" );
	QToolTip::add( m_autoModeButton, tmp );
	QWhatsThis::add( m_autoModeButton, tmp );

	transferModeButtonGroupLayout->addWidget( m_autoModeButton, 0, 2 );

	m_layout->addWidget( transferModeButtonGroup, 1, 0 );

	m_confirmCheckBox = new QCheckBox( this, "ConfirmCheckBox" );
	m_confirmCheckBox->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, m_confirmCheckBox->sizePolicy().hasHeightForWidth() ) );
	m_confirmCheckBox->setText( i18n( "On active transfers, always confirm before exiting." ) );
	tmp = i18n( "Check this option if you want the application to check if there are active or queued transfers,\n"
										"and if so, ask for confirmation before exiting." );
	QToolTip::add( m_confirmCheckBox, tmp );
	QWhatsThis::add( m_confirmCheckBox, tmp );

	m_layout->addWidget( m_confirmCheckBox );

	m_overWriteCheckBox = new QCheckBox( this, "OverWriteCheckBox" );
	m_overWriteCheckBox->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, m_confirmCheckBox->sizePolicy().hasHeightForWidth() ) );
	m_overWriteCheckBox->setText( i18n( "Overwrite files/directories by default." ) );
	tmp = i18n( "Check this option if you want the application to overwrite files/directories by default." );
	QToolTip::add( m_overWriteCheckBox, tmp );
	QWhatsThis::add( m_overWriteCheckBox, tmp );

	m_layout->addWidget( m_overWriteCheckBox );

	m_endSpacer = new QSpacerItem( 10, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum );
	m_layout->addItem( m_endSpacer );
//	clearWState( WState_Polished );

	// signals and slots connections
	connect( m_autoModeButton, SIGNAL( toggled(bool) ), m_extensionsListBox, SLOT( setEnabled(bool) ) );

	readSettings();

	m_layout->activate();
}
//-----------------------------------------------
TransferManager::TransferConfigWidget::~TransferConfigWidget() {
}
//-----------------------------------------------
void TransferManager::TransferConfigWidget::readSettings( bool defaultSettings ) {
	KConfig* config = kapp->config();
	KConfigGroupSaver( config, config->group() );
	config->setGroup( QString::fromLatin1("TransferManager" ) );
	if( defaultSettings ) {
		config->deleteEntry( "ConfirmOnExit" );
		config->deleteEntry( "OverWrite" );
		config->deleteEntry( "TransferMode" );
		config->deleteEntry( "AutoExtensions" );
		config->sync();
	}
	m_confirmCheckBox->setChecked( config->readBoolEntry( "ConfirmOnExit", true ) );
	m_overWriteCheckBox->setChecked( config->readBoolEntry( "OverWrite", false ) );
	unsigned int transferMode = config->readUnsignedNumEntry("TransferMode", KBear::Binary );
	switch( transferMode ) {
		case KBear::Ascii:
			m_asciiModeButton->setChecked( true );
			break;
		case KBear::Auto:
			m_autoModeButton->setChecked( true );
			break;
		default:
			m_binaryModeButton->setChecked( true );
	}
	m_extensionsListBox->setEnabled( m_autoModeButton->isChecked() );

	QStringList lst = config->readListEntry( "AutoExtensions" );
	m_extensionsListBox->insertStringList( lst );

	QObjectList* childList = queryList( "KBear::KBearConfigWidgetIface" );
	for( QObject* child = childList->first(); child; child = childList->next() ) {
		KBear::KBearConfigWidgetIface* w = dynamic_cast<KBear::KBearConfigWidgetIface*>( child );
		if( w )
			w->readSettings( defaultSettings );
	}
}
//-----------------------------------------------
void TransferManager::TransferConfigWidget::saveSettings() {
	KConfig* config = kapp->config();
	KConfigGroupSaver( config, config->group() );
	config->setGroup( QString::fromLatin1("TransferManager" ) );
	config->writeEntry( "ConfirmOnExit", m_confirmCheckBox->isChecked() );
	config->writeEntry( "OverWrite", m_overWriteCheckBox->isChecked() );

	if( m_asciiModeButton->isChecked() )
		config->writeEntry("TransferMode", KBear::Ascii );
	else if( m_autoModeButton->isChecked() )
		config->writeEntry("TransferMode", KBear::Auto );
	else
		config->writeEntry("TransferMode", KBear::Binary );

	config->writeEntry( "AutoExtensions", m_extensionsListBox->items() );

	config->sync();

	QObjectList* childList = queryList( "KBear::KBearConfigWidgetIface" );
	for( QObject* child = childList->first(); child; child = childList->next() ) {
		KBear::KBearConfigWidgetIface* w = dynamic_cast<KBear::KBearConfigWidgetIface*>( child );
		if( w )
			w->saveSettings();
	}
	TransferManager::getInstance()->emitConfigChanged();
}
//-----------------------------------------------
void TransferManager::TransferConfigWidget::swallow( QWidget* widget ) {
	if( ! widget )
		return;
	m_layout->removeItem( m_endSpacer );
	m_layout->addWidget( widget );
	m_layout->addItem( m_endSpacer );
	m_layout->activate();
}
//-----------------------------------------------
// class TransferManager::KBearQueryExit;
//-----------------------------------------------
TransferManager::KBearQueryExit::KBearQueryExit( QWidget* parent,  const char* name )
    : KDialogBase( parent, name, true, i18n( "Exiting application..." ), Ok|Cancel, Ok )
{
	setButtonText( Ok, i18n("&Quit") );
	setSizeGripEnabled( false );
	QFrame* mainWidget = makeMainWidget();
	QGridLayout* KBearQueryExitLayout = new QGridLayout( mainWidget, 1, 1, 11, 6, "KBearQueryExitLayout");

	QLabel* queryExitLabel = new QLabel( mainWidget, "queryExitLabel" );
	queryExitLabel->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, queryExitLabel->sizePolicy().hasHeightForWidth() ) );
/*
	queryExitLabel_font.setFamily( "adobe-times" );
	queryExitLabel_font.setPointSize( 18 );
	queryExitLabel_font.setBold( true );
	queryExitLabel_font.setItalic( true );
	queryExitLabel->setFont( queryExitLabel_font );
	QFont queryExitLabel_font(  queryExitLabel->font() );
*/
	queryExitLabel->setText( QString("<h1>%1</h1>").arg( i18n( "Do you really want to quit ?" ) ) );
	queryExitLabel->setAlignment( int( QLabel::AlignCenter ) );

	KBearQueryExitLayout->addMultiCellWidget( queryExitLabel, 0, 0, 0, 1 );

	QLabel* NumTransInfoLabel = new QLabel( mainWidget, "NumTransInfoLabel" );
	NumTransInfoLabel->setText( i18n( "Number of active transfers:" ) );

	 KBearQueryExitLayout->addMultiCellWidget( NumTransInfoLabel, 1, 1, 0, 0 );

	m_activeTransfers = new QLCDNumber( mainWidget, "m_activeTransfers" );
	m_activeTransfers->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, m_activeTransfers->sizePolicy().hasHeightForWidth() ) );
	m_activeTransfers->setNumDigits( 7 );
	m_activeTransfers->setSegmentStyle( QLCDNumber::Flat );
	QString tmp = i18n( "This field display the number of currently active transfers." );
	QToolTip::add( m_activeTransfers, tmp );
	QWhatsThis::add( m_activeTransfers, tmp );

	 KBearQueryExitLayout->addMultiCellWidget( m_activeTransfers, 1, 1, 1, 1 );

	QLabel* NumQueuedTransInfoLabel = new QLabel( mainWidget, "NumQueuedTransInfoLabel" );
	NumQueuedTransInfoLabel->setText( i18n( "Number of queued transfers:" ) );

	KBearQueryExitLayout->addMultiCellWidget( NumQueuedTransInfoLabel, 2, 2, 0, 0 );

	m_queuedTransfers = new QLCDNumber( mainWidget, "m_queuedTransfers" );
	m_queuedTransfers->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, m_queuedTransfers->sizePolicy().hasHeightForWidth() ) );
	m_queuedTransfers->setNumDigits( 7 );
	m_queuedTransfers->setSegmentStyle( QLCDNumber::Flat );
	tmp = i18n( "This field display the number of currently queued transfers." );
	QToolTip::add( m_queuedTransfers, tmp );
	QWhatsThis::add( m_queuedTransfers, tmp );

	KBearQueryExitLayout->addMultiCellWidget( m_queuedTransfers, 2, 2, 1, 1 );

	QLabel* WarningLabel = new QLabel( mainWidget, "WarningLabel" );
	WarningLabel->setText( QString("<i>%1</i>").arg( i18n( "If you quit, these transfers will be stopped or canceled !" ) ) );

	 KBearQueryExitLayout->addMultiCellWidget( WarningLabel, 3, 3, 0, 1 );
	m_askAgain = new QCheckBox( mainWidget, "m_askAgain" );
	m_askAgain->setText( i18n( "&Don't ask me again" ) );
	tmp = i18n( "Check this option if you don't want the application to ask for confirmation, even if there are ongoing transfers." );
	QToolTip::add( m_askAgain, tmp );
	QWhatsThis::add( m_askAgain, tmp );

	 KBearQueryExitLayout->addMultiCellWidget( m_askAgain, 4, 4, 0, 1 );

/*
	QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum );
	KBearQueryExitLayout->addItem( spacer, 5, 0 );
	QSpacerItem* spacer_2 = new QSpacerItem( 20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum );
	KBearQueryExitLayout->addItem( spacer_2, 5, 2 );
	QSpacerItem* spacer_3 = new QSpacerItem( 20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum );
	KBearQueryExitLayout->addItem( spacer_3, 5, 4 );
*/
// signals and slots connections
//    connect( this, SIGNAL( okClicked() ), this, SLOT( accept() ) );
//    connect( this, SIGNAL( cancelClicked() ), this, SLOT( reject() ) );

	KBearQueryExitLayout->activate();
}
//-----------------------------------------------
TransferManager::KBearQueryExit::~KBearQueryExit()
{
}
//-----------------------------------------------

