Amulet pl src

From AMule Project FAQ
Jump to: navigation, search

aMulet.pl source

#!/usr/bin/perl -w
#
# file aMulet.pl
# Copyright by AnimAlf
#
# This lines are under the GNU General Public License.
# http://www.gnu.org/copyleft/gpl.html
#

use strict;

my $binaMuled = 'amuled -f';
my $apppid = "$ENV{HOME}/.tx2z.pid"; # imagination
my $logMode = "debug"; # debug warning msg
my $verbose = 1; # true false

use vars qw( %lang_en %lang_es );
&initLang;

my %lang = %lang_en;

if (!defined($ENV{'DISPLAY'})){
  print &appRel . "\n\n$lang{not_X11_msg}\n\n";
  exit -1;
}

eval "use Gtk2::TrayIcon;";
if ($@) {
  print &appRel;
  print "\n\n$lang{not_TrayIcon_msg}\n";
  exit -1;
}

my $modUniCode;
eval "use Unicode::MapUTF8 qw(from_utf8);";
$modUniCode = !$@;

my $config = {};
my @appList = ( 'aMuleGui', 'wxCas', 'aLinkCreator');

# Los procesos hijo envían esta señal al padre cuando terminan y ésta
# debe ser atendida, si no se quedan zombies hasta que termine el padre.
$SIG{CHLD} = \&finalHijo;

# Si se recibe cualquier señal que pueda provocar la interrupción del
# normal funcionamiento, entonces nos encargamos de finalizar correctamente.
$SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = \&finalizar;

# Iniciando Gtk2
Gtk2->init;

# Comprobaciones iniciales. Cargar configuración.
if (!&inicializar){
  logsys ("msg", &appRel . $lang{interrupted_initialization});
  unlink $apppid or die $lang{bad_blockage_file};
  exit -1;
}
logsys ("msg", &appRel . $lang{initiated});

# Formas Gtk2
my $menu =              Gtk2::Menu->new();
my $menu_opciones =     Gtk2::MenuItem->new($lang{options});
my $menu_aLinkCreator = Gtk2::MenuItem->new("aLinkCreator");
my $menu_wxCas        = Gtk2::MenuItem->new("wxCas");
my $menu_aMuleGui     = Gtk2::MenuItem->new("aMuleGui");
my $menu_verLog       = Gtk2::MenuItem->new($lang{logfile});
my $menuSalir         = Gtk2::MenuItem->new($lang{quit});
my $pic;

eval {$pic = Gtk2::Gdk::Pixbuf->new_from_file ($config->{'iconPath'});};
if ($@){
  my @aMulet_xpm = ('18 24 17 1', '       c None', '.      c #312A28', '+      c #524842',
    '@      c #D42238', '#      c #835128', '$      c #985A20', '%      c #6A6B6A',
    '&      c #AA7B50', '*      c #EC5867', '=      c #BF7B3F', '-      c #C9792F',
    ';      c #898989', '>      c #E39854', ',      c #CB9D83', '"      c #A9AAAA',
    ')      c #CDCBC9', '!      c #F4F5F3', '                  ',
    '          $       ', '         !>       ', '  #!    )$$       ',
    '  ##    #-$       ', '  )##$  -,#       ', '   .+##)$,)       ',
    '    ...$,!"       ', '    ".$=-$"       ', '     ;==-!=       ',
    '     " >!  "      ', '     ; !&  ;      ', '     " !)))"      ',
    '     """"""!      ', '    %!."""");     ', '    ;))";;;"%;;)  ',
    '  ">-)";;;;"->""  ', '  )-=$,;;%@,->$)  ', '  ;%--#=>>**+%%;  ',
    ' +....&=>>>>#!))! ', '%"-=##$>>>>=&$--;;', '+)-=##&=>>>=#=->)+',
    '%;;=$+.+>>++$->,;%', ' "              . ');
  $pic = Gtk2::Gdk::Pixbuf->new_from_xpm_data (@aMulet_xpm);
  logsys ("warning", $lang{icon_load_Error} . $config->{'iconPath'});
  logsys ("msg", $lang{icon_load});
}

my $img= Gtk2::Image->new_from_pixbuf($pic->scale_simple(18, 24, "tiles"));
my $tray= Gtk2::TrayIcon->new("trayicon");
my $paraEvent = Gtk2::EventBox->new;
my $trayTooltip = Gtk2::Tooltips->new;
my $SeparadorMenu1 = Gtk2::SeparatorMenuItem->new;
my $SeparadorMenu2 = Gtk2::SeparatorMenuItem->new;
my $SeparadorMenu3 = Gtk2::SeparatorMenuItem->new;

$menu->append($menu_verLog);
$menu->append($SeparadorMenu1);
$menu->append($menu_opciones);
$menu->append($SeparadorMenu2);
$menu->append($menu_aLinkCreator);
$menu->append($menu_wxCas);
$menu->append($menu_aMuleGui);
$menu->append($SeparadorMenu3);
$menu->append($menuSalir);

$paraEvent->add($img);
$tray->add($paraEvent);
&statusText;

# Tratamiento de señales
logsys ("debug", $lang{signs_assignment});
$tray->signal_connect ('button-press-event' => \&ClickOnIcon);
$menu_opciones->signal_connect('activate' => \&opcionesGui);
$menu_verLog->signal_connect('activate' => \&visorTexto);
$menu_aLinkCreator->signal_connect('activate' => sub {&extAppStatus('aLinkCreator')});
$menu_wxCas->signal_connect('activate' => sub {&extAppStatus('wxCas')});
$menu_aMuleGui->signal_connect('activate' => sub {&extAppStatus('aMuleGui')});
$menuSalir->signal_connect('activate' => \&finalizar);
Glib::Timeout->add($config->{'signOnTime'}*1000, \&statusText) if $config->{'signOn'};

# show sobre los witgets para que sean visibles
logsys ("debug", $lang{witgets_show});
$menu->show_all;
$tray->show_all;
&popUpsAct;
# iniciando bucle de mensajes
logsys ("debug", $lang{init_msg_loop});
Gtk2->main;
# Fin. Aquí termina el flujo.

#############
# Funciones #
#############
# statusText Establece el texto del toolTip
sub statusText{
  my $tmpStr = &appRel . $lang{right_click_show};
  if ($config->{'signOn'}){
    &onlineInfo;
    # my $tmpStr;
    if ($config->{'ConectStatus'}){
      if ($config->{'typeId'}eq"H"){$tmpStr = $lang{Hid}} 
        elsif ($config->{'typeId'}eq"L"){$tmpStr = $lang{Lid}}
        else {$tmpStr = $lang{Conecting}}
      $tmpStr .= $lang{down} . $config->{'downSpeed'};
      $tmpStr .= " kb/s Up:" . $config->{'upSpeed'} ." Kb/s ";
      if ($config->{'kadStatus'}==2) {$tmpStr .= $lang{k_ok};
        } elsif ($config->{'kadStatus'}==1) {$tmpStr .= $lang{k_fire};
        } else {$tmpStr .= $lang{k_down}};
    } else {$tmpStr = &appRel . $lang{aMd_off}} 
  }
  $trayTooltip->set_tip($tray, $tmpStr);
  $tray->send_message($config->{'signOnTime'}*1000, "[AnimAlf dice] No entiendo");
}

# signatureOn Comprueba OnlineSignature en amule.conf
sub readSignatureConf {
  $config->{'signOn'} = 0;
  $config->{'signOnTime'} = 0;
  if (-f $config->{'aMuleDir'} . "/amule.conf"){
    if ( open( CONFIGFILE, $config->{'aMuleDir'} . "/amule.conf" ) ) {
      while (<CONFIGFILE>) {
        if ( $_ =~ /^OnlineSignature=(.+)/ ) { $config->{'signOn'} = $1 }
        if ( $_ =~ /^OnlineSignatureUpdate=(.+)/ ) { $config->{'signOnTime'} = $1 }
      }
      close CONFIGFILE;
    }
  }
}

# onlineInfo Recoge la información de amulesig.dat
sub onlineInfo {
  if ( open( SIGNFILE, $config->{'aMuleDir'} . "/amulesig.dat" ) ) {
    my @signFile;
    while (<SIGNFILE>) {
      $_ =~ /(.+)\n$/; push (@signFile, $1)
    }
    close SIGNFILE;
    $config->{'ConectStatus'} = $signFile[0];
    $config->{'nameServ'}     = $signFile[1];
    $config->{'ipServ'}       = $signFile[2];
    $config->{'portServ'}     = $signFile[3];
    $config->{'typeId'}       = $signFile[4];
    $config->{'kadStatus'}    = $signFile[5];
    $config->{'downSpeed'}    = $signFile[6];
    $config->{'upSpeed'}      = $signFile[7];
    $config->{'colaCli'}      = $signFile[8];
    $config->{'filesShared'}  = $signFile[9];
    $config->{'nickName'}     = $signFile[10];
    $config->{'totalDown'}    = $signFile[11];
    $config->{'totalUp'}      = $signFile[12];
    $config->{'aMuleVer'}     = $signFile[13];
    $config->{'SessionDown'}  = $signFile[14];
    $config->{'SessionUp'}    = $signFile[15];
    $config->{'TimeRun'}      = $signFile[16];
  }
}

# finalHijo atender la señal de los hijos (cuando terminan la mandan)
sub finalHijo {
  $SIG{CHLD} = \&finalHijo;
  my $pid = wait;
  return unless $config->{$pid}; # El system() realiza un fork() también.
  logsys ("msg", $lang{just_end} . $config->{$pid} . 
    " [" . $config->{$config->{$pid} . 'Pid'} . "]");
  undef $config->{$config->{$pid} . 'Pid'};
  undef $config->{$pid};
}

# finalizar correctamente y eliminar bloqueo
sub finalizar {
  $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = \&finalizar;
  logsys ("msg", $lang{ending}); 
  #Finalizar el bucle de mensajes
  Gtk2->main_quit;
  #Comprobar que no quede ninguna aplicación hijo en funcionamiento
  #y si existe eliminarlas antes de finalizar no vayan a quedar zombies.
  logsys ("msg", $lang{endChilds});
  # Ahora la señal de retorno del hijo la trataremos aquí.
  $SIG{CHLD} = 'DEFAULT';
  foreach my $app (@appList) {
    if (defined $config->{$app . "Pid"}){
      logsys ("msg", "[$app] $lang{end_run_chld}");
      kill ('SIGTERM', $config->{$app . "Pid"});
      waitpid($config->{$app . "Pid"}, 0);
    }
  }

  logsys ("msg", $lang{hasntChld} . &appRel . $lang{inSys});
  #TODO Si archivo de bloqueo es usado para log volcar a otro sitio.
  logsys ("warning", "TODO: $lang{to_do_1}");
  logsys ("msg", $lang{appEnd});
  logsys ("msg", "bye ;-)\n\n".&appRel."\n");
  # borrar archivo de bloqueo
  unlink $apppid or die "$lang{bad_blockage_file} $apppid";
}

# flushChars transforma utf8 a iso-8859-1
sub flushChars {
  my ($tmpStr) = @_;
  $tmpStr =~ s/([\200-\377]+)/from_utf8({ -string => $1, -charset => 'ISO-8859-1'})/eg
    if $modUniCode;
  return $tmpStr;
}

#logsys Mini sistema de logs.
sub logsys {
  my ($mode, $text) = @_;
  my $tmpStr;
  if (open LOG, ">>$apppid") {
    if (($logMode eq "debug" && ($mode eq "debug" or $mode eq "warning")) ||
      ($logMode eq "warning" && ($mode eq "warning" or $mode eq "msg")) || 
	($logMode eq "msg" && $mode eq "msg")){
          my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime (time);
          $year += 1900; $mon ++;
#          $tmpStr="[" . uc($mode) . "] " . sprintf("%02d",$mday) . "-" .
#           sprintf("%02d",$mon) . "-$year " . sprintf("%02d",$hour) . ":" .
#           sprintf("%02d",$min) . ":" . sprintf("%02d",$sec) . " $text\n";
          $tmpStr="[" . uc($mode) . "] " . sprintf("%02d",$mday) . "-";
          $tmpStr.= sprintf("%02d",$mon) . "-$year " . sprintf("%02d",$hour) . ":" if $logMode ne "debug";
          $tmpStr.= sprintf("%02d",$min) . ":" . sprintf("%02d",$sec) . " $text\n";
          print LOG $tmpStr; print $tmpStr if $verbose;
    }
    close LOG;
  }
}

# ClickOnIcon se lanzará tras un click en el TrayIcon.
# Para diferenciar el botón del ratón que se pulsó.
sub ClickOnIcon {
  logsys ("debug", "sub: ClickOnIcon start");
  my ($widget, $event) = @_;
  return 1 if $event->button == 2;
  $menu->popup(undef, undef, undef, undef, $event->button,$event->time) if $event->button == 3;
  &extAppStatus($config->{'appOnClick'}) if $event->button == 1;
}

# extAppStatus lanzará una instancia de la aplicación si no existe
sub extAppStatus {
  logsys ("debug", "sub: extAppStatus start");
  my ($refApp) = @_;
  $config->{ $refApp . 'Pid'} = fork() 
    unless ($config->{ $refApp . 'Pid'}); # Crea un proceso hijo
  die "$lang{fork_error} $!" if !defined($config->{$refApp . 'Pid'});
  if ( $config->{$refApp . 'Pid'} == 0) { # Si se trata del proceso hijo
    logsys ("msg", "$lang{child_begin} [$refApp]");
    if ($config->{$refApp . 'Ok'}) {
      $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = 'DEFAULT';
      logsys ("warning", "$lang{stdout_redirect} $refApp $lang{a} $apppid");
      open STDOUT, ">>$apppid";
      exec ($config->{$refApp . 'App'}) || 
        die "$lang{exec_fail} $refApp";
    } else {exit -1}
  } else { # Circuito del proceso padre
    logsys ("msg", "$lang{father_loop}$refApp pid:"
      . $config->{$refApp . 'Pid'} . "]");
    # Asigno una clave en la configuración con el valor de la pid con el padre
    $config->{$config->{$refApp . 'Pid'}} = $refApp 
      unless $config->{$config->{$refApp . 'Pid'}};
    # a ejecutar por el proceso padre
    logsys ("debug", "TODO: $lang{to_do_2}");
  }
}

# appRel nombre y versión del script
sub appRel {
  $0=~/.*\/(.*)$/;
  my $fileRun = $1;
  $fileRun = $0 unless $fileRun;
  $fileRun = "aMulet.pl [$1]" if $fileRun ne 'aMulet.pl';
  return $fileRun . " v.1.3 alpha";
}

# popUpsAct des/activar apartados del menú
sub popUpsAct {
  $menu_aLinkCreator->set_sensitive($config->{'aLinkCreatorOk'});
  $menu_wxCas->set_sensitive($config->{'wxCasOk'});
  $menu_aMuleGui->set_sensitive($config->{'aMuleGuiOk'});
}

# pathsVerify comprobar la ruta de las aplicaciones
sub pathsVerify{
  foreach my $app (@appList) {
    $config->{$app . 'Ok'} = (-x $config->{$app . 'App'});
  }
}

# inicializar comprobaciones iniciales
sub inicializar {
  my $tmpStr;
  my $runDaemon;

  # Comprobar si ya estamos en marcha
  if (-f $apppid){
    my $appVerify=0;
    # Comprobar si realmente la aplicación está en marcha. 
    if (open(APPPID, $apppid)){
      my $line;
      while ($line = <APPPID>) {
        chop($line); last;
      }
      close(APPPID);
      $appVerify=&isRunProcess($line);
    }
    if ($appVerify){
      $tmpStr = "<b>" . appRel . "</b> $lang{itsRun}\n\n";
      $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = 'DEFAULT';
      &showMessage( 'error', flushChars($tmpStr), 'ok');
      exit -1;
    } else {unlink $apppid}
  }

  # Iniciar Bloqueo
  logsys ("msg", $lang{blockInit});
  if (open LOG, ">$apppid"){print LOG "$$\n"}
  # Cargar la configuración
  logsys ("msg", $lang{loadConf});
  &loadConfig;
  readSignatureConf;

  # Comprobar el estado del aMule como servicio
  if ($config->{'aMuledOn'}){
    logsys ("msg", $lang{isaMuled});
    if (open(PROCESOS,"ps -A |")){
      while (<PROCESOS>){
        $runDaemon = 1 if ($_ =~ /amuled/);
      }
      close PROCESOS;
    }
    if (!$runDaemon) { $runDaemon = 1;
      logsys ("msg", $lang{noaMuled});
      if (open(AMULED,"$binaMuled |")){
        my $aMuleRun; 
        while (<AMULED>){
          logsys ("msg", $_);
          logsys ("msg", "$lang{lock_chg} [$binaMuled] $lang{yourself}") if $_ =~ /binary requires/;
          undef $runDaemon if $_ =~ /binary requires/;
          $aMuleRun = 1 if $_ =~ /Raising current running instance/;
        }
        close AMULED;
        if ($aMuleRun){ 
          logsys ("msg", "*"x56 );
          logsys ("msg", "*"x5 ." $lang{aMrun} " ."*"x6 );
          logsys ("msg", "*"x56 );
          logsys ("msg", $lang{tiTools} );
          logsys ("msg", "*"x56 );
          logsys ("msg", "* $lang{alfsay}" );
          logsys ("msg", "*"x56 );
          undef $runDaemon;
        };
        logsys ("msg", $lang{aMuledInit}) if $runDaemon;
      } else {
        undef $runDaemon;
        logsys ("msg", $lang{aMuledNoRun});
        logsys ("msg", $lang{jump_step});
        $tmpStr = "<u><b>$lang{aMuledNoRun}</b></u>.\n\n";
        $tmpStr .= "$lang{check_no_run}\n\n";
        $tmpStr .= $lang{aMnoHere};
        $tmpStr .= "\n\n$lang{noaMGui}" unless $config->{'aMuleGuiOk'};
        $tmpStr .= "\n$lang{whereaMGUI}" unless $config->{'aMuleGuiOk'};
        my $confirmacion= &showMessage( 'question', flushChars($tmpStr), 'yes-no');
        if ($confirmacion eq 'yes'){
          $config->{'aMuledOn'}=0;
          &saveConfig;
          $runDaemon = 1;
        };
      }
    } else {logsys ("msg", $lang{aMuledIs});}
  } else {
    $runDaemon = 1;
    logsys ("msg", $lang{noRunInit});
    logsys ("msg", $lang{noRunInit2});
  }

  # Comprobar que la aplicación que arranca tras el click en el icono existe.
  # Esto no afectará al retorno de esta función.
  if ($runDaemon){
    logsys ("msg", $lang{click_veryfy});
    if (!$config->{$config->{'appOnClick'} . 'Ok'}){
         $tmpStr = "$lang{writeItInConf}\n";
         $tmpStr .= "$lang{of_app} <b>$config->{'appOnClick'}</b> $lang{another}\n";
         $tmpStr .= $lang{appAnsw};
      &showMessage( 'warning', flushChars($tmpStr), 'ok');
      &opcionesGui;
    }
    logsys ("debug", "TODO: $lang{to_do_3}");
  } # TODO: Intentar mostrarlo como modal y esperar respuesta.
  return $runDaemon;
}

# visorTexto Crea una ventana Gtk en la que muestra el logfile del aMule
sub visorTexto {
  logsys ("debug", "sub: visorTexto start");
  my ($widget, $event) = @_;
  logsys ("debug", $lang{menu_off});
  $widget->set_sensitive(0);
  my $visorTextWin = Gtk2::Window->new("toplevel");
  my $vbox = Gtk2::VBox->new;
  my $scrolledwindow = Gtk2::ScrolledWindow->new;
  my $textBuffer = Gtk2::TextBuffer->new;
  my $ok = Gtk2::Button->new_from_stock("gtk-close");
  my $textView = Gtk2::TextView->new_with_buffer($textBuffer);
  my $LineaLog;

  $visorTextWin->set_title($lang{texView});
  $visorTextWin->set_position('center');
  $visorTextWin->set_default_size(640, 300);
  logsys ("debug", "Leyendo " . $config->{'aMuleDir'} . "/logfile");
  open (LOGFILE, $config->{'aMuleDir'} . "/logfile") || logsys ("warning", $config->{'aMuleDir'} . "/logfile: $!");
  while (<LOGFILE>) {$LineaLog .= $_;}
  close LOGFILE;
  $textView->set_editable(0);
  $textView->set_cursor_visible(0);
  $textBuffer->set_text($LineaLog);
  $scrolledwindow->set_policy('automatic', 'automatic');

  $scrolledwindow->add($textView);
  $vbox->add($scrolledwindow );
  $vbox->pack_end($ok, 0, 0, 3);
  $visorTextWin->add($vbox);

  $ok->signal_connect("clicked", sub { $visorTextWin->destroy; } );
  $visorTextWin->signal_connect('destroy' => sub { $widget->set_sensitive(1); });
  logsys ("msg", $lang{Shw_log_win});
  $visorTextWin->show_all;
}

# isRunProcess comprobará si un proceso está en ejecución
sub isRunProcess {
  my ($proceso) = @_;
  my $runDaemon = 0;
  if (open(PROCESOS,"ps -A |")){
    while (<PROCESOS>){$runDaemon = 1 if $_ =~ /^$proceso\s/;}
    close PROCESOS;
  }
  return $runDaemon;
}

sub infoOnLine {
  my $tmpStr = '';
  &onlineInfo if $config->{'signOn'};
  if ($config->{'signOn'} && $config->{'ConectStatus'}==1){
    $tmpStr = "\n\n<b>" . $config->{'nickName'} . "</b> $lang{with} <b>aMule</b> [<i>";
    $tmpStr .= $config->{'aMuleVer'} . "</i>]\n";
    $tmpStr .= "$lang{connPort} <b>" . $config->{'portServ'};
    $tmpStr .= "</b> $lang{of} <b>" . $config->{'nameServ'} . "</b>\n$lang{with} <b>ID ";
    $tmpStr .= $config->{'typeId'}eq"H"?"$lang{hi}</b>":"$lang{low}</b>";
    $tmpStr .= " $lang{ande} <b>$lang{nk} ";
    if ($config->{'kadStatus'}==2) {$tmpStr .= "$lang{okcon}</b>\n";
      } elsif ($config->{'kadStatus'}==1) {$tmpStr .= "$lang{infire}</b>\n";
      } else {$tmpStr .= "$lang{disconnec}</b>\n"};
    $tmpStr .= $lang{ittake};
    my $tmpStr2 = $config->{'TimeRun'} % 60 . $lang{sec};
    my $tiempo = sprintf("%d",$config->{'TimeRun'} / 60);
    $tmpStr2 = $tiempo % 60 . " $lang{min} $tmpStr2" if $tiempo;
    $tiempo = sprintf("%d",$tiempo / 60) if $tiempo;
    $tmpStr2 = $tiempo % 24 . "$lang{hours} $tmpStr2" if $tiempo;
    $tiempo = sprintf("%d",$tiempo / 24) if $tiempo;
    $tmpStr2 = $tiempo . " $lang{days} $tmpStr2" if $tiempo;
    $tmpStr .= $tmpStr2 . " $lang{connected}\n";
    $tmpStr .= "$lang{inthistime}<b>";
    $tmpStr .= sprintf("%.2f",$config->{'SessionDown'}/1048576) . " Mb</b>\n";
    $tmpStr .= $lang{downTotal};
    $tmpStr .= sprintf("%.2f",$config->{'totalDown'}/1048576) . " Mb\n";
    $tmpStr .= "$lang{sharealso} <b>" . $config->{'filesShared'} . "</b> $lang{sesionFiles}\n";
    $tmpStr .= "$lang{upload} <b>" .  sprintf("%.2f",$config->{'SessionUp'}/1048576);
    $tmpStr .= " Mb</b> $lang{obtaining}\n$lang{atotal} " .  sprintf("%.2f",$config->{'totalUp'}/1048576);
    $tmpStr .= " Mb $lang{totalup},\n$lang{hasRight} ";
    $tmpStr .= $config->{'colaCli'} . $lang{cli};
  }
  return flushChars($tmpStr);
}

# opcionesGui muestra la ventana de opciones
sub opcionesGui {
  my ($widget, $event) = @_;
  logsys ("debug", $lang{callOff});
  $widget->set_sensitive(0) if defined $widget;
  my $guiOpciones = Gtk2::Window->new;
  my $vboxPrincipal = Gtk2::VBox->new;
  my $notebook = Gtk2::Notebook->new;
  my $select_aMuleGui = Gtk2::RadioButton->new('appOnClick', 'aMuleGui');
  my @grupo = $select_aMuleGui->get_group;
  my $select_alc = Gtk2::RadioButton->new_with_label(@grupo, 'aLinkCreator');
  my $select_wxcas = Gtk2::RadioButton->new_with_label(@grupo, 'wxCas');
  my $check_aMuled_on = new Gtk2::CheckButton->new(flushChars($lang{runAsServer}));
  my $vBoxTabRutas = Gtk2::VBox->new;
  my $vBoxTabAbout = Gtk2::VBox->new;
  my $hboxPrincipal = Gtk2::HBox->new;
  my $hBoxTabRutas1 = Gtk2::HBox->new;
  my $hBoxTabRutas2 = Gtk2::HBox->new;
  my $hBoxTabRutas3 = Gtk2::HBox->new(1);
  my $hseparator1 = Gtk2::HSeparator->new;
  my $hseparator2 = Gtk2::HSeparator->new;
  my $hseparator3 = Gtk2::HSeparator->new;
  my $labelTabRutas = Gtk2::Label->new($lang{general});
  my $labelTabAbout = Gtk2::Label->new($lang{about});
  my $labelTabRut1 = Gtk2::Label->new($lang{aboutAmuled});
  my $labelTabRut2 = Gtk2::Label->new($lang{AHD});
  my $labelTabRut3 = Gtk2::Label->new($lang{appPaht});
  my $labelTabRut4 = Gtk2::Label->new('aMuleGui: ');
  my $labelTabRut5 = Gtk2::Label->new('wxCas: ');
  my $labelTabRut6 = Gtk2::Label->new('aLinkCreator: ');
  my $labelTabRut7 = Gtk2::Label->new(flushChars($lang{iconShow}));
  my $labelTabRut8 = Gtk2::Label->new($lang{icon});
  my $labelTabRut9 = Gtk2::Label->new(flushChars($lang{whatapp}));
  my $labelAbout1 = Gtk2::Label->new('aMulet.pl');
  my $labelAbout2 = Gtk2::Label->new($lang{oneHawk});
  my $labelAbout3 = Gtk2::Label->new($lang{oneIdea});
  my $labelAbout4 = Gtk2::Label->new($lang{licence});
  my $labelAbout5 = Gtk2::Label->new('http://www.gnu.org/copyleft/gpl.html');
  my $labelAbout6 = Gtk2::Label->new;
  my $edit_home_aMule = Gtk2::Entry->new;
  my $edit_aMuleGui_path = Gtk2::Entry->new;
  my $edit_wxcas_path = Gtk2::Entry->new;
  my $edit_alc_path = Gtk2::Entry->new;
  my $edit_icon_path = Gtk2::Entry->new;
  my $btnOk = Gtk2::Button->new_from_stock("gtk-apply");
  my $btnCancel = Gtk2::Button->new_from_stock("gtk-cancel");
  my $btnRutas1 = Gtk2::Button->new('...');
  my $btnRutas2 = Gtk2::Button->new('...');
  my $btnRutas3 = Gtk2::Button->new('...');
  my $btnRutas4 = Gtk2::Button->new('...');
  my $btnRutas5 = Gtk2::Button->new($lang{selec});
  my $tableTabRutas = Gtk2::Table->new(3, 3, 0 );

  # Posicionando en la ventana principal
  $guiOpciones->add($vboxPrincipal);
  # Posicionando en el notebook (contenedor de pestañas)
  $vboxPrincipal->add($notebook);	

  # primera pestaña
  $notebook->append_page($vBoxTabRutas, $labelTabRutas);

  $vBoxTabRutas->pack_start($labelTabRut1,     0, 0, 3);
  $vBoxTabRutas->pack_start($hBoxTabRutas1,    0, 0, 3);

  $hBoxTabRutas1->pack_start($labelTabRut2,    0, 0, 3);
  $hBoxTabRutas1->add($edit_home_aMule);
  $hBoxTabRutas1->pack_end($btnRutas1,         0, 0, 3);
  $vBoxTabRutas->pack_start($check_aMuled_on,  0, 0, 3);

  $vBoxTabRutas->pack_start($hseparator2,      0, 0, 3);
  $vBoxTabRutas->pack_start($labelTabRut3,     0, 0, 3);
  $vBoxTabRutas->pack_start($tableTabRutas,    0, 0, 3);
		    
  $tableTabRutas->attach($labelTabRut4,        0, 1, 0, 1, ['fill'], [], 0, 0 );
  $tableTabRutas->attach($edit_aMuleGui_path,  1, 2, 0, 1, ['expand', 'fill'], [], 0, 0 );
  $tableTabRutas->attach($btnRutas2,           2, 3, 0, 1, ['fill'], [], 0, 0 );
  $tableTabRutas->attach($labelTabRut5,        0, 1, 1, 2, ['fill'], [], 0, 0 );
  $tableTabRutas->attach($edit_wxcas_path,     1, 2, 1, 2, ['expand', 'fill'], [], 0, 0 );
  $tableTabRutas->attach($btnRutas3,           2, 3, 1, 2, ['fill'], [], 0, 0 );
  $tableTabRutas->attach($labelTabRut6,        0, 1, 2, 3, ['fill'], [], 0, 0 );
  $tableTabRutas->attach($edit_alc_path,       1, 2, 2, 3, ['expand', 'fill'], [], 0, 0 );
  $tableTabRutas->attach($btnRutas4,           2, 3, 2, 3, ['fill'], [], 0, 0 );

  $vBoxTabRutas->pack_start($hseparator1,      0, 0, 3);
  $vBoxTabRutas->pack_start($labelTabRut9,     0, 0, 3);
  $vBoxTabRutas->pack_start($hBoxTabRutas3,    0, 0, 3);
  $hBoxTabRutas3->pack_start($select_aMuleGui, 0, 0, 3);
  $hBoxTabRutas3->pack_start($select_alc,      0, 0, 3);
  $hBoxTabRutas3->pack_start($select_wxcas,    0, 0, 3);

  $vBoxTabRutas->pack_end($hBoxTabRutas2,      0, 0, 3);

  $hBoxTabRutas2->pack_start($labelTabRut8,    0, 0, 3);
  $hBoxTabRutas2->add($edit_icon_path);
  $hBoxTabRutas2->pack_end($btnRutas5,         0, 0, 3);

  $vBoxTabRutas->pack_end($labelTabRut7,       0, 0, 3);
  $vBoxTabRutas->pack_end($hseparator3,        0, 0, 3);

  # Segunda pestaña
  $notebook->append_page($vBoxTabAbout, $labelTabAbout);
  $vBoxTabAbout->pack_start($labelAbout1,      0, 0, 3);
  $vBoxTabAbout->pack_start($labelAbout2,      0, 0, 3);
  $vBoxTabAbout->pack_start($labelAbout3,      0, 0, 3);
  $vBoxTabAbout->pack_start($labelAbout4,      0, 0, 3);
  $vBoxTabAbout->pack_start($labelAbout5,      0, 0, 3);
  $vBoxTabAbout->pack_start($labelAbout6,      0, 0, 3);

  # Posicionando en la parte inferior de la ventana principal
  $vboxPrincipal->pack_end($hboxPrincipal,     0, 0, 3);
  $hboxPrincipal->pack_start($btnOk,           0, 0, 3);
  $hboxPrincipal->pack_end($btnCancel,         0, 0, 3);

  $labelAbout1->set_markup('<span foreground="DarkRed" size="x-large"><b>' . appRel . ' </b></span>');
  #TODO: Intentar conseguir una UrlLabel, fácil con gnome-open (pero y si no existe gnome?)
  #http://forum.amule.org/thread.php?threadid=9751
  $labelAbout3->set_markup("<span>$lang{ideaOf} <b>tx2z</b> $lang{in} http://forum.amule.org</span>");
  #Añado un mini resumen de la información disponible en amulesig.dat
  $labelAbout6->set_markup(infoOnLine);
  if ($config->{'signOn'}){
    Glib::Timeout->add($config->{'signOnTime'}*1000, sub {
      $labelAbout6->set_markup(infoOnLine);
      $tray->send_message($config->{'signOnTime'}*1000, "[AnimAlf dice] No entiendo");});
  }

  # Propiedades de la ventana principal
  $guiOpciones->set_title($lang{options});
  $guiOpciones->set_position('center');
  #TODO: Intentar que actuase como una ventana modal, como el showMessage
  #      y el punto de la llamada esperase la respuesta ok-cancel
  logsys ("msg", $lang{shoOpsWin});
  logsys ("warning", "*"x36) unless $widget;
  logsys ("warning", "TODO: $lang{beModal}") unless $widget;
  logsys ("warning", "*"x36) unless $widget;

  # Propiedades del notebook
  $notebook->set_tab_pos('top');
  $notebook->set_show_tabs  (1);
  $notebook->set_show_border(1);
  $notebook->set_scrollable (0);
  $notebook->set_tab_hborder(2);
  $notebook->set_tab_vborder(2);

  # alineando de algunas etiquetas
  $labelTabRut4->set_alignment(1,0.5);
  $labelTabRut5->set_alignment(1,0.5);
  $labelTabRut6->set_alignment(1,0.5);

  # Asignando la configuración.
  $edit_home_aMule->set_text($config->{'aMuleDir'});
  $edit_aMuleGui_path->set_text($config->{'aMuleGuiApp'});
  $edit_wxcas_path->set_text($config->{'wxCasApp'});
  $edit_alc_path->set_text($config->{'aLinkCreatorApp'});
  $edit_icon_path->set_text($config->{'iconPath'});

  $check_aMuled_on->set_active($config->{'aMuledOn'});

  $select_wxcas->set_active($config->{'appOnClick'} eq 'wxCas');
  $select_alc->set_active($config->{'appOnClick'} eq 'aLinkCreator');
  $select_aMuleGui->set_active($config->{'appOnClick'} eq 'aMuleGui');

  $select_wxcas->set_sensitive($config->{'wxCasOk'});
  $select_alc->set_sensitive($config->{'aLinkCreatorOk'});
  $select_aMuleGui->set_sensitive($config->{'aMuleGuiOk'});

  # Lo mostramos todo
  $guiOpciones->show_all;
  # La asignación de señales
  $btnOk->signal_connect("clicked", sub { 
      my ($tmpStr, $tmpStr1);

      $tmpStr1 = 'wxCas' if $select_wxcas->get_active;
      $tmpStr1 = 'aLinkCreator' if $select_alc->get_active;
      $tmpStr1 = 'aMuleGui' if $select_aMuleGui->get_active;

      $tmpStr .= $edit_home_aMule->get_text . ": $lang{isntDir}\n"
        if !(-d $edit_home_aMule->get_text);
      $tmpStr .= $edit_aMuleGui_path->get_text . ": <b>$lang{isntExe}</b> ($lang{itisnt})\n"
        if !(-x $edit_aMuleGui_path->get_text);
      $tmpStr .= $edit_wxcas_path->get_text . ": <b>$lang{isntExe}</b> ($lang{itisnt})\n"
        if !(-x $edit_wxcas_path->get_text);
      $tmpStr .= $edit_alc_path->get_text . ": <b>$lang{isntExe}</b> ($lang{itisnt})\n"
        if !(-x $edit_alc_path->get_text);
      $tmpStr .= $edit_icon_path->get_text . ": <b>$lang{dontExist}</b>\n"
        if !(-e $edit_icon_path->get_text);

      if (defined $tmpStr){
          $tmpStr = "<b>$lang{detectAny}</b>\n\n$tmpStr\n\n" . flushChars($lang{wantContinue});
          my $confirmacion= &showMessage( 'question', $tmpStr, 'yes-no');
          return if ($confirmacion eq 'no');
      }

      $config->{'appOnClick'} = 'wxCas' if $select_wxcas->get_active;
      $config->{'appOnClick'} = 'aLinkCreator' if $select_alc->get_active;
      $config->{'appOnClick'} = 'aMuleGui' if $select_aMuleGui->get_active;

      $config->{'aMuleDir'} = $edit_home_aMule->get_text;
      $config->{'aMuleGuiApp'} = $edit_aMuleGui_path->get_text;
      $config->{'wxCasApp'} = $edit_wxcas_path->get_text;
      $config->{'aLinkCreatorApp'} = $edit_alc_path->get_text;
      &showMessage( 'info', flushChars($lang{iconWhenRestart}), 'ok')
        if $config->{'iconPath'} ne $edit_icon_path->get_text;
      $config->{'iconPath'} = $edit_icon_path->get_text;

      $config->{'aMuledOn'} = $check_aMuled_on->get_active;

      &saveConfig; pathsVerify; popUpsAct; readSignatureConf;
      $guiOpciones->destroy; 
    } 
  );
  $btnCancel->signal_connect("clicked", sub { $guiOpciones->destroy; } );
  $guiOpciones->signal_connect('destroy' => sub {$widget->set_sensitive(1) if defined $widget;});
  $btnRutas1->signal_connect('clicked' => sub { dialogOpen($edit_home_aMule,
    $lang{selHomaMu}, 'select-folder'); });
  $btnRutas2->signal_connect('clicked' => sub { dialogOpen($edit_aMuleGui_path,
    flushChars($lang{selaMguiApp}), 'open'); });
  $btnRutas3->signal_connect('clicked' => sub { dialogOpen($edit_wxcas_path,
    flushChars($lang{selwxCasApp}), 'open'); });
  $btnRutas4->signal_connect('clicked' => sub { dialogOpen($edit_alc_path,
    flushChars($lang{selALCapp}), 'open'); });
  $btnRutas5->signal_connect('clicked' => sub { dialogOpen($edit_icon_path,
    flushChars($lang{selIcon}), 'open'); });
}

# loadConfig carga la configuración o la crea si no existe
sub loadConfig {
  if ( open( CONFIGFILE, "$ENV{HOME}/.aMule/amulet.rc" ) ) {
    while (<CONFIGFILE>) {
      if ( $_ =~ /(\w+)\s=\s(.+)/ ) { $config->{$1} = $2 }
    }
    close CONFIGFILE;
  } else {
    # es la primera vez.
    mkdir "$ENV{HOME}/.aMule" unless (-d "$ENV{HOME}/.aMule");
    $config = { # Por defecto
      'aMuleDir'        => "$ENV{'HOME'}/.aMule",
      'aMuleGuiApp'     => 'amulegui',
      'wxCasApp'        => 'wxcas',
      'aLinkCreatorApp' => 'alc',
      'iconPath'        => '/usr/share/pixmaps/amule.xpm',
      'appOnClick'      => 'aMuleGui',
      'aMuledOn'        => 1
    };
    foreach my $app (@appList) {
      $config->{$app . 'App'} = which($config->{$app . 'App'});
    }
    pathsVerify;
    &saveConfig;
  }
  pathsVerify;
}

# saveConfig guarda la configuración en un archivo
sub saveConfig {
  my @keyList = ('aMuleDir', 'aMuleGuiApp', 'wxCasApp',
    'aLinkCreatorApp', 'iconPath', 'appOnClick', 'aMuledOn');
  if ( open( CONFIGFILE, '>', "$ENV{HOME}/.aMule/amulet.rc" ) ) {
    foreach my $key (@keyList) {
      print CONFIGFILE "$key = $config->{$key}\n" if $config->{$key} ne '';
    }
    close CONFIGFILE;
  }else {logSys("warning", $lang{noConfWrite});}
};

# showMessage Muestra una ventana con un mensaje, y espera respuesta.
sub showMessage {
  #$icon info warning error question
  #$type none ok close cancel yes-no ok-cancel
  my ($icon,$text,$type) = @_;
  my $dialog = Gtk2::MessageDialog->new_with_markup (undef,
     [qw/modal destroy-with-parent/], $icon, $type, sprintf "$text");
  my $retval = $dialog->run;
  $dialog->destroy;
  return $retval;
}

# which Devuelve el path completo a la aplicación.
sub which {
  my $appFile = shift;
  foreach (split(':', $ENV{PATH})) {
    my $tmpStr = "$_/$appFile";
    if (-x $tmpStr) {
      $appFile = $tmpStr;
      last;
    }
  }
  return $appFile;
}

# dialogOpen ventana de selección de archivos o directorios y escribe
# el resultado en en el entry que debe ser el primer parámetro.
sub dialogOpen {
  # $widget debe ser un entry
  # $type open save select-folder create-folder
  my($widget,$caption,$type) =@_;
  my $chooserDialog =  Gtk2::FileChooserDialog->new ($caption, undef, $type,
    'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok');
  my $filename = $chooserDialog->get_filename if 'ok' eq $chooserDialog->run;
  $widget->set_text ($filename) if defined $filename;
  $chooserDialog->destroy;
  return;
}

# Translations
sub initLang {
  %lang_en = (
    not_X11_msg => "ATTENTION: This script needs to be executed under the X Window",
    not_TrayIcon_msg => "ATTENTION: This script needs Gtk2::TrayIcon module\n" .
  	"\tYou can install it through CPAN in the following way:\n\n" .
        "\t~ \$ perl -MCPAN -e \'install Gtk2::TrayIcon\'\n\nbye",
    interrupted_initialization => " ha abortado el arranque.",
    bad_blockage_file => "I can't eliminate the blockade file",
    initiated => " Initiate",
    icon_load_Error => "Icon load error: ",
    options => "options",
    logfile => "aMule log",
    quit => "Exit",
    icon_load => "Itself proceeds to load the internal icon.",
    signs_assignment => "Signs assignment",
    witgets_show => "Visualizing witgets",
    init_msg_loop => "Initiating messages loop",
    just_end => "It has just concluded: ",
    right_click_show => " - Right click to show options",
    Hid => "[Hight ID]",
    Lid => "[Low ID]",
    Conecting => "[Connecting]",
    dowSpeed => "downSpeed",
    upSpeed => "upSpeed",
    k_ok => "[kad ok]",
    k_fire => "[kad firewalled]",
    k_down => "[kad off]",
    aMd_off => " [aMuled Not Conected]",
    down => " Down:",
    ending => "Concluding ...",
    endChilds => "Concluding possible children",
    end_run_chld => "it's in progress. Concluding him... ",
    hasntChld => "There aren't child process of ",
    to_do_1 => "Overt log files to final log file [if config]",
    to_do_2 => "It send setFocus to the application",
    to_do_3 => "try to show it as modal and wait the answer.",
    inSys => " in the system",
    appEnd => "Execution end",
    child_begin => "child process beginning with",
    fork_error => "error when making fork:",
    stdout_redirect => "STDOUT redirect for",
    a => "to",
    exec_fail => "ATTENTION: It failed the execution of",
    father_loop => "Process father circuit [son =>",
    itsRun => "it\'s already running!",
    blockInit => "block file init",
    loadConf => "Loading the configuration",
    isaMuled => "Beginning the amuled existence verification",
    noaMuled => "It isn\'t detected. Beginning amuled ...",
    lock_chg => "ATTENTION: You changes the order  ",
    yourself => "under your responsibility  ",
    aMrun => "It has been detected that aMule is running ",
    tiTools => "aMulet.pl was designed thinking of the remote tools",
    alfsay => "It would WORK, but I don't see the necessity of it.  STOP!!",
    aMuledInit => "The amuled has been started.",
    aMuledNoRun => "It hasn\'t been possible to execute the amuled! ",
    check_no_run => "Do I disable the option of pulling up the amuled in the configuration? ",
    aMnoHere => "Disable this option if the aMuled is residing in another machine of your net.",
    noaMGui => "I haven\'t detected the aMuleGui.",
    whereaMGUI => "It will indicate where is this located in the configuration",
    aMuledIs => "aMuled has been detected:)) ",
    noRunInit => "ATTENTION won't be detected neither it will pull up the aMuled",
    noRunInit2 => "          It can modify this in the configuration",
    click_veryfy => "Verifying the application that icon click responds.",
    writeItInConf => "You should indicate in the configuration where are the executable one",
    of_app => "of the application",
    another => "or to choose one another",
    jump_step => "You can indicate in the configuration file that jumps this step",
    appAnsw => "application that icon click responds",
    menu_off => "Disabling menu call",
    texView => "Text viewer",
    Shw_log_win => "Showing log win",
    with => "with",
    connPort => "it\'s connected to  port",
    hi => "high",
    low => "low",
    ande => "and the",
    nk => "kad net",
    okcon => "connected OK",
    infire => "in firewalled",
    disconnec => "disconnected",
    ittake => "it takes ",
    sec => " seconds",
    min => "minutes and",
    hours => " hours",
    days => "days",
    of => "of",
    connected => "connected",
    inthistime => "and in this time it has discharged: ",
    downTotal => "with that has a total discharged of ",
    sharealso => "also shares",
    sesionFiles => "files and in this session",
    obtaining => "obtaining a",
    upload => "they has ascended",
    atotal => "total of",
    totalup => "ascended to the Net",
    hasRight => "in line it has right now",
    cli => "clients",
    callOff => "Disabling the call in the menu",
    runAsServer => "Run aMule like service at the beginning (if don't run).",
    general => "General",
    about => "About",
    aboutAmuled => "About aMuled Service",
    AHD => "aMule Home Dir",
    appPaht => "Applications path",
    iconShow => "Icon that will be shown in the task bar",
    icon => "Icon:",
    whatapp => "What application will be launcher when icon click?",
    oneHawk => "by AnimAlf - AnimAlf\@users.sourceforge.net",
    oneIdea => "a tx2z idea in http://forum.amule.org,",
    ideaOf => "An idea of",
    in => "in",
    options => "aMulet.pl options",
    shoOpsWin => "Showing options widget",
    beModal => "Mush be modal as showMessage",
    licence => "Distributed under GPL license",
    selec => "Select",
    itisnt => "or it doesn\'t exist",
    isntDir => "It isn\'t a directory",
    isntExe => "It isn\'t an executable one",
    dontExist => "It doesn\'t seem that it exists",
    detectAny => "The following things has been detected:",
    wantContinue => "Do you want continue anyway?",
    iconWhenRestart => "Icon will change when you restarts the application.",
    selHomaMu => "Select the aMule home directory",
    selaMguiApp => "Select the aMuleGui application",
    selwxCasApp => "Select the wxCas application",
    selALCapp => "Select the aLinCreator application",
    selIcon => "Select the icon that will use aMulet",
    noConfWrite => "One cann\'t write in the configuration file!"
  );

  %lang_es = (
    not_X11_msg => "ATENCIÓN: Este script necesita ser ejecutado bajo las X Window",
    not_TrayIcon_msg => "ATENCIÓN: Este script necesita el módulo Gtk2::TrayIcon\n" .
  	"\tPuede instalarlo a través de CPAN del siguiente modo:\n\n" .
        "\t~ \$ perl -MCPAN -e \'install Gtk2::TrayIcon\'\n\nbye",
    interrupted_initialization => " ha abortado el arranque.",
    bad_blockage_file => "No puedo eliminar el archivo de bloqueo",
    initiated => " iniciado",
    icon_load_Error => "Error al cargar el icono: ",
    options => "opciones",
    logfile => "log del aMule",
    quit => "Salir",
    icon_load => "Se procede a cargar el icono interno.",
    signs_assignment => "Asignación de señales",
    witgets_show => "Visualizando los witgets",
    init_msg_loop => "Inicio del bucle de mensajes",
    just_end => "Acaba de finalizar: ",
    right_click_show => " - Click derecho para opciones",
    Hid => "[ID alta]",
    Lid => "[ID baja]",
    Conecting => "[Conectando]",
    dowSpeed => "downSpeed",
    upSpeed => "upSpeed",
    k_ok => "[kad ok]",
    k_fire => "[kad firewalled]",
    k_down => "[kad off]",
    aMd_off => " [aMuled No Conectado]",
    down => " Bajada:",
    ending => "Finalizando ...",
    endChilds => "Finalizando posibles hijos",
    end_run_chld => "está en marcha. Finalizándolo ...",
    hasntChld => "No quedan procesos hijo de ",
    to_do_1 => "volcar archivo log a log final [si se le ordena]",
    to_do_2 => "Enviar setFocus a la aplicación",
    to_do_3 => "Intentar mostrarlo como modal y esperar respuesta.",
    inSys => " en el sistema",
    appEnd => "Terminada la ejecución",
    child_begin => "child process beginning with",
    fork_error => "error al hacer fork:",
    stdout_redirect => "Redirección de STDOUT para",
    a => "a",
    exec_fail => "ATENCIÓN: Falló la ejecución de",
    father_loop => "Circuito del proceso padre [hijo=>",
    itsRun => "ya está funcionando!",
    blockInit => "Iniciando archivo de bloqueo",
    loadConf => "Cargando la configuración",
    isaMuled => "Iniciando la verificación de la existencia de amuled",
    noaMuled => "No se detecta. Iniciando amuled ...",
    lock_chg => "ATENCIÓN: Cambie la orden",
    yourself => "bajo su responsabilidad",
    aMrun => "Se ha detectado que el aMule está en marcha ",
    tiTools => "aMulet.pl se diseñó pensando en las herramientas remotas",
    alfsay => "FUNCIONARÍA, pero no veo la necesidad de ello.  STOP!!",
    aMuledInit => "El amuled ha sido puesto en marcha.",
    aMuledNoRun => "No se ha podido ejecutar el amuled!",
    check_no_run => "¿Desactivo la opción de arrancar el amuled en la configuración?",
    aMnoHere => "Desactive esta opción si el aMuled está residente en otra máquina de su red.",
    noaMGui => "No he detectado el aMuleGui.",
    whereaMGUI => "Deberá indicar donde está situado éste en la configuración",
    aMuledIs => "El aMuled ha sido detectado :))",
    noRunInit => "ATENCIÓN No se detectará ni arrancará el aMuled",
    noRunInit2 => "         Se puede modificar esto en la configuración",
    click_veryfy => "Verificando la aplicación que responde al click del icono.",
    writeItInConf => "Debe indicar en la configuración dónde residen el ejecutable",
    of_app => "de la aplicación",
    another => "o escoger otra",
    jump_step => "Se puede indicar en la configuración que se salte este paso",
    appAnsw => "aplicación que responda al click en el icono",
    menu_off => "Deshabilitando la llamada en el menú",
    texView => "Visor de Texto",
    Shw_log_win => "Mostrando la ventana de logs",
    with => "con",
    connPort => "está conectado al puerto",
    hi => "alta",
    low => "baja",
    ande => "y la",
    nk => "red kad",
    okcon => "bien conectada",
    infire => "en firewalled",
    disconnec => "desconectada",
    ittake => "lleva ",
    sec => " segundos",
    min => "minutos y",
    hours => " horas",
    days => "dias",
    of => "de",
    connected => "conectado",
    inthistime => "y en este tiempo ha descargado: ",
    downTotal => "con lo que tiene un total descagado de ",
    sharealso => "Además comparte",
    sesionFiles => "archivos y en esta sesión",
    obtaining => "obteniendo un",
    upload => "se han subido",
    atotal => "total de",
    totalup => "subidos a la Red",
    hasRight => "en cola tiene ahora mismo",
    cli => "clientes",
    callOff => "Deshabilitando la llamada en el menú",
    runAsServer => "Arrancar aMule como servicio al principio (si no lo está)",
    general => "General",
    about => "About",
    aboutAmuled => "Relacionado con el Servicio amuled",
    AHD => "aMule Home Dir",
    appPaht => "Ruta a las aplicaciones",
    iconShow => "Icono que se mostrará en la barra",
    icon => "Icono:",
    whatapp => "¿Qué aplicación arrancará tras hacer click en el icono?",
    oneHawk => "by AnimAlf - AnimAlf\@users.sourceforge.net",
    oneIdea => "una idea de tx2z en http://forum.amule.org",
    ideaOf => "Una idea de",
    in => "en",
    options => "Opciones aMulet.pl",
    shoOpsWin => "Mostrando la ventana de opciones",
    beModal => "Que sea modal tipo showMessage",
    licence => "Distribuido bajo la licencia GPL",
    selec => "Selecciona",
    itisnt => "o no existe",
    isntDir => "No es un directorio",
    isntExe => "No es un ejecutable",
    dontExist => "No parece que exista",
    detectAny => "Se ha detectado lo siguiente:",
    wantContinue => "¿Desea continuar de todos modos?",
    iconWhenRestart => "El icono cambiará cuando reinicie la aplicación.",
    selHomaMu => "Seleccione el directorio home de aMule",
    selaMguiApp => "Seleccione la aplicación aMuleGui",
    selwxCasApp => "Seleccione la aplicación wxCas",
    selALCapp => "Seleccione la aplicación aLinCreator",
    selIcon => "Seleccione el icono que utilizará aMulet",
    noConfWrite => "No se puede escribir en el archivo de configuración!"
  );
}