/***************************************************************************
 *                                                                         *
 *   Copyright (C) 2005, 2006 by Kevin Gilbert                             *
 *   kev.gilbert@cdu.edu.au                                                *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 *                                                                         *
 ***************************************************************************/

#include <tqbuttongroup.h>
#include <tqcheckbox.h>
#include <tqcombobox.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqlineedit.h>
#include <tqlistbox.h>
#include <tqpushbutton.h>
#include <tqradiobutton.h>
#include <tqstringlist.h>
#include <tqvalidator.h>

#include <tdeconfig.h>
#include <kdebug.h>
#include <tdeglobal.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdemessagebox.h>

#include "commonwidget.h"
#include "whatsthis.h"

//	constructor
//	===========

CommonWidget::CommonWidget( TQWidget* parent, const char* name )
: TQWidget( parent, name ),
  m_hosts( NULL ),
  m_portRangeIgnoreChange( false ),
  m_portRanges( NULL )
{	createLayout( );
	m_portRangeAddButton->setEnabled( false );
	m_portRangeDeleteButton->setEnabled( false );
}

//	destructor
//	==========

CommonWidget::~CommonWidget( )
{	if( m_hosts != NULL )
		delete m_hosts;

	if( m_portRanges != NULL )
		delete m_portRanges;
}

//	buildPortRangesTables
//	=====================

bool CommonWidget::buildPortRangesTables( const boolPtr tcpPorts, const boolPtr udpPorts )
{	memset( tcpPorts, 0, 64 * 1024 );
	memset( udpPorts, 0, 64 * 1024 );

	TQStringList portRanges;
	getPortRanges( &portRanges );

	for( TQStringList::Iterator it = portRanges.begin( ); it != portRanges.end( ); ++it )
	{	TQString portRange = *it;
		bool    tcp       = false;
		bool    udp       = false;

		if( portRange[ 0 ].isDigit( ))
		{	tcp = true;
			udp = true;
		}
		else
		if( portRange[ 0 ].lower( ) == 't' )
		{	tcp = true;
			portRange = portRange.right( portRange.length( ) - 2 );
		}
		else
		if( portRange[ 0 ].lower( ) == 'u' )
		{	udp = true;
			portRange = portRange.right( portRange.length( ) - 2 );
		}
		else
		{	KMessageBox::error( this, i18n( "Internal error - Unknown Port Range protocol '%1'" ).arg( portRange[ 0 ]), i18n( "Internal error" ));
			return false;
		}

		TQStringList ports = TQStringList::split( "-", portRange );

		if( ports.count( ) > 2 )
		{	KMessageBox::error( this, i18n( "Internal error - Illegal Port Range encountered" ), i18n( "Internal error" ));
			return false;
		}

		ushort portFirst = ports.front( ).toUShort( );
		ushort portLast  = portFirst;

		if( ports.count( ) > 1 )
			portLast = ports.back( ).toUShort( );

		for( uint port = portFirst; port <= portLast; port++ )
		{	if( tcp )
				tcpPorts[ port ] = true;

			if( udp )
				udpPorts[ port ] = true;
		}
	}

	return true;
}

//	createLayout
//	============

void CommonWidget::createLayout( )
{	TQGridLayout* gridLayout        = new TQGridLayout( this );
	TDEIconLoader* iconLoader        = TDEGlobal::iconLoader( );
	TQIconSet     clearRightIconSet = iconLoader->loadIconSet( "locationbar_erase", TDEIcon::Small );

 	byte row = 1;
	m_hostButton   = new TQPushButton( clearRightIconSet, NULL, this, "host button" );
	m_hostComboBox = new TQComboBox( true, this, "target hosts combobox" );
	TQHBoxLayout* hostLayout = new TQHBoxLayout( );

	byte col = 0;
	hostLayout->insertStretch( col++, 0 );
	hostLayout->insertWidget(  col++, new TQLabel( i18n( "Target host(s)" ), this, "target hosts label" ), 0 );
	hostLayout->insertStretch( col++, 1 );
	hostLayout->insertWidget(  col++, m_hostButton, 0 );
	hostLayout->insertStretch( col++, 1 );
	hostLayout->insertWidget(  col++, m_hostComboBox, 100 );
	hostLayout->insertStretch( col++, 0 );
	gridLayout->addMultiCellLayout( hostLayout, row, row, 1, 5 );

	TQButtonGroup* resloveGroup = new TQButtonGroup( 3, TQt::Vertical, i18n( "Resolve names" ), this, "resolve names group" );
	m_resovleDefaultRadio      = new TQRadioButton( i18n( "Default"     ), resloveGroup, "default resolve radio" );
	m_resovleAlwaysRadio       = new TQRadioButton( i18n( "Always (-R)" ), resloveGroup, "always resolve radio"  );
	m_resovleNeverRadio        = new TQRadioButton( i18n( "Never (-n)"  ), resloveGroup, "never resolve radio"   );

	row = 4;
	gridLayout->addMultiCellWidget( resloveGroup, row, row + 3, 1, 1 );
	byte rowBlock1 = ++row;

	m_portRangeAddButton    = new TQPushButton( i18n( "Add" ),    this, "add port range button" );
	m_portRangeDeleteButton = new TQPushButton( i18n( "Delete" ), this, "delete port range button" );
	m_portRangeComboBox     = new TQComboBox( this, "port range combobox" );
	m_portRangeLineEdit     = new TQLineEdit( this, "port range line edit" );
	m_portRangeListBox      = new TQListBox( this, "port range listbox" );
	m_portRangesCheckBox    = new TQCheckBox( i18n( "Port ranges (-p <port ranges>)" ), this, "port ranges checkbox" );

	m_portRangeComboBox->insertItem( i18n( "Both" ), BothProtocol );
	m_portRangeComboBox->insertItem( i18n( "TCP"  ), TCPProtocol  );
	m_portRangeComboBox->insertItem( i18n( "UDP"  ), UDPProtocol  );

	m_portRangeLineEdit->setValidator( new TQRegExpValidator( TQRegExp( "^\\d{1,5}-{1}\\d{1,5}$" ), this, "port range regx" ));

	row = 3;
	gridLayout->addMultiCellWidget( m_portRangesCheckBox, row, row, 3, 5, TQt::AlignCenter );
	row++;

	m_portRangeButton = new TQPushButton( clearRightIconSet, NULL, this, "host button" );
	TQHBoxLayout* portRangeLayout = new TQHBoxLayout( );

	col = 0;
	portRangeLayout->insertStretch( col++, 0 );
	portRangeLayout->insertWidget(  col++, new TQLabel( i18n( "New range data: " ), this, "new range data label" ), 0 );
	portRangeLayout->insertStretch( col++, 1 );
	portRangeLayout->insertWidget(  col++, m_portRangeButton, 0 );
	portRangeLayout->insertStretch( col++, 1 );
	portRangeLayout->insertWidget(  col++, m_portRangeLineEdit, 100 );
	portRangeLayout->insertStretch( col++, 0 );
	gridLayout->addMultiCellLayout( portRangeLayout, row, row, 3, 5 );

	gridLayout->addWidget( new TQLabel( i18n( "Protocol" ), this, "protocol label" ), row + 1, 3 );
	gridLayout->addWidget( m_portRangeComboBox,     row + 2, 3 );
	gridLayout->addWidget( m_portRangeAddButton,    row + 4, 3 );
	gridLayout->addWidget( m_portRangeDeleteButton, row + 5, 3 );
	byte rowBlock2 = _max_( row + 5, rowBlock1 );
	gridLayout->addMultiCellWidget( m_portRangeListBox,  row + 1, rowBlock2, 5, 5 );

	gridLayout->setColStretch(  0,  4 );
	gridLayout->setColStretch(  2,  2 );
	gridLayout->setColStretch(  5, 10 );
	gridLayout->setColStretch(  6,  4 );

	gridLayout->setRowStretch( 0, 10 );
	gridLayout->setRowStretch( 2, 10 );
	gridLayout->setRowStretch( rowBlock2 + 1, 10 );
}

//	enablePortRangeWidgets
//	======================

void CommonWidget::enablePortRangeWidgets( )
{	bool portRangesState = m_portRangesCheckBox->isChecked( );

	m_portRangeAddButton->setEnabled( false );
	m_portRangeDeleteButton->setEnabled( false );
	m_portRangeButton->setEnabled( portRangesState );
	m_portRangeLineEdit->setEnabled( portRangesState );
	m_portRangeLineEdit->clear( );
	m_portRangeComboBox->setEnabled( portRangesState );
	m_portRangeListBox->setEnabled( portRangesState );

	if( portRangesState )
		emit( disableFastScan( ));
}

//	finaliseInitialisation
//	======================

void CommonWidget::finaliseInitialisation( )
{	WhatsThis* whatsThis = new WhatsThis( this );

	connect( m_hostButton,             TQ_SIGNAL( clicked( )),                     TQ_SLOT( slotHostButtonClicked( )));
	connect( m_hostComboBox,           TQ_SIGNAL( activated( int )),               TQ_SLOT( slotHostActivated( int )));
	connect( m_hostComboBox,           TQ_SIGNAL( textChanged( const TQString& )),  TQ_SLOT( slotHostTextChanged( const TQString& )));
	connect( m_portRangeAddButton,     TQ_SIGNAL( clicked( )),                     TQ_SLOT( slotPortRangeAddClicked( )));
	connect( m_portRangeButton,        TQ_SIGNAL( clicked( )),                     TQ_SLOT( slotPortRangeButtonClicked( )));
	connect( m_portRangeDeleteButton,  TQ_SIGNAL( clicked( )),                     TQ_SLOT( slotPortRangeDeleteClicked( )));
	connect( m_portRangeComboBox,      TQ_SIGNAL( activated( int )),               TQ_SLOT( slotPortRangeActivated( int )));
	connect( m_portRangeLineEdit,      TQ_SIGNAL( textChanged( const TQString& )),  TQ_SLOT( slotPortRangeTextChanged( const TQString& )));
	connect( m_portRangeListBox,       TQ_SIGNAL( doubleClicked( TQListBoxItem* )), TQ_SLOT( slotPortRangeDoubleClicked( TQListBoxItem* )));
	connect( m_portRangeListBox,       TQ_SIGNAL( highlighted( int )),             TQ_SLOT( slotPortRangeHighlighted( )));
	connect( m_portRangesCheckBox,     TQ_SIGNAL( clicked( )),                     TQ_SLOT( slotPortRangesClicked( )));
	connect( whatsThis,                TQ_SIGNAL( clicked( )),                     TQ_SLOT( slotWhatsThisClicked( )));

	connect( m_hostButton,             TQ_SIGNAL( clicked( )),                     TQ_SIGNAL( optionsDirty( )));
	connect( m_hostComboBox,           TQ_SIGNAL( activated ( int )),              TQ_SIGNAL( optionsDirty( )));
	connect( m_hostComboBox,           TQ_SIGNAL( textChanged( const TQString& )),  TQ_SIGNAL( optionsDirty( )));
	connect( m_portRangeAddButton,     TQ_SIGNAL( clicked( )),                     TQ_SIGNAL( optionsDirty( )));
	connect( m_portRangeButton,        TQ_SIGNAL( clicked( )),                     TQ_SIGNAL( optionsDirty( )));
	connect( m_portRangeComboBox,      TQ_SIGNAL( activated( int )),               TQ_SIGNAL( optionsDirty( )));
	connect( m_portRangeDeleteButton,  TQ_SIGNAL( clicked( )),                     TQ_SIGNAL( optionsDirty( )));
	connect( m_portRangeLineEdit,      TQ_SIGNAL( textChanged( const TQString& )),  TQ_SIGNAL( optionsDirty( )));
	connect( m_portRangeListBox,       TQ_SIGNAL( doubleClicked( TQListBoxItem* )), TQ_SIGNAL( optionsDirty( )));
	connect( m_portRangeListBox,       TQ_SIGNAL( highlighted ( int )),            TQ_SIGNAL( optionsDirty( )));
	connect( m_portRangesCheckBox,     TQ_SIGNAL( clicked( )),                     TQ_SIGNAL( optionsDirty( )));
	connect( m_resovleAlwaysRadio,     TQ_SIGNAL( clicked( )),                     TQ_SIGNAL( optionsDirty( )));
	connect( m_resovleDefaultRadio,    TQ_SIGNAL( clicked( )),                     TQ_SIGNAL( optionsDirty( )));
	connect( m_resovleNeverRadio,      TQ_SIGNAL( clicked( )),                     TQ_SIGNAL( optionsDirty( )));

	emit( targetChanged( m_hostComboBox->currentText( )));
}
TQString CommonWidget::getHostName( ) const
{	return m_hostComboBox->currentText( );
}

//	getHosts
//	========

void CommonWidget::getHosts( TQStringList* hosts )
{	hosts->clear( );

	for( ushort i = 0; i < m_hostComboBox->count( ); i++ )
		hosts->append( m_hostComboBox->text( i ));
}

//	getOptions
//	==========

bool CommonWidget::getOptions( )
{	TQStringList portRanges;
	getPortRanges( &portRanges );

	bool portRangesState = m_portRangesCheckBox->isChecked( );

	if( portRangesState && portRanges.isEmpty( ))
	{	KMessageBox::error( this, i18n( "Port ranges not specified" ), i18n( "Port ranges error" ));
		return false;
	}

	m_host                 = m_hostComboBox->currentText( );
	m_hostCurrentItem      = m_hostComboBox->currentItem( );
	m_portRangeCurrentItem = m_portRangeComboBox->currentItem( );
	m_portRangesState      = portRangesState;
	m_resovleAlwaysState   = m_resovleAlwaysRadio->isChecked( );
	m_resovleDefaultState  = m_resovleDefaultRadio->isChecked( );
	m_resovleNeverState    = m_resovleNeverRadio->isChecked( );

	if( m_portRanges != NULL )
		delete m_portRanges;

	m_portRanges = new TQStringList( portRanges );
	getHosts( m_hosts );

	disconnect( m_hostComboBox, TQ_SIGNAL( activated( int )),              this, TQ_SLOT( slotHostActivated( int )));
	disconnect( m_hostComboBox, TQ_SIGNAL( textChanged( const TQString& )), this, TQ_SLOT( slotHostTextChanged( const TQString& )));

	disconnect( m_hostComboBox, TQ_SIGNAL( activated ( int )),             this, TQ_SIGNAL( optionsDirty( )));
	disconnect( m_hostComboBox, TQ_SIGNAL( textChanged( const TQString& )), this, TQ_SIGNAL( optionsDirty( )));

	byte i;
	TQStringList::Iterator it;

	for( i = 0, it = m_hosts->begin( ); it != m_hosts->end( ); i++, ++it )
		if( *it == m_host )
			break;

	if( it != m_hosts->end( ))
	{	m_hostComboBox->removeItem( i );
		m_hosts->remove( it );
	}
	else
		while( m_hostComboBox->count( ) > MAX_HOST_HISTORY - 1 )
		{	m_hostComboBox->removeItem( MAX_HOST_HISTORY - 1 );
			m_hosts->pop_back( );
		}

	m_hostComboBox->insertItem( m_host, 0 );
	m_hostComboBox->setCurrentItem( 0 );
	m_hosts->prepend( m_host );

	connect( m_hostComboBox, TQ_SIGNAL( activated( int )),              TQ_SLOT( slotHostActivated( int )));
	connect( m_hostComboBox, TQ_SIGNAL( textChanged( const TQString& )), TQ_SLOT( slotHostTextChanged( const TQString& )));

	connect( m_hostComboBox, TQ_SIGNAL( activated ( int )),             TQ_SIGNAL( optionsDirty( )));
	connect( m_hostComboBox, TQ_SIGNAL( textChanged( const TQString& )), TQ_SIGNAL( optionsDirty( )));

	return true;
}

//	getPortRanges
//	=============

void CommonWidget::getPortRanges( TQStringList* portRanges )
{	portRanges->clear( );

	for( ushort i = 0; i < m_portRangeListBox->count( ); i++ )
		portRanges->append( m_portRangeListBox->text( i ));
}

//	portRangesOverlapping
//	=====================

bool CommonWidget::portRangesOverlapping( const ushort portFirst, const ushort portLast )
{	boolPtr tcpPorts = new bool[ 64 * 1024 ];
	boolPtr udpPorts = new bool[ 64 * 1024 ];

	if( !buildPortRangesTables( tcpPorts, udpPorts ))
	{	delete [] tcpPorts;
		delete [] udpPorts;
		return false;
	}

	bool tcp = false;
	bool udp = false;

	switch( m_portRangeComboBox->currentItem( ))
	{	case 0: tcp = udp = true; break;
		case 1: tcp = true;       break;
		case 2: udp = true;       break;

		default:
			kdDebug( ) << i18n( "unknown value in Port Range Protocol combo box" ) << endl;
			Q_ASSERT( false );
			delete [] tcpPorts;
			delete [] udpPorts;
			return false;
	}

	uint    port;
	TQString protocol;

	for( port = portFirst; port <= portLast; port++ )
	{	if( tcp && tcpPorts[ port ])
		{	protocol = "TCP";
			break;
		}

		if( udp && udpPorts[ port ])
		{	protocol = "UDP";
			break;
		}
	}

	if( port <= portLast )
	{	KMessageBox::sorry( this, i18n( "Overlapping Port Range - %1 port %2" ).arg( protocol ).arg( TQString::number( port )), i18n( "Overlapping Port Range" ));
		delete [] tcpPorts;
		delete [] udpPorts;
		return false;
	}

	delete [] tcpPorts;
	delete [] udpPorts;
	return true;
}

//	readProfile
//	===========

void CommonWidget::readProfile( TDEConfig* config )
{	m_hostCurrentItem      = config->readNumEntry(  "hostCurrentItem"      );
	m_portRangeCurrentItem = config->readNumEntry(  "portRangeCurrentItem" );
	m_portRangesState      = config->readBoolEntry( "portRangesState"      );
	m_resovleAlwaysState   = config->readBoolEntry( "resovleAlwaysState"   );
	m_resovleDefaultState  = config->readBoolEntry( "resovleDefaultState"  );
	m_resovleNeverState    = config->readBoolEntry( "resovleNeverState"    );

	m_hosts      = new TQStringList( config->readListEntry( "hosts"      ));
	m_portRanges = new TQStringList( config->readListEntry( "portRanges" ));
}

//	saveProfile
//	===========

void CommonWidget::saveProfile( TDEConfig* config )
{	config->writeEntry( "hostCurrentItem",      m_hostCurrentItem      );
	config->writeEntry( "hosts",               *m_hosts                );
	config->writeEntry( "portRanges",          *m_portRanges           );
	config->writeEntry( "portRangeCurrentItem", m_portRangeCurrentItem );
	config->writeEntry( "portRangesState",      m_portRangesState      );
	config->writeEntry( "resovleAlwaysState",   m_resovleAlwaysState   );
	config->writeEntry( "resovleDefaultState",  m_resovleDefaultState  );
	config->writeEntry( "resovleNeverState",    m_resovleNeverState    );
}

//	setInitialValues
//	================

void CommonWidget::setInitialValues( )
{	m_hostComboBox->clear( );
	m_hostComboBox->insertStringList( *m_hosts );
	m_portRangeListBox->insertStringList( *m_portRanges );
	m_portRangeComboBox->setCurrentItem( m_portRangeCurrentItem );
	m_portRangesCheckBox->setChecked( m_portRangesState );
	m_resovleAlwaysRadio->setChecked( m_resovleAlwaysState );
	m_resovleDefaultRadio->setChecked( m_resovleDefaultState );
	m_resovleNeverRadio->setChecked( m_resovleNeverState );

	if( m_hostComboBox->count( ))
		m_hostComboBox->setCurrentItem( m_hostCurrentItem );

	enablePortRangeWidgets( );
}

//	slotDisablePortRanges
//	=====================

void CommonWidget::slotDisablePortRanges( )
{	m_portRangesCheckBox->setChecked( false );
	slotPortRangesClicked( );
}

//	slotHostActivated
//	=================

void CommonWidget::slotHostActivated( int /* index */)
{	emit( targetChanged( m_hostComboBox->currentText( )));
}

//	slotHostButtonClicked
//	=====================

void CommonWidget::slotHostButtonClicked( )
{	m_hostComboBox->clearEdit( );
}

//	slotHostTextChanged
//	===================

void CommonWidget::slotHostTextChanged( const TQString& text )
{	emit( targetChanged( text ));
}

//	slotPortRangeAddClicked
//	=======================

void CommonWidget::slotPortRangeAddClicked( )
{	TQString text;

	if( !validatePortRange( text ))
		return;

	switch( m_portRangeComboBox->currentItem( ))
	{	case BothProtocol:                     break;
		case TCPProtocol: text = "T:" + text; break;
		case UDPProtocol: text = "U:" + text; break;

		default:
			kdDebug( ) << i18n( "unknown value in Port Range Protocol combo box" ) << endl;
			Q_ASSERT( false );
	}

	m_portRangeAddButton->setEnabled( false );
	emit( optionsDirty( ));
	m_portRangeLineEdit->clear( );
	m_portRangeListBox->insertItem( text );
}

//	slotPortRangeDeleteClicked
//	==========================

void CommonWidget::slotPortRangeDeleteClicked( )
{	m_portRangeIgnoreChange = true;
	m_portRangeListBox->removeItem( m_portRangeListBox->currentItem( ));
	m_portRangeAddButton->setEnabled( true );
	m_portRangeDeleteButton->setEnabled( false );
	emit( optionsDirty( ));
}

//	slotPortRangeActivated
//	======================

void CommonWidget::slotPortRangeActivated( int /* index */)
{	m_portRangeAddButton->setEnabled( true );
}

//	slotPortRangeActivated
//	======================

void CommonWidget::slotPortRangeButtonClicked( )
{	m_portRangeAddButton->setEnabled( false );
	m_portRangeDeleteButton->setEnabled( false );
	m_portRangeLineEdit->clear( );
}

//	slotPortRangeDoubleClicked
//	==========================

void CommonWidget::slotPortRangeDoubleClicked( TQListBoxItem* item )
{	if( item == NULL )
		return;

	TQString text = item->text( );

	if( text[ 0 ].isDigit( ))
		m_portRangeComboBox->setCurrentItem( BothProtocol ); 
	else
	{	switch( text[ 0 ].latin1( ))
		{	case 'T': m_portRangeComboBox->setCurrentItem( TCPProtocol ); break;
			case 'U': m_portRangeComboBox->setCurrentItem( UDPProtocol ); break;

			default:
				kdDebug( ) << i18n( "unknown value in Port Range Protocol" ) << endl;
				Q_ASSERT( false );
				m_portRangeComboBox->setCurrentItem( BothProtocol ); 
		}

		text = text.right( text.length( ) - 2 );
	}

	m_portRangeIgnoreChange = true;
	m_portRangeLineEdit->setText( text );
	m_portRangeDeleteButton->setEnabled( true );
}

//	slotPortRangeHighlighted
//	========================

void CommonWidget::slotPortRangeHighlighted( )
{	if( m_portRangeIgnoreChange )
		m_portRangeIgnoreChange = false;
	else
	{	m_portRangeAddButton->setEnabled( false );
		m_portRangeDeleteButton->setEnabled( false );
		m_portRangeLineEdit->clear( );
	}
}

//	slotPortRangesClicked
//	=====================

void CommonWidget::slotPortRangesClicked( )
{	enablePortRangeWidgets( );
}

//	slotPortRangeTextChanged
//	========================

void CommonWidget::slotPortRangeTextChanged( const TQString& /* text */)
{	if( m_portRangeIgnoreChange )
		m_portRangeIgnoreChange = false;
	else
		m_portRangeAddButton->setEnabled( m_portRangeLineEdit->text( ).length( ));
}

//	slotWhatsThisClicked
//	====================

void CommonWidget::slotWhatsThisClicked( )
{		 if( m_hostButton->hasMouse( ))            emit( displayHelp( "target" ));
	else if( m_hostComboBox->hasMouse( ))          emit( displayHelp( "target" ));
	else if( m_portRangeAddButton->hasMouse( ))    emit( displayDocBook( "common_options" ));
	else if( m_portRangeButton->hasMouse( ))       emit( displayDocBook( "common_options" ));
	else if( m_portRangeComboBox->hasMouse( ))     emit( displayDocBook( "common_options" ));
	else if( m_portRangeDeleteButton->hasMouse( )) emit( displayDocBook( "common_options" ));
	else if( m_portRangeLineEdit->hasMouse( ))     emit( displayDocBook( "common_options" ));
	else if( m_portRangeListBox->hasMouse( ))      emit( displayDocBook( "common_options" ));
	else if( m_portRangesCheckBox->hasMouse( ))    emit( displayHelp( "-p" ));
	else if( m_resovleAlwaysRadio->hasMouse( ))    emit( displayHelp( "-R" ));
	else if( m_resovleDefaultRadio->hasMouse( ))   emit( displayDocBook( "common_options" ));
	else if( m_resovleNeverRadio->hasMouse( ))     emit( displayHelp( "-n" ));
	else emit( displayUnknown( ));
}

//	validatePortRange
//	=================

bool CommonWidget::validatePortRange( TQString& text )
{	uint portFirst;
	uint portLast;

	if( !validatePortRangeText( text, portFirst, portLast ))
		return false;

	if( !portRangesOverlapping( portFirst, portLast ))
		return false;

	return true;
}

//	validatePortRangeText
//	=====================

bool CommonWidget::validatePortRangeText( TQString& text, uint& portFirst, uint& portLast )
{	text = m_portRangeLineEdit->text( );
	TQStringList ports = TQStringList::split( "-", text );

	if( ports.count( ) > 2 )
	{	KMessageBox::error( this, i18n( "Internal error - you seem to have been allowed to entered an illegal Port Range" ), i18n( "Internal error" ));
		return false;
	}

	portFirst = ports.front( ).toUInt( );
	portLast  = portFirst;

	if( ports.count( ) > 1 )
		portLast  = ports.back( ).toUInt( );

	if( !portFirst || portFirst > 65535 || !portLast || portLast > 65535 || portFirst > portLast )
	{	KMessageBox::sorry( this,
							i18n( "Ports must be in the range 1 to 65,535 and ranges must be in ascending order" ),
							i18n( "Invalid Port Range" ));
		return false;
	}

	return true;
}

#include "commonwidget.moc"
