/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
/*
Author: Christian Hubinger <chubinger@gmail.com>, (C) 2001-2004
*/

#include "kmfconfigdialog.h"
#include "kmfconfigdialog.moc"

// QT includes
#include <qstring.h>
#include <qframe.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qcheckbox.h>
#include <qradiobutton.h>
#include <qbuttongroup.h>
#include <qregexp.h>
#include <qmessagebox.h>

// KDE includes
#include <kapplication.h>
#include <kdebug.h>
#include <klocale.h>
#include <kurlrequester.h>
#include <kguiitem.h>
#include <kpushbutton.h>
#include <knuminput.h>
#include <klistbox.h>
#include <kcombobox.h>
#include <kiconloader.h>
#include <kglobal.h>
#include <kmessagebox.h>
#include <klistview.h>
#include <ktrader.h>
#include <kparts/part.h>
#include <kparts/plugin.h>
#include <kparts/factory.h>


// Project includes
#include "core/kmfdoc.h"
// #include "core/kmfconfiguration.h"
#include "core/kmfconfig.h"


#include "kmfwidgets/kmfchecklistoutput.h"
#include "interfaces/kmfcompilerinterface.h"

KMFConfigDialog::KMFConfigDialog( QWidget *parent, const char *name, bool modal ) : KDialogBase( IconList, i18n( "Configure" ), User1 | Ok | Apply | Cancel,
        Ok, parent, name, modal, true, i18n( "Try Auto Configuration" ) ) {
	loadIcons();
	childproc = new KShellProcess( "/bin/sh" );
	connect( childproc, SIGNAL( processExited( KProcess* ) ), this, SLOT( slotProcessExited( KProcess* ) ) ) ;
	connect( childproc, SIGNAL( receivedStdout( KProcess*, char*, int ) ), this, SLOT( slotReceivedOutput( KProcess*, char*, int ) ) );
	connect( childproc, SIGNAL( receivedStderr( KProcess*, char*, int ) ), this, SLOT( slotReceivedError( KProcess*, char*, int ) ) );
	connect( this, SIGNAL( user1Clicked() ), this, SLOT( slotAutoConf() ) );

	m_backends = new QPtrList<QStringList>;
	showButton( KDialogBase::User1, true );
	setupGeneral();
	setupPlatformBackend();
	setupPaths();
	setupInterfaces();
	setupListView();
	setupPlugins();
	checkPlugins();
	slotReadConfig();
	if ( checkFirstRun() )
		slotAutoConf();
	
	setBaseSize( 800, 600 );
	
}

KMFConfigDialog::~KMFConfigDialog() {}

void KMFConfigDialog::slotApply() {
	kdDebug() << "void KMFConfigDialog::accept()" << endl;
	slotSaveConfig();
	KMFConfig::writeConfig();
	emit sigConfigChanged();
}

void KMFConfigDialog::accept() {
	kdDebug() << "void KMFConfigDialog::accept()" << endl;
	slotSaveConfig();
	KMFConfig::writeConfig();
	emit sigConfigChanged();
	QDialog::accept();
}

void KMFConfigDialog::slotReadConfig() {
	KMFConfig::self()->readConfig();
	m_lb_interfaces->clear();
	m_cb_show_splash->setChecked( KMFConfig::showSplash() );
	m_cb_generic_interface->setChecked( KMFConfig::useGenericInterface() );
	m_cb_show_desc->setChecked( KMFConfig::showDocumentation() );
	m_cb_show_cmds->setChecked( KMFConfig::showCommandLine() );
	m_cb_show_objectID->setChecked( KMFConfig::showObjectID() );
	
	
	
	m_lb_interfaces-> insertStringList( KMFConfig::interfaces() );
	kdDebug() << "found Interfaces " << KMFConfig::interfaces() << endl;
	m_sb_max_undo->setValue( KMFConfig::maxUndo() );
	
	
	kdDebug() << "Found Distribution" << KMFConfig::distribution() << endl;
	
	if ( KMFConfig::distribution() == "sysv" ) {
		m_cb_dist->setCurrentItem( 0 );
		slotEnableGentooMode( false );
		slotEnableSlackwareMode( false );
	} else if (  KMFConfig::distribution() == "gentoo" ) {
		m_cb_dist->setCurrentItem( 1 );
		slotEnableSlackwareMode( false );
		slotEnableGentooMode( true );
	} else if ( KMFConfig::distribution() == "slackware" ) {
		m_cb_dist->setCurrentItem( 2 );
		slotEnableGentooMode( false );
		slotEnableSlackwareMode( true );
	}
	
	m_url_init_path->setURL( KMFConfig::initPath() );
	m_url_runlevel_path->setURL( KMFConfig::rcDefaultPath() );
	m_url_ipt_path->setURL( KMFConfig::iPTPath() );
	m_url_modprobe_path->setURL( KMFConfig::modprobePath() );

	m_cb_backend->clear();
	bool found = false;
	QStringList *lst = 0;
	for ( uint i = 0; i < m_backends->count(); i++ ) {
		QStringList *l = m_backends->at( i );
		l = m_backends->at( i );
		if ( *l->at( 0 ) == KMFConfig::oS() ) {
			lst = l;
		}
	}
	
	if  ( lst != 0 ) {
		for ( int i = 0; i <  m_cb_os->count() && ! found ; i++ )  {
			QString name = *lst->at( 1 );
			kdDebug() << "Found item: " << m_cb_os->text( i ) << " comparing with name: " << name << endl;
			if ( m_cb_os->text( i ) == name ) {
				m_cb_os->setCurrentItem( i );
				slotSetOS( i );
				kdDebug() << "Setting item: " << m_cb_os->text( i ) << endl;
				found = true;
			}
		}
	}
	
	m_lvp_text1->setEnabled( ! KMFConfig::useGenericInterface() ); 
	m_cb_show_desc->setEnabled( ! KMFConfig::useGenericInterface() ); 
	m_lvp_text2->setEnabled( ! KMFConfig::useGenericInterface() ); 
	m_cb_show_cmds->setEnabled( ! KMFConfig::useGenericInterface() ); 
	m_lvp_text3->setEnabled( ! KMFConfig::useGenericInterface() ); 
	m_cb_show_objectID->setEnabled( ! KMFConfig::useGenericInterface() ); 
}


void KMFConfigDialog::slotSaveConfig() {
	KMFConfig::setFirstRun( false );
	KMFConfig::setShowSplash(  m_cb_show_splash->isChecked() );
	
	switch ( m_cb_dist->currentItem() ) {
		case 0:
		KMFConfig::setDistribution( "sysv" );
		break;

		case 1:
		KMFConfig::setDistribution( "gentoo" );
		break;

		case 2:
		KMFConfig::setDistribution( "slackware" );
		break;
	}
	
	KMFConfig::setUseGenericInterface( m_cb_generic_interface->isChecked() );
	KMFConfig::setShowDocumentation( m_cb_show_desc->isChecked() );
	KMFConfig::setShowCommandLine( m_cb_show_cmds->isChecked() );
	KMFConfig::setShowObjectID( m_cb_show_objectID->isChecked() );
	
	KMFConfig::setInitPath( m_url_init_path->url() );
	KMFConfig::setRcDefaultPath( m_url_runlevel_path->url() );
	KMFConfig::setIPTPath( m_url_ipt_path->url() );
	KMFConfig::setModprobePath( m_url_modprobe_path->url() );
	
	KMFConfig::interfaces().clear();
	
	QStringList *lst = m_backends->at( m_cb_os->currentItem() );
	
	
	KMFConfig::setOS( *lst->at( 0 ) );
	KMFConfig::setBackend( *lst->at( 2 ) );
	KMFConfig::setShowSelInterface( m_cb_show_selInterface->isChecked() );
	
	QStringList ifs;
	for ( uint i = 0;i < m_lb_interfaces->count();i++ ) {
		QString interf = m_lb_interfaces->text( i );
		if ( !interf.isEmpty() ) {
			kdDebug() << "Found Interface " << interf << endl;
			ifs << interf;
		}
	}
	KMFConfig::setInterfaces( ifs );
	KMFConfig::setMaxUndo( m_sb_max_undo->value() );
	KMFConfig::self()->writeConfig();
}

bool KMFConfigDialog::checkFirstRun() {
	return KMFConfig::firstRun();
}


void KMFConfigDialog::setupGeneral() {
	QFrame * page = addPage( i18n( "General Setting" ), QString::null, icon_general );
	QGridLayout *lay = new QGridLayout( page, 2, 2, 2 );
	m_cb_show_splash = new QCheckBox( i18n( "Show splash screen on startup" ), page );
	m_cb_show_splash->setChecked( true );
	m_cb_show_selInterface = new QCheckBox( i18n( "Show interface selection dialog at startup" ), page );
	m_cb_show_selInterface->setChecked( KMFConfig::showSelInterface() );
	
	QGroupBox* gb_generic = new QGroupBox( 2, Qt::Vertical, i18n("Generic Interface"), page, "gb_generic" );
	/*QLabel *text1 = */new QLabel( i18n( "<qt>By using the Generic Interface the creation of rulesets is much easier but it is not as flexible as the Normal Interface.</qt>" ), gb_generic );
	m_cb_generic_interface = new QCheckBox( i18n( "Use the Generic Interface" ), gb_generic );
	m_cb_generic_interface->setChecked( KMFConfig::useGenericInterface() );
	connect( m_cb_generic_interface, SIGNAL( toggled( bool ) ), 
		this, SLOT( slotEnableGenericInterface( bool ) ) );

	QLabel *text2 = new QLabel( i18n( "<qt>Max. stored Undos:</qt>" ), page );
	m_sb_max_undo = new KIntSpinBox( 0, 50, 1, 10, 10, page, "spin_box" );
	m_sb_max_undo->setValue( 10 );
	m_b_enable_warnings = new KPushButton( i18n( "Reenable All Messages" ), page );
	m_b_enable_warnings->setFixedHeight( 30 );
	connect( m_b_enable_warnings, SIGNAL( clicked() ), this, SLOT( slotEnableWarnings() ) );

	lay->addMultiCellWidget( gb_generic, 0, 0, 0, 1 );
	lay->addMultiCellWidget( m_cb_show_splash, 1, 1 , 0, 0 );
	lay->addMultiCellWidget( m_cb_show_selInterface, 1, 1 , 1, 1 );
	lay->addMultiCellWidget( text2, 3, 3 , 0, 0 );
	lay->addMultiCellWidget( m_sb_max_undo, 3, 3, 1, 1 );
	lay->addMultiCellWidget( m_b_enable_warnings, 4, 4, 0, 1 );
	
	QSpacerItem* spacer = new QSpacerItem( 0, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
	lay->addItem( spacer, 5, 0 );

}

void KMFConfigDialog::setupPlatformBackend() {
	pageGeneric = addPage( i18n( "Platform/Backend" ), QString::null, icon_general );
	connect( m_cb_generic_interface, SIGNAL( toggled( bool ) ), 
	pageGeneric, SLOT( setEnabled( bool ) ) );

	QGridLayout *lay = new QGridLayout( pageGeneric, 2, 2, 2 );
	QLabel *text1 = new QLabel( i18n( "<qt>Select the Operating System you are using.</qt>" ), pageGeneric );
	m_cb_os = new KComboBox( pageGeneric, "m_cb_os" );
	connect( m_cb_os, SIGNAL( activated( int ) ), this, SLOT( slotSetOS( int ) ) );
	
	QLabel *text2 = new QLabel( i18n( "<qt>Select the firewall backend you would like to use.</qt>" ), pageGeneric );
	m_cb_backend = new KComboBox( pageGeneric, "m_cb_backend" );
	lay->addMultiCellWidget( text1, 0, 0, 0, 1 );
	lay->addMultiCellWidget( m_cb_os, 1, 1, 0, 1 );
	lay->addMultiCellWidget( text2, 2, 2, 0, 1 );
	lay->addMultiCellWidget( m_cb_backend, 3, 3, 0, 1 );
	
	QSpacerItem* spacer = new QSpacerItem( 0, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
	lay->addItem( spacer, 5, 0 );
}



void KMFConfigDialog::registerCompiler( KMFCompilerInterface* compiler ) {
	kdDebug() << "KMFConfigDialog::registerCompiler: OS: " << compiler->osGUIName() << " Backend: " << compiler->backendGUIName() << endl;
	m_cb_os->insertItem( compiler->osGUIName() );
	QStringList *stl = new QStringList();
	stl->append( compiler->osName() );
	stl->append( compiler->osGUIName() );
	stl->append( compiler->backendName() );
	stl->append( compiler->backendGUIName() );
	m_backends->append( stl );
}


void KMFConfigDialog::setupPaths() {
	QFrame * page = addPage( i18n( "System Paths" ), QString::null, icon_paths );
	QGridLayout *lay = new QGridLayout( page, 9, 2, 2 );
	QLabel *text1 = new QLabel( i18n( "<qt><p>As Gentoo and Slackware are using a non-standard "
	                                  "SysV init system it is required to select your distribution in order to make the "
									  "firewall install properly into your boot setup.</qt>" ), page );

	m_cb_dist = new KComboBox(page, "m_cb_dist");
	m_cb_dist->insertItem( i18n("LSB Distribution") );
	m_cb_dist->insertItem( i18n("Gentoo") );
	m_cb_dist->insertItem( i18n("Slackware") );
	connect( m_cb_dist, SIGNAL( activated( int ) ), this, SLOT( slotDistChanged( int ) ) );

	QLabel *text2 = new QLabel( i18n( "<qt><b>Please specify the needed paths here.</b></qt>" ), page );
	m_lab_ipt_path = new QLabel( i18n( "<qt>Path to the <b>iptables</b> binary:</qt>" ), page );
	m_lab_modprobe_path = new QLabel( i18n( "<qt>Path to the <b>modprobe</b> binary:</qt>" ), page );
	m_lab_init_path = new QLabel( i18n( "<qt>Path to <b>init</b> directory:</qt>" ), page );
	m_lab_runlevel_path = new QLabel( i18n( "<qt>Path to the default <b>runlevel</b> directory:</qt>" ), page );
	m_url_ipt_path = new KURLRequester( "/usr/sbin/iptables", page );
	m_url_modprobe_path = new KURLRequester( "/usr/sbin/modprobe", page );
	m_url_init_path = new KURLRequester( "/etc/init.d", page );
	m_url_runlevel_path = new KURLRequester( "/etc/rc5.d", page );
	lay->addMultiCellWidget( text1, 0, 0, 0, 1 );
	lay->addMultiCellWidget( m_cb_dist, 1, 1, 0, 1 );
	lay->addMultiCellWidget( text2, 3, 3, 0, 1 );
	lay->addWidget( m_lab_ipt_path, 4, 0 );
	lay->addWidget( m_url_ipt_path, 4, 1 );
	lay->addWidget( m_lab_modprobe_path, 5, 0 );
	lay->addWidget( m_url_modprobe_path, 5, 1 );
	lay->addWidget( m_lab_init_path, 6, 0 );
	lay->addWidget( m_url_init_path, 6, 1 );
	lay->addWidget( m_lab_runlevel_path, 7, 0 );
	lay->addWidget( m_url_runlevel_path, 7, 1 );
	QSpacerItem* spacer = new QSpacerItem( 0, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
	lay->addItem( spacer, 8, 0 );
}

void KMFConfigDialog::setupInterfaces() {
	QFrame * page = addPage( i18n( "Network Interfaces" ), QString::null, icon_interfaces );
	QLabel *text = new QLabel( page );
	text->setText( i18n( "<qt>List all network interfaces that are available on your computer here.</qt>" ) );
	QGridLayout *lay = new QGridLayout( page, 2, 2, 2 );
	text->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum, true );
	m_b_add_interface = new KPushButton( page, "hj" );
	m_b_add_interface->setText( i18n( "Add Interface" ) );
	m_b_add_interface->setFixedHeight( 30 );
	m_b_del_interface = new KPushButton( page, "hj" );
	m_b_del_interface->setFixedHeight( 30 );
	m_b_del_interface->setText( i18n( "Remove Interface" ) );
	connect( m_b_add_interface, SIGNAL( clicked() ), this, SLOT( slotAddInterface() ) );
	connect( m_b_del_interface, SIGNAL( clicked() ), this, SLOT( slotDelInterface() ) );

	m_sb_interface_number = new KIntSpinBox( page );
	m_lb_interfaces = new KListBox( page );
	m_lb_interfaces->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding );
	m_cb_interface_name = new KComboBox( page );
	m_cb_interface_name->insertItem( "eth" );
	m_cb_interface_name->insertItem( "ppp" );
	m_cb_interface_name->insertItem( "ippp" );
	m_cb_interface_name->insertItem( "ppoe" );
	m_cb_interface_name->insertItem( "wlan" );
	m_cb_interface_name->insertItem( "tun" );
	m_cb_interface_name->insertItem( "tap" );
	m_cb_interface_name->insertItem( "gre" );
	m_cb_interface_name->insertItem( "lo" );
	m_cb_interface_name->setEditable( true );
	m_cb_interface_name->setDuplicatesEnabled( false );
	lay->addMultiCellWidget( text, 0, 0, 0, 2 );
	lay->addMultiCellWidget( m_cb_interface_name, 1, 1, 0, 0 );
	lay->addMultiCellWidget( m_sb_interface_number, 1, 1, 1, 2 );
	lay->addMultiCellWidget( m_lb_interfaces, 2, 4, 1, 2 );
	lay->addMultiCellWidget( m_b_add_interface, 2, 2, 0, 0 );
	lay->addMultiCellWidget( m_b_del_interface, 3, 3, 0, 0 );
	QSpacerItem* spacer = new QSpacerItem( 0, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
	lay->addItem( spacer, 4, 0 );
}

void KMFConfigDialog::setupListView() {
	QFrame * page = addPage( i18n( "Listview Preferences" ), QString::null, icon_listview );
	QGridLayout *lay = new QGridLayout( page, 5, 1, 2 );
	m_lvp_text1 = new QLabel( i18n( "<qt>Define here if you like to see the documentation  "
	                                 "for tables and built-in chains in the main listview.</qt>" ), page );
	lay->addWidget( m_lvp_text1, 0, 0 );
	m_cb_show_desc = new QCheckBox( i18n( "Show documentation for all Objects." ), page );
	lay->addWidget( m_cb_show_desc, 1, 0 );

	m_lvp_text2 = new QLabel( i18n( "<qt>Turn this box on of you like to see the "
	                                  "generated iptables command lines in the main listview</qt>" ), page );
	lay->addWidget( m_lvp_text2, 2, 0 );

	m_cb_show_cmds = new QCheckBox( i18n( "Show iptables commands." ), page );
	lay->addWidget( m_cb_show_cmds, 3, 0 );

	
	m_lvp_text3 = new QLabel( i18n( "<qt>Enable this to show the internally-used Object IDs in the listview. Mainly useful for debuging.</qt>" ), page );
	lay->addWidget( m_lvp_text3, 4, 0 );
	
	
	m_cb_show_objectID = new QCheckBox( i18n( "Show objectIDs." ), page );
	lay->addWidget( m_cb_show_objectID, 5, 0 );
	
	
	QLabel *text4 = new QLabel( i18n( "<qt><b>Note:</b> Those settings are only available for the normal interface. This options are disabled when using the generic interface.</qt>" ), page );
	lay->addWidget( text4, 6, 0 );
	QSpacerItem* spacer = new QSpacerItem( 0, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
	lay->addItem( spacer, 7, 0 );
	
	
}

void KMFConfigDialog::setupPlugins(){
	kdDebug() << "\nvoid KMFConfigDialog::setupPlugins()" << endl;
	QFrame * page = addPage( i18n( "Plugins" ), QString::null, icon_listview );
	QVBoxLayout *lay = new QVBoxLayout( page );
	QLabel *text1 = new QLabel( i18n( "<qt>In the list you can see which plugins have been found.</qt>" ), page );
	lay->addWidget( text1 );
	m_lv_plugins = new KListView( page );
	m_lv_plugins->addColumn( i18n("Name") );
	m_lv_plugins->addColumn( i18n("Description") );
	m_lv_plugins->addColumn( i18n("Library") );
	lay->addWidget( m_lv_plugins );
	
	
/*	QSpacerItem* spacer = new QSpacerItem( 0, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
	lay->addItem( spacer );*/
}

void KMFConfigDialog::checkPlugins() {
	kdDebug() << "void KMFConfigDialog::checkPlugins()" << endl;
	m_lv_plugins->clear();
	KListViewItem *item_installers = new KListViewItem( m_lv_plugins, 0,0 );
	item_installers->setText( 0, i18n("Installers") );
	item_installers->setOpen( true );
	
	KListViewItem *item_compilers = new KListViewItem( m_lv_plugins, 0,0 );
	item_compilers->setText( 0, i18n("Compilers") );
	item_compilers->setOpen( true );
	
	KListViewItem *item_optioneditors = new KListViewItem( m_lv_plugins, 0,0 );
	item_optioneditors->setText( 0, i18n("Rule Option Editors") );
	item_optioneditors->setOpen( true );
	
	KListViewItem *item_targetoptioneditors = new KListViewItem( m_lv_plugins, 0,0 );
	item_targetoptioneditors->setText( 0, i18n("Rule Target Option Editors") );
	item_targetoptioneditors->setOpen( true );
	
	kdDebug() << "\nStart query" << endl;
	KTrader::OfferList offers = KTrader::self()->query( "KMyFirewall/Installer");
	kdDebug() << "Query performed for KMyFirewall/Installer" << endl;
	KTrader::OfferList::iterator it;
	if ( offers.empty() ) {
		KListViewItem *item = new KListViewItem( item_installers, 0,0);
		item->setText(0, i18n("No installer plugins found!") );
		kdDebug() << "NO MATCHING PLUGIN FOUND" << endl;
	}
	for ( it = offers.begin(); it != offers.end(); ++it ) {
		KService::Ptr ptr = *it;
		KListViewItem *item = new KListViewItem( item_installers, 0,0);
		item->setText(0, ptr->name() );
		item->setText(1, ptr->comment() );
		item->setText(2, ptr->library().local8Bit().data() );
		kdDebug() << "Found Plugin: " << ptr->name()  << "\nLibrary: "<<  ptr->library().local8Bit().data()  <<endl;
	
	}
	
	KTrader::OfferList offers2 = KTrader::self()->query( "KMyFirewall/Compiler" );
	kdDebug() << "Query performed for KMyFirewall/Compiler" << endl;
	if ( offers2.empty() ) {
		KListViewItem *item = new KListViewItem( item_compilers, 0,0);
		item->setText(0, i18n("No compiler plugins found!") );
		kdDebug() << "NO MATCHING PLUGIN FOUND" << endl;
	}
	for ( it = offers2.begin(); it != offers2.end(); ++it ) {
		KService::Ptr ptr = *it;
		KListViewItem *item = new KListViewItem( item_compilers, 0,0);
		item->setText(0, ptr->name() );
		item->setText(1, ptr->comment() );
		item->setText(2, ptr->library().local8Bit().data() );
		kdDebug() << "Found Plugin: " << ptr->name()  << "\nLibrary: "<<  ptr->library().local8Bit().data()  <<endl;
		KLibFactory *factory = KLibLoader::self()->factory( ptr->library().local8Bit().data() );
		kdDebug() << KLibLoader::self()->lastErrorMessage() << endl;

		if ( !factory ) {
			KMessageBox::error( 0, i18n("<qt><b>Compiler plugin could not be loaded.</b></qt>") );
			kdDebug() << "Couldn't load plugin: "  <<  ptr->name() << endl;
		}
		
		if ( KMFCompilerInterface *part = dynamic_cast<KMFCompilerInterface*> ( factory->create( this , "KMFCompilerInterface") ) ) {
			kdDebug() << "Returning Compiler Plugin." << endl;
			registerCompiler( part );
		}
	}
	
	
	
	KTrader::OfferList offers3 = KTrader::self()->query( "KMyFirewall/RuleOptionEdit" );
	kdDebug() << "Query performed for KMyFirewall/RuleOptionEdit" << endl;
	if ( offers3.empty() ) {
		KListViewItem *item = new KListViewItem( item_optioneditors, 0,0);
		item->setText(0, i18n("No RuleOptionEdit plugins found.") );
		kdDebug() << "NO MATCHING PLUGIN FOUND" << endl;
	}
	
	for ( it = offers3.begin(); it != offers3.end(); ++it ) {
		KService::Ptr ptr = *it;
		KListViewItem *item = new KListViewItem( item_optioneditors, 0,0);
		item->setText(0, ptr->name() );
		item->setText(1, ptr->comment() );
		item->setText(2, ptr->library().local8Bit().data() );
		kdDebug() << "Found Plugin: " << ptr->name()  << "\nLibrary: "<<  ptr->library().local8Bit().data()  <<endl;
	}

	KTrader::OfferList offers4 = KTrader::self()->query( "KMyFirewall/RuleTargetOptionEdit" );
	kdDebug() << "Query performed for KMyFirewall/RuleTargetOptionEdit" << endl;
	if ( offers4.empty() ) {
		KListViewItem *item = new KListViewItem( item_targetoptioneditors, 0,0);
		item->setText(0, i18n("No RuleTargetOptionEdit plugins found.") );
		kdDebug() << "NO MATCHING PLUGIN FOUND" << endl;
	}
	for ( it = offers4.begin(); it != offers4.end(); ++it ) {
		KService::Ptr ptr = *it;
		KListViewItem *item = new KListViewItem( item_targetoptioneditors, 0,0);
		item->setText(0, ptr->name() );
		item->setText(1, ptr->comment() );
		item->setText(2, ptr->library().local8Bit().data() );
		kdDebug() << "Found Plugin: " << ptr->name()  << "\nLibrary: "<<  ptr->library().local8Bit().data()  <<endl;
	}

	
}




void KMFConfigDialog::slotDistChanged( int index ) {
	switch( index ) {
		case 0:
		slotEnableGentooMode( false );
		slotEnableSlackwareMode( false );
		break;
		case 1:
		slotEnableSlackwareMode( false );
		slotEnableGentooMode( true );
		break;
		case 2:
		slotEnableGentooMode( false );
		slotEnableSlackwareMode( true );
	}
}

void KMFConfigDialog::slotSetBackend( int index ){
	kdDebug() << "void KMFConfigDialog::slotSetBackend( " << index << " )" << endl;
	QStringList *list = m_backends->at( index );
	KMFConfig::setBackend( *list->at( 2 ) );
	
	// Config().m_backend = *list->at( 2 );
}

void KMFConfigDialog::slotSetOS( int index ){
	kdDebug() << "void KMFConfigDialog::slotSetOS( " << index << " )" << endl;
	QStringList *list = m_backends->at( index );
	
	m_cb_backend->clear();
/*	m_cb_backend->insertItem( *list->at( 0 ) );
	m_cb_backend->insertItem( *list->at( 1 ) );		
	m_cb_backend->insertItem( *list->at( 2 ) );	*/
	m_cb_backend->insertItem( *list->at( 3 ) );			
	
	KMFConfig::setOS( *list->at( 0 ) );
	
	//Config().m_os = *list->at( 0 );
	KMFConfig::setBackend( *list->at( 2 ) );
	// Config().m_backend = *list->at( 2 );
	KMFConfig::self()->writeConfig();
}

void KMFConfigDialog::slotEnableGentooMode( bool enable ) {
	kdDebug() << "void KMFConfigDialog::slotEnableGentooMode( bool enable )" << endl;
	if ( enable ) {
		slotEnableSlackwareMode( false );
		m_url_runlevel_path->setURL( "/etc/runlevels/default/" );
		m_url_ipt_path->setURL( "/sbin/iptables" );
		m_url_modprobe_path->setURL( "/sbin/modprobe" );
		m_url_init_path->setURL( "/etc/init.d/" );
	} else {
		m_url_runlevel_path->setURL( KMFConfig::rcDefaultPath() );
		m_url_ipt_path->setURL( KMFConfig::iPTPath() );
		m_url_modprobe_path->setURL( KMFConfig::modprobePath() );
		m_url_init_path->setURL( KMFConfig::initPath() );
/*		m_url_runlevel_path->setURL( Config().m_defaultRcDefaultPath );
		m_url_ipt_path->setURL( Config().m_defaultIptPath );
		m_url_modprobe_path->setURL( Config().m_defaultModprobePath );
		m_url_init_path->setURL( Config().m_defaultInitPath );*/
	}
}

void KMFConfigDialog::slotEnableSlackwareMode( bool enable ) {
	kdDebug() << "void KMFConfigDialog::slotSlackwareMode( bool enable )" << endl;
	if ( enable ) {
		slotEnableGentooMode( false );
		m_url_runlevel_path->setURL( "/etc/rc.d/" );
		m_url_ipt_path->setURL( "/usr/sbin/iptables" );
		m_url_modprobe_path->setURL( "/usr/sbin/modprobe" );
		m_url_init_path->setEnabled( false );
		m_lab_init_path->setEnabled( false );
	} else {
		m_url_init_path->setEnabled( true );
		m_lab_init_path->setEnabled( true );
		m_url_runlevel_path->setURL( KMFConfig::rcDefaultPath() );
		m_url_ipt_path->setURL( KMFConfig::iPTPath() );
		m_url_modprobe_path->setURL( KMFConfig::modprobePath() );
		m_url_init_path->setURL( KMFConfig::initPath() );
/*		m_url_runlevel_path->setURL( Config().m_defaultRcDefaultPath );
		m_url_ipt_path->setURL( Config().m_defaultIptPath );
		m_url_modprobe_path->setURL( Config().m_defaultModprobePath );
		m_url_init_path->setURL( Config().m_defaultInitPath );*/
	}
}

void KMFConfigDialog::slotEnableGenericInterface( bool enable ) {
	if ( enable != KMFConfig::useGenericInterface() )
		KMessageBox::information( this, i18n( "<qt>Please not that you have to restart KMyFirewall to make the changes take effect. </qt>" ), QString( "" ), "info_change_interface" );
		m_lvp_text1->setEnabled( ! enable );
		m_lvp_text2->setEnabled( ! enable );
		m_cb_show_desc->setEnabled( ! enable );
		m_cb_show_cmds->setEnabled( ! enable );
}

bool KMFConfigDialog::isRunning() {
	return childproc->isRunning();
}

void KMFConfigDialog::slotProcessExited( KProcess* ) {
	kdDebug() << "void KMFConfigDialog::slotProcessExited(KProcess*)" << endl;

}

void KMFConfigDialog::slotReceivedError( KProcess *, char *buffer, int buflen ) {
	kdDebug() << "void KMFConfigDialog::slotReceivedError(KProcess *, char *buffer, int buflen)" << endl;
	kdDebug() << "received string: " << QString::fromLatin1( buffer, buflen ) << endl;
}

void KMFConfigDialog::slotReceivedOutput( KProcess *, char *buffer, int buflen ) {
	kdDebug() << "void KMFConfigDialog::slotReceivedOutput(KProcess *, char *buffer, int buflen) " << endl;
	kdDebug() << "Buffer: \n" << buffer << endl;
	if ( m_processName == "ifconfig" ) {
		QString tmp = QString::fromLatin1( buffer, buflen );
		tmp = tmp.replace( QRegExp( "\n" ), "|" );
		kdDebug() << "Orig: " << tmp << endl;
		tmp = tmp.left( tmp.length() - 1 );
		kdDebug() << "Cut last Orig: " << tmp << endl;
		m_lb_interfaces->clear();
		while ( !tmp.isEmpty() ) {
			int pos;
			QString in;
			int l;
			pos = tmp.find( "|" );
			if ( pos == -1 ) {
				in = tmp.left( pos );
				m_progView->appendLine( i18n( "Found Interface: %1" ).arg( in ) );
				m_lb_interfaces->insertItem( in );
				m_progView->setStatus( true, "0" );
				tmp = "";
			} else {
				kdDebug() << "found | at " << pos << endl;
				in = tmp.left( pos );
				kdDebug() << "Orig: " << tmp << endl;
				m_progView->appendLine( i18n( "Found Interface: %1" ).arg( in ) );
				m_lb_interfaces->insertItem( in );
				m_progView->setStatus( true, "0" );
				l = tmp.length();
				tmp = tmp.right( l - ( pos + 1 ) );
				kdDebug() << "Rest: " << tmp << endl;
			}
		}
	} /* FIXME: The must be a better way to find out about the kde home path 
		else if ( m_processName == "kde-config" ) {
		QString tmp = QString::fromLatin1( buffer, buflen );
		tmp = tmp.replace( QRegExp( "\n" ), "|" );
		kdDebug() << "Orig: " << tmp << endl;
		tmp = tmp.left( tmp.length() - 1 );
		kdDebug() << "Setting localprefix to: " << tmp  << endl;
		Config().m_kdeHomePath = tmp;
	} */
}

void KMFConfigDialog::slotAutoConf() {
	kdDebug() << "void KMFConfig::slotAutoConf() " << endl;

	// Output widget for the checks
	m_progView = new KMFCheckListOutput( this, "progView", true );
	m_progView->show();
	m_progView->clearList();

	FILE *sbin1;
	FILE *sbin2;
	FILE *sbin3;
	FILE *sbin4;
	FILE *sbin5;
	FILE *sbin6;

	// Gentoo and Slackware checks
	sbin1 = fopen( "/usr/bin/emerge", "r" );
	sbin2 = fopen( "/etc/slackware-version", "r" );
	if ( sbin1 != NULL ) {
		m_cb_dist->setCurrentItem( 1 );
		m_progView->appendLine( "Looks like Gentoo." );
		m_progView->setStatus( true, "" );
		slotEnableGentooMode( true );
		m_progView->appendLine( "Setting paths..." );
		m_progView->setStatus( true, "" );
		fclose( sbin1 );
		if ( sbin2 )
			fclose( sbin2 );
	} else if ( sbin2 != NULL ) {
		m_cb_dist->setCurrentItem( 2 );
		m_progView->appendLine( "Looks like Slackware." );
		m_progView->setStatus( true, "" );
		slotEnableSlackwareMode( true );
		m_progView->appendLine( "Setting paths..." );
		m_progView->setStatus( true, "" );
		if ( sbin1 )
			fclose( sbin1 );
		fclose( sbin2 );
	} else {
		m_cb_dist->setCurrentItem( 0 );
		slotEnableGentooMode( false );
		slotEnableSlackwareMode( false );

		m_progView->appendLine( "Checking for iptables..." );

		bool found_ipt = false;

		sbin1 = fopen( "/usr/bin/iptables", "r" );
		sbin2 = fopen( "/usr/local/bin/iptables", "r" );
		sbin3 = fopen( "/sbin/iptables", "r" );
		sbin4 = fopen( "/usr/sbin/iptables", "r" );
		sbin5 = fopen( "/usr/local/sbin/iptables", "r" );
		sbin6 = fopen( "/bin/iptables", "r" );

		if ( sbin1 != NULL ) {
			found_ipt = true;
			m_url_ipt_path->setURL( "/usr/bin/iptables" );
			fclose( sbin1 );
		} else if ( sbin2 != NULL ) {
			found_ipt = true;
			m_url_ipt_path->setURL( "/usr/local/bin/iptables" );
			fclose( sbin2 );

		} else if ( sbin3 != NULL ) {
			found_ipt = true;
			m_url_ipt_path->setURL( "/sbin/iptables" );
			fclose( sbin3 );
		} else if ( sbin4 != NULL ) {
			found_ipt = true;
			m_url_ipt_path->setURL( "/usr/sbin/iptables" );
			fclose( sbin4 );
		} else if ( sbin5 != NULL ) {
			found_ipt = true;
			m_url_ipt_path->setURL( "/usr/local/sbin/iptables" );
			fclose( sbin5 );
		} else if ( sbin6 != NULL ) {
			found_ipt = true;
			m_url_ipt_path->setURL( "/bin/iptables" );
			fclose( sbin6 );
		}

		if ( found_ipt ) {
			m_progView->setStatus( true, "0" );
		} else {
			m_progView->setStatus( true, i18n( "iptables binary not found. Make sure you have installed it and set the path manually." ) );
		}

		m_progView->appendLine( "Checking for modprobe..." );

		bool found_modprobe = false;

		sbin1 = fopen( "/usr/bin/modprobe", "r" );
		sbin2 = fopen( "/usr/local/bin/modprobe", "r" );
		sbin3 = fopen( "/sbin/modprobe", "r" );
		sbin4 = fopen( "/usr/sbin/modprobe", "r" );
		sbin5 = fopen( "/usr/local/sbin/modprobe", "r" );
		sbin6 = fopen( "/bin/modprobe", "r" );

		if ( sbin1 != NULL ) {
			found_modprobe = true;
			m_url_modprobe_path->setURL( "/usr/bin/modprobe" );
			fclose( sbin1 );
		} else if ( sbin2 != NULL ) {
			found_modprobe = true;
			m_url_modprobe_path->setURL( "/usr/local/bin/modprobe" );
			fclose( sbin2 );

		} else if ( sbin3 != NULL ) {
			found_modprobe = true;
			m_url_modprobe_path->setURL( "/sbin/modprobe" );
			fclose( sbin3 );
		} else if ( sbin4 != NULL ) {
			found_modprobe = true;
			m_url_modprobe_path->setURL( "/usr/sbin/modprobe" );
			fclose( sbin4 );
		} else if ( sbin5 != NULL ) {
			found_modprobe = true;
			m_url_modprobe_path->setURL( "/usr/local/sbin/modprobe" );
			fclose( sbin5 );
		} else if ( sbin6 != NULL ) {
			found_modprobe = true;
			m_url_modprobe_path->setURL( "/bin/modprobe" );
			fclose( sbin6 );
		}

		if ( found_modprobe ) {
			m_progView->setStatus( true, "0" );
		} else {
			m_progView->setStatus( true, i18n( "modprobe binary not found. Make sure you have installed it and set the path manually." ) );
		}



		m_progView->appendLine( "Searching for the init.d dir ..." );
		sbin1 = fopen( "/etc/init.d", "r" );
		sbin2 = fopen( "/sbin/init.d", "r" );
		if ( sbin1 != NULL ) {
			m_url_init_path->setURL( "/etc/init.d" );
			m_progView->appendLine( "Found init.d at: /etc/init.d" );
			m_progView->setStatus( true, "0" );
			fclose( sbin1 );
		} else if ( sbin2 != NULL ) {
			m_url_init_path->setURL( "/sbin/init.d" );
			m_progView->appendLine( "Found init.d at: /sbin/init.d" );
			m_progView->setStatus( true, "0" );
			fclose( sbin2 );
		} else {
			m_progView->appendLine( "Sorry cannot find init.d dir :-(" );
			m_progView->setStatus( false, i18n( "init.d directory not found. Please set the path manually." ) );
		}

		bool found_rl_dir = false;
		m_progView->appendLine( "Searching for Default Runlevel." );

		sbin1 = fopen( "/etc/init.d/rc2.d", "r" );
		sbin2 = fopen( "/etc/init.d/rc3.d", "r" );
		sbin3 = fopen( "/etc/init.d/rc5.d", "r" );
		if ( sbin1 != NULL || sbin2 != NULL || sbin3 != NULL ) {
			fclose( sbin1 );
			fclose( sbin2 );
			fclose( sbin3 );
			m_progView->appendLine( "Found Runlevel Dirs at: /etc/init.d/rcX.d\nRunlevel 5 is guessed to be the default runlevel." );
			m_progView->setStatus( true, "0" );
			m_url_runlevel_path->setURL( "/etc/init.d/rc5.d" );
		}

		sbin1 = fopen( "/etc/rc2.d", "r" );
		sbin2 = fopen( "/etc/rc3.d", "r" );
		sbin3 = fopen( "/etc/rc5.d", "r" );

		if ( sbin1 != NULL || sbin2 != NULL || sbin3 != NULL ) {
			fclose( sbin1 );
			fclose( sbin2 );
			fclose( sbin3 );
			// check for debian to set the right default runlevel
			sbin4 = fopen( "/etc/debian_version", "r" );
			if ( sbin4 != NULL ) {
				fclose( sbin4 );
				m_progView->appendLine( "Found Runlevel Dirs at: /etc/rcX.d\nThis is Debian setting Default Runlevel 2." );
				m_progView->setStatus( true, "0" );
				m_url_runlevel_path->setURL( "/etc/rc2.d" );
				found_rl_dir = true;
			} else {
				m_progView->appendLine( "Found Runlevel Dirs at: /etc/rcX.d\nRunlevel 5 is guessed to be the default runlevel." );
				m_progView->setStatus( true, "0" );
				m_url_runlevel_path->setURL( "/etc/rc5.d" );
				found_rl_dir = true;
			}
		}

		sbin1 = fopen( "/sbin/rc2.d", "r" );
		sbin2 = fopen( "/sbin/rc3.d", "r" );
		sbin3 = fopen( "/sbin/rc5.d", "r" );

		if ( sbin1 != NULL || sbin2 != NULL || sbin3 != NULL ) {
			fclose( sbin1 );
			fclose( sbin2 );
			fclose( sbin3 );
			m_progView->appendLine( "Found Runlevel Dirs at: /sbin/rcX.d\nRunlevel 5 is guessed to be the default runlevel." );
			m_progView->setStatus( true, "0" );
			m_url_runlevel_path->setURL( "/sbin/rc5.d" );
			found_rl_dir = true;
		}


		if ( !found_rl_dir ) {
			m_progView->appendLine( i18n( "Default runlevel directory not found.\nPlease set the path to\nyour default runlevel manually." ) );
			m_progView->setStatus( false, "" );
			m_url_runlevel_path->setURL( "" );
		}
	}


	m_progView->appendLine( i18n( "Searching for interfaces..." ) );
	m_processName = "ifconfig";
	childproc->clearArguments();
	*childproc << "/sbin/ifconfig | grep ' Link' | cut -f1 -d' ' | sort";
	childproc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
}

void KMFConfigDialog::slotAddInterface() {
	QString int_name = m_cb_interface_name->currentText();
	int int_num = m_sb_interface_number->value();
	QString str_num;
	str_num.setNum( int_num );
	QString interface = int_name;
	if ( int_name != "lo" )
		interface += str_num;
	for ( uint i = 0;i < m_lb_interfaces->count();i++ ) {
		QString interf = m_lb_interfaces->text( i );
		if ( interface == interf ) {
			KMessageBox::sorry( this, i18n( "You cannot have more then one interface with the same name." ),
			                    i18n( "Configuration" ) );
			return ;
		}
	}
	m_lb_interfaces->insertItem( interface );
}

void KMFConfigDialog::slotDelInterface() {
	int index = m_lb_interfaces->currentItem();
	if ( index > -1 ) {
		switch ( QMessageBox::warning( this, i18n( "Configuration" ),
		                               i18n( "Are you sure that you want to delete\n"
		                                     "this interface?\n" ),
		                               i18n( "&OK" ), i18n( "&Cancel" ),
		                               0, 2 ) ) {

		case 0:      // OK clicked
			m_lb_interfaces->removeItem( index );
			break;
		}

	} else {
		KMessageBox::sorry( this, i18n( "You have to select an interface first before you can delete it." ),
		                    i18n( "Configuration" ) );
		return ;

	}
}

void KMFConfigDialog::slotEnableWarnings() {
	kdDebug() << "KMFConfigDialog::slotEnableWarnings()" << endl;
	KMessageBox::enableAllMessages();
	KMessageBox::information( this, i18n( "Reenabled all warnings." ) );
}

void KMFConfigDialog::loadIcons() {
	KIconLoader * loader = KGlobal:: iconLoader();
	QString icon_name;

	icon_name = "about_kde";
	icon_general = loader->loadIcon( icon_name, KIcon::Desktop );

	icon_name = "folder";
	icon_paths = loader->loadIcon( icon_name, KIcon::Desktop );

	icon_name = "network";
	icon_interfaces = loader->loadIcon( icon_name, KIcon::Desktop );

	icon_name = "view_tree";
	icon_listview = loader->loadIcon( icon_name, KIcon::Desktop );

}

