Logo Search packages:      
Sourcecode: ygraph version File versions  Download package

ygraph.c

Go to the documentation of this file.
/**
 * @file    ygraph.c
 * @brief   Main program.
 *
 *          Initialise data structures and bring up the interface window.
 *
 * @author  Denis Pollney
 * @date    1 Oct 2001
 *
 * @todo    New Feature: Skip datasets control-panel field.
 * @todo    New Feature: Menu option for setting legend position.
 * @todo    New Feature: No-legend startup option, turn of legend menu option.
 * @todo    New Feature: User configuration file.
 * @todo    New Feature: Set log axes from command line, or single key stroke.
 * @todo    Bug: Automatically set lower range when switching to log scale.
 * @todo    Bug: Subtracting two datasets with single time value doesn't work.
 * @todo    Bug: Currently get segfault when linking statically.
 * @todo    Source code cleanup. The names DataSet, data_set, and dataset
 *          are used inconsistently throughout the docs and function names.
 *          Same for plot_window and plot_area.
 * @todo    GTK+2 conversion.
 *
 * @par Copyright (C) 2001-2002 Denis Pollney
 *
 *  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.
 * @par
 *  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.
 * @par
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <popt.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "ygraph.h"

/** 
 * @defgroup  globals  Global variables (general).
 * @{
 */

/** Used for picking a colormap for plot lines. */
00053 gulong global_base_color[NCOLORS][3] = {
  {0,     0, 255},
  {0,   255,   0},
  {0,   255, 255},
  {255,   0,   0},
  {255,   0, 255},
  {255, 255,   0},
  {0,     0,   0}
};

/** The intensity of the cross-hatch lines on the grid. */
00064 gulong global_grid_intensity = GRID_INTENSITY;

/** The working directory. */
00067 gchar* global_working_directory = NULL;

/** The x-range of all the loaded data. */
00070 gdouble* global_x_range;

/** The y-range of all the loaded data. */
00073 gdouble* global_y_range;

/** String of tokens representing NaNs. */
00076 gchar** nan_string;

/** The column the values for x are expected */
00079 gint global_x_column;

/** The column the values for y are expected */
00082 gint global_y_column;

/** The format string for the column reading */
00085 gchar *global_column_format_string;
/** @} */


/**
 * @defgroup  status  Status indicators.
 * @{
 */

/** The index of the current frame. */
00095 gint global_current_frame = FIRST_FRAME;

/** The index of the last frame in the global list. */
00098 gint global_last_frame = FIRST_FRAME;

/** The current plot display mode. */
00101 DISPLAY_MODE global_display_mode = SHOW_ALL_MODE;

/**
 * A list of time values corresponding to Frames which have been loaded.
 * Elements are of type gdouble.
 */
00107 GArray* global_time_list;

/** @} */

/**
 * @defgroup  interface  Pointers to the main interface components.
 * @{
 */

/** Pointer to the control panel widget. */
00117 ControlPanel* global_control_panel = NULL;

/** Pointer to the scale panel widget. */
00120 GtkWidget* global_scale_panel = NULL;

/** List of pointers to the open plot windows. Elements are of type Plot*. */
00123 GArray* global_plot_window = NULL;

/** The total number of open plots. */
00126 gint global_plot_nbr = 0;

/** List of loaded data sets. Elements are of type DataSet*. */
00129 GArray* global_data_set_list = NULL;

/** Pointer to the About window pixmap. */
00132 GdkPixmap* global_about_pixmap = NULL;

/** @} */

/**
 * @defgroup  cmdline  Command line options.
 * @{
 */

/** TRUE if the program should start without a control panel widget. */
00142 gboolean option_start_without_control_panel = FALSE;

/** TRUE if the version message should be printed. */
00145 gboolean option_version_msg = FALSE;

/**
 * TRUE if each plot which is loaded from the command line should open
 * a seperate window.
 */
00151 gboolean option_separate_start_windows = FALSE;

/** TRUE if a grid should be drawn on the initial plot window. */
00154 gboolean option_draw_grid = TRUE;

/** TRUE if range values should be drawn on corners of the plot window. */
00157 gboolean option_draw_range = TRUE;

/** Set the position of the plot legend ('a', 'o', 'r', '0') */
00160 gchar* option_legend_position = "o";


/**
 * TRUE if the next two files specified on the command line should be
 * subtracted.
 */
00167 gboolean option_subtract = FALSE;

/** A string containing the ':'-separated list of two columns */
00170 gchar* option_columns = NULL;

/** A string containing a x-range specified on the command line. */
00173 gchar* option_x_range = NULL;

/** A string containing a y-range specified on the command line. */
00176 gchar* option_y_range = NULL;

/** TRUE if next file should be integrated **/
00179 gboolean option_f_int = FALSE;
gboolean option_t_int = FALSE;
gboolean option_int = FALSE;

/** @} */

/**
 * @defgroup  config  Configuration options
 * @{
 */

/**
 * Delay between individual frames in an animation, measured in milliseconds.
 */
00193 gint option_animate_delay = DEFAULT_ANIMATE_DELAY;

/**
 * Read only every nth frame from input files.
 */
00198 gint option_read_skip_step = DEFAULT_SKIP_STEP;

/** TRUE if a dot should be drawn at each data value. */
00201 gboolean option_draw_points = TRUE;

/** The width of plot lines. */
00204 gint option_line_width = DEFAULT_LINE_WIDTH;
/* steerable by command line */
gdouble font_size_factor;

gchar* option_font_size_factor;

/**
 * Command line argument table.
 */
00213 static struct poptOption popt_options[] =
  {
    {"no-control-panel",
     'c',
     POPT_ARG_NONE,
     &option_start_without_control_panel,
     0, "Start without the control panel",
     NULL
    },
    {"separate-windows",
     's',
     POPT_ARG_NONE,
     &option_separate_start_windows,
     0,
     "Start with each requested plot in a separate window",
     NULL
    },
    {"no-points",
     'p',
     POPT_ARG_NONE,
     &option_draw_points,
     0,
     "Draw lines only, without points indicating each data value",
     NULL
    },
    {"delay",
     'd',
     POPT_ARG_INT,
     &option_animate_delay,
     0,
     "Delay between animation frames (in milliseconds)",
     NULL
    },
    {"skip",
     'k',
     POPT_ARG_INT,
     &option_read_skip_step,
     0,
     "Read only every nth frame from the input files",
     NULL
    },
    {"legend",
     'l',
     POPT_ARG_STRING,
     &option_legend_position,
     0,
     "Set the position of the legend relative to the plot",
     NULL
    },
    {"no-grid",
     'g',
     POPT_ARG_VAL,
     &option_draw_grid,
     0,
     "Don't draw a grid on the plot background",
     NULL
    },
    {"no-range",
     'r',
     POPT_ARG_VAL,
     &option_draw_range,
     0,
     "Don't draw range values on the plot background",
     NULL
    },
    {"columns",
     'C',
     POPT_ARG_STRING,
     &option_columns,
     0,
     "Set the columns the x and y values are expected in, format: x:y",
     NULL
    },
    {"xrange",
     'x',
     POPT_ARG_STRING,
     &option_x_range,
     0,
     "Set initial range for the x-axis as a comma-separated pair: xmin,xmax",
     NULL
    },
    {"yrange",
     'y',
     POPT_ARG_STRING,
     &option_y_range,
     0,
     "Set initial range for the y-axis as a comma separated pair: ymin,ymax",
     NULL
    },
    {"subtract",
     'S',
     POPT_ARG_NONE,
     &option_subtract,
     0,
     "Subtract <filename2> from <filename1>",
     NULL
    },
    {"integrate",
     'I',
     POPT_ARG_NONE,
     &option_int,
     0,
     "Integrate frames of <filename>",
     NULL
    },
    {"frame_integrate",
     (char)NULL,
     POPT_ARG_NONE,
     &option_f_int,
     0,
     "Integrate over frames of <filename>",
     NULL
    },
    {"time_integrate",
     (char)NULL,
     POPT_ARG_NONE,
     &option_t_int,
     0,
     "Integrate over frame of <filename> and multiply with time",
     NULL
    },
    {"font_size_factor",
     (char)NULL,
     POPT_ARG_STRING,
     &option_font_size_factor,
     0,
     "Change this to something != 1.0 to change font size",
     NULL
    },
    {"version",
     'v',
     POPT_ARG_NONE,
     &option_version_msg,
     0,
     "Print a version message and exit",
     NULL
    },
    POPT_AUTOHELP
    { NULL, 0, 0, NULL, 0, NULL, NULL }
  };
/** @} */

GArray* cmd_line_process(gint, gchar **);
void init_globals(void);

/**
 * @brief    Main program.
 * 
 *           Initialises the various widget toolkits, calls the
 *           command line processor, and starts the interface components.
 *
 * @param    argc  A count of command line arguments.
 * @param    argv  A list of command line options.
 * @returns  0 if everything went well.
 */
int
00369 main (int argc, char* argv[])
{
  GArray* data;

  init_globals();
  
  /*
   * Initialise GTK.
   */
  gtk_set_locale ();
  gtk_init (&argc, &argv);
  gdk_imlib_init();

  /*
   * Read data files specified on the command line.
   */
  global_working_directory = g_get_current_dir();
  data = cmd_line_process(argc, argv);

  /*
   * Create a new plot window.
   */
  if (data->len > 0)
      plot_window_show();

  /*
   * Create a control panel.
   */
  if (!option_start_without_control_panel)
    control_panel_raise();

  /*
   * GTK event loop.
   */
  gtk_main ();


  /*
   * Close cleanly.
   */
  exit(0);
}


/**
 * @brief    Parse the command line.
 *
 *           The command line is parsed using the getopt library. If
 *           any files are indicated on the command line, then these
 *           are read and a pointer to the data passed back to the main
 *           program for display. Any global options specified on the
 *           command line are set here.
 *
 * @param    argc  A count of the command line arguments.
 * @param    argv  A pointer to a list of character strings corresponding
 *                 to the command line arguments.
 *
 * @note     The argv argument is declared as a char**, in contrast to
 *           the char*[] which is passed from the main program. For
 *           whatever reason, this was neccessary for it to run properly.
 */
GArray*
00431 cmd_line_process(int argc, char** argv)
{
  poptContext options_context;
  GArray* data;
  GArray* sep_data_set;
  gchar **input_files;
  gchar o;
  gint start_i;
  gint new_data_set_idx;
  gint i;
  guint k;

  /* replace single '-' */
  for (i=0; i<argc; i++)
      if ((strlen(argv[i])==1) && (argv[i][0]=='-'))
          argv[i]=INTERNAL_STDIN_STR;

  options_context = poptGetContext(NULL, argc, (const char **)argv,
                                   popt_options, 0);
  poptSetOtherOptionHelp(options_context, 
                         "[OPTIONS]* <filename1> <filename2> ...");
  o = poptGetNextOpt(options_context);

  input_files = (gchar **) poptGetArgs(options_context);
  
  if (option_version_msg)
    {
      g_print("%s %s\n", PACKAGE, VERSION);
      exit(0);
    }

  if (option_columns != NULL)
    {
      global_x_column=global_y_column=-1;
      string_to_columns(option_columns);
      if (global_x_column==-1)
      {
        message_dialog("Could not interpret specified columns");
        global_x_column=1;
        global_y_column=2;
      }
      printf("Columns set to %d:%d\n", global_x_column, global_y_column);
    }
  else
  {
    global_x_column=1;
    global_y_column=2;
  }
  set_global_column_format_string();

  if (option_x_range != NULL)
    {
      global_x_range = string_to_range(option_x_range);
      if (global_x_range == NULL)
        message_dialog("Could not interpret specified x-range");
    }

  if (option_y_range != NULL)
    {
      global_y_range = string_to_range(option_y_range);
      if (global_y_range == NULL)
        message_dialog("Could not interpret specified y-range");
    }

  if (option_font_size_factor != NULL)
    {
      font_size_factor = str_to_double(option_font_size_factor);
      if (font_size_factor < 0.0)
        font_size_factor *= -1.0;
    }
  else
    font_size_factor=1.0;

  data = g_array_new(FALSE, FALSE, sizeof(gint));

  if (input_files == NULL)
  {
    poptFreeContext(options_context);
    return data;
  }

  start_i = 0;

  if (option_f_int || option_t_int)
    {
      if (!input_files[start_i])
        message_dialog
          ("You need to specify one file to perfom an integration");
      else
        {
          new_data_set_idx = dataset_read_frame_integrate_file(
                                 input_files[start_i],
                                 option_read_skip_step,
                                 option_t_int);
          if (new_data_set_idx != FAIL)
          {
            g_array_append_val(data, new_data_set_idx);
            start_i++;
          }
        }
    }
  if (option_int)
    {
      if (!input_files[start_i])
        message_dialog
          ("You need to specify one file to perfom an integration");
      else
        {
          new_data_set_idx = dataset_read_integrate_file(
                                 input_files[start_i],
                                 option_read_skip_step);
          if (new_data_set_idx != FAIL)
          {
            g_array_append_val(data, new_data_set_idx);
            start_i++;
          }
        }
    }

  if (option_subtract)
    {
      if (!(input_files[0] && input_files[1]))
        message_dialog
          ("You need to specify two files to perform a subtraction");
      else
        {
          new_data_set_idx = dataset_read_subtract_files(input_files[0],
                                                         input_files[1]);
          if (new_data_set_idx != FAIL)
            g_array_append_val(data, new_data_set_idx);
              
          start_i = 2;
        }
    }

  for (i=start_i; input_files[i]; ++i)
    {
      new_data_set_idx = dataset_read_from_file(input_files[i],
                                                option_read_skip_step);
      if (new_data_set_idx != FAIL)
        g_array_append_val(data, new_data_set_idx);
    }

  if (option_separate_start_windows == TRUE)
    {
      for (k=0; k<data->len; ++i)
        {
          sep_data_set = g_array_new(FALSE, FALSE, sizeof(gint));
          g_array_append_val(sep_data_set, g_array_index(data, gint, k));
          plot_data_init(sep_data_set);
        }
    }
  else
    {
      plot_data_init(data);
    }

  poptFreeContext(options_context);
  return data;
}

/**
 * Initialise any global variables that are independent of command line
 * options.
 */
void
00597 init_globals(void)
{
  nan_string = g_strsplit(NAN_STRING, " ", 0);
}


Generated by  Doxygen 1.6.0   Back to index