"Fossies" - the Fresh Open Source Software Archive

Member "g3data-1.5.4/g3data/main.c" (13 Jan 2011, 62341 Bytes) of package /linux/privat/old/g3data-1.5.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "main.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 
    3 g3data : A program for grabbing data from scanned graphs
    4 Copyright (C) 2000 Jonas Frantz
    5 
    6     This file is part of g3data.
    7 
    8     g3data is free software; you can redistribute it and/or modify
    9     it under the terms of the GNU General Public License as published by
   10     the Free Software Foundation; either version 2 of the License, or
   11     (at your option) any later version.
   12 
   13     g3data is distributed in the hope that it will be useful,
   14     but WITHOUT ANY WARRANTY; without even the implied warranty of
   15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16     GNU General Public License for more details.
   17 
   18     You should have received a copy of the GNU General Public License
   19     along with this program; if not, write to the Free Software
   20     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21 
   22 
   23 Authors email : jonas.frantz@welho.com
   24 
   25 */
   26 
   27 #include <gtk/gtk.h>                                    /* Include gtk library */
   28 #include <stdio.h>                                  /* Include stdio library */
   29 #include <gdk-pixbuf/gdk-pixbuf.h>
   30 #include <gdk/gdkkeysyms.h>
   31 #include <stdlib.h>                                 /* Include stdlib library */
   32 #include <string.h>                                 /* Include string library */
   33 #include <math.h>                                   /* Include math library */
   34 #include <libgen.h>
   35 #include "main.h"
   36 #include "drawing.h"
   37 #include "strings.h"
   38 #include "points.h"
   39 
   40 #ifdef NOSPACING
   41 #define SECT_SEP 0
   42 #define GROUP_SEP 0
   43 #define ELEM_SEP 0
   44 #define FRAME_INDENT 0
   45 #define WINDOW_BORDER 0
   46 #else
   47 #define SECT_SEP 12
   48 #define GROUP_SEP 12
   49 #define ELEM_SEP 6
   50 #define FRAME_INDENT 18
   51 #define WINDOW_BORDER 12
   52 #endif
   53 
   54 /* Declaration of gtk variables */
   55 GtkWidget   *window;                                /* Window */
   56 GtkWidget   *drawing_area[MAXNUMTABS], *zoom_area[MAXNUMTABS];          /* Drawing areas */
   57 GtkWidget   *xyentry[MAXNUMTABS][4];
   58 GtkWidget   *exportbutton[MAXNUMTABS], *remlastbutton[MAXNUMTABS];          /* Various buttons */
   59 GtkWidget   *setxybutton[MAXNUMTABS][4];
   60 GtkWidget   *remallbutton[MAXNUMTABS];                      /* Even more various buttons */
   61 GtkWidget   *xc_entry[MAXNUMTABS],*yc_entry[MAXNUMTABS];
   62 GtkWidget   *file_entry[MAXNUMTABS], *nump_entry[MAXNUMTABS];
   63 GtkWidget   *xerr_entry[MAXNUMTABS],*yerr_entry[MAXNUMTABS];            /* Coordinate and filename entries */
   64 GtkWidget       *logbox[MAXNUMTABS] = {NULL}, *zoomareabox[MAXNUMTABS] = {NULL}, *oppropbox[MAXNUMTABS] = {NULL};
   65 GtkWidget   *pm_label, *pm_label2, *file_label;
   66 GtkWidget   *ViewPort = NULL;
   67 GdkColor        *colors;                                /* Pointer to colors */
   68 GdkPixbuf       *gpbimage[MAXNUMTABS];
   69 GtkWidget   *mainnotebook;
   70 GtkActionGroup  *tab_action_group;
   71 
   72 /* Declaration of global variables */
   73 /* axiscoords[][][0] will be set to -1 when not used */
   74 gint        axiscoords[MAXNUMTABS][4][2];                       /* X,Y coordinates of axispoints */
   75 gint        **points[MAXNUMTABS];                           /* Indexes of graphpoints and their coordinates */
   76 gint        numpoints[MAXNUMTABS];
   77 gint        ordering[MAXNUMTABS];
   78 gint        XSize[MAXNUMTABS], YSize[MAXNUMTABS];
   79 gint        file_name_length[MAXNUMTABS];
   80 gint        MaxPoints[MAXNUMTABS] = {MAXPOINTS};
   81 gint        ViewedTabNum = -1;                          /* The currently viewed tab */
   82 gint        NoteBookNumPages = 0;
   83 gint xpointer = -1;
   84 gint ypointer = -1;
   85 gdouble     realcoords[MAXNUMTABS][4];                      /* X,Y coords on graph */
   86 gboolean    print2file[MAXNUMTABS];
   87 gboolean    UseErrors[MAXNUMTABS];
   88 gboolean    setxypressed[MAXNUMTABS][4];
   89 gboolean    bpressed[MAXNUMTABS][4];                        /* What axispoints have been set out ? */
   90 gboolean    valueset[MAXNUMTABS][4];
   91 gboolean    logxy[MAXNUMTABS][2] = {{FALSE,FALSE}};
   92 gboolean        ShowLog = FALSE, ShowZoomArea = FALSE, ShowOpProp = FALSE;
   93 const gchar *file_name[MAXNUMTABS];
   94 gchar       *FileNames[MAXNUMTABS];
   95 FILE        *FP;                                    /* File pointer */
   96 
   97 GtkWidget   *drawing_area_alignment;
   98 
   99 static gint close_application(GtkWidget *widget, GdkEvent *event, gpointer data);
  100 static void SetButtonSensitivity(int TabNum);
  101 static gint button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data);
  102 static gint motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data);
  103 static gboolean expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data);
  104 static gint expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data);
  105 static gint configure_event(GtkWidget *widget, GdkEventConfigure *event,gpointer data);
  106 static void toggle_xy(GtkWidget *widget, gpointer func_data);
  107 static void SetOrdering(GtkWidget *widget, gpointer func_data);
  108 static void SetAction(GtkWidget *widget);
  109 static void UseErrCB(GtkWidget *widget, gpointer func_data);
  110 static void read_xy_entry(GtkWidget *entry, gpointer func_data);
  111 static void read_file_entry(GtkWidget *entry, gpointer func_data);
  112 static void islogxy(GtkWidget *widget, gpointer func_data);
  113 static void remove_last(GtkWidget *widget, gpointer data);
  114 static void remove_all(GtkWidget *widget, gpointer data) ;
  115 static gint key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer pointer);
  116 static gint InsertImage(char *filename, gdouble Scale, gdouble maxX, gdouble maxY, gint TabNum);
  117 static void update_preview_cb (GtkFileChooser *file_chooser, gpointer data);
  118 static gint SetupNewTab(char *filename, gdouble Scale, gdouble maxX, gdouble maxY, gboolean UsePreSetCoords);
  119 static void drag_data_received(GtkWidget *widget,
  120                               GdkDragContext *drag_context,
  121                               gint x, gint y,
  122                               GtkSelectionData *data,
  123                               guint info,
  124                               guint event_time,
  125                               gpointer user_data);
  126 static GCallback menu_file_open(void);
  127 static GCallback menu_help_about(void);
  128 static GCallback menu_tab_close(void);
  129 static GCallback full_screen_action_callback(GtkWidget *widget, gpointer func_data);
  130 static GCallback hide_zoom_area_callback(GtkWidget *widget, gpointer func_data);
  131 static GCallback hide_axis_settings_callback(GtkWidget *widget, gpointer func_data);
  132 static GCallback hide_output_prop_callback(GtkWidget *widget, gpointer func_data);
  133 static GCallback NoteBookTabChange(GtkNotebook *notebook, GtkNotebookPage *page, 
  134                 guint page_num, gpointer user_data);
  135 
  136 /****************************************************************/
  137 /* This function closes the window when the application is  */
  138 /* killed.                          */
  139 /****************************************************************/
  140 static gint close_application(GtkWidget *widget, GdkEvent *event, gpointer data)
  141 {
  142     gtk_main_quit();                                    /* Quit gtk */
  143     return FALSE;
  144 }
  145 
  146 
  147 /****************************************************************/
  148 /* This function sets the sensitivity of the buttons depending  */
  149 /* the control variables.                   */
  150 /****************************************************************/
  151 static void SetButtonSensitivity(int TabNum)
  152 {
  153   char ttbuf[256];
  154 
  155     if (print2file[TabNum] == TRUE) {
  156     snprintf(ttbuf, sizeof(ttbuf), printfilett, gtk_entry_get_text(GTK_ENTRY (file_entry[TabNum])));
  157         gtk_widget_set_tooltip_text(exportbutton[TabNum],ttbuf);
  158 
  159     gtk_widget_set_sensitive(file_entry[TabNum], TRUE);
  160     if (valueset[TabNum][0] && valueset[TabNum][1] && 
  161         valueset[TabNum][2] && valueset[TabNum][3] && 
  162         bpressed[TabNum][0] && bpressed[TabNum][1] && 
  163         bpressed[TabNum][2] && bpressed[TabNum][3] && 
  164         numpoints[TabNum] > 0 && file_name_length[TabNum] > 0) 
  165         gtk_widget_set_sensitive(exportbutton[TabNum], TRUE);
  166     else gtk_widget_set_sensitive(exportbutton[TabNum], FALSE);
  167     } else {
  168         gtk_widget_set_tooltip_text(exportbutton[TabNum],printrestt);
  169     gtk_widget_set_sensitive(file_entry[TabNum], FALSE);
  170     if (valueset[TabNum][0] && valueset[TabNum][1] && 
  171         valueset[TabNum][2] && valueset[TabNum][3] && 
  172         bpressed[TabNum][0] && bpressed[TabNum][1] && 
  173         bpressed[TabNum][2] && bpressed[TabNum][3] && 
  174         numpoints[TabNum] > 0)
  175         gtk_widget_set_sensitive(exportbutton[TabNum], TRUE);
  176     else gtk_widget_set_sensitive(exportbutton[TabNum], FALSE);
  177     }
  178 
  179     if (numpoints[TabNum]==0 &&
  180         axiscoords[TabNum][0][0] == -1 &&
  181         axiscoords[TabNum][1][0] == -1 &&
  182         axiscoords[TabNum][2][0] == -1 &&
  183         axiscoords[TabNum][3][0] == -1) {
  184         gtk_widget_set_sensitive(remlastbutton[TabNum],FALSE);
  185         gtk_widget_set_sensitive(remallbutton[TabNum],FALSE);
  186     } else if (numpoints[TabNum]==0 &&
  187               (axiscoords[TabNum][0][0] != -1 ||
  188                axiscoords[TabNum][1][0] != -1 ||
  189                axiscoords[TabNum][2][0] != -1 ||
  190                axiscoords[TabNum][3][0] != -1)) {
  191         gtk_widget_set_sensitive(remlastbutton[TabNum],FALSE);
  192         gtk_widget_set_sensitive(remallbutton[TabNum],TRUE);
  193     } else {
  194         gtk_widget_set_sensitive(remlastbutton[TabNum],TRUE);
  195         gtk_widget_set_sensitive(remallbutton[TabNum],TRUE);
  196     }
  197 }
  198 
  199 
  200 /****************************************************************/
  201 /* When a button is pressed inside the drawing area this    */
  202 /* function is called, it handles axispoints and graphpoints    */
  203 /* and paints a square in that position.            */
  204 /****************************************************************/
  205 static gint button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
  206 {
  207     gint x, y, i, j, TabNum;
  208 
  209     TabNum = GPOINTER_TO_INT(data);
  210 
  211     gdk_window_get_pointer (event->window, &x, &y, NULL);
  212 
  213     if (event->button == 1) {
  214         /* If none of the set axispoint buttons been pressed */
  215         if (!setxypressed[TabNum][0] && !setxypressed[TabNum][1] && !setxypressed[TabNum][2] && !setxypressed[TabNum][3]) {
  216             if (numpoints[TabNum] > MaxPoints[TabNum]-1) {
  217                 i = MaxPoints[TabNum];
  218                 MaxPoints[TabNum] += MAXPOINTS;
  219                 points[TabNum] = realloc(points[TabNum],sizeof(gint *) * MaxPoints[TabNum]);
  220                 if (points[TabNum]==NULL) {
  221                     printf("Error reallocating memory for points. Exiting.\n");
  222                     exit(-1);
  223                 }
  224                 for (;i<MaxPoints[TabNum];i++) {
  225                     points[TabNum][i] = malloc(sizeof(gint) * 2);
  226                     if (points[TabNum][i]==NULL) {
  227                         printf("Error allocating memory for points[%d]. Exiting.\n",i);
  228                         exit(-1);
  229                     }
  230                 }
  231             }
  232             points[TabNum][numpoints[TabNum]][0]=x;
  233             points[TabNum][numpoints[TabNum]][1]=y;
  234             numpoints[TabNum]++;
  235             SetNumPointsEntry(nump_entry[TabNum], numpoints[TabNum]);
  236         } else {
  237             for (i=0;i<4;i++) {
  238                 /* If any of the set axispoint buttons are pressed */
  239                 if (setxypressed[TabNum][i]) {
  240                     axiscoords[TabNum][i][0]=x;
  241                     axiscoords[TabNum][i][1]=y;
  242                     for (j=0;j<4;j++) {
  243                         if (i!=j) {
  244                             gtk_widget_set_sensitive(setxybutton[TabNum][j],TRUE);
  245                         }
  246                     }
  247                     gtk_widget_set_sensitive(xyentry[TabNum][i],TRUE);
  248                     gtk_editable_set_editable(GTK_EDITABLE(xyentry[TabNum][i]),TRUE);
  249                     gtk_widget_grab_focus(xyentry[TabNum][i]);
  250                     setxypressed[TabNum][i]=FALSE;
  251                     bpressed[TabNum][i]=TRUE;
  252                     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(setxybutton[TabNum][i]),FALSE);
  253                 }
  254             }
  255         }
  256     } else if (event->button == 2) {
  257         for (i=0;i<2;i++) {
  258             if (!bpressed[TabNum][i]) {
  259                 axiscoords[TabNum][i][0]=x;
  260                 axiscoords[TabNum][i][1]=y;
  261                 for (j=0;j<4;j++) {
  262                     if (i!=j) {
  263                         gtk_widget_set_sensitive(setxybutton[TabNum][j],TRUE);
  264                     }
  265                 }
  266                 gtk_widget_set_sensitive(xyentry[TabNum][i],TRUE);
  267                 gtk_editable_set_editable(GTK_EDITABLE(xyentry[TabNum][i]),TRUE);
  268                 gtk_widget_grab_focus(xyentry[TabNum][i]);
  269                 setxypressed[TabNum][i]=FALSE;
  270                 bpressed[TabNum][i]=TRUE;
  271                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(setxybutton[TabNum][i]),FALSE);
  272 
  273                 break;
  274             }
  275         }
  276     } else if (event->button == 3) {
  277         for (i=2;i<4;i++) {
  278             if (!bpressed[TabNum][i]) {
  279                 axiscoords[TabNum][i][0]=x;
  280                 axiscoords[TabNum][i][1]=y;
  281                 for (j=0;j<4;j++) {
  282                     if (i!=j) {
  283                         gtk_widget_set_sensitive(setxybutton[TabNum][j],TRUE);
  284                     }
  285                 }
  286                 gtk_widget_set_sensitive(xyentry[TabNum][i],TRUE);
  287                 gtk_editable_set_editable(GTK_EDITABLE(xyentry[TabNum][i]),TRUE);
  288                 gtk_widget_grab_focus(xyentry[TabNum][i]);
  289                 setxypressed[TabNum][i]=FALSE;
  290                 bpressed[TabNum][i]=TRUE;
  291                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(setxybutton[TabNum][i]),FALSE);
  292 
  293                 break;
  294             }
  295         }
  296     }
  297     SetButtonSensitivity(TabNum);
  298     gtk_widget_queue_draw(drawing_area[TabNum]);
  299 
  300     return TRUE;
  301 }
  302 
  303 
  304 static gint motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
  305 {
  306     gint x, y, TabNum;
  307     gchar buf[32];
  308     struct PointValue CalcVal;
  309 
  310     TabNum = GPOINTER_TO_INT(data);
  311 
  312     gdk_window_get_pointer (event->window, &x, &y, NULL);
  313     xpointer = x;
  314     ypointer = y;
  315 
  316     /* If pointer over image, and axis points have been set,
  317        then print the coordinates. */
  318     if (x >= 0 && y >= 0 && x < XSize[TabNum] && y < YSize[TabNum] &&
  319        (valueset[TabNum][0] && valueset[TabNum][1] && valueset[TabNum][2] && valueset[TabNum][3])) {
  320 
  321         CalcVal = CalcPointValue(x,y,TabNum);
  322         g_ascii_formatd(buf, 32, "%.5f", CalcVal.Xv);
  323         gtk_entry_set_text(GTK_ENTRY(xc_entry[TabNum]),buf);
  324         g_ascii_formatd(buf, 32, "%.5f", CalcVal.Yv);
  325         gtk_entry_set_text(GTK_ENTRY(yc_entry[TabNum]),buf);
  326         g_ascii_formatd(buf, 32, "%.5f", CalcVal.Xerr);
  327         gtk_entry_set_text(GTK_ENTRY(xerr_entry[TabNum]),buf);
  328         g_ascii_formatd(buf, 32, "%.5f", CalcVal.Yerr);
  329         gtk_entry_set_text(GTK_ENTRY(yerr_entry[TabNum]),buf);
  330     } else {
  331         gtk_entry_set_text(GTK_ENTRY(xc_entry[TabNum]),"");
  332         gtk_entry_set_text(GTK_ENTRY(yc_entry[TabNum]),"");
  333         gtk_entry_set_text(GTK_ENTRY(xerr_entry[TabNum]),"");
  334         gtk_entry_set_text(GTK_ENTRY(yerr_entry[TabNum]),"");
  335     }
  336     gtk_widget_queue_draw(zoom_area[TabNum]);
  337 
  338     return TRUE;
  339 }
  340 
  341 
  342 /* expose_event_callback for the zoom area. */
  343 static gboolean expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
  344     gint TabNum;
  345     cairo_t *cr;
  346 
  347     TabNum = GPOINTER_TO_INT(data);
  348     cr = gdk_cairo_create (gtk_widget_get_window(widget));
  349 
  350     if (xpointer >= 0 && ypointer >= 0 && xpointer < XSize[TabNum] && ypointer < YSize[TabNum]) {
  351         cairo_save(cr);
  352         cairo_translate(cr, -xpointer*ZOOMFACTOR + ZOOMPIXSIZE/2, -ypointer*ZOOMFACTOR + ZOOMPIXSIZE/2);
  353         cairo_scale(cr, 1.0*ZOOMFACTOR, 1.0*ZOOMFACTOR);
  354         gdk_cairo_set_source_pixbuf (cr, gpbimage[TabNum], 0, 0);
  355         cairo_paint(cr);
  356         cairo_restore(cr);
  357     }
  358 
  359     /* Then draw the square in the middle of the zoom area */
  360     DrawMarker(cr, ZOOMPIXSIZE/2, ZOOMPIXSIZE/2, 2, colors);
  361     cairo_destroy (cr);
  362     return TRUE;
  363 }
  364 
  365 
  366 /****************************************************************/
  367 /* This function is called when the drawing area is exposed, it */
  368 /* simply redraws the pixmap on it.             */
  369 /****************************************************************/
  370 static gint expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
  371 {
  372     gint i, TabNum;
  373     cairo_t *cr = gdk_cairo_create (gtk_widget_get_window(widget));
  374 
  375     TabNum = GPOINTER_TO_INT(data);
  376 
  377     gdk_cairo_set_source_pixbuf (cr, gpbimage[TabNum], 0, 0);
  378     cairo_paint (cr);
  379 
  380     for (i=0;i<4;i++) if (bpressed[TabNum][i]) DrawMarker(cr, axiscoords[TabNum][i][0], axiscoords[TabNum][i][1], i/2, colors);
  381     for (i=0;i<numpoints[TabNum];i++) DrawMarker(cr, points[TabNum][i][0], points[TabNum][i][1], 2, colors);
  382 
  383     cairo_destroy (cr);
  384     return FALSE;
  385 }   
  386 
  387 
  388 /****************************************************************/
  389 /* This function is called when the drawing area is configured  */
  390 /* for the first time, currently this function does not perform */
  391 /* any task.                            */
  392 /****************************************************************/
  393 static gint configure_event(GtkWidget *widget, GdkEventConfigure *event,gpointer data)
  394 {
  395     return TRUE;
  396 }
  397 
  398 
  399 /****************************************************************/
  400 /* This function is called when the "Set point 1/2 on x/y axis" */
  401 /* button is pressed. It inactivates the other "Set" buttons    */
  402 /* and makes sure the button stays down even when pressed on.   */
  403 /****************************************************************/
  404 static void toggle_xy(GtkWidget *widget, gpointer func_data)
  405 {
  406     gint i, j;
  407 
  408     i = GPOINTER_TO_INT (func_data);
  409 
  410     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
  411     setxypressed[ViewedTabNum][i] = TRUE;                       /* The button is pressed down */
  412     for (j = 0; j < 4; j++) {
  413         if (i != j) gtk_widget_set_sensitive(setxybutton[ViewedTabNum][j],FALSE);
  414     }
  415     if (bpressed[i]) {                              /* If the x axis point is already set */
  416         axiscoords[ViewedTabNum][i][0] = -1;
  417         axiscoords[ViewedTabNum][i][1] = -1;
  418     }
  419     bpressed[ViewedTabNum][i]=FALSE;                        /* Set x axis point 1 to unset */
  420     } else {                                        /* If button is trying to get unpressed */
  421     if (setxypressed[ViewedTabNum][i]) 
  422         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),TRUE);       /* Set button down */
  423     }
  424     gtk_widget_queue_draw(drawing_area[ViewedTabNum]);
  425 }
  426 
  427 
  428 /****************************************************************/
  429 /* Set type of ordering at output of data.          */
  430 /****************************************************************/
  431 static void SetOrdering(GtkWidget *widget, gpointer func_data)
  432 {
  433     ordering[ViewedTabNum] = GPOINTER_TO_INT (func_data);               /* Set ordering control variable */
  434 }
  435 
  436 
  437 /****************************************************************/
  438 /****************************************************************/
  439 static void SetAction(GtkWidget *widget)
  440 {
  441     print2file[ViewedTabNum] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
  442     SetButtonSensitivity(ViewedTabNum);
  443 }
  444 
  445 
  446 /****************************************************************/
  447 /* Set whether to use error evaluation and printing or not. */
  448 /****************************************************************/
  449 static void UseErrCB(GtkWidget *widget, gpointer func_data)
  450 {
  451     UseErrors[ViewedTabNum] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
  452 }
  453 
  454 
  455 /****************************************************************/
  456 /* When the value of the entry of any axis point is changed,    */
  457 /* this function gets called.                   */
  458 /****************************************************************/
  459 static void read_xy_entry(GtkWidget *entry, gpointer func_data)
  460 {
  461     const gchar *xy_text;
  462     gint i;
  463     
  464     i = GPOINTER_TO_INT (func_data);
  465 
  466     xy_text = gtk_entry_get_text(GTK_ENTRY (entry));
  467     sscanf(xy_text,"%lf",&realcoords[ViewedTabNum][i]);             /* Convert string to double value and */
  468                                             /* store in realcoords[0]. */
  469     if (logxy[ViewedTabNum][i/2] && realcoords[ViewedTabNum][i] > 0) valueset[ViewedTabNum][i]=TRUE;
  470     else if (logxy[ViewedTabNum][i/2]) valueset[ViewedTabNum][i]=FALSE;
  471     else valueset[ViewedTabNum][i] = TRUE;
  472 
  473     SetButtonSensitivity(ViewedTabNum);
  474 }
  475 
  476 
  477 /****************************************************************/
  478 /* If all the axispoints has been put out, values for these */
  479 /* have been assigned and at least one point has been set on    */
  480 /* the graph activate the write to file button.         */
  481 /****************************************************************/
  482 static void read_file_entry(GtkWidget *entry, gpointer func_data)
  483 {
  484 
  485   gint TabNum;
  486 
  487     TabNum = GPOINTER_TO_INT (func_data);
  488 
  489     file_name[TabNum] = gtk_entry_get_text (GTK_ENTRY (entry));
  490     file_name_length[TabNum] = strlen(file_name[TabNum]);           /* Get length of string */
  491 
  492     if (bpressed[TabNum][0] && bpressed[TabNum][1] && bpressed[TabNum][2] && 
  493     bpressed[TabNum][3] && valueset[TabNum][0] && valueset[TabNum][1] && 
  494     valueset[TabNum][2] && valueset[TabNum][3] && numpoints[TabNum] > 0 &&
  495     file_name_length[TabNum] > 0) {
  496     gtk_widget_set_sensitive(exportbutton[TabNum],TRUE);
  497     }
  498     else gtk_widget_set_sensitive(exportbutton[TabNum],FALSE);
  499 
  500 }
  501 
  502 
  503 /****************************************************************/
  504 /* If the "X/Y axis is logarithmic" check button is toggled */
  505 /* this function gets called. It sets the logx variable to its  */
  506 /* correct value corresponding to the buttons state.        */
  507 /****************************************************************/
  508 static void islogxy(GtkWidget *widget, gpointer func_data)
  509 {
  510   gint i;
  511 
  512     i = GPOINTER_TO_INT (func_data);
  513 
  514     logxy[ViewedTabNum][i] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
  515                                             /* logxy = TRUE else FALSE. */
  516     if (logxy[ViewedTabNum][i]) {
  517     if (realcoords[ViewedTabNum][i*2] <= 0) {                   /* If a negative value has been insert */
  518         valueset[ViewedTabNum][i*2]=FALSE;
  519         gtk_entry_set_text(GTK_ENTRY(xyentry[ViewedTabNum][i*2]),"");       /* Zero it */
  520     }
  521     if (realcoords[ViewedTabNum][i*2+1] <= 0) {                 /* If a negative value has been insert */
  522         valueset[ViewedTabNum][i*2+1]=FALSE;
  523         gtk_entry_set_text(GTK_ENTRY(xyentry[ViewedTabNum][i*2+1]),"");     /* Zero it */
  524         }
  525     }
  526 }
  527 
  528 
  529 /* Removes the last data point inserted */
  530 static void remove_last(GtkWidget *widget, gpointer data)
  531 {
  532     gint TabNum = GPOINTER_TO_INT(data);
  533 
  534     /* If there are any points, remove one. */
  535     if (numpoints[TabNum] > 0) {
  536         points[TabNum][numpoints[TabNum]][0] = -1;
  537         points[TabNum][numpoints[TabNum]][1] = -1;
  538         numpoints[TabNum]--;
  539         SetNumPointsEntry(nump_entry[TabNum], numpoints[TabNum]);
  540     }
  541 
  542     SetButtonSensitivity(TabNum);
  543     gtk_widget_queue_draw(drawing_area[ViewedTabNum]);
  544 }
  545 
  546 
  547 /****************************************************************/
  548 /* This function sets the proper variables and then calls   */
  549 /* remove_last, to remove all points except the axis points.    */
  550 /****************************************************************/
  551 static void remove_all(GtkWidget *widget, gpointer data) 
  552 {
  553     gint i, TabNum;
  554 
  555     TabNum = GPOINTER_TO_INT(data);
  556 
  557     /* set axiscoords to -1, so the axis points do not get drawn*/
  558     for (i = 0; i < 4; i++) {
  559         axiscoords[TabNum][i][0] = -1;
  560         axiscoords[TabNum][i][1] = -1;
  561         /* Clear axis points text entries, make buttons insensitive */
  562         valueset[TabNum][i] = FALSE;
  563         bpressed[TabNum][i] = FALSE;
  564         gtk_entry_set_text(GTK_ENTRY(xyentry[TabNum][i]), "");
  565         gtk_widget_set_sensitive(xyentry[TabNum][i], FALSE);
  566     }
  567 
  568     numpoints[TabNum] = 0;
  569     SetNumPointsEntry(nump_entry[TabNum], numpoints[TabNum]);
  570 
  571     remove_last(widget, data);
  572 }
  573 
  574 
  575 /****************************************************************/
  576 /* This function handles all of the keypresses done within the  */
  577 /* main window and handles the  appropriate measures.       */
  578 /****************************************************************/
  579 static gint key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer pointer)
  580 {
  581   GtkAdjustment *adjustment;
  582   gdouble adj_val;
  583   GdkCursor *cursor;
  584 
  585     if (ViewPort != NULL) {
  586 
  587     if (event->keyval==GDK_Left) {
  588     adjustment = gtk_viewport_get_hadjustment(GTK_VIEWPORT(ViewPort));
  589     adj_val = gtk_adjustment_get_value(adjustment);
  590     adj_val -= gtk_adjustment_get_page_size(adjustment)/10.0;
  591     if (adj_val < gtk_adjustment_get_lower(adjustment)) adj_val = gtk_adjustment_get_lower(adjustment);
  592     gtk_adjustment_set_value(adjustment, adj_val);
  593     gtk_viewport_set_hadjustment(GTK_VIEWPORT(ViewPort), adjustment);
  594     } else if (event->keyval==GDK_Right) {
  595     adjustment = gtk_viewport_get_hadjustment(GTK_VIEWPORT(ViewPort));
  596     adj_val = gtk_adjustment_get_value(adjustment);
  597     adj_val += gtk_adjustment_get_page_size(adjustment)/10.0;
  598     if (adj_val > (gtk_adjustment_get_upper(adjustment)-gtk_adjustment_get_page_size(adjustment))) adj_val = (gtk_adjustment_get_upper(adjustment)-gtk_adjustment_get_page_size(adjustment));
  599     gtk_adjustment_set_value(adjustment, adj_val);
  600     gtk_viewport_set_hadjustment(GTK_VIEWPORT(ViewPort), adjustment);
  601     } else if (event->keyval==GDK_Up) {
  602     adjustment = gtk_viewport_get_vadjustment(GTK_VIEWPORT(ViewPort));
  603     adj_val = gtk_adjustment_get_value(adjustment);
  604     adj_val -= gtk_adjustment_get_page_size(adjustment)/10.0;
  605     if (adj_val < gtk_adjustment_get_lower(adjustment)) adj_val = gtk_adjustment_get_lower(adjustment);
  606     gtk_adjustment_set_value(adjustment, adj_val);
  607     gtk_viewport_set_vadjustment(GTK_VIEWPORT(ViewPort), adjustment);
  608     } else if (event->keyval==GDK_Down) {
  609     adjustment = gtk_viewport_get_vadjustment(GTK_VIEWPORT(ViewPort));
  610     adj_val = gtk_adjustment_get_value(adjustment);
  611     adj_val += gtk_adjustment_get_page_size(adjustment)/10.0;
  612     if (adj_val > (gtk_adjustment_get_upper(adjustment)-gtk_adjustment_get_page_size(adjustment))) adj_val = (gtk_adjustment_get_upper(adjustment)-gtk_adjustment_get_page_size(adjustment));
  613     gtk_adjustment_set_value(adjustment, adj_val);
  614     gtk_viewport_set_vadjustment(GTK_VIEWPORT(ViewPort), adjustment);
  615     }
  616     }
  617 
  618   return 0;
  619 }
  620 
  621 
  622 /****************************************************************/
  623 /* This function loads the image, and inserts it into the tab   */
  624 /* and sets up all of the different signals associated with it. */
  625 /****************************************************************/
  626 static gint InsertImage(char *filename, gdouble Scale, gdouble maxX, gdouble maxY, gint TabNum) {
  627     gboolean has_alpha;
  628     gint width, height;
  629     GdkPixbuf *loadgpbimage;
  630     GdkCursor *cursor;
  631     GtkWidget *dialog;
  632 
  633     loadgpbimage = gdk_pixbuf_new_from_file(filename,NULL);             /* Load image */
  634     if (loadgpbimage==NULL) {                               /* If unable to load image */
  635     dialog = gtk_message_dialog_new (GTK_WINDOW(window),                /* Notify user of the error */
  636                                   GTK_DIALOG_DESTROY_WITH_PARENT,           /* with a dialog */
  637                                   GTK_MESSAGE_ERROR,
  638                                   GTK_BUTTONS_CLOSE,
  639                                   "Error loading file '%s'",
  640                                   filename);
  641     gtk_dialog_run (GTK_DIALOG (dialog));
  642     gtk_widget_destroy (dialog);
  643 
  644     return -1;                                  /* exit */
  645     }
  646 
  647     width = gdk_pixbuf_get_width(loadgpbimage);
  648     height = gdk_pixbuf_get_height(loadgpbimage);
  649     has_alpha = gdk_pixbuf_get_has_alpha(loadgpbimage);
  650 
  651     if (maxX != -1 && maxY != -1 && Scale == -1) {
  652         if (width > maxX || height > maxY) {
  653             Scale = fmin((double) (maxX/width), (double) (maxY/height));
  654         }
  655     }
  656 
  657     if (Scale != -1) {
  658         width = width * Scale;
  659         height = height * Scale;
  660         gpbimage[TabNum] = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8, width, height);
  661         gdk_pixbuf_composite(loadgpbimage, gpbimage[TabNum], 0, 0, width, height,
  662                  0, 0, Scale, Scale, GDK_INTERP_BILINEAR, 255);
  663         g_object_unref(loadgpbimage);
  664     } else {
  665         gpbimage[TabNum] = loadgpbimage;
  666     }
  667 
  668     XSize[TabNum] = width;
  669     YSize[TabNum] = height;
  670 
  671     drawing_area[TabNum] = gtk_drawing_area_new ();                 /* Create new drawing area */
  672     gtk_widget_set_size_request (drawing_area[TabNum], XSize[TabNum], YSize[TabNum]);
  673 
  674     g_signal_connect (G_OBJECT (drawing_area[TabNum]), "expose_event",          /* Connect drawing area to */
  675               G_CALLBACK (expose_event), GINT_TO_POINTER (TabNum));         /* expose_event. */
  676 
  677     g_signal_connect (G_OBJECT (drawing_area[TabNum]), "configure_event",       /* Connect drawing area to */
  678               G_CALLBACK (configure_event), GINT_TO_POINTER (TabNum));          /* configure_event. */
  679 
  680     g_signal_connect (G_OBJECT (drawing_area[TabNum]), "button_press_event",        /* Connect drawing area to */
  681               G_CALLBACK (button_press_event), GINT_TO_POINTER (TabNum));       /* button_press_event. */
  682 
  683     g_signal_connect (G_OBJECT (drawing_area[TabNum]), "motion_notify_event",       /* Connect drawing area to */
  684               G_CALLBACK (motion_notify_event), GINT_TO_POINTER (TabNum));      /* motion_notify_event. */
  685 
  686     gtk_widget_set_events (drawing_area[TabNum], GDK_EXPOSURE_MASK |            /* Set the events active */
  687                GDK_BUTTON_PRESS_MASK | 
  688                GDK_BUTTON_RELEASE_MASK |
  689                GDK_POINTER_MOTION_MASK | 
  690                GDK_POINTER_MOTION_HINT_MASK);
  691 
  692     gtk_container_add(GTK_CONTAINER(drawing_area_alignment), drawing_area[TabNum]);
  693 
  694     gtk_widget_show(drawing_area[TabNum]);
  695 
  696     cursor = gdk_cursor_new (GDK_CROSSHAIR);
  697     gdk_window_set_cursor (gtk_widget_get_window(drawing_area[TabNum]), cursor);
  698  
  699     return 0;
  700 }
  701 
  702 
  703 /****************************************************************/
  704 /* This callback sets up the thumbnail in the Fileopen dialog.  */
  705 /****************************************************************/
  706 static void update_preview_cb (GtkFileChooser *file_chooser, gpointer data) {
  707   GtkWidget *preview;
  708   gchar *filename;
  709   GdkPixbuf *pixbuf;
  710   gboolean have_preview;
  711 
  712     preview = GTK_WIDGET (data);
  713     filename = gtk_file_chooser_get_preview_filename (file_chooser);
  714     if (filename != NULL) {
  715         pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL);
  716         have_preview = (pixbuf != NULL);
  717         g_free (filename);
  718 
  719         gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
  720         if (pixbuf)
  721             g_object_unref (pixbuf);
  722 
  723         gtk_file_chooser_set_preview_widget_active (file_chooser, have_preview);
  724     }
  725 }
  726 
  727 
  728 /****************************************************************/
  729 /* This function sets up a new tab, sets up all of the widgets  */
  730 /* needed.                          */
  731 /****************************************************************/
  732 static gint SetupNewTab(char *filename, gdouble Scale, gdouble maxX, gdouble maxY, gboolean UsePreSetCoords)
  733 {
  734   GtkWidget     *table;                                 /* GTK table/box variables for packing */
  735   GtkWidget *tophbox, *bottomhbox;
  736   GtkWidget *trvbox, *tlvbox, *brvbox, *blvbox, *subvbox;
  737   GtkWidget     *xy_label[4];                               /* Labels for texts in window */
  738   GtkWidget     *logcheckb[2];                              /* Logarithmic checkbuttons */
  739   GtkWidget     *nump_label, *ScrollWindow;                     /* Various widgets */
  740   GtkWidget *APlabel, *PIlabel, *ZAlabel, *Llabel, *tab_label;
  741   GtkWidget     *alignment;
  742   GtkWidget     *x_label, *y_label, *tmplabel;
  743   GtkWidget *ordercheckb[3], *UseErrCheckB, *print_to_stdout_button, *print_to_file_button;
  744   GtkWidget *Olabel, *Elabel, *Alabel;
  745   GSList    *group;
  746   GtkWidget *dialog;
  747 
  748     gchar buf[20];
  749     gchar *buffer, *buffer2;
  750   gint      i, TabNum;
  751   static gint   NumberOfTabs=0;
  752 
  753     if (NumberOfTabs == MAXNUMTABS-1) {
  754     dialog = gtk_message_dialog_new (GTK_WINDOW(window),                /* Notify user of the error */
  755                                   GTK_DIALOG_DESTROY_WITH_PARENT,           /* with a dialog */
  756                                   GTK_MESSAGE_ERROR,
  757                                   GTK_BUTTONS_CLOSE,
  758                                   "Cannot open more tabs, maximum number reached (%d)",
  759                                   MAXNUMTABS);
  760     gtk_dialog_run (GTK_DIALOG (dialog));
  761     gtk_widget_destroy (dialog);
  762     return -1;
  763     }
  764 
  765     NumberOfTabs++;
  766 
  767     tab_label = gtk_label_new(basename(filename));
  768 
  769     table = gtk_table_new(1, 2 ,FALSE);                         /* Create table */
  770     gtk_container_set_border_width (GTK_CONTAINER (table), WINDOW_BORDER);
  771     gtk_table_set_row_spacings(GTK_TABLE(table), SECT_SEP);             /* Set spacings */
  772     gtk_table_set_col_spacings(GTK_TABLE(table), 0);
  773     TabNum = gtk_notebook_append_page(GTK_NOTEBOOK(mainnotebook), 
  774                       table, tab_label);
  775     if (TabNum == -1) {
  776     return -1;
  777     }
  778 
  779 /* Init datastructures */
  780     FileNames[TabNum] = g_strdup_printf("%s", basename(filename));
  781 
  782     for (i = 0; i < 4; i++) {
  783         axiscoords[TabNum][i][0] = -1;
  784         axiscoords[TabNum][i][1] = -1;
  785         bpressed[TabNum][i] = FALSE;
  786         valueset[TabNum][i] = FALSE;
  787     }
  788 
  789     numpoints[TabNum] = 0;
  790     ordering[TabNum] = 0;
  791 
  792     points[TabNum] = (void *) malloc(sizeof(gint *) * MaxPoints[TabNum]);
  793     if (points[TabNum]==NULL) {
  794     printf("Error allocating memory for points. Exiting.\n");
  795     return -1;
  796     }
  797     for (i=0;i<MaxPoints[TabNum];i++) {
  798     points[TabNum][i] = (gint *) malloc(sizeof(gint) * 2);
  799     if (points[TabNum][i]==NULL) {
  800         printf("Error allocating memory for points[%d]. Exiting.\n",i);
  801         return -1;
  802     }
  803     }
  804 
  805     for (i=0;i<4;i++) {
  806     /* buttons for setting axis points x_1, x_2, etc. */
  807     tmplabel = gtk_label_new(NULL);
  808     gtk_label_set_markup_with_mnemonic(GTK_LABEL(tmplabel), setxylabel[i]);
  809     setxybutton[TabNum][i] = gtk_toggle_button_new();               /* Create button */
  810     gtk_container_add(GTK_CONTAINER(setxybutton[TabNum][i]), tmplabel);
  811     g_signal_connect (G_OBJECT (setxybutton[TabNum][i]), "toggled",         /* Connect button */
  812               G_CALLBACK (toggle_xy), GINT_TO_POINTER (i));
  813         gtk_widget_set_tooltip_text(setxybutton[TabNum][i],setxytts[i]);
  814 
  815     /* labels for axis points x_1, x_2, etc. */
  816     xy_label[i] = gtk_label_new(NULL);
  817     gtk_label_set_markup(GTK_LABEL(xy_label[i]), xy_label_text[i]);
  818 
  819     /* text entries to enter axis points x_1, x_2, etc. */
  820     xyentry[TabNum][i] = gtk_entry_new();                       /* Create text entry */
  821     gtk_entry_set_max_length (GTK_ENTRY (xyentry[TabNum][i]), 20);
  822     gtk_editable_set_editable(GTK_EDITABLE(xyentry[TabNum][i]),FALSE);
  823     gtk_widget_set_sensitive(xyentry[TabNum][i],FALSE);             /* Inactivate it */
  824     g_signal_connect (G_OBJECT (xyentry[TabNum][i]), "changed",         /* Init the entry to call */
  825               G_CALLBACK (read_xy_entry), GINT_TO_POINTER (i));     /* read_x1_entry whenever */
  826         gtk_widget_set_tooltip_text (xyentry[TabNum][i],entryxytt[i]);
  827     }
  828 
  829     /* Processing information labels and text entries */
  830     x_label = gtk_label_new(x_string);
  831     y_label = gtk_label_new(y_string);
  832     xc_entry[TabNum] = gtk_entry_new();                         /* Create text entry */
  833     gtk_entry_set_max_length (GTK_ENTRY (xc_entry[TabNum]), 16);
  834     gtk_editable_set_editable(GTK_EDITABLE(xc_entry[TabNum]),FALSE);
  835     yc_entry[TabNum] = gtk_entry_new();                         /* Create text entry */
  836     gtk_entry_set_max_length (GTK_ENTRY (yc_entry[TabNum]), 16);
  837     gtk_editable_set_editable(GTK_EDITABLE(yc_entry[TabNum]),FALSE);
  838 
  839     /* plus/minus (+/-) symbol labels */
  840     pm_label = gtk_label_new(pm_string);
  841     pm_label2 = gtk_label_new(pm_string);
  842     /* labels and error text entries */
  843     xerr_entry[TabNum] = gtk_entry_new();                       /* Create text entry */
  844     gtk_entry_set_max_length (GTK_ENTRY (xerr_entry[TabNum]), 16);
  845     gtk_editable_set_editable(GTK_EDITABLE(xerr_entry[TabNum]),FALSE);
  846     yerr_entry[TabNum] = gtk_entry_new();                       /* Create text entry */
  847     gtk_entry_set_max_length (GTK_ENTRY (yerr_entry[TabNum]), 16);
  848     gtk_editable_set_editable(GTK_EDITABLE(yerr_entry[TabNum]),FALSE);
  849 
  850     /* Number of points label and entry */
  851     nump_label = gtk_label_new(nump_string);
  852     nump_entry[TabNum] = gtk_entry_new();                       /* Create text entry */
  853     gtk_entry_set_max_length (GTK_ENTRY (nump_entry[TabNum]), 10);
  854     gtk_editable_set_editable(GTK_EDITABLE(nump_entry[TabNum]),FALSE);
  855     SetNumPointsEntry(nump_entry[TabNum], numpoints[TabNum]);
  856 
  857     /* Zoom area */
  858     zoom_area[TabNum] = gtk_drawing_area_new ();                    /* Create new drawing area */
  859     gtk_widget_set_size_request (zoom_area[TabNum], ZOOMPIXSIZE, ZOOMPIXSIZE);
  860     g_signal_connect(G_OBJECT(zoom_area[TabNum]), "expose_event", G_CALLBACK(expose_event_callback), GINT_TO_POINTER (TabNum));
  861 
  862     setcolors(&colors);
  863 
  864     /* Remove points buttons and labels */
  865     remlastbutton[TabNum] = gtk_button_new_with_mnemonic (RemLastBLabel);       /* Create button */
  866     g_signal_connect (G_OBJECT (remlastbutton[TabNum]), "clicked",          /* Connect button */
  867                   G_CALLBACK (remove_last), GINT_TO_POINTER (TabNum));
  868     gtk_widget_set_sensitive(remlastbutton[TabNum],FALSE);
  869     gtk_widget_set_tooltip_text(remlastbutton[TabNum],removeltt);
  870 
  871     remallbutton[TabNum] = gtk_button_new_with_mnemonic (RemAllBLabel);         /* Create button */
  872     g_signal_connect (G_OBJECT (remallbutton[TabNum]), "clicked",           /* Connect button */
  873                   G_CALLBACK (remove_all), GINT_TO_POINTER (TabNum));
  874     gtk_widget_set_sensitive(remallbutton[TabNum],FALSE);
  875         gtk_widget_set_tooltip_text(remallbutton[TabNum],removeatts);
  876 
  877     /* Logarithmic axes */
  878     for (i=0;i<2;i++) {
  879     logcheckb[i] = gtk_check_button_new_with_mnemonic(loglabel[i]);         /* Create check button */
  880     g_signal_connect (G_OBJECT (logcheckb[i]), "toggled",               /* Connect button */
  881               G_CALLBACK (islogxy), GINT_TO_POINTER (i));
  882         gtk_widget_set_tooltip_text (logcheckb[i],logxytt[i]);
  883     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(logcheckb[i]), logxy[TabNum][i]);
  884     }
  885 
  886     tophbox = gtk_hbox_new (FALSE, SECT_SEP);
  887     alignment = gtk_alignment_new (0,0,0,0);
  888     gtk_table_attach(GTK_TABLE(table), alignment, 0, 1, 0, 1, 5, 0, 0, 0);
  889     gtk_container_add(GTK_CONTAINER(alignment), tophbox);
  890 
  891     bottomhbox = gtk_hbox_new (FALSE, SECT_SEP);
  892     alignment = gtk_alignment_new (0, 0, 1, 1);
  893     gtk_table_attach(GTK_TABLE(table), alignment, 0, 1, 1, 2, 5, 5, 0, 0);
  894     gtk_container_add(GTK_CONTAINER(alignment), bottomhbox);
  895 
  896     /* Packing the axis points labels and entries */
  897     tlvbox = gtk_vbox_new (FALSE, ELEM_SEP);
  898     gtk_box_pack_start (GTK_BOX (tophbox), tlvbox, FALSE, FALSE, ELEM_SEP);
  899     APlabel = gtk_label_new (NULL);
  900     gtk_label_set_markup (GTK_LABEL (APlabel), APheader);
  901     alignment = gtk_alignment_new (0, 1, 0, 0);
  902     gtk_container_add((GtkContainer *) alignment, APlabel);
  903     gtk_box_pack_start (GTK_BOX (tlvbox), alignment, FALSE, FALSE, 0);
  904     table = gtk_table_new(3, 4 ,FALSE);
  905     gtk_table_set_row_spacings(GTK_TABLE(table), ELEM_SEP);
  906     gtk_table_set_col_spacings(GTK_TABLE(table), ELEM_SEP);
  907     gtk_box_pack_start (GTK_BOX (tlvbox), table, FALSE, FALSE, 0);
  908     for (i=0;i<4;i++) {
  909         gtk_table_attach_defaults(GTK_TABLE(table), setxybutton[TabNum][i], 0, 1, i, i+1);
  910         gtk_table_attach_defaults(GTK_TABLE(table), xy_label[i], 1, 2, i, i+1);
  911         gtk_table_attach_defaults(GTK_TABLE(table), xyentry[TabNum][i], 2, 3, i, i+1);
  912     }
  913 
  914     /* Packing the point information boxes */
  915     trvbox = gtk_vbox_new (FALSE, ELEM_SEP);
  916     gtk_box_pack_start (GTK_BOX (tophbox), trvbox, FALSE, FALSE, ELEM_SEP);
  917 
  918     PIlabel = gtk_label_new (NULL);
  919     gtk_label_set_markup (GTK_LABEL (PIlabel), PIheader);
  920     alignment = gtk_alignment_new (0, 1, 0, 0);
  921     gtk_container_add(GTK_CONTAINER(alignment), PIlabel);
  922     gtk_box_pack_start (GTK_BOX (trvbox), alignment, FALSE, FALSE, 0);
  923 
  924     table = gtk_table_new(4, 2 ,FALSE);
  925     gtk_table_set_row_spacings(GTK_TABLE(table), ELEM_SEP);
  926     gtk_table_set_col_spacings(GTK_TABLE(table), ELEM_SEP);
  927     gtk_box_pack_start (GTK_BOX (trvbox), table, FALSE, FALSE, 0);
  928     gtk_table_attach_defaults(GTK_TABLE(table), x_label, 0, 1, 0, 1);
  929     gtk_table_attach_defaults(GTK_TABLE(table), xc_entry[TabNum], 1, 2, 0, 1);
  930     gtk_table_attach_defaults(GTK_TABLE(table), pm_label, 2, 3, 0, 1);
  931     gtk_table_attach_defaults(GTK_TABLE(table), xerr_entry[TabNum], 3, 4, 0, 1);
  932     gtk_table_attach_defaults(GTK_TABLE(table), y_label, 0, 1, 1, 2);
  933     gtk_table_attach_defaults(GTK_TABLE(table), yc_entry[TabNum], 1, 2, 1, 2);
  934     gtk_table_attach_defaults(GTK_TABLE(table), pm_label2, 2, 3, 1, 2);
  935     gtk_table_attach_defaults(GTK_TABLE(table), yerr_entry[TabNum], 3, 4, 1, 2);
  936 
  937     /* Pack number of points boxes */
  938     table = gtk_table_new(3, 1 ,FALSE);
  939     gtk_table_set_row_spacings(GTK_TABLE(table), 6);
  940     gtk_table_set_col_spacings(GTK_TABLE(table), 6);
  941     gtk_box_pack_start (GTK_BOX (trvbox), table, FALSE, FALSE, 0);
  942     alignment = gtk_alignment_new (0, 1, 0, 0);
  943     gtk_container_add(GTK_CONTAINER(alignment), nump_label);
  944     gtk_table_attach(GTK_TABLE(table), alignment, 0, 1, 0, 1, 0, 0, 0, 0);
  945     gtk_table_attach(GTK_TABLE(table), nump_entry[TabNum], 1, 2, 0, 1, 0, 0, 0, 0);
  946 
  947     /* Pack remove points buttons */
  948     blvbox = gtk_vbox_new (FALSE, GROUP_SEP);
  949     gtk_box_pack_start (GTK_BOX (bottomhbox), blvbox, FALSE, FALSE, ELEM_SEP);
  950 
  951     subvbox = gtk_vbox_new (FALSE, ELEM_SEP);
  952     gtk_box_pack_start (GTK_BOX (blvbox), subvbox, FALSE, FALSE, 0);
  953     gtk_box_pack_start (GTK_BOX (subvbox), remlastbutton[TabNum], FALSE, FALSE, 0); /* Pack button in vert. box */
  954     gtk_box_pack_start (GTK_BOX (subvbox), remallbutton[TabNum], FALSE, FALSE, 0);      /* Pack button in vert. box */
  955 
  956     /* Pack zoom area */
  957     subvbox = gtk_vbox_new (FALSE, ELEM_SEP);
  958     zoomareabox[TabNum] = subvbox;
  959     gtk_box_pack_start (GTK_BOX (blvbox), subvbox, FALSE, FALSE, 0);
  960     ZAlabel = gtk_label_new (NULL);
  961     gtk_label_set_markup (GTK_LABEL (ZAlabel), ZAheader);
  962     alignment = gtk_alignment_new (0, 1, 0, 0);
  963     gtk_container_add((GtkContainer *) alignment, ZAlabel);
  964     gtk_box_pack_start (GTK_BOX (subvbox), alignment, FALSE, FALSE, 0);
  965     gtk_box_pack_start (GTK_BOX (subvbox), zoom_area[TabNum], FALSE, FALSE, 0);
  966 
  967     /* Pack logarithmic axes */
  968     subvbox = gtk_vbox_new (FALSE, ELEM_SEP);
  969     logbox[TabNum] = subvbox;
  970     gtk_box_pack_start (GTK_BOX (blvbox), subvbox, FALSE, FALSE, 0);
  971     Llabel = gtk_label_new (NULL);
  972     gtk_label_set_markup (GTK_LABEL (Llabel), Lheader);
  973     alignment = gtk_alignment_new (0, 1, 0, 0);
  974     gtk_container_add((GtkContainer *) alignment, Llabel);
  975     gtk_box_pack_start (GTK_BOX (subvbox), alignment, FALSE, FALSE, 0);
  976     for (i=0;i<2;i++) {
  977     gtk_box_pack_start (GTK_BOX (subvbox), logcheckb[i], FALSE, FALSE, 0);          /* Pack checkbutton in vert. box */
  978     }
  979 
  980     /* Create and pack radio buttons for sorting */
  981     group = NULL;
  982     for (i=0;i<ORDERBNUM;i++) {
  983     ordercheckb[i] = gtk_radio_button_new_with_label (group, orderlabel[i]);    /* Create radio button */
  984     g_signal_connect (G_OBJECT (ordercheckb[i]), "toggled",             /* Connect button */
  985               G_CALLBACK (SetOrdering), GINT_TO_POINTER (i));
  986     group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (ordercheckb[i]));     /* Get buttons group */
  987     }
  988     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ordercheckb[0]), TRUE);        /* Set no ordering button active */
  989 
  990     subvbox = gtk_vbox_new (FALSE, ELEM_SEP);
  991     oppropbox[TabNum] = subvbox;
  992     gtk_box_pack_start (GTK_BOX (blvbox), subvbox, FALSE, FALSE, 0);
  993     Olabel = gtk_label_new (NULL);
  994     gtk_label_set_markup (GTK_LABEL (Olabel), Oheader);
  995     alignment = gtk_alignment_new (0, 1, 0, 0);
  996     gtk_container_add((GtkContainer *) alignment, Olabel);
  997     gtk_box_pack_start (GTK_BOX (subvbox), alignment, FALSE, FALSE, 0);
  998     for (i=0;i<ORDERBNUM;i++) {
  999     gtk_box_pack_start (GTK_BOX (subvbox), ordercheckb[i], FALSE, FALSE, 0);            /* Pack radiobutton in vert. box */
 1000     }
 1001 
 1002     /* Create and pack value errors button */
 1003     UseErrCheckB = gtk_check_button_new_with_mnemonic(PrintErrCBLabel);
 1004     g_signal_connect (G_OBJECT (UseErrCheckB), "toggled",
 1005               G_CALLBACK (UseErrCB), GINT_TO_POINTER (TabNum));
 1006     gtk_widget_set_tooltip_text (UseErrCheckB,uetts);
 1007     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(UseErrCheckB), UseErrors[TabNum]);
 1008 
 1009     Elabel = gtk_label_new (NULL);
 1010     gtk_label_set_markup (GTK_LABEL (Elabel), Eheader);
 1011     alignment = gtk_alignment_new (0, 1, 0, 0);
 1012     gtk_container_add(GTK_CONTAINER(alignment), Elabel);
 1013     gtk_box_pack_start (GTK_BOX (subvbox), alignment, FALSE, FALSE, 0);
 1014     gtk_box_pack_start (GTK_BOX (subvbox), UseErrCheckB, FALSE, FALSE, 0);
 1015 
 1016     /* Create and pack buttons for output to stdout or file */
 1017     subvbox = gtk_vbox_new (FALSE, ELEM_SEP);
 1018     gtk_box_pack_start (GTK_BOX (blvbox), subvbox, FALSE, FALSE, 0);
 1019     group = NULL;
 1020     print_to_stdout_button = gtk_radio_button_new_with_label (group, actionlabel[0]);
 1021     group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (print_to_stdout_button)); /* Get buttons group */
 1022     print_to_file_button = gtk_radio_button_new_with_label (group, actionlabel[1]);
 1023     g_signal_connect (G_OBJECT (print_to_file_button), "toggled",           /* Connect to toggled signal of only print_to_file_button */
 1024               G_CALLBACK (SetAction), NULL);
 1025     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (print_to_stdout_button), TRUE);        /* Set no ordering button active */
 1026 
 1027     Alabel = gtk_label_new (NULL);
 1028     gtk_label_set_markup (GTK_LABEL (Alabel), Aheader);
 1029     alignment = gtk_alignment_new (0, 1, 0, 0);
 1030     gtk_container_add(GTK_CONTAINER(alignment), Alabel);
 1031     gtk_box_pack_start (GTK_BOX (subvbox), alignment, FALSE, FALSE, 0);
 1032     gtk_box_pack_start (GTK_BOX (subvbox), print_to_stdout_button, FALSE, FALSE, 0);
 1033     gtk_box_pack_start (GTK_BOX (subvbox), print_to_file_button, FALSE, FALSE, 0);
 1034 
 1035     file_entry[TabNum] = gtk_entry_new();                       /* Create text entry */
 1036     gtk_entry_set_max_length (GTK_ENTRY (file_entry[TabNum]), 256);
 1037     gtk_editable_set_editable(GTK_EDITABLE(file_entry[TabNum]),TRUE);
 1038     g_signal_connect (G_OBJECT (file_entry[TabNum]), "changed",             /* Init the entry to call */
 1039                     G_CALLBACK (read_file_entry), GINT_TO_POINTER (TabNum));
 1040     gtk_widget_set_tooltip_text(file_entry[TabNum],filenamett);
 1041 
 1042     buffer = g_strdup_printf(Window_Title, filename);
 1043     buffer2 = g_strdup_printf("%s.dat", filename);
 1044     gtk_window_set_title (GTK_WINDOW (window), buffer);                         /* Set window title */
 1045 
 1046     gtk_box_pack_start (GTK_BOX (subvbox), file_entry[TabNum], FALSE, FALSE, 0);
 1047     gtk_widget_set_sensitive(file_entry[TabNum],FALSE);
 1048 
 1049     exportbutton[TabNum] = gtk_button_new_with_mnemonic (PrintBLabel);          /* Create button */
 1050 
 1051     gtk_box_pack_start (GTK_BOX (subvbox), exportbutton[TabNum], FALSE, FALSE, 0);
 1052     gtk_widget_set_sensitive(exportbutton[TabNum],FALSE);
 1053 
 1054     g_signal_connect (G_OBJECT (exportbutton[TabNum]), "clicked",
 1055                   G_CALLBACK (print_results), GINT_TO_POINTER(FALSE));
 1056     gtk_widget_set_tooltip_text(exportbutton[TabNum],printrestt);
 1057 
 1058     brvbox = gtk_vbox_new (FALSE, GROUP_SEP);
 1059     gtk_box_pack_start (GTK_BOX (bottomhbox), brvbox, TRUE, TRUE, 0);
 1060 
 1061     gtk_entry_set_text(GTK_ENTRY (file_entry[TabNum]), buffer2);                /* Set text of text entry to filename */
 1062 
 1063     /* Create a scroll window to hold image */
 1064     ScrollWindow = gtk_scrolled_window_new(NULL,NULL);
 1065     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(ScrollWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 1066     ViewPort = gtk_viewport_new(NULL,NULL);
 1067     gtk_box_pack_start (GTK_BOX (brvbox), ScrollWindow, TRUE, TRUE, 0);
 1068     drawing_area_alignment = gtk_alignment_new (0, 0, 0, 0);
 1069     gtk_container_add (GTK_CONTAINER (ViewPort), drawing_area_alignment);
 1070     gtk_container_add (GTK_CONTAINER (ScrollWindow), ViewPort);
 1071 
 1072     gtk_widget_show_all(window);
 1073 
 1074 
 1075     gtk_notebook_set_current_page(GTK_NOTEBOOK(mainnotebook), TabNum);
 1076 
 1077     if (InsertImage(filename, Scale, maxX, maxY, TabNum) == -1) {
 1078     gtk_notebook_remove_page(GTK_NOTEBOOK(mainnotebook), TabNum);
 1079     return -1;
 1080     }
 1081 
 1082     if (UsePreSetCoords) {
 1083     axiscoords[TabNum][0][0] = 0;
 1084     axiscoords[TabNum][0][1] = YSize[TabNum]-1;
 1085     axiscoords[TabNum][1][0] = XSize[TabNum]-1;
 1086     axiscoords[TabNum][1][1] = YSize[TabNum]-1;
 1087     axiscoords[TabNum][2][0] = 0;
 1088     axiscoords[TabNum][2][1] = YSize[TabNum]-1;
 1089     axiscoords[TabNum][3][0] = 0;
 1090     axiscoords[TabNum][3][1] = 0;
 1091     for (i=0;i<4;i++) {
 1092         gtk_widget_set_sensitive(xyentry[TabNum][i],TRUE);
 1093         gtk_editable_set_editable(GTK_EDITABLE(xyentry[TabNum][i]),TRUE);
 1094         g_ascii_formatd(buf, 20, "%lf", realcoords[TabNum][i]);
 1095         gtk_entry_set_text(GTK_ENTRY(xyentry[TabNum][i]), buf);
 1096         valueset[TabNum][i] = TRUE;
 1097         bpressed[TabNum][i] = TRUE;
 1098         setxypressed[TabNum][i]=FALSE;
 1099     }
 1100     gtk_widget_set_sensitive(exportbutton[TabNum],TRUE);
 1101     }
 1102 
 1103     gtk_action_group_set_sensitive(tab_action_group, TRUE);
 1104     NoteBookNumPages++;
 1105 
 1106     if (ShowZoomArea)
 1107         for (i = 0; i < MAXNUMTABS; i++)
 1108             if (zoomareabox[i] != NULL)
 1109                 gtk_widget_show(zoomareabox[i]);
 1110     if (ShowLog)
 1111         for (i = 0; i < MAXNUMTABS; i++)
 1112             if (logbox[i] != NULL)
 1113                 gtk_widget_show(logbox[i]);
 1114     if (ShowOpProp)
 1115         for (i = 0; i < MAXNUMTABS; i++)
 1116             if (oppropbox[i] != NULL)
 1117                 gtk_widget_show(oppropbox[i]);
 1118 
 1119   return 0;
 1120 }
 1121 
 1122 
 1123 /****************************************************************/
 1124 /****************************************************************/
 1125 static void drag_data_received(GtkWidget *widget,
 1126                               GdkDragContext *drag_context,
 1127                               gint x, gint y,
 1128                               GtkSelectionData *data,
 1129                               guint info,
 1130                               guint event_time,
 1131                               gpointer user_data)
 1132 {
 1133     gchar *filename;
 1134     gchar **uri_list;
 1135     gint i;
 1136     GError *error;
 1137 
 1138     if (info == URI_LIST) {
 1139         uri_list = gtk_selection_data_get_uris(data);
 1140         i = 0;
 1141         while (uri_list[i] != NULL) {
 1142             error = NULL;
 1143             filename = g_filename_from_uri(uri_list[i], NULL, &error);
 1144             if (filename == NULL) {
 1145                 g_message("Null filename: %s", error->message);
 1146                 g_error_free(error);
 1147             } else{
 1148                 SetupNewTab(filename, 1.0, -1, -1, FALSE);
 1149             }
 1150             i++;
 1151         }
 1152         g_strfreev(uri_list);
 1153     }
 1154     gtk_drag_finish (drag_context, TRUE, FALSE, event_time);
 1155 }
 1156 
 1157 
 1158 /****************************************************************/
 1159 /* This callback handles the file - open dialog.        */
 1160 /****************************************************************/
 1161 static GCallback menu_file_open(void)
 1162 {
 1163   GtkWidget *dialog, *scalespinbutton, *hboxextra, *scalelabel;
 1164   GtkImage *preview;
 1165   GtkAdjustment *scaleadj;
 1166   GtkFileFilter *filefilter;
 1167 
 1168     dialog = gtk_file_chooser_dialog_new ("Open File",
 1169                           GTK_WINDOW (window),
 1170                           GTK_FILE_CHOOSER_ACTION_OPEN,
 1171                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 1172                           GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
 1173                           NULL);
 1174     
 1175 // Set filtering of files to open to filetypes gdk_pixbuf can handle
 1176     filefilter = gtk_file_filter_new();
 1177     gtk_file_filter_add_pixbuf_formats(filefilter);
 1178     gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), GTK_FILE_FILTER(filefilter));
 1179 
 1180 
 1181     hboxextra = gtk_hbox_new(FALSE, ELEM_SEP);
 1182 
 1183     scalelabel = gtk_label_new(scale_string);
 1184 
 1185     scaleadj = (GtkAdjustment *) gtk_adjustment_new(1, 0.1, 100, 0.1, 0.1, 0);
 1186     scalespinbutton = gtk_spin_button_new(GTK_ADJUSTMENT(scaleadj), 0.1, 1);
 1187 
 1188     gtk_box_pack_start (GTK_BOX (hboxextra), scalelabel, FALSE, FALSE, 0);
 1189     gtk_box_pack_start (GTK_BOX (hboxextra), scalespinbutton, FALSE, FALSE, 0);
 1190 
 1191     gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), hboxextra);
 1192 
 1193     gtk_widget_show(hboxextra);
 1194     gtk_widget_show(scalelabel);
 1195     gtk_widget_show(scalespinbutton);
 1196 
 1197     preview = (GtkImage *) gtk_image_new ();
 1198     gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER(dialog), GTK_WIDGET(preview));
 1199     g_signal_connect (dialog, "update-preview",
 1200               G_CALLBACK (update_preview_cb), preview);
 1201 
 1202     if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
 1203     char *filename;
 1204 
 1205         filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
 1206     SetupNewTab(filename, gtk_spin_button_get_value(GTK_SPIN_BUTTON(scalespinbutton)), -1, -1, FALSE);
 1207 
 1208         g_free (filename);
 1209     }
 1210 
 1211     gtk_widget_destroy (dialog);
 1212 
 1213     return NULL;
 1214 }
 1215 
 1216 
 1217 /****************************************************************/
 1218 /* This Callback generates the help - about dialog.     */
 1219 /****************************************************************/
 1220 static GCallback menu_help_about(void)
 1221 {
 1222     const gchar *authors[] = AUTHORS;
 1223 
 1224     gtk_show_about_dialog(GTK_WINDOW(window), 
 1225     "authors", authors, 
 1226     "comments", COMMENTS,
 1227     "copyright", COPYRIGHT,
 1228     "license", LICENSE,
 1229     "program-name", PROGNAME,
 1230     "version", VERSION,
 1231     "website", HOMEPAGEURL,
 1232     "website-label", HOMEPAGELABEL,
 1233     NULL);
 1234 
 1235   return NULL;
 1236 }
 1237 
 1238 
 1239 /****************************************************************/
 1240 /* This function is called when a tab is closed. It removes the */
 1241 /* page from the notebook, all widgets within the page are  */
 1242 /* destroyed.                           */
 1243 /****************************************************************/
 1244 static GCallback menu_tab_close(void)
 1245 {
 1246     logxy[ViewedTabNum][0] = FALSE;
 1247     logxy[ViewedTabNum][1] = FALSE;
 1248 
 1249     zoomareabox[ViewedTabNum] = NULL;
 1250     logbox[ViewedTabNum] = NULL;
 1251     oppropbox[ViewedTabNum] = NULL;
 1252 
 1253     NoteBookNumPages--;
 1254 
 1255     gtk_notebook_remove_page(GTK_NOTEBOOK(mainnotebook), ViewedTabNum);
 1256 
 1257     if (NoteBookNumPages == 0) gtk_action_group_set_sensitive(tab_action_group, FALSE);
 1258 
 1259   return NULL;
 1260 }
 1261 
 1262 /****************************************************************/
 1263 /* This callback handles the fullscreen toggling.       */
 1264 /****************************************************************/
 1265 static GCallback full_screen_action_callback(GtkWidget *widget, gpointer func_data)
 1266 {
 1267     if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(widget))) {
 1268     gtk_window_fullscreen(GTK_WINDOW (window));
 1269     } else {
 1270     gtk_window_unfullscreen(GTK_WINDOW (window));
 1271     }
 1272   return NULL;
 1273 }
 1274 
 1275 /****************************************************************/
 1276 /* This callback handles the hide zoom area toggling.       */
 1277 /****************************************************************/
 1278 static GCallback hide_zoom_area_callback(GtkWidget *widget, gpointer func_data)
 1279 {
 1280   int i;
 1281 
 1282     if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(widget))) {
 1283         for (i = 0; i < MAXNUMTABS; i++)
 1284             if (zoomareabox[i] != NULL)
 1285                 gtk_widget_show(zoomareabox[i]);
 1286         ShowZoomArea = TRUE;
 1287     } else {
 1288         for (i = 0; i < MAXNUMTABS; i++)
 1289             if (zoomareabox[i] != NULL)
 1290                 gtk_widget_hide(zoomareabox[i]);
 1291         ShowZoomArea = FALSE;
 1292     }
 1293   return NULL;
 1294 }
 1295 
 1296 /****************************************************************/
 1297 /* This callback handles the hide axis settings toggling.   */
 1298 /****************************************************************/
 1299 static GCallback hide_axis_settings_callback(GtkWidget *widget, gpointer func_data)
 1300 {
 1301   int i;
 1302 
 1303     if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(widget))) {
 1304         for (i=0;i<MAXNUMTABS;i++)
 1305             if (logbox[i] != NULL)
 1306                 gtk_widget_show(logbox[i]);
 1307         ShowLog = TRUE;
 1308     } else {
 1309         for (i=0;i<MAXNUMTABS;i++)
 1310             if (logbox[i] != NULL)
 1311                 gtk_widget_hide(logbox[i]);
 1312         ShowLog = FALSE;
 1313     }
 1314   return NULL;
 1315 }
 1316 
 1317 /****************************************************************/
 1318 /* This callback handles the hide output properties toggling.   */
 1319 /****************************************************************/
 1320 static GCallback hide_output_prop_callback(GtkWidget *widget, gpointer func_data)
 1321 {
 1322   int i;
 1323 
 1324     if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(widget))) {
 1325         for (i=0;i<MAXNUMTABS;i++)
 1326             if (oppropbox[i] != NULL)
 1327                 gtk_widget_show(oppropbox[i]);
 1328         ShowOpProp = TRUE;
 1329     } else {
 1330         for (i=0;i<MAXNUMTABS;i++)
 1331             if (oppropbox[i] != NULL)
 1332                 gtk_widget_hide(oppropbox[i]);
 1333         ShowOpProp = FALSE;
 1334     }
 1335   return NULL;
 1336 }
 1337 
 1338 /****************************************************************/
 1339 /* This callback is called when the notebook page is changed.   */
 1340 /* It sets up the ViewedTabNum value as well as the title of    */
 1341 /* the window to match the image currently viewed.      */
 1342 /****************************************************************/
 1343 static GCallback NoteBookTabChange(GtkNotebook *notebook, GtkNotebookPage *page, 
 1344                 guint page_num, gpointer user_data)
 1345 {
 1346     ViewedTabNum = page_num;
 1347     if (FileNames[ViewedTabNum] != NULL) {
 1348         gtk_window_set_title (GTK_WINDOW (window), FileNames[ViewedTabNum]);
 1349     }
 1350 
 1351     return NULL;
 1352 }
 1353 
 1354 
 1355 /****************************************************************/
 1356 /* This is the main function, this function gets called when    */
 1357 /* the program is executed. It allocates the necessary work-    */
 1358 /* spaces and initialized the main window and its widgets.  */
 1359 /****************************************************************/
 1360 int main (int argc, char **argv)
 1361 {
 1362   gint      FileIndex[MAXNUMTABS], NumFiles = 0, i, maxX, maxY;
 1363   gdouble   Scale;
 1364   gboolean  UsePreSetCoords, UseError, Uselogxy[2];
 1365   gdouble   TempCoords[4];
 1366 
 1367   GtkWidget *mainvbox;
 1368 
 1369   GtkWidget *menubar;
 1370   GtkActionGroup *action_group;
 1371   GtkUIManager *ui_manager;
 1372   GtkAccelGroup *accel_group;
 1373   GError *error;
 1374 
 1375 #include "vardefs.h"
 1376 
 1377     gtk_init (&argc, &argv);                                /* Init GTK */
 1378 
 1379     if (argc > 1) if (strcmp(argv[1],"-h")==0 ||                    /* If no parameters given, -h or --help */
 1380     strcmp(argv[1],"--help")==0) {
 1381     printf("%s",HelpText);                              /* Print help */
 1382     exit(0);                                    /* and exit */
 1383     }
 1384 
 1385     maxX = -1;
 1386     maxY = -1;
 1387     Scale = -1;
 1388    UseError = FALSE;
 1389     UsePreSetCoords = FALSE;
 1390     Uselogxy[0] = FALSE;
 1391     Uselogxy[1] = FALSE;
 1392     for (i=1;i<argc;i++) {
 1393     if (*(argv[i])=='-') {
 1394         if (strcmp(argv[i],"-scale")==0) {
 1395         if (argc-i < 2) {
 1396             printf("Too few parameters for -scale\n");
 1397             exit(0);
 1398         }
 1399         if (sscanf(argv[i+1],"%lf",&Scale)!=1) {
 1400             printf("-scale parameter in invalid form !\n");
 1401             exit(0);
 1402         }
 1403         i++;
 1404         if (i >= argc) break;
 1405         } else if (strcmp(argv[i],"-errors")==0) {
 1406         UseError = TRUE;
 1407         } else if (strcmp(argv[i],"-lnx")==0) {
 1408         Uselogxy[0] = TRUE;
 1409         } else if (strcmp(argv[i],"-lny")==0) {
 1410         Uselogxy[1] = TRUE;
 1411         } else if (strcmp(argv[i],"-max")==0) {
 1412         if (argc-i < 3) {
 1413             printf("Too few parameters for -max\n");
 1414             exit(0);
 1415         }
 1416         if (sscanf(argv[i+1],"%d", &maxX)!=1) {
 1417             printf("-max first parameter in invalid form !\n");
 1418             exit(0);
 1419         }
 1420         if (sscanf(argv[i+2],"%d", &maxY)!=1) {
 1421             printf("-max second parameter in invalid form !\n");
 1422             exit(0);
 1423         }
 1424         i+=2;
 1425         if (i >= argc) break;
 1426         } else if (strcmp(argv[i],"-coords")==0) {
 1427         UsePreSetCoords = TRUE;
 1428         if (argc-i < 5) {
 1429             printf("Too few parameters for -coords\n");
 1430             exit(0);
 1431         }
 1432         if (sscanf(argv[i+1],"%lf", &TempCoords[0])!=1) {
 1433             printf("-max first parameter in invalid form !\n");
 1434             exit(0);
 1435         }
 1436         if (sscanf(argv[i+2],"%lf", &TempCoords[1])!=1) {
 1437             printf("-max second parameter in invalid form !\n");
 1438             exit(0);
 1439         } 
 1440         if (sscanf(argv[i+3],"%lf", &TempCoords[2])!=1) {
 1441             printf("-max third parameter in invalid form !\n");
 1442             exit(0);
 1443         } 
 1444         if (sscanf(argv[i+4],"%lf", &TempCoords[3])!=1) {
 1445             printf("-max fourth parameter in invalid form !\n");
 1446             exit(0);
 1447         }
 1448         i+=4;
 1449         if (i >= argc) break;
 1450 /*      } else if (strcmp(argv[i],"-hidelog")==0) {
 1451         HideLog = TRUE;
 1452         } else if (strcmp(argv[i],"-hideza")==0) {
 1453         HideZoomArea = TRUE;
 1454         } else if (strcmp(argv[i],"-hideop")==0) {
 1455         HideOpProp = TRUE; */
 1456         } else {
 1457         printf("Unknown parameter : %s\n", argv[i]);
 1458         exit(0);
 1459         }
 1460         continue;
 1461     } else {
 1462         FileIndex[NumFiles] = i;
 1463         NumFiles++;
 1464     }
 1465     }
 1466 
 1467 
 1468     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);                   /* Create window */
 1469     gtk_window_set_default_size(GTK_WINDOW(window), 640, 480);
 1470     gtk_window_set_title(GTK_WINDOW (window), Window_Title_NoneOpen);           /* Set window title */
 1471     gtk_window_set_resizable(GTK_WINDOW (window), TRUE);
 1472     gtk_container_set_border_width(GTK_CONTAINER (window), 0);              /* Set borders in window */
 1473     mainvbox = gtk_vbox_new(FALSE, 0);
 1474     gtk_container_add( GTK_CONTAINER(window), mainvbox);
 1475 
 1476     g_signal_connect(G_OBJECT (window), "delete_event",                 /* Init delete event of window */
 1477                         G_CALLBACK (close_application), NULL);
 1478 
 1479     gtk_drag_dest_set(window, GTK_DEST_DEFAULT_ALL, ui_drop_target_entries, NUM_IMAGE_DATA, (GDK_ACTION_COPY | GDK_ACTION_MOVE));
 1480     g_signal_connect(G_OBJECT (window), "drag-data-received",               /* Drag and drop catch */
 1481                         G_CALLBACK (drag_data_received), NULL);
 1482 
 1483 /* Create menues */
 1484     action_group = gtk_action_group_new("MenuActions");
 1485     gtk_action_group_add_actions(action_group, entries, G_N_ELEMENTS (entries), window);
 1486     gtk_action_group_add_toggle_actions(action_group, full_screen, G_N_ELEMENTS (full_screen), window);
 1487 
 1488     tab_action_group = gtk_action_group_new("TabActions");
 1489     gtk_action_group_add_actions(tab_action_group, closeaction, G_N_ELEMENTS (closeaction), window);
 1490     gtk_action_group_add_toggle_actions(tab_action_group, toggle_entries, G_N_ELEMENTS (toggle_entries), window);
 1491     gtk_action_group_set_sensitive(tab_action_group, FALSE);
 1492 
 1493     ui_manager = gtk_ui_manager_new();
 1494     gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);
 1495     gtk_ui_manager_insert_action_group(ui_manager, tab_action_group, 0);
 1496  
 1497     accel_group = gtk_ui_manager_get_accel_group(ui_manager);
 1498     gtk_window_add_accel_group(GTK_WINDOW (window), accel_group);
 1499  
 1500     error = NULL;
 1501     if (!gtk_ui_manager_add_ui_from_string(ui_manager, ui_description, -1, &error)) {
 1502         g_message("building menus failed: %s", error->message);
 1503         g_error_free(error);
 1504         exit(EXIT_FAILURE);
 1505     }
 1506  
 1507     menubar = gtk_ui_manager_get_widget(ui_manager, "/MainMenu");
 1508     gtk_box_pack_start(GTK_BOX (mainvbox), menubar, FALSE, FALSE, 0);
 1509 
 1510     mainnotebook = gtk_notebook_new();
 1511     gtk_box_pack_start(GTK_BOX (mainvbox), mainnotebook, TRUE, TRUE, 0);
 1512 
 1513     g_signal_connect(G_OBJECT (mainnotebook), "switch-page",                /* Init switch-page event of notebook */
 1514                         G_CALLBACK (NoteBookTabChange), NULL);
 1515 
 1516     if (NumFiles > 0) {
 1517     for (i=0;i<NumFiles;i++) {
 1518         realcoords[i][0] = TempCoords[0];
 1519         realcoords[i][2] = TempCoords[1];
 1520         realcoords[i][1] = TempCoords[2];
 1521         realcoords[i][3] = TempCoords[3];
 1522         logxy[i][0] = Uselogxy[0];
 1523         logxy[i][1] = Uselogxy[1];
 1524         UseErrors[i] = UseError;
 1525         SetupNewTab(argv[FileIndex[i]], Scale, maxX, maxY, UsePreSetCoords);
 1526     }
 1527     }
 1528 
 1529     g_signal_connect_swapped (G_OBJECT (window), "key_press_event",
 1530                       G_CALLBACK (key_press_event), NULL);
 1531 
 1532     gtk_widget_show_all(window);                            /* Show all widgets */
 1533 
 1534     gtk_main();                                     /* This is where it all starts */
 1535               
 1536     free(colors);                                   /* Deallocate memory */
 1537 
 1538     return(0);                                      /* Exit. */
 1539 }