package PACExpectEntry;

##################################################################
# This file is part of PAC( Perl Auto Connector)
#
# Copyright (C) 2010-2015  David Torrejon Vaquerizas
# 
# 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 3 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, see <http://www.gnu.org/licenses/>.
###################################################################

$|++;

###################################################################
# Import Modules

# Standard
use strict;
use warnings;

use FindBin qw ( $RealBin $Bin $Script );
#use Data::Dumper;

# GTK2
use Gtk2 '-init';

# PAC modules
use PACUtils;

# END: Import Modules
###################################################################

###################################################################
# Define GLOBAL CLASS variables



# END: Define GLOBAL CLASS variables
###################################################################

###################################################################
# START: Public class methods

sub new {
	my $class	= shift;
	
	my $self	= {};
	
	$self -> {cfg}			= shift;
	$self -> {variables}	= shift;
	
	$self -> {container}	= undef;
	$self -> {frame}		= {};
	$self -> {list}			= [];
	
	_buildExpectGUI( $self );
	defined $self -> {cfg} and PACExpectEntry::update( $self -> {cfg} );
	
	bless( $self, $class );
	return $self;
}

sub update {
	my $self		= shift;
	my $cfg			= shift;
	my $variables	= shift;
	
	defined $cfg and $$self{cfg} = $cfg;
	defined $variables and $$self{variables} = $variables;
	
	# Destroy previuos widgets
	$$self{frame}{vbexpect} -> foreach( sub { $_[0] -> destroy(); } );
	
	# Empty parent's widgets' list
	$$self{list} = [];
	
	# Now, add the -new?- widgets
	foreach my $hash ( @{ $$self{cfg} } ) { _buildExpect( $self, $hash ); }
	
	# Delete "up" arrow from first element...
	defined $$self{list}[0] and $$self{list}[0]{ebup} -> destroy();
	
	# ... and delete "down" arrow from last element.
	defined $$self{list}[ $#{ $$self{list} } ] and  $$self{list}[ $#{ $$self{list} } ]{ebdown} -> destroy();
	
	return 1;
}

sub get_cfg {
	my $self = shift;
	
	my @cfg;
	
	foreach my $w ( @{ $self -> {list} } ) {
		my %hash;
		$hash{expect}	= $$w{expect}		-> get_chars( 0, -1 );
		$hash{send}		= $$w{send}			-> get_chars( 0, -1 );
		$hash{hidden}	= $$w{hidden}		-> get_active || '0';
		$hash{active}	= $$w{active}		-> get_active || '0';
		$hash{return}	= $$w{return}		-> get_active || '0';
		
		if ( $$w{cbOnMatch} -> get_active )	{ $hash{on_match} = $$w{rbOnMatchGoto} -> get_active ? $$w{on_match} -> get_chars( 0, -1 ) : -2; }
		else								{ $hash{on_match} = -1; }
		
		if ( $$w{cbOnFail} -> get_active )	{ $hash{on_fail} = $$w{rbOnFailGoto} -> get_active ? $$w{on_fail} -> get_chars( 0, -1 ) : -2; }
		else								{ $hash{on_fail} = -1; }
		
		$hash{time_out}	= $$w{cbTimeOut}	-> get_active ? $$w{time_out}	-> get_chars( 0, -1 ) : -1;
		push( @cfg, \%hash );
	}
	
	return \@cfg;
}

# END: Public class methods
###################################################################

###################################################################
# START: Private functions definitions

sub _buildExpectGUI {
	my $self	= shift;
	
	my $cfg		= $self -> {cfg};
	
	my %w;
	
	# Build a vbox for:buttons, separator and expect widgets
	$w{vbox} = Gtk2::VBox -> new( 0, 0 );
		
		# Build a hbuttonbox for widgets actions (add, etc.)
		$w{bbox} = Gtk2::HButtonBox -> new();
		$w{vbox} -> pack_start( $w{bbox}, 0, 1, 0 );
		$w{bbox} -> set_layout( 'GTK_BUTTONBOX_START' );
			
			# Build 'add' button
			$w{btnadd} = Gtk2::Button -> new_from_stock( 'gtk-add' );
			$w{bbox} -> add( $w{btnadd} );
			
		# Build a separator
		$w{sep} = Gtk2::HSeparator -> new();
		$w{vbox} -> pack_start( $w{sep}, 0, 1, 5 );
		
		# Build a scrolled window
		$w{sw} = Gtk2::ScrolledWindow -> new();
		$w{vbox} -> pack_start( $w{sw}, 1, 1, 0 );
		$w{sw} -> set_policy( 'automatic', 'automatic' );
		$w{sw} -> set_shadow_type( 'none' );
			
			$w{vp} = Gtk2::Viewport -> new();
			$w{sw} -> add( $w{vp} );
			$w{vp} -> set_property( 'border-width', 5 );
			$w{vp} -> set_shadow_type( 'none' );
				
				# Build and add the vbox that will contain the expect widgets
				$w{vbexpect} = Gtk2::VBox -> new( 0, 0 );
				$w{vp} -> add( $w{vbexpect} );
	
	$$self{container} = $w{vbox};
	$$self{frame} = \%w;
	
	# Button(s) callback(s)
	
	$w{btnadd} -> signal_connect( 'clicked', sub {
		# Save current cfg
		$$self{cfg} = $self -> get_cfg();
		# Append an empty expect entry to cfg
		push( @{ $$self{cfg} }, { 'expect' => '', 'send' => '', 'active' => 1, 'hidden' => 0 } );
		# Update gui
		$self -> update();
		# Set keyboard focus on last created entry
		$$self{list}[ $#{ $$self{list} } ]{expect} -> grab_focus();
		return 1;
	} );
	
	return 1;
}

sub _buildExpect {
	my $self	= shift;
	my $hash	= shift;
	
	my $exp			= $$hash{'expect'} // '';
	my $cmd			= $$hash{'send'} // '';
	my $hide		= $$hash{'hidden'} // 0;
	my $active		= $$hash{'active'} // ( ( $cmd ne '' ) && ( $exp ne '' ) );
	my $return		= $$hash{'return'} // 1;
	my $on_match	= $$hash{'on_match'} // -1;
	my $on_fail		= $$hash{'on_fail'} // -1;
	my $time_out	= $$hash{'time_out'} // -1;
	
	my @undo_expect;
	my $undoing_expect = 0;
	my @undo_exec;
	my $undoing_exec = 0;
	
	my %w;
	
	$w{position} = scalar @{ $$self{list} };
	
	# Make a checkbox to use as frame's label
	$w{active} = Gtk2::CheckButton -> new_with_label( 'Expect #' . $w{position} . ' ' );
	$w{active} -> set_active( $active );
	
	# Make an container frame
	$w{frame} = Gtk2::Frame -> new;
	$w{frame} -> set_label_widget( $w{active} );
		
		# Build an HBox
		$w{hbox1} = Gtk2::HBox -> new( 0, 0 );
		$w{frame} -> add( $w{hbox1} );
			
			# Build a vbox for event_boxes 1 & 2
			$w{vbox1} = Gtk2::VBox -> new( 0, 0 );
			$w{hbox1} -> pack_start( $w{vbox1}, 0, 1, 0 );
				
				# Build first event_box and add a go-up arrow
				$w{ebup} = Gtk2::EventBox -> new;
				$w{vbox1} -> pack_start( $w{ebup}, 1, 1, 0 );
				$w{ebup} -> add( Gtk2::Image -> new_from_stock( 'gtk-go-up', 'small-toolbar' ) );
				
				# Build first event_box and add a go-down arrow
				$w{ebdown} = Gtk2::EventBox -> new;
				$w{vbox1} -> pack_start( $w{ebdown}, 1, 1, 0 );
				$w{ebdown} -> add( Gtk2::Image -> new_from_stock( 'gtk-go-down', 'small-toolbar' ) );
			
			# Build a vbox for expect and send entries
			$w{vbox2} = Gtk2::VBox -> new( 0, 0 );
			$w{hbox1} -> pack_start( $w{vbox2}, 1, 1, 0 );
			$w{vbox2} -> set_sensitive( $active );
				
				# Build an HBox to contain label & expect entry
				$w{hboxExpect} = Gtk2::HBox -> new( 0, 0 );
				$w{vbox2} -> pack_start( $w{hboxExpect}, 0, 1, 0 );
					
					# Build and add the label
					$w{hboxExpect} -> pack_start( Gtk2::Label -> new( 'Expect: ' ), 0, 1, 0 );
					
					# Build and add the expect entry
					$w{expect} = Gtk2::Entry -> new;
					$w{hboxExpect} -> pack_start( $w{expect}, 1, 1, 0 );
					$w{expect} -> set_text( $exp );
					$w{expect} -> set_icon_from_stock( 'primary', 'pac-prompt' );
					
					$w{cbTimeOut} = Gtk2::CheckButton -> new( 'Time out (seconds): ' );
					$w{cbTimeOut} -> set_active( $time_out != -1 );
					$w{hboxExpect} -> pack_start( $w{cbTimeOut}, 0, 1, 0 );
					$w{time_out} = Gtk2::SpinButton -> new_with_range( 1, 65535, 1 );
					$w{time_out} -> set_value( $time_out);
					$w{time_out} -> set_sensitive( $w{cbTimeOut} -> get_active );
					$w{hboxExpect} -> pack_start( $w{time_out}, 0, 1, 0 );
				
				# Build an HBox to contain label, hide checkbox & send entry
				$w{hboxSend} = Gtk2::HBox -> new( 0, 0 );
				$w{vbox2} -> pack_start( $w{hboxSend}, 1, 1, 0 );
					
					# Build and add the label
					$w{hboxSend} -> pack_start( Gtk2::Label -> new( 'Send( ' ), 0, 1, 0 );
					
					# Build the hide checkbox
					$w{hidden} = Gtk2::CheckButton -> new_with_label( 'Hide' );
					$w{hboxSend} -> pack_start( $w{hidden}, 0, 1, 0 );
					$w{hidden} -> set_active( $hide );
					
					# Build and add the label
					$w{hboxSend} -> pack_start( Gtk2::Label -> new( '): ' ), 0, 1, 0 );
					
					# Build and add the send entry
					$w{send} = Gtk2::Entry -> new;
					$w{hboxSend} -> pack_start( $w{send}, 1, 1, 0 );
					$w{send} -> set_icon_from_stock( 'primary', 'gtk-media-play' );
					$w{send} -> set_text( $cmd );
					$w{send} -> set_visibility( ! $hide );
					
					# Build and add the return checkbox
					$w{return} = Gtk2::CheckButton -> new_with_label( 'Return' );
					$w{hboxSend} -> pack_start( $w{return}, 0, 1, 0 );
					$w{return} -> set_active( $return );
					$w{return} -> set_tooltip_text( 'Sends a <RETURN> (\n) after the string is entered.\nFor IBM 3270 connections, sends a \r\f (Carriage Return and Line Feed)' );
			
			# Add ON_MATCH, ON_FAIL and TIME_OUT entries
			
			$w{vbox33} = Gtk2::HBox -> new( 0, 0);
			$w{vbox2} -> pack_start( $w{vbox33}, 0, 1, 0 );
				
				$w{hbox33} = Gtk2::HBox -> new( 0, 0 );
				$w{hbox33} -> set_tooltip_text( 'If "Expect" IS matched, the "Send" string will be sent and we will "go to" selected Expect number. If stop is selected, Expect processing will stop, and control will be returned to user (no disconnect will happen)' );
				$w{vbox33} -> pack_start( $w{hbox33}, 0, 1, 0 );
					
					$w{cbOnMatch} = Gtk2::CheckButton -> new( 'On MATCH: ' );
					$w{cbOnMatch} -> set_active( $on_match != -1 );
					$w{hbox33} -> pack_start( $w{cbOnMatch}, 1, 1, 0 );
					
					$w{onmatchhbox} = Gtk2::HBox -> new( 0, 0 );
					$w{onmatchhbox} -> set_sensitive( $w{cbOnMatch} -> get_active );
					$w{hbox33} -> pack_start( $w{onmatchhbox}, 0, 1, 0 );
						
						$w{rbOnMatchGoto} = Gtk2::RadioButton -> new_with_label( undef, 'goto ' );
						$w{rbOnMatchGoto} -> set_active( $on_match > -1 );
						$w{onmatchhbox} -> pack_start( $w{rbOnMatchGoto}, 1, 1, 0 );
						
						$w{on_match} = Gtk2::SpinButton -> new_with_range( 0, 65535, 1 );
						$w{on_match} -> set_value( $on_match );
						$w{on_match} -> set_sensitive( $w{rbOnMatchGoto} -> get_active );
						$w{onmatchhbox} -> pack_start( $w{on_match}, 0, 1, 0 );
						
						$w{rbOnMatchStop} = Gtk2::RadioButton -> new_with_label_from_widget( $w{rbOnMatchGoto}, 'stop' );
						$w{rbOnMatchStop} -> set_active( $on_match == -2 );
						$w{onmatchhbox} -> pack_start( $w{rbOnMatchStop}, 1, 1, 0 );
				
				$w{hbox33} -> pack_start( Gtk2::VSeparator -> new, 0, 1, 5 );
				
				$w{hbox34} = Gtk2::HBox -> new( 0, 0 );
				$w{hbox34} -> set_tooltip_text( 'If "Expect" IS NOT matched, no string will be sent, and we will "go to" selected Expect. If stop is selected, Expect processing will stop, and control will be returned to user (no disconnect will happen)' );
				$w{vbox33} -> pack_start( $w{hbox34}, 0, 1, 0 );
					
					$w{cbOnFail} = Gtk2::CheckButton -> new( 'On FAIL: ' );
					$w{cbOnFail} -> set_active( $on_fail != -1 );
					$w{hbox34} -> pack_start( $w{cbOnFail}, 1, 1, 0 );
					
					$w{onfailhbox} = Gtk2::HBox -> new( 0, 0 );
					$w{onfailhbox} -> set_sensitive( $w{cbOnFail} -> get_active );
					$w{hbox34} -> pack_start( $w{onfailhbox}, 0, 1, 0 );
						
						$w{rbOnFailGoto} = Gtk2::RadioButton -> new_with_label( undef, 'goto ' );
						$w{rbOnFailGoto} -> set_active( $on_fail > -1 );
						$w{onfailhbox} -> pack_start( $w{rbOnFailGoto}, 1, 1, 0 );
						
						$w{on_fail} = Gtk2::SpinButton -> new_with_range( 0, 65535, 1 );
						$w{on_fail} -> set_value( $on_fail );
						$w{on_fail} -> set_sensitive( $w{rbOnFailGoto} -> get_active );
						$w{onfailhbox} -> pack_start( $w{on_fail}, 0, 1, 0 );
						
						$w{rbOnFailStop} = Gtk2::RadioButton -> new_with_label_from_widget( $w{rbOnFailGoto}, 'stop' );
						$w{rbOnFailStop} -> set_active( $on_fail == -2 );
						$w{onfailhbox} -> pack_start( $w{rbOnFailStop}, 1, 1, 0 );
			
			# Build delete button
			$w{btn} = Gtk2::Button -> new_from_stock( 'gtk-delete' );
			$w{hbox1} -> pack_start( $w{btn}, 0, 1, 0 );
	
	# Add built control to main container
	$$self{frame}{vbexpect} -> pack_start( $w{frame}, 0, 1, 0 );
	$$self{frame}{vbexpect} -> show_all;
	
	$$self{list}[$w{position}] = \%w;
	
	# Setup some callbacks
	
	$w{on_match} -> signal_connect( 'value_changed' => sub {
		my $v = $w{on_match} -> get_chars( 0, -1 );
		return 1 if $v <= scalar( @{ $$self{cfg} } -1 );
		$w{on_match} -> set_value( scalar( @{ $$self{cfg} } ) - 1 );
	} );
	
	$w{on_fail} -> signal_connect( 'value_changed' => sub {
		my $v = $w{on_fail} -> get_chars( 0, -1 );
		return 1 if $v <= scalar( @{ $$self{cfg} } - 1 );
		$w{on_fail} -> set_value( scalar( @{ $$self{cfg} } ) - 1 );
	} );
	
	# Asign Drag and Drop functions
	$w{active} -> drag_source_set( 'GDK_BUTTON1_MASK', [ 'move' ], { 'target' => 'PAC Expect', 'flags' => [], 'info' => 0 } );
	$w{active} -> signal_connect( 'drag_begin' => sub {
		$_[1] -> set_icon_pixbuf( _scale( _screenshot( $$self{list}[$w{position}]{'frame'} ), 256, 128, 1), 0, 0 );
		$$self{_DND_SOURCE} = \%w;
	} );
	
	$w{active} -> drag_dest_set( 'GTK_DEST_DEFAULT_ALL', [ 'move' ], { 'target' => 'PAC Expect', 'flags' => [], 'info' => 0 } );
	$w{active} -> signal_connect( 'drag_drop' => sub {
		my $source_w = splice( @{ $$self{cfg} }, $$self{_DND_SOURCE}{position}, 1 );
		splice( @{ $$self{cfg} }, $w{position}, 0, $source_w );
		$self -> update;
	} );

	$w{frame} -> drag_dest_set( 'GTK_DEST_DEFAULT_ALL', [ 'move' ], { 'target' => 'PAC Expect', 'flags' => [], 'info' => 0 } );
	$w{frame} -> signal_connect( 'drag_drop' => sub {
		my $source_w = splice( @{ $$self{cfg} }, $$self{_DND_SOURCE}{position}, 1 );
		splice( @{ $$self{cfg} }, $w{position}, 0, $source_w );
		$self -> update;
	} );
	
	# Asign a callback to show right-click mouse menu
	$w{active} -> signal_connect( 'button_press_event' => sub {
		my ( $widget, $event ) = @_;
		
		( $event -> button ne 3 ) and return 0;
		
		my @exec_menu_items;
		
		# Copy
		push( @exec_menu_items, {
			label => 'Copy',
			stockicon => 'gtk-copy',
			sensitive => ( $w{active} -> get_active() ),
			code => sub {
				$self -> {_COPY_EXPECT}{'expect'}			= $w{expect}		-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'exec'}				= $w{send}			-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'show'}				= $w{hidden}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'use'}				= $w{active}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'return'}			= $w{return}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'cbOnMatch'}		= $w{cbOnMatch}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'rbOnMatchGoto'}	= $w{rbOnMatchGoto}	-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'on_match'}			= $w{on_match}		-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'cbOnFail'}			= $w{cbOnFail}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'rbOnFailGoto'}		= $w{rbOnFailGoto}	-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'on_fail'}			= $w{on_fail}		-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'cbTimeOut'}		= $w{cbTimeOut}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'time_out'}			= $w{time_out}		-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'cut'}				= 0;
			}
		} );
		# Cut
		push( @exec_menu_items, {
			label => 'Cut',
			stockicon => 'gtk-cut',
			sensitive => ( $w{active} -> get_active() ),
			code => sub {
				$self -> {_COPY_EXPECT}{'expect'}			= $w{expect}		-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'exec'}				= $w{send}			-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'show'}				= $w{hidden}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'use'}				= $w{active}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'return'}			= $w{return}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'cbOnMatch'}		= $w{cbOnMatch}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'rbOnMatchGoto'}	= $w{rbOnMatchGoto}	-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'on_match'}			= $w{on_match}		-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'cbOnFail'}			= $w{cbOnFail}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'rbOnFailGoto'}		= $w{rbOnFailGoto}	-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'on_fail'}			= $w{on_fail}		-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'cbTimeOut'}		= $w{cbTimeOut}		-> get_active() || '0';
				$self -> {_COPY_EXPECT}{'time_out'}			= $w{time_out}		-> get_chars( 0, -1 );
				$self -> {_COPY_EXPECT}{'cut'}				= 1;
				$w{expect} -> set_text( '' );
				$w{send} -> set_text( '' );
				$w{hidden} -> set_active( 1 );
				$w{active} -> set_active( 0 );
			}
		} );
		# Paste ?
		push( @exec_menu_items, {
			label => 'Paste',
			stockicon => 'gtk-paste',
			sensitive => ( defined $self -> {_COPY_EXPECT} ),
			code => sub {
				$w{expect}			-> set_text( $self			-> {_COPY_EXPECT}{'expect'} );
				$w{send}			-> set_text( $self			-> {_COPY_EXPECT}{'exec'} );
				$w{hidden}			-> set_active( $self		-> {_COPY_EXPECT}{'show'} );
				$w{active}			-> set_active( $self		-> {_COPY_EXPECT}{'use'} );
				$w{return}			-> set_active( $self		-> {_COPY_EXPECT}{'return'} );
				$w{cbOnMatch}		-> set_active( $self		-> {_COPY_EXPECT}{'cbOnMatch'} );
				$w{rbOnMatchGoto}	-> set_active( $self		-> {_COPY_EXPECT}{'rbOnMatchGoto'} );
				$w{on_match}		-> set_value( $self			-> {_COPY_EXPECT}{'on_match'} );
				$w{cbOnFail}		-> set_active( $self		-> {_COPY_EXPECT}{'cbOnFail'} );
				$w{rbOnFailGoto}-> set_active( $self			-> {_COPY_EXPECT}{'rbOnFailGoto'} );
				$w{on_fail}			-> set_value( $self			-> {_COPY_EXPECT}{'on_fail'} );
				$w{cbTimeOut}		-> set_active( $self		-> {_COPY_EXPECT}{'cbTimeOut'} );
				$w{time_out}		-> set_value( $self			-> {_COPY_EXPECT}{'time_out'} );
				$$self{_COPY_EXPECT}{'cut'} and $self	-> {_COPY_EXPECT} = undef;
			}
		} );
		push( @exec_menu_items, { separator => 1 } );
		# Delete
		push( @exec_menu_items, {
			label		=> 'Delete',
			stockicon	=> 'gtk-delete',
			code		=> sub {
				$$self{cfg} = $self -> get_cfg();
				splice( @{ $$self{list} }, $w{position}, 1 );
				splice( @{ $$self{cfg} }, $w{position}, 1 );
				$self -> update;
			}
		} );
		
		PACUtils::_wPopUpMenu( \@exec_menu_items, $event );
		
		return 1;
	} );
	
	# Asign a callback for visibility of entry
	$w{hidden} -> signal_connect( 'toggled' => sub { $w{send} -> set_visibility( ! $w{hidden} -> get_active ); return 1; } );
	
	# Asign a callback for entry sensitiveness
	$w{active} -> signal_connect( 'toggled' => sub { $w{vbox2} -> set_sensitive( $w{active} -> get_active ); } );
	
	# Asign a callback for move up arrow click
	$w{ebup} -> signal_connect( 'button_release_event' => sub {
		return 1 if $w{position} == 0;
		
		# Save moving widget
		my $exp				= $w{expect}		-> get_chars( 0, -1 );
		my $cmd				= $w{send}			-> get_chars( 0, -1 );
		my $hide			= $w{hidden}		-> get_active() || '0';
		my $active			= $w{active}		-> get_active() || '0';
		my $return			= $w{return}		-> get_active() || '0';
		my $cbOnMatch		= $w{cbOnMatch}		-> get_active() || '0';
		my $rbOnMatchGoto	= $w{rbOnMatchGoto}	-> get_active() || '0';
		my $on_match		= $w{on_match}		-> get_chars( 0, -1 );
		my $cbOnFail		= $w{cbOnFail}		-> get_active() || '0';
		my $rbOnFailGoto	= $w{rbOnFailGoto}	-> get_active() || '0';
		my $on_fail			= $w{on_fail}		-> get_chars( 0, -1 );
		my $cbTimeOut		= $w{cbTimeOut}		-> get_active() || '0';
		my $time_out		= $w{time_out}		-> get_chars( 0, -1 );
		
		# Put in moving widget data from previous (position - 1)
		$w{expect}			-> set_text( $$self{list}[$w{position} - 1]{expect}				-> get_chars( 0, -1 ) );
		$w{send}			-> set_text( $$self{list}[$w{position} - 1]{send}				-> get_chars( 0, -1 ) );
		$w{hidden}			-> set_active( $$self{list}[$w{position} - 1]{hidden}			-> get_active() || '0' );
		$w{active}			-> set_active( $$self{list}[$w{position} - 1]{active}			-> get_active() || '0' );
		$w{return}			-> set_active( $$self{list}[$w{position} - 1]{'return'}			-> get_active || '0' );
		$w{cbOnMatch}		-> set_active( $$self{list}[$w{position} - 1]{'cbOnMatch'}		-> get_active || '0' );
		$w{rbOnMatchGoto}	-> set_active( $$self{list}[$w{position} - 1]{'rbOnMatchGoto'}	-> get_active || '0' );
		$w{on_match}		-> set_value( $$self{list}[$w{position} - 1]{'on_match'}		-> get_chars( 0, -1 ) );
		$w{cbOnFail}		-> set_active( $$self{list}[$w{position} - 1]{'cbOnFail'}		-> get_active || '0' );
		$w{rbOnFailGoto}	-> set_active( $$self{list}[$w{position} - 1]{'rbOnFailGoto'}	-> get_active || '0' );
		$w{on_fail}			-> set_value( $$self{list}[$w{position} - 1]{'on_fail'}			-> get_chars( 0, -1 ) );
		$w{cbTimeOut}		-> set_active( $$self{list}[$w{position} - 1]{'cbTimeOut'}		-> get_active || '0' );
		$w{time_out}		-> set_value( $$self{list}[$w{position} - 1]{'time_out'}		-> get_chars( 0, -1 ) );
		
		# Put in previous widget (position - 1) data from the moving one
		$$self{list}[$w{position} - 1]{expect}			-> set_text( $exp );
		$$self{list}[$w{position} - 1]{send}			-> set_text( $cmd );
		$$self{list}[$w{position} - 1]{hidden}			-> set_active( $hide );
		$$self{list}[$w{position} - 1]{active}			-> set_active( $active );
		$$self{list}[$w{position} - 1]{return}			-> set_active( $return );
		$$self{list}[$w{position} - 1]{cbOnMatch}		-> set_active( $cbOnMatch );
		$$self{list}[$w{position} - 1]{rbOnMatchGoto}	-> set_active( $rbOnMatchGoto );
		$$self{list}[$w{position} - 1]{on_match}		-> set_value( $on_match );
		$$self{list}[$w{position} - 1]{cbOnFail}		-> set_active( $cbOnFail );
		$$self{list}[$w{position} - 1]{rbOnFailGoto}	-> set_active( $rbOnFailGoto );
		$$self{list}[$w{position} - 1]{on_fail}			-> set_value( $on_fail );
		$$self{list}[$w{position} - 1]{cbTimeOut}		-> set_active( $cbTimeOut );
		$$self{list}[$w{position} - 1]{time_out}		-> set_value( $time_out );
		
		return 1;
	} );
	
	# Asign a callback for move down arrow click
	$w{ebdown} -> signal_connect( 'button_release_event' => sub {
		return 1 if $w{position} == $#{ $$self{list} };
		
		my $exp				= $w{expect}		-> get_chars( 0, -1 );
		my $cmd				= $w{send}			-> get_chars( 0, -1 );
		my $hide			= $w{hidden}		-> get_active() || '0';
		my $active			= $w{active}		-> get_active() || '0';
		my $return			= $w{return}		-> get_active() || '0';
		my $cbOnMatch		= $w{cbOnMatch}		-> get_active() || '0';
		my $rbOnMatchGoto	= $w{rbOnMatchGoto}	-> get_active() || '0';
		my $on_match		= $w{on_match}		-> get_chars( 0, -1 );
		my $cbOnFail		= $w{cbOnFail}		-> get_active() || '0';
		my $rbOnFailGoto	= $w{rbOnFailGoto}	-> get_active() || '0';
		my $on_fail			= $w{on_fail}		-> get_chars( 0, -1 );
		my $cbTimeOut		= $w{cbTimeOut}		-> get_active() || '0';
		my $time_out		= $w{time_out}		-> get_chars( 0, -1 );
		
		# Put in moving widget data from previous (position - 1)
		$w{expect}			-> set_text( $$self{list}[$w{position} + 1]{expect}			-> get_chars( 0, -1 ) );
		$w{send}			-> set_text( $$self{list}[$w{position} + 1]{send}			-> get_chars( 0, -1 ) );
		$w{hidden}			-> set_active( $$self{list}[$w{position} + 1]{hidden}		-> get_active() || '0' );
		$w{active}			-> set_active( $$self{list}[$w{position} + 1]{active}		-> get_active() || '0' );
		$w{return}			-> set_active( $$self{list}[$w{position} + 1]{'return'}		-> get_active || '0' );
		$w{cbOnMatch}		-> set_active( $$self{list}[$w{position} + 1]{'cbOnMatch'}	-> get_active || '0' );
		$w{rbOnMatchGoto}	-> set_active( $$self{list}[$w{position} + 1]{'rbOnMatchGoto'}	-> get_active || '0' );
		$w{on_match}		-> set_value( $$self{list}[$w{position} + 1]{'on_match'}	-> get_chars( 0, -1 ) );
		$w{cbOnFail}		-> set_active( $$self{list}[$w{position} + 1]{'cbOnFail'}	-> get_active || '0' );
		$w{rbOnFailGoto}	-> set_active( $$self{list}[$w{position} + 1]{'rbOnFailGoto'}	-> get_active || '0' );
		$w{on_fail}			-> set_value( $$self{list}[$w{position} + 1]{'on_fail'}		-> get_chars( 0, -1 ) );
		$w{cbTimeOut}		-> set_active( $$self{list}[$w{position} + 1]{'cbTimeOut'}	-> get_active || '0' );
		$w{time_out}		-> set_value( $$self{list}[$w{position} + 1]{'time_out'}	-> get_chars( 0, -1 ) );
		
		# Put in previous widget (position - 1) data from the moving one
		$$self{list}[$w{position} + 1]{expect}			-> set_text( $exp );
		$$self{list}[$w{position} + 1]{send}			-> set_text( $cmd );
		$$self{list}[$w{position} + 1]{hidden}			-> set_active( $hide );
		$$self{list}[$w{position} + 1]{active}			-> set_active( $active );
		$$self{list}[$w{position} + 1]{return}			-> set_active( $return );
		$$self{list}[$w{position} + 1]{cbOnMatch}		-> set_active( $cbOnMatch );
		$$self{list}[$w{position} + 1]{rbOnMatchGoto}	-> set_active( $rbOnMatchGoto );
		$$self{list}[$w{position} + 1]{on_match}		-> set_value( $on_match );
		$$self{list}[$w{position} + 1]{cbOnFail}		-> set_active( $cbOnFail );
		$$self{list}[$w{position} + 1]{rbOnFailGoto}	-> set_active( $rbOnFailGoto );
		$$self{list}[$w{position} + 1]{on_fail}			-> set_value( $on_fail );
		$$self{list}[$w{position} + 1]{cbTimeOut}		-> set_active( $cbTimeOut );
		$$self{list}[$w{position} + 1]{time_out}		-> set_value( $time_out );
		
		return 1;
	} );
	
	# Asign a callback for deleting entry
	$w{btn} -> signal_connect( 'clicked' => sub {
		$$self{cfg} = $self -> get_cfg();
		splice( @{ $$self{list} }, $w{position}, 1 );
		splice( @{ $$self{cfg} }, $w{position}, 1 );
		$self -> update();
		return 1;
	} );
	
	# Asign a callback to populate this entry with oir own context menu
	$w{expect} -> signal_connect( 'button_press_event' => sub {
		my ( $widget, $event ) = @_;
		
		return 0 unless $event -> button eq 3;
		
		my @menu_items;
		
		# Populate with user defined command prompt
		push( @menu_items, {
			label => '<command prompt>',
			tooltip => 'Expect for a sting matching a COMMAND PROMPT (as defined under "Preferences")',
			stockicon => 'pac-prompt',
			code => sub { $w{expect} -> insert_text( '<command prompt>', -1, $w{expect} -> get_position ); }
		} );
		
		# Populate with user defined variables
		my @variables_menu;
		my $i = 0;
		foreach my $value ( @{ $$self{variables} } ) {
			my $j = $i;
			push( @variables_menu, {
				label => "<V:$j> ($value)",
				code => sub { $w{expect} -> insert_text( "<V:$j>", -1, $w{expect} -> get_position ); }
			} );
			++$i;
		}
		push( @menu_items, {
			label => 'User variables...',
			sensitive => scalar @{ $$self{variables} },
			submenu => \@variables_menu
		} );
		
		# Populate with global defined variables
		my @global_variables_menu;
		foreach my $var ( sort { $a cmp $b } keys %{ $PACMain::FUNCS{_MAIN}{_CFG}{'defaults'}{'global variables'} } ) {
			my $val = $PACMain::FUNCS{_MAIN}{_CFG}{'defaults'}{'global variables'}{$var}{'value'};
			push( @global_variables_menu, {
				label => "<GV:$var> ($val)",
				code => sub { $w{expect} -> insert_text( "<GV:$var>", -1, $w{expect} -> get_position ); }
			} );
		}
		push( @menu_items, {
			label => 'Global variables...',
			sensitive => scalar( @global_variables_menu ),
			submenu => \@global_variables_menu
		} );
		
		# Populate with <CMD:*> special string
		push( @menu_items, {
			label => 'Use a command output as value',
			tooltip => 'The given command line will be locally executed, and its output (both STDOUT and STDERR) will be used to replace this value',
			stockicon => 'gtk-execute',
			code => sub {
				my $pos = $w{expect} -> get_property( 'cursor_position' );
				$w{expect} -> insert_text( '<CMD:command to launch>', -1, $w{expect} -> get_position );
				$w{expect} -> select_region( $pos + 5, $pos + 22 );
			}
		} );
		
		# Populate with PAC internal variables
		my @int_variables_menu;
		push( @int_variables_menu, { label => "UUID",		code => sub { $w{send} -> insert_text( "<UUID>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TIMESTAMP",	code => sub { $w{send} -> insert_text( "<TIMESTAMP>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "DATE_Y",		code => sub { $w{send} -> insert_text( "<DATE_Y>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "DATE_M",		code => sub { $w{send} -> insert_text( "<DATE_M>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "DATE_D",		code => sub { $w{send} -> insert_text( "<DATE_D>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TIME_H",		code => sub { $w{send} -> insert_text( "<TIME_H>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TIME_M",		code => sub { $w{send} -> insert_text( "<TIME_M>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TIME_S",		code => sub { $w{send} -> insert_text( "<TIME_S>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "NAME",		code => sub { $w{send} -> insert_text( "<NAME>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TITLE",		code => sub { $w{send} -> insert_text( "<TITLE>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "IP",			code => sub { $w{send} -> insert_text( "<IP>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "USER",		code => sub { $w{send} -> insert_text( "<USER>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "PASS",		code => sub { $w{send} -> insert_text( "<PASS>", -1, $w{send} -> get_position ); } } );
		push( @menu_items, { label => 'PAC internal variables...', submenu => \@int_variables_menu } );
		
		# Populate with <KPX_(title|username|url):*> special string
		if ( $PACMain::FUNCS{_MAIN}{_CFG}{'defaults'}{'keepass'}{'use_keepass'} ) {
			my ( @titles, @usernames, @urls );
			foreach my $hash ( $PACMain::FUNCS{_KEEPASS} -> find ) {
				push( @titles, {
					label => "<KPX_title:$$hash{title}>",
					tooltip => "$$hash{password}",
					code => sub { $w{expect} -> insert_text( "<KPX_title:$$hash{title}>", -1, $w{expect} -> get_position ); }
				} );
				push( @usernames, {
					label => "<KPX_username:$$hash{username}>",
					tooltip => "$$hash{password}",
					code => sub { $w{expect} -> insert_text( "<KPX_username:$$hash{username}>", -1, $w{expect} -> get_position ); }
				} );
				push( @usernames, {
					label => "<KPX_url:$$hash{url}>",
					tooltip => "$$hash{password}",
					code => sub { $w{expect} -> insert_text( "<KPX_url:$$hash{url}>", -1, $w{expect} -> get_position ); }
				} );
			}
			
			push( @menu_items, {
				label => 'KeePassX',
				stockicon => 'pac-keepass',
				submenu => [
					{
						label => 'KeePassX title values',
						submenu => \@titles
					}, {
						label => 'KeePassX username values',
						submenu => \@usernames
					}, {
						label => 'KeePassX URL values',
						submenu => \@urls
					}, {
						label => "KeePass Extended Query",
						tooltip => "This allows you to select the value to be returned, based on another value's match againt a Perl Regular Expression",
						code => sub { $w{expect} -> insert_text( "<KPXRE_GET_(title|username|password|url)_WHERE_(title|username|password|url)==Your_RegExp_here==>", -1, $w{expect} -> get_position ); }
					}
				]
			} );
		}
		
		_wPopUpMenu( \@menu_items, $event );
		
		return 1;
	} );
	
	# Asign a callback to populate this entry with oir own context menu
	$w{send} -> signal_connect( 'button_press_event' => sub {
		my ( $widget, $event ) = @_;
		
		return 0 unless $event -> button eq 3;
		
		my @menu_items;
		
		# Populate with user defined variables
		my @variables_menu;
		my $i = 0;
		foreach my $value ( @{ $$self{variables} } ) {
			my $j = $i;
			push( @variables_menu, {
				label => "<V:$j> ($value)",
				code => sub { $w{send} -> insert_text( "<V:$j>", -1, $w{send} -> get_position ); }
			} );
			++$i;
		}
		push( @menu_items, {
			label => 'User variables...',
			sensitive => scalar @{ $$self{variables} },
			submenu => \@variables_menu
		} );
		
		# Populate with global defined variables
		my @global_variables_menu;
		foreach my $var ( sort { $a cmp $b } keys %{ $PACMain::FUNCS{_MAIN}{_CFG}{'defaults'}{'global variables'} } ) {
			my $val = $PACMain::FUNCS{_MAIN}{_CFG}{'defaults'}{'global variables'}{$var}{'value'};
			push( @global_variables_menu, {
				label => "<GV:$var> ($val)",
				code => sub { $w{send} -> insert_text( "<GV:$var>", -1, $w{send} -> get_position ); }
			} );
		}
		push( @menu_items, {
			label => 'Global variables...',
			sensitive => scalar( @global_variables_menu ),
			submenu => \@global_variables_menu
		} );
		
		# Populate with environment variables
		my @environment_menu;
		foreach my $key ( sort { $a cmp $b } keys %ENV ) {
			my $value = $ENV{$key};
			push( @environment_menu, {
				label => "<ENV:" . __( $key ) . ">",
				tooltip => "$key=$value",
				code => sub { $w{send} -> insert_text( "<ENV:$key>", -1, $w{send} -> get_position ); }
			} );
		}
		push( @menu_items, {
			label => 'Environment variables...',
			submenu => \@environment_menu
		} );
		
		# Populate with <ASK:#> special string
		push( @menu_items, {
			label => 'Interactive user input',
			tooltip => 'User will be prompted to provide a value with a text box (free data type)',
			stockicon => 'gtk-dialog-question',
			code => sub {
				my $pos = $w{send} -> get_property( 'cursor_position' );
				$w{send} -> insert_text( '<ASK:number>', -1, $w{send} -> get_position );
				$w{send} -> select_region( $pos + 5, $pos + 11 );
			}
		} );
		
		# Populate with <ASK:*|> special string
		push( @menu_items, {
			label => 'Interactive user choose from list',
			tooltip => 'User will be prompted to choose a value form a user defined list separated with "|" (pipes without quotes)',
			stockicon => 'gtk-dialog-question',
			code => sub {
				my $pos = $w{send} -> get_property( 'cursor_position' );
				$w{send} -> insert_text( '<ASK:descriptive line|opt1|opt2|...|optN>', -1, $w{send} -> get_position );
				$w{send} -> select_region( $pos + 5, $pos + 40 );
			}
		} );
		
		# Populate with <CMD:*> special string
		push( @menu_items, {
			label => 'Use a command output as value',
			tooltip => 'The given command line will be locally executed, and its output (both STDOUT and STDERR) will be used to replace this value',
			stockicon => 'gtk-execute',
			code => sub {
				my $pos = $w{send} -> get_property( 'cursor_position' );
				$w{send} -> insert_text( '<CMD:command to launch>', -1, $w{send} -> get_position );
				$w{send} -> select_region( $pos + 5, $pos + 22 );
			}
		} );
		
		# Populate with PAC internal variables
		my @int_variables_menu;
		push( @int_variables_menu, { label => "UUID",		code => sub { $w{send} -> insert_text( "<UUID>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TIMESTAMP",	code => sub { $w{send} -> insert_text( "<TIMESTAMP>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "DATE_Y",		code => sub { $w{send} -> insert_text( "<DATE_Y>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "DATE_M",		code => sub { $w{send} -> insert_text( "<DATE_M>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "DATE_D",		code => sub { $w{send} -> insert_text( "<DATE_D>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TIME_H",		code => sub { $w{send} -> insert_text( "<TIME_H>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TIME_M",		code => sub { $w{send} -> insert_text( "<TIME_M>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TIME_S",		code => sub { $w{send} -> insert_text( "<TIME_S>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "NAME",		code => sub { $w{send} -> insert_text( "<NAME>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "TITLE",		code => sub { $w{send} -> insert_text( "<TITLE>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "IP",			code => sub { $w{send} -> insert_text( "<IP>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "USER",		code => sub { $w{send} -> insert_text( "<USER>", -1, $w{send} -> get_position ); } } );
		push( @int_variables_menu, { label => "PASS",		code => sub { $w{send} -> insert_text( "<PASS>", -1, $w{send} -> get_position ); } } );
		push( @menu_items, { label => 'PAC internal variables...', submenu => \@int_variables_menu } );
		
		# Populate with <KPX_(title|username|url):*> special string
		if ( $PACMain::FUNCS{_MAIN}{_CFG}{'defaults'}{'keepass'}{'use_keepass'} ) {
			my ( @titles, @usernames, @urls );
			foreach my $hash ( $PACMain::FUNCS{_KEEPASS} -> find ) {
				push( @titles, {
					label => "<KPX_title:$$hash{title}>",
					tooltip => "$$hash{password}",
					code => sub { $w{send} -> insert_text( "<KPX_title:$$hash{title}>", -1, $w{send} -> get_position ); }
				} );
				push( @usernames, {
					label => "<KPX_username:$$hash{username}>",
					tooltip => "$$hash{password}",
					code => sub { $w{send} -> insert_text( "<KPX_username:$$hash{username}>", -1, $w{send} -> get_position ); }
				} );
				push( @usernames, {
					label => "<KPX_url:$$hash{url}>",
					tooltip => "$$hash{password}",
					code => sub { $w{send} -> insert_text( "<KPX_url:$$hash{url}>", -1, $w{send} -> get_position ); }
				} );
			}
			
			push( @menu_items, {
				label => 'KeePassX',
				stockicon => 'pac-keepass',
				submenu => [
					{
						label => 'KeePassX title values',
						submenu => \@titles
					}, {
						label => 'KeePassX username values',
						submenu => \@usernames
					}, {
						label => 'KeePassX URL values',
						submenu => \@urls
					}, {
						label => "KeePass Extended Query",
						tooltip => "This allows you to select the value to be returned, based on another value's match againt a Perl Regular Expression",
						code => sub { $w{send} -> insert_text( "<KPXRE_GET_(title|username|password|url)_WHERE_(title|username|password|url)==Your_RegExp_here==>", -1, $w{send} -> get_position ); }
					}
				]
			} );
		}
		
		_wPopUpMenu( \@menu_items, $event );
		
		return 1;
	} );
	
	$w{expect} -> signal_connect( 'delete_text' => sub { ! $undoing_expect and push( @undo_expect, $w{expect} -> get_chars( 0, -1 ) ); return $_[1], $_[3]; } );
	$w{expect} -> signal_connect( 'insert_text' => sub { ! $undoing_expect and push( @undo_expect, $w{expect} -> get_chars( 0, -1 ) ); return $_[1], $_[3]; } );
	$w{expect} -> signal_connect( 'key_press_event' => sub {
		my ( $widget, $event ) = @_; 
		my $keyval	= '' . ( $event -> keyval );
		my $state	= '' . ( $event -> state );
		# Check if <Ctrl>z is pushed
		if ( ( $event -> state >= 'control-mask' ) && ( chr( $keyval ) eq 'z' ) && ( scalar @undo_expect ) ) {
			$undoing_expect = 1;
			$w{expect} -> set_text( pop( @undo_expect ) );
			$undoing_expect = 0;
			return 1;
		}
		return 0;
	} );
	
	$w{send} -> signal_connect( 'delete_text' => sub { ! $undoing_exec and push( @undo_exec, $w{send} -> get_chars( 0, -1 ) ); return $_[1], $_[3]; } );
	$w{send} -> signal_connect( 'insert_text' => sub { ! $undoing_exec and push( @undo_exec, $w{send} -> get_chars( 0, -1 ) ); return $_[1], $_[3]; } );
	$w{send} -> signal_connect( 'key_press_event' => sub
	{
		my ( $widget, $event ) = @_; 
		my $keyval	= '' . ( $event -> keyval );
		my $state	= '' . ( $event -> state );
		# Check if <Ctrl>z is pushed
		if ( ( $event -> state >= 'control-mask' ) && ( chr( $keyval ) eq 'z' ) && ( scalar @undo_exec ) ) {
			$undoing_exec = 1;
			$w{send} -> set_text( pop( @undo_exec ) );
			$undoing_exec = 0;
			return 1;
		}
		return 0;
	} );
	
	
	$w{rbOnMatchGoto}	-> signal_connect( 'toggled' => sub { $w{on_match}		-> set_sensitive( $w{rbOnMatchGoto}	-> get_active ); } );
	$w{rbOnFailGoto}	-> signal_connect( 'toggled' => sub { $w{on_fail}		-> set_sensitive( $w{rbOnFailGoto}	-> get_active ); } );
	$w{cbOnMatch}		-> signal_connect( 'toggled' => sub { $w{onmatchhbox}	-> set_sensitive( $w{cbOnMatch}		-> get_active ); } );
	$w{cbOnFail}		-> signal_connect( 'toggled' => sub { $w{onfailhbox}	-> set_sensitive( $w{cbOnFail}		-> get_active ); } );
	$w{cbTimeOut}		-> signal_connect( 'toggled' => sub { $w{time_out}		-> set_sensitive( $w{cbTimeOut}		-> get_active ); } );
	return %w;
}

# END: Private functions definitions
###################################################################

1;
