« Fichier de ressource BashGnuplot Post Processor v1 »

Gnuplot Post Processor v2

14.11.09

Permalink 07:32:41 pm, by mazet Email , 5440 words   English (US) latin1
Categories: Programmation, Perl

Gnuplot Post Processor v2

Gnuplot Post Processor written in perl/gtk2
#!/usr/bin/perl -w
# gpp - a GnuPlot Post Processor
# Copyright (C) 2005 Laurent Mazet

# 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, 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.  */

# Changelog:
# - 1.2.2
#   new feature: curve width
# - 1.2.1
#   * adapt color line definition from gnuplot 4.2 to standard colormap
# - 1.2.0
#   * adapt to gnuplot 4.2 postscript
# - 1.1.0
#   * add grid parameters
# - 1.0.0
#   * all tests passed
# - 0.9.1
#   * start command line implementation
# - 0.9.0
#   * rebuild GUI on gtk2
# - 0.8.1
#   * set last radio name for font selection
# - 0.8
#   * most wanted functionality have been implented and tested
# - 0.0.1
#   * initial release

# Potential bugs:
# - none

# library
use strict;
use Gtk2;
use POSIX qw(locale_h);

# gobal variables
my $version = "1.2.1";
use vars qw/$gpver/;
use vars qw/$fullfile $font $status $gui $is_check_color/;
use vars qw/$filename $outputname/;
use vars qw/$format $solid $colored $rounded $ssh $ssw $linewidth $curvewidth $fontname/;
use vars qw/$griddash $gridred $gridgreen $gridblue/;
use vars qw/@red @green @blue @dash @lw/;

use constant TRUE => 1;
use constant FALSE => 0;

# constants
my @default_r = (1, 0, 0, 1, 0, 1, 0, 1, 0.5);
my @default_g = (0, 1, 0, 0, 1, 1, 0, 0.3, 0.5);
my @default_b = (0, 0, 1, 1, 1, 0, 0, 0, 0.5);
my @rainbow_r = (0.9, 1, 0.9, 0.1, 0.1, 0.1, 0.9, 0.5, 0.5);
my @rainbow_g = (0.1, 0.4, 0.8, 0.75, 0.8, 0.1, 0, 0.3, 0.5);
my @rainbow_b = (0.1, 0, 0.2, 0.1, 0.8, 0.9, 0.8, 0.1, 0.5);
my @invrain_r = (0.9, 0.1, 0.1, 0.1, 0.9, 1, 0.9, 0.5, 0.5);
my @invrain_g = (0, 0.1, 0.8, 0.75, 0.8, 0.4, 0.1, 0.3, 0.5);
my @invrain_b = (0.8, 0.9, 0.8, 0.1, 0.2, 0, 0.1, 0.1, 0.5);
my @dash1 = ("", "4 2", "2 3", "1 1.5", "5 2 1 2", "4 3 1 3", "2 2 2 4",
             "2 2 2 2 2 4", "2 2 2 2 2 2 2 4");
my @dash2 = ("", "4 1 1 1", "4 2 2 2", "4 3 3 3", "4 4", "4 4 1 1", "4 4 2 2",
             "4 4 3 3" , "2 2");

# refresh fontname
sub check_fontname {
  if ($fontname =~ "Helvetica") {
    $font = 1;
  } elsif ($fontname =~ "Times-Roman") {
    $font = 0;
  } else {
    $font = -1;
  }
}

# check color
sub check_color {
  my ($c) = @_;
  $is_check_color = TRUE;
  $red[$c] = 1 if ($red[$c] > 1); $red[$c] = 0 if ($red[$c] < 0);
  $green[$c] = 1 if ($green[$c] > 1); $green[$c] = 0 if ($green[$c] < 0);
  $blue[$c] = 1 if ($blue[$c] > 1); $blue[$c] = 0 if ($blue[$c] < 0);
  &refresh_color_name($c) if ($gui);
  &refresh_color($c) if ($gui);
  $is_check_color = FALSE;
}

# scan file
sub scan_file {

  # start processing
  (my $tmp) = ($filename =~ /[\/\\]/) ?
    ($filename=~/.*[\/\\]([^\/\\]+)/) : $filename;
  $status = "scanning file '$tmp'";
  &refresh_status if ($gui);

  # check if the file exists
  if (!open (IN, "<", $filename)) {
    $status = "can't find file '$filename'";
    &refresh_status if ($gui);
    &desactivate_tabs if ($gui);
    return;
  }

  # read all the file
  my @f;
  my $k = 0;
  foreach my $line (<IN>) {
    $f[$k++] = $line;
  }
  $fullfile = join("", @f);
  close (IN);

  # check if the file is produced by gnuplot
  if ($fullfile !~ /\n%%Creator: gnuplot/) {
    $status = "'$filename' isn't a Gnuplot file";
    &refresh_status if ($gui);
    &desactivate_tabs if ($gui);
    return;
  }

  # get format
  ($format) = ($fullfile =~ /%!PS-Adobe-2\.0 *(.*)\n/);
  $format = ($format =~ "EPSF-2.0") ? 0 : 1;
  &refresh_format if ($gui);

  # get solid state
  ($solid) = ($fullfile =~ /\/Solid ([a-z]+) def\n/);
  $solid = ($solid =~ "true") ? 1 : 0;
  &refresh_solid if ($gui);

  # get color state
  ($colored) = ($fullfile =~ /\/Color ([a-z]+) def\n/);
  $colored = ($colored =~ "true") ? 1 : 0;
  &refresh_colored if ($gui);

  # get rounded state
  ($rounded) = ($fullfile =~ /\/Rounded ([a-z]+) def\n/);
  $rounded = ($rounded =~ "true") ? 1 : 0;
  &refresh_rounded if ($gui);

  # get global line width
  ($linewidth) = ($fullfile =~ /\/gnulinewidth ([.0-9]+) def\n/);
  &refresh_linewidth if ($gui);

  # get symbol height
  ($ssh) = ($fullfile =~ /\/hpt_ ([.0-9]+) def\n/);
  &refresh_ssh if ($gui);

  # get symbol width
  ($ssw) = ($fullfile =~ /\/vpt_ ([.0-9]+) def\n/);
  &refresh_ssw if ($gui);

  # get font
  ($fontname) = ($fullfile =~ /\((.+)\) findfont [.0-9]+ scalefont setfont\n/);
  check_fontname;
  &refresh_fontname if ($gui);

  ## get grid dash and colors
  ($gpver) = ($fullfile =~ /\%\%Creator: gnuplot ([.0-9]+) patchlevel [0-9]+\n/);
  if ($gpver > 4.0) {
    ($gridred, $gridgreen, $gridblue) = ($fullfile =~ /\/LCa {([.0-9]+) ([.0-9]+) ([.0-9]+)} def\n/);
    ($griddash) = ($fullfile =~ /\/LTa {AL \[1 udl mul (.*) udl mul\] 0 setdash LCa setrgbcolor} def\n/);
  } else {
    ($griddash, $gridred, $gridgreen, $gridblue) = ($fullfile =~ /\/LTa { AL \[1 udl mul ([.0-9]+) udl mul\] 0 setdash ([.0-9]+) ([.0-9]+) ([.0-9]+) setrgbcolor } def\n/);
  }
  &refresh_griddash if ($gui);

  # get color and dash styles
  for (my $c=0; $c<9; $c++) {
    if ($gpver > 4.0) {
      ($red[$c], $green[$c], $blue[$c]) = ($fullfile =~ /\/LC$c {([.0-9]+) ([.0-9]+) ([.0-9]+)} def\n/);
     ($dash[$c], $lw[$c]) = ($fullfile =~ /\/LT$c {PL \[(.*)\] LC$c DL(.*)} def\n/);
      $dash[$c] =~ s/ dl[12]//g;
    } else {
      ($dash[$c], $red[$c], $green[$c], $blue[$c], $lw[$c]) = ($fullfile =~ /\/LT$c { PL \[(.*)\] ([.0-9]+) ([.0-9]+) ([.0-9]+) DL (.*)} def\n/);
      $dash[$c] =~ s/ dl//g;
    }
    $lw[$c] =~ s/ *([.0-9]+) setlinewidth */$1/;
    $lw[$c] = 0 if ($lw[$c] =~ /^ *$/);
    check_color $c;
  }
  &refresh_dashs if ($gui);

  # get curve width
  $curvewidth = ($lw[0] > 0) ? $lw[0] : -1;
  for (my $c=0; $c<9; $c++) {
    if ($lw[0] > 0) { $curvewidth = -2 if ($lw[$c] != $curvewidth) };
  }
  if ($curvewidth == -1) { $curvewidth = $linewidth; };
  &refresh_curvewidth if ($gui);

  # activate other tabs
  &activate_tabs if ($gui);

  # create output filename
  ($outputname = $filename) =~ s/(\.[^.]*)$/-n$1/;
  &refresh_outputname if ($gui);
}

# process file
sub process {
  my $req;
  my $f = $fullfile;
  $status = "writing file '$outputname'";
  &refresh_status if ($gui);

  # set locale
  my $old_locale = setlocale(LC_NUMERIC);
  setlocale(LC_NUMERIC, "C");

  # change format
  if ($format != ($f !~ /^%!PS-Adobe-2\.0 EPSF-2\.0\n/)) {
    if ($format == 1) {
      # Postscript
      $f =~ s/(%!PS-Adobe-2.0)[^\n]*(\n)/$1$2/;
      $f =~ s/(%%BoundingBox:)[ 0-9]*(\n)/$1 50 50 554 770$2/;
      $f =~ s/(%%Orientation:) Portrait(\n)/$1 Landscape\n%%Pages: (atend)$2/;
      $f =~ s/(%%EndProlog\n)/$1%%Page: 1 1\n/;
      $f =~ s/0\.050 0\.050 scale\n/0\.100 0\.100 scale\n90 rotate\n0 -5040 translate\n/;
      $f =~ s/$/\n%%Pages: 1/;
    } else {
      # EPS
      $f =~ s/(%!PS-Adobe-2.0)(\n)/$1 EPSF-2.0$2/;
      $f =~ s/(%%BoundingBox:)[ 0-9]*(\n)/$1 50 50 410 302$2/;
      $f =~ s/(%%Orientation:) Landscape\n%%Pages: \(atend\)(\n)/$1 Portrait$2/;
      $f =~ s/(%%EndProlog\n)(%%Page: 1 1\n)/$1/;
      $f =~ s/0\.100 0\.100 scale\n90 rotate\n0 -5040 translate\n/0\.050 0\.050 scale\n/;
      $f =~ s/\n%%Pages: 1$//;
    }
  }

  # change solid state
  $req = ($solid == 1) ? "true" : "false";
  $f =~ s/(\/Solid )[a-z]*( def\n)/$1$req$2/;

  # change color state
  $req = ($colored == 1) ? "true" : "false";
  $f =~ s/(\/Color )[a-z]*( def\n)/$1$req$2/;

  # change rounded state
  $req = ($rounded == 1) ? "true" : "false";
  $f =~ s/(\/Rounded )[a-z]*( def\n)/$1$req$2/;

  # change global line width
  $f =~ s/(\/gnulinewidth )[0-9.]*( def\n)/$1$linewidth$2/;

  # change symbol height
  $f =~ s/(\/hpt_ )[0-9.]*( def\n)/$1$ssh$2/;

  # change symbol width
  $f =~ s/(\/vpt_ )[0-9.]*( def\n)/$1$ssw$2/;

  # get font
  (my $oldfontname) = ($f =~ /\((.+)\) findfont [.0-9]+ scalefont setfont\n/);
  $f =~ s/$oldfontname/$fontname/g if ($fontname !~ $oldfontname);

  ## change grid dash and colors
  if ($gpver > 4.0) {
    $f =~ s/(\/LCa {)[.0-9]+ [.0-9]+ [.0-9]+(} def\n)/$1$gridred $gridgreen $gridblue$2/;
    $f =~ s/(\/LTa {AL \[1 udl mul )[.0-9]+( udl mul\] 0 setdash LCa setrgbcolor} def\n)/$1$griddash$2/;
  } else {
    $f =~ s/(\/LTa { AL \[1 udl mul )[.0-9]+( udl mul\] 0 setdash )[.0-9]+ [.0-9]+ [.0-9]+ (setrgbcolor } def\n)/$1$griddash$2$gridred $gridgreen $gridblue $3/;
  }

  # use line definition
  if ($gpver > 4.0) {
    for (my $c=0; $c<9; $c++) {
      my $st = sprintf("%1.2f %1.2f %1.2f C ",
                       $default_r[$c], $default_g[$c], $default_b[$c]);
      $st =~ s/\./\\./g;
      $f =~ s/(\nLT)0\n$st/$1$c\n/g;
    }
    $f =~ s/\nLT[0-8](\nLT)/$1/g
  }

  # change curve width
  my $slw = ($curvewidth == -1) ? "" : " $curvewidth setlinewidth";

  # change color and dash styles
  for (my $c=0; $c<9; $c++) {
    my $st;
    if ($gpver > 4.0) {
      $f =~ s/(\/LC$c {)[.0-9]+ [.0-9]+ [.0-9]+(} def\n)/$1$red[$c] $green[$c] $blue[$c]$2/;
      ($st = "$dash[$c]") =~ s/ +/ dl /g;
      ($st = "$dash[$c]") =~ s/(.) dl (.) dl/$1 dl1 $2 dl2/g;
      $f =~ s/(\/LT$c {PL \[).*(\] LC$c DL).*(} def\n)/$1$st$2$slw$3/;
    } else {
      ($st = "$dash[$c]") =~ s/ +/ dl /g;
      $st =~ s/$/ dl/ if ($st);
      $req = "[$st] $red[$c] $green[$c] $blue[$c]";
      $f =~ s/(\/LT$c { PL ).*( DL).*( } def\n)/$1$req$2$slw$3/;
    }
  }

  # open file for writing
  if (!open (OUT, ">", "$outputname")) {
    $status = "can't open file '$outputname' for writing";
    &refresh_status if ($gui);
    return;
  }

  # save file
  print OUT $f;
  close (OUT);

  # reset locale
  setlocale(LC_NUMERIC, $old_locale);
}

# preset default color
sub preset_color {
  for (my $i=0; $i<9; $i++) {
    check_color $i;
  }
}
sub preset_default {
  @red = @default_r; @green = @default_g; @blue = @default_b;
  preset_color;
}

# preset rainbow color
sub preset_rainbow {
  @red = @rainbow_r; @green = @rainbow_g; @blue = @rainbow_b;
  preset_color;
}

# preset invrain color
sub preset_invrain {
  @red = @invrain_r; @green = @invrain_g; @blue = @invrain_b;
  preset_color;
}

# preset dash 1
sub preset_dash1 {
  @dash = @dash1;
  &refresh_dashs if ($gui);
}

# preset dash 2
sub preset_dash2 {
  @dash = @dash2;
  &refresh_dashs if ($gui);
}

sub error {
  my ($msg) = (@_);
  print $msg;
  exit;
}

# process arguments
$gui = FALSE;
use vars qw/$arg_filename $arg_outputname/;
use vars qw/$arg_format $arg_solid $arg_colored $arg_rounded $arg_linewidth $arg_curvewidth $arg_ssh $arg_ssw $arg_fontname $arg_griddash $arg_colorset $arg_dashset/;
foreach my $arg (@ARGV) {
  # second argument
  if (defined($arg_outputname) && ($arg_outputname eq -1)) {
    $arg_outputname = $arg;
  } elsif (defined($arg_format) && ($arg_format eq -1)) {
    $arg_format = $arg;
  } elsif (defined($arg_solid) && ($arg_solid eq -1)) {
    $arg_solid = $arg;
  } elsif (defined($arg_colored) && ($arg_colored eq -1)) {
    $arg_colored = $arg;
  } elsif (defined($arg_rounded) && ($arg_rounded eq -1)) {
    $arg_rounded = $arg;
  } elsif (defined($arg_linewidth) && ($arg_linewidth eq -1)) {
    $arg_linewidth = $arg;
  } elsif (defined($arg_curvewidth) && ($arg_curvewidth eq -1)) {
    $arg_curvewidth = $arg;
  } elsif (defined($arg_ssh) && ($arg_ssh eq -1)) {
    $arg_ssh = $arg;
  } elsif (defined($arg_ssw) && ($arg_ssw eq -1)) {
    $arg_ssw = $arg;
  } elsif (defined($arg_fontname) && ($arg_fontname eq -1)) {
    $arg_fontname = $arg;
  } elsif (defined($arg_griddash) && ($arg_griddash eq -1)) {
    $arg_griddash = $arg;
  } elsif (defined($arg_colorset) && ($arg_colorset eq -1)) {
    $arg_colorset = $arg;
  } elsif (defined($arg_dashset) && ($arg_dashset eq -1)) {
    $arg_dashset = $arg;
  # first argument
  } elsif ($arg =~ /^-v$/) {
    error ("gpp version $version\n");
  } elsif ($arg =~ /^-h$/) {
    print "usage: gpp [-f eps|ps] [-ls dashed|solid] [-lc mono|colored] [-lr rough|rounded] [-lw <int>] [-cw <int>] [-sh <int>] [-sw <int>] [-F Times-Roman|Helvetica|<font>] [-gd <int>] [-cs default|rainbow|invrain] [-ds dash1|dash2] [-o outputname] <file>\n";
    exit;
  } elsif ($arg =~ /^-o/) {
    ($arg_outputname) = ($arg =~ /^-o=?(.*)$/);
    $arg_outputname = -1 if ($arg_outputname =~ /^$/);
  } elsif ($arg =~ /^-f/) {
    ($arg_format) = ($arg =~ /^-f=?(.*)$/);
    $arg_format = -1 if ($arg_format =~ /^$/);
  } elsif ($arg =~ /^-ls/) {
    ($arg_solid) = ($arg =~ /^-ls=?(.*)$/);
    $arg_solid = -1 if ($arg_solid =~ /^$/);
  } elsif ($arg =~ /^-lc/) {
    ($arg_colored) = ($arg =~ /^-lc=?(.*)$/);
    $arg_colored = -1 if ($arg_colored =~ /^$/);
  } elsif ($arg =~ /^-lr/) {
    ($arg_rounded) = ($arg =~ /^-lr=?(.*)$/);
    $arg_rounded = -1 if ($arg_rounded =~ /^$/);
  } elsif ($arg =~ /^-lw/) {
    ($arg_linewidth) = ($arg =~ /^-lw=?(.*)$/);
    $arg_linewidth = -1 if ($arg_linewidth =~ /^$/);
  } elsif ($arg =~ /^-cw/) {
    ($arg_curvewidth) = ($arg =~ /^-cw=?(.*)$/);
    $arg_curvewidth = -1 if ($arg_curvewidth =~ /^$/);
  } elsif ($arg =~ /^-sh/) {
    ($arg_ssh) = ($arg =~ /^-sh=?(.*)$/);
    $arg_ssh = -1 if ($arg_ssh =~ /^$/);
  } elsif ($arg =~ /^-sw/) {
    ($arg_ssw) = ($arg =~ /^-sw=?(.*)$/);
    $arg_ssw = -1 if ($arg_ssw =~ /^$/);
  } elsif ($arg =~ /^-F/) {
    ($arg_fontname) = ($arg =~ /^-F=?(.*)$/);
    $arg_fontname = -1 if ($arg_fontname =~ /^$/);
  } elsif ($arg =~ /^-gd/) {
    ($arg_griddash) = ($arg =~ /^-gd=?(.*)$/);
    $arg_griddash = -1 if ($arg_griddash) =~ /^$/;
  } elsif ($arg =~ /^-cs/) {
    ($arg_colorset) = ($arg =~ /^-cs=?(.*)$/);
    $arg_colorset = -1 if ($arg_colorset =~ /^$/);
  } elsif ($arg =~ /^-ds/) {
    ($arg_dashset) = ($arg =~ /^-ds=?(.*)$/);
    $arg_dashset = -1 if ($arg_dashset) =~ /^$/;
  } else {
    $arg_filename = $arg;
  }
}

# check if any option ahve been set
if (defined($arg_outputname) || defined($arg_format) || defined($arg_solid) ||
    defined($arg_colored) || defined($arg_rounded) ||
    defined($arg_linewidth) || defined($arg_curvewidth) ||
    defined($arg_ssh) || defined($arg_ssw) ||
    defined($arg_fontname) || defined($arg_griddash) ||
    defined($arg_colorset) || defined($arg_dashset)) {
  # process if there is no gui

  # check file name
  error ("No file input\n") if (!defined($arg_filename));
  $filename = $arg_filename;
  scan_file;

  # check output name
  if (defined($arg_outputname)) {
    error ("No output file specified\n") if ($arg_outputname eq -1);
    $outputname = $arg_outputname;
  }

  # check format
  if (defined($arg_format)) {
    error ("No format specified\n") if ($arg_format eq -1);
    $format = $arg_format;
    $format = 0 if ($format =~ /^EPS$|^eps$/);
    $format = 1 if ($format =~ /^Postscript$|^ps$/);
    error ("Unkown format\n") if (($format ne 0) && ($format ne 1));
  }

  # check line state
  if (defined($arg_solid)) {
    error ("No line state (dashed or solid) specified\n") if ($arg_solid eq -1);
    $solid = $arg_solid;
    $solid = 0 if ($solid =~ /^dashed$/);
    $solid = 1 if ($solid =~ /^solid$/);
    error ("Unkown line state (dashed or solid)\n") if (($solid ne 0) && ($solid ne 1));
  }

  # check line style
  if (defined($arg_colored)) {
    error ("No line style (nono or colored) specified\n") if ($arg_colored eq -1);
    $colored = $arg_colored;
    $colored = 0 if ($colored =~ /^nono$/);
    $colored = 1 if ($colored =~ /^colored$/);
    error ("Unkown line style (nono or colored)\n") if (($colored ne 0) && ($colored ne 1));
  }

  # check line ending
  if (defined($arg_rounded)) {
    error ("No line ending (rough or rounded) specified\n") if ($arg_rounded eq -1);
    $rounded = $arg_rounded;
    $rounded = 0 if ($rounded =~ /^rough$/);
    $rounded = 1 if ($rounded =~ /^rounded$/);
    error ("Unkown line ending (rough or rounded)\n") if (($rounded ne 0) && ($rounded ne 1));
  }

  # check line width
  if (defined($arg_linewidth)) {
    error ("No line width specified\n") if ($arg_linewidth eq -1);
    $linewidth = $arg_linewidth;
  }

  # check curve width
  if (defined($arg_curvewidth)) {
    error ("No curve width specified\n") if ($arg_curvewidth eq -1);
    $curvewidth = $arg_curvewidth;
  }

  # check symbol height
  if (defined($arg_ssh)) {
    error ("No symbole height specified\n") if ($arg_ssh eq -1);
    $ssh = $arg_ssh;
  }

  # check symbol width
  if (defined($arg_ssw)) {
    error ("No symbole width specified\n") if ($arg_ssw eq -1);
    $ssw = $arg_ssw;
  }

  # check font name
  if (defined($arg_fontname)) {
    error ("No font specified\n") if ($arg_fontname eq -1);
    $fontname = $arg_fontname;
    $fontname = "Times-Roman" if ($fontname eq 0);
    $fontname = "Helvetica" if ($fontname eq 1);
    check_fontname;
  }

  # check grid dash
  if (defined($arg_griddash)) {
    error ("No grid dash width specified\n") if ($arg_griddash eq -1);
    $griddash = $arg_griddash;
  }

  # check color set
  if (defined($arg_colorset)) {
    error ("No color set specified (default or rainbow or invrain)\n") if ($arg_colorset eq -1);
    $arg_colorset = 0 if ($arg_colorset =~ /^default$/);
    $arg_colorset = 1 if ($arg_colorset =~ /^rainbow$/);
    $arg_colorset = 2 if ($arg_colorset =~ /^invrain$/);
    if ($arg_colorset eq 0) {
      preset_default;
    } elsif ($arg_colorset eq 1) {
      preset_rainbow;
    } elsif ($arg_colorset eq 2) {
      preset_invrain;
    } else {
     error ("Unkown color set (default or rainbow or invrain)\n");
   }
  }

  # check dash set
  if (defined($arg_dashset)) {
    error ("No dash set specified (dash1 or dash2)\n") if ($arg_dashset eq -1);
    $arg_dashset = $arg_dashset;
    $arg_dashset = 0 if ($arg_dashset =~ /^dash1$/);
    $arg_dashset = 1 if ($arg_dashset =~ /^dash2$/);
    if ($arg_dashset eq 0) {
      preset_dash1;
    } elsif ($arg_dashset eq 1) {
      preset_dash2;
    } else {
     error ("Unkown dash set (dash1 or dash2)\n");
   }
  }

  # process now
  process;
  exit;
}

# prepare for gui
$filename = $outputname = $status = "";
$filename = $arg_filename if (defined($arg_filename));
$gui = TRUE;
$is_check_color = FALSE;

# gui top level
Gtk2->init ();
my $mw = Gtk2::Window->new ("toplevel");
$mw->signal_connect ("delete_event" , sub{Gtk2->main_quit();});
$mw->signal_connect ("destroy", sub{exit});
$mw->set_title ("Gnuplot Pre-Processor");
$mw->set_border_width (2);
$mw->set_default_size (320, 100) ;

# main box
my $mw_box = Gtk2::VBox->new (FALSE, 0);
$mw->add($mw_box);

# status bar
my $status_frame = Gtk2::Frame->new ();
$status_frame->set_shadow_type ("etched-out");
$mw_box->pack_end ($status_frame, FALSE, FALSE, 0);
my $status_box = Gtk2::HBox->new (FALSE, 0);
$status_frame->add ($status_box);
my $status_label = Gtk2::Label->new ();
$status_label->set_justify ("left");
$status_box->pack_start ($status_label, FALSE, FALSE, 1);

# action button bar
my $action_box = Gtk2::HBox->new (FALSE, 0);
$mw_box->pack_end ($action_box, FALSE, FALSE, 5);
my $process_button = Gtk2::Button->new_from_stock("gtk-execute");
$process_button->signal_connect ("clicked", sub{process});
$action_box->pack_start ($process_button, TRUE, FALSE, 0);
my $quit_button = Gtk2::Button->new_from_stock("gtk-quit");
$quit_button->signal_connect ("clicked", sub{exit});
$action_box->pack_end ($quit_button, TRUE, FALSE, 0);

# note book
my $notebook = Gtk2::Notebook->new ();
$notebook->set_tab_pos ("top");
$mw_box->pack_start ($notebook, TRUE, TRUE, 3);

# file selection tab
my $file_select_tab = Gtk2::VBox->new (FALSE, 0);
my $file_select_tab_label = Gtk2::Label->new ("File selection");
$notebook->append_page_menu ($file_select_tab, $file_select_tab_label, undef);

# file name
my $file_name_box = Gtk2::HBox->new (FALSE, 0);
$file_select_tab->pack_start ($file_name_box, FALSE, FALSE, 3);
my $file_name_label = Gtk2::Label->new ("File name:");
$file_name_box->pack_start ($file_name_label, FALSE, FALSE, 2);
my $file_name_entry = Gtk2::Entry->new();
$file_name_entry->set_text($filename);
$file_name_entry->signal_connect ("focus_out_event", sub{$filename = $file_name_entry->get_text; return FALSE});
$file_name_box->pack_start ($file_name_entry, TRUE, TRUE, 2);
my $file_name_dialog =  Gtk2::FileSelection->new("File open");
$file_name_dialog->hide_fileop_buttons();
$file_name_dialog->ok_button->signal_connect ("clicked", sub{$filename = $file_name_dialog->get_filename(); $mw_box->set_sensitive(TRUE); $file_name_dialog->hide; $file_name_entry->set_text($filename)});
$file_name_dialog->cancel_button->signal_connect ("clicked", sub{$mw_box->set_sensitive(TRUE); $file_name_dialog->hide});
$file_name_dialog->signal_connect ("destroy", sub{$mw_box->set_sensitive(TRUE); $file_name_dialog->hide});
my $file_name_button = Gtk2::Button->new_from_stock("gtk-open");
$file_name_button->signal_connect ("clicked", sub{$mw_box->set_sensitive(FALSE); $file_name_dialog->show});
$file_name_box->pack_start ($file_name_button, FALSE, FALSE, 2);

# output name
my $output_name_box = Gtk2::HBox->new (FALSE, 0);
$file_select_tab->pack_start ($output_name_box, FALSE, FALSE, 3);
my $output_name_label = Gtk2::Label->new ("File name:");
$output_name_box->pack_start ($output_name_label, FALSE, FALSE, 2);
my $output_name_entry = Gtk2::Entry->new();
$output_name_entry->signal_connect ("focus_out_event", sub{$outputname = $output_name_entry->get_text; return FALSE});
$output_name_box->pack_start ($output_name_entry, TRUE, TRUE, 2);
my $output_name_dialog =  Gtk2::FileSelection->new("File save");
$output_name_dialog->hide_fileop_buttons();
$output_name_dialog->ok_button->signal_connect ("clicked", sub{$outputname = $output_name_dialog->get_filename(); $mw_box->set_sensitive(TRUE); $output_name_dialog->hide; $output_name_entry->set_text($outputname)});
$output_name_dialog->cancel_button->signal_connect ("clicked", sub{$mw_box->set_sensitive(TRUE); $output_name_dialog->hide});
$output_name_dialog->signal_connect ("destroy", sub{$mw_box->set_sensitive(TRUE); $output_name_dialog->hide});
my $output_name_button = Gtk2::Button->new_from_stock("gtk-save-as");
$output_name_button->signal_connect ("clicked", sub{$mw_box->set_sensitive(FALSE); $output_name_dialog->show});
$output_name_box->pack_start ($output_name_button, FALSE, FALSE, 2);

# rescan button
my $rescan_box = Gtk2::HBox->new (FALSE, 0);
$file_select_tab->pack_start ($rescan_box, FALSE, FALSE, 10);
my $rescan_button = Gtk2::Button->new_from_stock("gtk-refresh");
#$rescan_button->set_label("Rescan");
$rescan_button->signal_connect ("clicked", sub{$filename = $file_name_entry->get_text(); $outputname = $output_name_entry->get_text(); scan_file; return FALSE});
$rescan_box->pack_start ($rescan_button, TRUE, FALSE, 0);

# parameters tab
my $parameters_tab = Gtk2::VBox->new (FALSE, 0);
my $parameters_tab_label = Gtk2::Label->new ("Parameters");
$notebook->append_page_menu ($parameters_tab, $parameters_tab_label, undef);

# format
my $format_box = Gtk2::HBox->new (FALSE, 0);
$parameters_tab->pack_start ($format_box, FALSE, FALSE, 3);
my $format_label = Gtk2::Label->new ("Format:");
$format_box->pack_start ($format_label, FALSE, FALSE, 2);
my $eps_button = Gtk2::RadioButton->new (undef, "EPS");
$eps_button->signal_connect ("clicked", sub{$format = 0});
$format_box->pack_start ($eps_button, FALSE, FALSE, 2);
my $ps_button = Gtk2::RadioButton->new_from_widget ($eps_button, "Postscript");
$ps_button->signal_connect ("clicked", sub{$format = 1});
$format_box->pack_start ($ps_button, FALSE, FALSE, 2);

# style options
my $style_options_box = Gtk2::HBox->new (FALSE, 0);
$parameters_tab->pack_start ($style_options_box, FALSE, FALSE, 3);
my $style_options_label = Gtk2::Label->new ("Style options:");
$style_options_box->pack_start ($style_options_label, FALSE, FALSE, 2);
my $solid_button = Gtk2::CheckButton->new ("Solid/Dashed");
$solid_button->signal_connect ("clicked", sub{$solid = $solid_button->get_active});
$style_options_box->pack_start ($solid_button, FALSE, FALSE, 2);
my $colored_button = Gtk2::CheckButton->new ("Colored");
$colored_button->signal_connect ("clicked", sub{$colored = $colored_button->get_active});
$style_options_box->pack_start ($colored_button, FALSE, FALSE, 2);
my $rounded_button = Gtk2::CheckButton->new ("Rounded");
$rounded_button->signal_connect ("clicked", sub{$rounded = $rounded_button->get_active});
$style_options_box->pack_start ($rounded_button, FALSE, FALSE, 2);

# global line width
my $linewidth_box = Gtk2::HBox->new (FALSE, 0);
$parameters_tab->pack_start ($linewidth_box, FALSE, FALSE, 3);
my $linewidth_label = Gtk2::Label->new ("Global line width:");
$linewidth_box->pack_start ($linewidth_label, FALSE, FALSE, 2);
my $linewidth_adj = Gtk2::Adjustment->new(0.0, 0.0, 200, 0.5, 5.0, 0.0);
my $linewidth_spinner = Gtk2::SpinButton->new($linewidth_adj, 1, 1);
$linewidth_spinner->set_wrap(FALSE);
$linewidth_spinner->set_width_chars (5);
$linewidth_spinner->set_alignment(1);
$linewidth_spinner->signal_connect ("value-changed", sub{$linewidth = $linewidth_spinner->get_value});
$linewidth_box->pack_start ($linewidth_spinner, FALSE, FALSE, 2);

# Curve width
my $curvewidth_box = Gtk2::HBox->new (FALSE, 0);
$parameters_tab->pack_start ($curvewidth_box, FALSE, FALSE, 3);
my $curvewidth_label = Gtk2::Label->new ("Curve width:");
$curvewidth_box->pack_start ($curvewidth_label, FALSE, FALSE, 2);
my $curvewidth_adj = Gtk2::Adjustment->new(0.0, 0.0, 200, 0.5, 5.0, 0.0);
my $curvewidth_spinner = Gtk2::SpinButton->new($curvewidth_adj, 1, 1);
$curvewidth_spinner->set_wrap(FALSE);
$curvewidth_spinner->set_width_chars (5);
$curvewidth_spinner->set_alignment(1);
$curvewidth_spinner->signal_connect ("value-changed", sub{$curvewidth = $curvewidth_spinner->get_value});
$curvewidth_box->pack_start ($curvewidth_spinner, FALSE, FALSE, 2);

# symbol size
my $symbolsize_box = Gtk2::HBox->new (FALSE, 0);
$parameters_tab->pack_start ($symbolsize_box, FALSE, FALSE, 3);
my $symbolsize_label = Gtk2::Label->new ("Symbol size:");
$symbolsize_box->pack_start ($symbolsize_label, FALSE, FALSE, 2);
my $symbolsize_height_label = Gtk2::Label->new ("Height");
$symbolsize_box->pack_start ($symbolsize_height_label, FALSE, FALSE, 2);
my $symbolsize_height_adj = Gtk2::Adjustment->new(0.0, 0.0, 200, 0.5, 5.0, 0.0);
my $symbolsize_height_spinner = Gtk2::SpinButton->new($symbolsize_height_adj, 1, 1);
$symbolsize_height_spinner->set_wrap(FALSE);
$symbolsize_height_spinner->set_width_chars (5);
$symbolsize_height_spinner->set_alignment(1);
$symbolsize_height_spinner->signal_connect ("value-changed", sub{$ssh = $symbolsize_height_spinner->get_value});
$symbolsize_box->pack_start ($symbolsize_height_spinner, FALSE, FALSE, 2);
my $symbolsize_width_label = Gtk2::Label->new ("Width");
$symbolsize_box->pack_start ($symbolsize_width_label, FALSE, FALSE, 2);
my $symbolsize_width_adj = Gtk2::Adjustment->new(0.0, 0.0, 200, 0.5, 5.0, 0.0);
my $symbolsize_width_spinner = Gtk2::SpinButton->new($symbolsize_width_adj, 1, 1);
$symbolsize_width_spinner->set_wrap(FALSE);
$symbolsize_width_spinner->set_width_chars (5);
$symbolsize_width_spinner->set_alignment(1);
$symbolsize_width_spinner->signal_connect ("value-changed", sub{$ssw = $symbolsize_width_spinner->get_value});
$symbolsize_box->pack_start ($symbolsize_width_spinner, FALSE, FALSE, 2);

# font
my $font_box = Gtk2::HBox->new (FALSE, 0);
$parameters_tab->pack_start ($font_box, FALSE, FALSE, 3);
my $font_label = Gtk2::Label->new ("Font:");
$font_box->pack_start ($font_label, FALSE, FALSE, 2);
my $helvetica_button = Gtk2::RadioButton->new (undef, "Helvetica");
$font_box->pack_start ($helvetica_button, FALSE, FALSE, 2);
my $timesroman_button = Gtk2::RadioButton->new_from_widget ($helvetica_button, "Times-Roman");
$font_box->pack_start ($timesroman_button, FALSE, FALSE, 2);
my $otherfont_button = Gtk2::RadioButton->new_from_widget ($helvetica_button, "Other");
$font_box->pack_start ($otherfont_button, FALSE, FALSE, 2);
my $font_entry = Gtk2::Entry->new();
$font_entry->set_width_chars (12);
$helvetica_button->signal_connect ("clicked", sub{$font_entry->set_text($fontname = "Helvetica"); $font_entry->set_sensitive(FALSE)});
$timesroman_button->signal_connect ("clicked", sub{$font_entry->set_text($fontname = "Times-Roman"); $font_entry->set_sensitive(FALSE)});
$otherfont_button->signal_connect ("clicked", sub{$font_entry->set_sensitive(TRUE)});
$font_entry->signal_connect ("focus_out_event", sub{$fontname = $font_entry->get_text; return FALSE});
$font_box->pack_start ($font_entry, FALSE, FALSE, 2);

# grid dash
my $griddash_box = Gtk2::HBox->new (FALSE, 0);
$parameters_tab->pack_start ($griddash_box, FALSE, FALSE, 3);
my $griddash_label = Gtk2::Label->new ("Grid dash thicknes:");
$griddash_box->pack_start ($griddash_label, FALSE, FALSE, 2);
my $griddash_adj = Gtk2::Adjustment->new(0.0, 0.0, 20, 0.1, 2.0, 0.0);
my $griddash_spinner = Gtk2::SpinButton->new($griddash_adj, 1, 1);
$griddash_spinner->set_wrap(FALSE);
$griddash_spinner->set_width_chars (4);
$griddash_spinner->set_alignment(1);
$griddash_spinner->signal_connect ("value-changed", sub{$griddash = $griddash_spinner->get_value});
$griddash_box->pack_start ($griddash_spinner, FALSE, FALSE, 2);

# color and line styles tab
my $colorline_tab = Gtk2::VBox->new (FALSE, 0);
my $colorline_tab_label = Gtk2::Label->new ("Color and lines styles");
$notebook->append_page_menu ($colorline_tab, $colorline_tab_label, undef);

# style $i
use vars qw/@style_box @style_label @red_label @red_spinner @green_label @green_spinner @blue_label @blue_spinner @dash_label @dash_entry/;
my @rgb_adj;
for (my $i=0; $i<9; $i++) {
  $style_box[$i] = Gtk2::HBox->new (FALSE, 0);
  $colorline_tab->pack_start ($style_box[$i], FALSE, FALSE, 3);
  $style_label[$i] = Gtk2::Label->new ("Style $i:");
  $style_box[$i]->pack_start ($style_label[$i], FALSE, FALSE, 2);

  $red_label[$i] = Gtk2::Label->new ("Red");
  $style_box[$i]->pack_start ($red_label[$i], FALSE, FALSE, 2);
  $red_spinner[$i] = Gtk2::SpinButton->new(Gtk2::Adjustment->new(0.0, 0.0, 1.0, 0.001, 0.005, 0.0), 0, 3);
  $red_spinner[$i]->set_wrap(FALSE);
  $red_spinner[$i]->set_width_chars (6);
  $red_spinner[$i]->signal_connect ("value-changed", \&change_color, $i);
  $style_box[$i]->pack_start ($red_spinner[$i], FALSE, FALSE, 2);

  $green_label[$i] = Gtk2::Label->new ("Green");
  $style_box[$i]->pack_start ($green_label[$i], FALSE, FALSE, 2);
  $green_spinner[$i] = Gtk2::SpinButton->new(Gtk2::Adjustment->new(0.0, 0.0, 1.0, 0.001, 0.005, 0.0), 0, 3);
  $green_spinner[$i]->set_wrap(FALSE);
  $green_spinner[$i]->set_width_chars (5);
  $green_spinner[$i]->signal_connect ("value-changed",\&change_color, $i);
  $style_box[$i]->pack_start ($green_spinner[$i], FALSE, FALSE, 2);

  $blue_label[$i] = Gtk2::Label->new ("Blue");
  $style_box[$i]->pack_start ($blue_label[$i], FALSE, FALSE, 2);
  $blue_spinner[$i] = Gtk2::SpinButton->new(Gtk2::Adjustment->new(0.0, 0.0, 1.0, 0.001, 0.005, 0.0), 0, 3);
  $blue_spinner[$i]->set_wrap(FALSE);
  $blue_spinner[$i]->set_width_chars (5);
  $blue_spinner[$i]->signal_connect ("value-changed", \&change_color, $i);
  $style_box[$i]->pack_start ($blue_spinner[$i], FALSE, FALSE, 2);

  $dash_entry[$i] = Gtk2::Entry->new();
  $dash_entry[$i]->set_width_chars (15);
  $dash_entry[$i]->signal_connect ("focus_out_event", \&change_dash, $i);
  $style_box[$i]->pack_end ($dash_entry[$i], FALSE, FALSE, 2);
  $dash_label[$i] = Gtk2::Label->new ("Dash");
  $style_box[$i]->pack_end ($dash_label[$i], FALSE, FALSE, 2);
}

# colors and styles preset
my $preset_box = Gtk2::HBox->new (FALSE, 0);
$colorline_tab->pack_start ($preset_box, FALSE, FALSE, 3);
my $preset_default_button = Gtk2::Button->new_with_label("Default");
$preset_default_button->signal_connect ("clicked", sub{&preset_default});
$preset_box->pack_start ($preset_default_button, FALSE, FALSE, 3);
my $preset_rainbow_button = Gtk2::Button->new_with_label("Rainbow");
$preset_rainbow_button->signal_connect ("clicked", sub{&preset_rainbow});
$preset_box->pack_start ($preset_rainbow_button, FALSE, FALSE, 3);
my $preset_invrain_button = Gtk2::Button->new_with_label("InvRain");
$preset_invrain_button->signal_connect ("clicked", sub{&preset_invrain});
$preset_box->pack_start ($preset_invrain_button, FALSE, FALSE, 3);
my $preset_dash2_button = Gtk2::Button->new_with_label("Dash 2");
$preset_dash2_button->signal_connect ("clicked", sub{&preset_dash2});
$preset_box->pack_end ($preset_dash2_button, FALSE, FALSE, 3);
my $preset_dash1_button = Gtk2::Button->new_with_label("Dash 1");
$preset_dash1_button->signal_connect ("clicked", sub{&preset_dash1});
$preset_box->pack_end ($preset_dash1_button, FALSE, FALSE, 3);

# show all...
$preset_dash1_button->show ();
$preset_dash2_button->show ();
$preset_invrain_button->show ();
$preset_rainbow_button->show ();
$preset_default_button->show ();
$preset_box->show ();

for (my $i=0; $i<9; $i++) {
  $dash_label[$i]->show ();
  $dash_entry[$i]->show ();
  $blue_spinner[$i]->show ();
  $blue_label[$i]->show ();
  $green_spinner[$i]->show ();
  $green_label[$i]->show ();
  $red_spinner[$i]->show ();
  $red_label[$i]->show ();
  $style_label[$i]->show ();
  $style_box[$i]->show ();
}

$colorline_tab_label->show ();
$colorline_tab->show ();

$griddash_spinner->show ();
$griddash_label->show ();
$griddash_box->show ();

$font_entry->show ();
$otherfont_button->show ();
$timesroman_button->show ();
$helvetica_button->show ();
$font_label->show ();
$font_box->show ();

$symbolsize_width_spinner->show ();
$symbolsize_width_label->show ();
$symbolsize_height_spinner->show ();
$symbolsize_height_label->show ();
$symbolsize_label->show ();
$symbolsize_box->show ();

$linewidth_spinner->show ();
$linewidth_label->show ();
$linewidth_box->show ();

$curvewidth_spinner->show ();
$curvewidth_label->show ();
$curvewidth_box->show ();

$rounded_button->show ();
$colored_button->show ();
$solid_button->show ();
$style_options_label->show ();
$style_options_box->show ();

$eps_button->show ();
$ps_button->show ();
$format_label->show ();
$format_box->show ();

$parameters_tab_label->show ();
$parameters_tab->show ();

$rescan_button->show ();
$rescan_box->show ();

$output_name_button->show ();
$output_name_entry->show ();
$output_name_label->show ();
$output_name_box->show ();

$file_name_button->show ();
$file_name_entry->show ();
$file_name_label->show ();
$file_name_box->show ();

$file_select_tab_label->show ();
$file_select_tab->show ();

$notebook->show ();

$quit_button->show ();
$process_button->show ();
$action_box->show ();

$status_label->show ();
$status_box->show ();
$status_frame->show ();

$mw_box->show ();

$mw->show ();

&desactivate_tabs();
scan_file if ($arg_filename);

Gtk2->main ();

# refresh status
sub refresh_status {
  $status_label->set_text($status);
}

# desactivate tabs
sub desactivate_tabs {
  $parameters_tab_label->set_sensitive(FALSE);
  $parameters_tab->set_sensitive(FALSE);
  $colorline_tab_label->set_sensitive(FALSE);
  $colorline_tab->set_sensitive(FALSE);
  $output_name_box->set_sensitive(FALSE);
  $process_button->set_sensitive(FALSE);
  $parameters_tab_label->set_sensitive(FALSE);
}

# activate tabs
sub activate_tabs {
  $parameters_tab_label->set_sensitive(TRUE);
  $parameters_tab->set_sensitive(TRUE);
  $colorline_tab_label->set_sensitive(TRUE);
  $colorline_tab->set_sensitive(TRUE);
  $colorline_tab->set_sensitive(TRUE);
  $output_name_box->set_sensitive(TRUE);
  $process_button->set_sensitive(TRUE);
}

# refresh color name
sub refresh_color_name {
  my ($c) = @_;
  return if (!exists($red[$c]));
  my $tc = sprintf("#%02x%02x%02x",
                   $red[$c]*255, $green[$c]*255, $blue[$c]*255);
  $style_label[$c]->set_markup("<span foreground='$tc'>Style $c:</span>");
}

# refresh color
sub refresh_color {
  my ($c) = @_;
  return if (!exists($red[$c]));
  $red_spinner[$c]->set_value($red[$c]);
  $green_spinner[$c]->set_value($green[$c]);
  $blue_spinner[$c]->set_value($blue[$c]);
}

# change color
sub change_color {
  my ($w, $c) = @_;
  return if ($is_check_color);
  $red[$c] = $red_spinner[$c]->get_value;
  $green[$c] = $green_spinner[$c]->get_value;
  $blue[$c] = $blue_spinner[$c]->get_value;
  refresh_color_name($c);
}

# refresh dash
sub refresh_dash {
  my ($i) = @_;
  return if (!exists($dash[$i]));
  $dash_entry[$i]->set_text($dash[$i]);
}

# refresh dashs
sub refresh_dashs {
  for (my $i=0; $i<9; $i++) {
    &refresh_dash($i);
  }
}

# change dash
sub change_dash {
  my ($w, $e, $i) = @_;
  $dash[$i] = $dash_entry[$i]->get_text;
  return FALSE;
}

# refresh filename
sub refresh_filename {
  $file_name_entry->set_text($filename);
}

# refresh format
sub refresh_format {
  if ($format) {
    $ps_button->clicked;
  } else {
    $eps_button->clicked;
  }
}

# refresh solid
sub refresh_solid {
  if ($solid) {
    $solid_button->clicked;
  } else {
    $solid_button->released;
  }
}

# refresh colored
sub refresh_colored {
  if ($colored) {
    $colored_button->clicked;
  } else {
    $colored_button->released;
  }
}

# refresh rounded
sub refresh_rounded {
  if ($rounded) {
    $rounded_button->clicked;
  } else {
    $rounded_button->released;
  }
}

# refresh linewidth
sub refresh_linewidth {
  $linewidth_spinner->set_value($linewidth);
}

# refresh curvewidth
sub refresh_curvewidth {
  if ($curvewidth == -2) {
    $curvewidth_spinner->set_sensitive(FALSE);
  } else {
    $curvewidth_spinner->set_sensitive(TRUE);
    $curvewidth_spinner->set_value($curvewidth);
  }
}

# refresh ssh
sub refresh_ssh {
  $symbolsize_height_spinner->set_value($ssh);
}

# refresh ssw
sub refresh_ssw {
  $symbolsize_width_spinner->set_value($ssw);
}

# refresh fontname
sub refresh_fontname {
  $font_entry->set_sensitive($font eq -1);
  $font_entry->set_text($fontname);
}

# refresh griddash
sub refresh_griddash {
  $griddash_spinner->set_value($griddash);
}

# refresh outputname
sub refresh_outputname {
  $output_name_entry->set_text($outputname);
}