callbacks.c

Go to the documentation of this file.
00001 /*
00002  * gEDA - GNU Electronic Design Automation
00003  * This file is a part of gerbv.
00004  *
00005  *   Copyright (C) 2000-2003 Stefan Petersen (spe@stacken.kth.se)
00006  *
00007  * $Id$
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
00022  */
00023 
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032 
00033 #include <gtk/gtk.h>
00034 #include <gdk/gdk.h>
00035 #ifndef WIN32
00036 #include <gdk/gdkx.h>
00037 #endif
00038 #include <gdk/gdkkeysyms.h>
00039 
00040 #ifdef HAVE_STDLIB_H
00041 #include <stdlib.h>
00042 #endif
00043 
00044 #ifdef HAVE_STRING_H
00045 #include <string.h>
00046 #endif
00047 
00048 #ifdef HAVE_UNISTD_H
00049 #include <unistd.h>
00050 #endif
00051 
00052 #include <math.h>
00053 #include "gerbv.h"
00054 #include "main.h"
00055 #include "callbacks.h"
00056 #include "interface.h"
00057 #include "attribute.h"
00058 #include "render.h"
00059 
00060 #include "draw-gdk.h"
00061 #ifndef RENDER_USING_GDK
00062   #include "draw.h"
00063   #ifdef WIN32
00064     #include <cairo-win32.h>
00065   #else
00066     #include <cairo-xlib.h>
00067   #endif
00068 #endif
00069 
00070 #define dprintf if(DEBUG) printf
00071 
00072 #define SAVE_PROJECT 0
00073 #define SAVE_AS_PROJECT 1
00074 #define OPEN_PROJECT 2
00075 #  define _(String) (String)
00076 
00080 extern gerbv_screen_t screen;
00081 extern gerbv_render_info_t screenRenderInfo;
00082 
00083 /* These are the names of the valid apertures.  These
00084  * values are used in several places in this file.
00085  * Please keep this in sync with the gerbv_aperture_type_t 
00086  * enum defined in gerbv.h */
00087 char *ap_names[] = {"NONE",
00088                   "CIRCLE",
00089                   "RECTANGLE",
00090                   "OVAL",           /* an ovular (obround) aperture */
00091                   "POLYGON",        /* a polygon aperture */
00092                   "MACRO",          /* a RS274X macro */
00093                   "MACRO_CIRCLE",   /* a RS274X circle macro */
00094                   "MACRO_OUTLINE",  /* a RS274X outline macro */
00095                   "MACRO_POLYGON",  /* a RS274X polygon macro */
00096                   "MACRO_MOIRE",    /* a RS274X moire macro */
00097                   "MACRO_THERMAL",  /* a RS274X thermal macro */
00098                   "MACRO_LINE20",   /* a RS274X line (code 20) macro */
00099                   "MACRO_LINE21",   /* a RS274X line (code 21) macro */
00100                   "MACRO_LINE22"    /* a RS274X line (code 22) macro */
00101 };
00102 
00103 gint callbacks_get_selected_row_index  (void);
00104 
00105 /* --------------------------------------------------------- */
00106 GtkWidget *
00107 callbacks_generate_alert_dialog (gchar *primaryText, gchar *secondaryText){
00108        GtkWidget *dialog, *label;
00109 
00110        dialog = gtk_dialog_new_with_buttons (primaryText,
00111                                            (GtkWindow *)screen.win.topLevelWindow,
00112                                            GTK_DIALOG_DESTROY_WITH_PARENT,
00113                                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
00114                                            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
00115                                            NULL);
00116        label = gtk_label_new (secondaryText);
00117        /* Add the label, and show everything we've added to the dialog. */
00118        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
00119                          label);
00120        gtk_widget_show_all (dialog);
00121        return dialog;
00122 }
00123 
00124 /* --------------------------------------------------------- */
00130 void
00131 callbacks_new_activate                        (GtkMenuItem     *menuitem,
00132                                         gpointer         user_data)
00133 {
00134        if (mainProject->last_loaded >= 0) {
00135               if (!interface_get_alert_dialog_response (
00136                      "Do you want to close any open layers and start a new project?",
00137                      "Starting a new project will cause all currently open layers to be closed. Any unsaved changes will be lost.",
00138                      FALSE,
00139                      NULL))
00140                      return;
00141        }
00142        /* Unload all layers and then clear layer window */
00143        gerbv_unload_all_layers (mainProject);
00144        callbacks_update_layer_tree ();
00145 
00146        /* Destroy project info */
00147        if (mainProject->project) {
00148            g_free(mainProject->project);
00149            mainProject->project = NULL;
00150        }
00151        render_refresh_rendered_image_on_screen();
00152 }
00153 
00154 
00155 /* --------------------------------------------------------- */
00161 void
00162 callbacks_open_project_activate               (GtkMenuItem     *menuitem,
00163                                         gpointer         user_data)
00164 {
00165        gchar *filename=NULL;
00166 
00167        screen.win.gerber = 
00168        gtk_file_chooser_dialog_new ("Open project file...",
00169                                  NULL,
00170                                  GTK_FILE_CHOOSER_ACTION_OPEN,
00171                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
00172                                  GTK_STOCK_OPEN,   GTK_RESPONSE_ACCEPT,
00173                                  NULL);
00174        gtk_file_chooser_set_current_folder ((GtkFileChooser *) screen.win.gerber,
00175               mainProject->path);
00176        gtk_widget_show (screen.win.gerber);
00177        if (gtk_dialog_run ((GtkDialog*)screen.win.gerber) == GTK_RESPONSE_ACCEPT) {
00178               filename =
00179                   gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (screen.win.gerber));
00180               /* update the last folder */
00181               g_free (mainProject->path);
00182               mainProject->path = gtk_file_chooser_get_current_folder ((GtkFileChooser *) screen.win.gerber);
00183        }
00184        gtk_widget_destroy (screen.win.gerber);
00185 
00186        if (mainProject->last_loaded >= 0) {
00187               if (!interface_get_alert_dialog_response (
00188                        "Do you want to close any open layers and load an existing project?",
00189                      "Loading a project will cause all currently open layers to be closed. Any unsaved changes will be lost.",
00190                      FALSE,
00191                      NULL))
00192                      return;
00193        }
00194 
00195        if (filename)
00196               main_open_project_from_filename (mainProject, filename);
00197        gerbv_render_zoom_to_fit_display (mainProject, &screenRenderInfo);
00198        render_refresh_rendered_image_on_screen();
00199        callbacks_update_layer_tree();
00200 
00201        return;
00202 }
00203 
00204 
00205 /* --------------------------------------------------------- */
00211 void
00212 callbacks_open_layer_activate                 (GtkMenuItem     *menuitem,
00213                                         gpointer         user_data)
00214 {
00215        GSList *filenames=NULL;
00216        GSList *filename=NULL;
00217 
00218        screen.win.gerber = 
00219        gtk_file_chooser_dialog_new ("Open Gerber, drill, or pick & place file(s)...",
00220                                  NULL,
00221                                  GTK_FILE_CHOOSER_ACTION_OPEN,
00222                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
00223                                  GTK_STOCK_OPEN,   GTK_RESPONSE_ACCEPT,
00224                                  NULL);
00225 
00226        g_object_set (screen.win.gerber, "select-multiple", TRUE, NULL);
00227        gtk_file_chooser_set_current_folder ((GtkFileChooser *) screen.win.gerber,
00228               mainProject->path);
00229        gtk_widget_show (screen.win.gerber);
00230        if (gtk_dialog_run ((GtkDialog*)screen.win.gerber) == GTK_RESPONSE_ACCEPT) {
00231               filenames =
00232                   gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER (screen.win.gerber));
00233               /* update the last folder */
00234               g_free (mainProject->path);
00235               mainProject->path = gtk_file_chooser_get_current_folder ((GtkFileChooser *) screen.win.gerber);
00236        }
00237        gtk_widget_destroy (screen.win.gerber);
00238 
00239        /* Now try to open all gerbers specified */
00240        for (filename=filenames; filename; filename=filename->next) {
00241               gerbv_open_layer_from_filename (mainProject, filename->data);
00242        }
00243        g_slist_free(filenames);
00244        
00245        gerbv_render_zoom_to_fit_display (mainProject, &screenRenderInfo);
00246        render_refresh_rendered_image_on_screen();
00247        callbacks_update_layer_tree();
00248 
00249        return;
00250 }
00251 
00252 /* --------------------------------------------------------- */
00253 void
00254 callbacks_revert_activate                     (GtkMenuItem     *menuitem,
00255                                         gpointer         user_data)
00256 {
00257        gerbv_revert_all_files (mainProject);
00258        render_refresh_rendered_image_on_screen();
00259        callbacks_update_layer_tree();
00260 }
00261 
00262 /* --------------------------------------------------------- */
00263 void
00264 callbacks_save_project_activate                       (GtkMenuItem     *menuitem,
00265                                         gpointer         user_data)
00266 {
00267   if (mainProject->project)
00268     main_save_project_from_filename (mainProject, mainProject->project);
00269   else
00270     callbacks_generic_save_activate (menuitem, (gpointer) CALLBACKS_SAVE_PROJECT_AS);
00271   return;
00272 }
00273 
00274 /* --------------------------------------------------------- */
00275 void
00276 callbacks_save_layer_activate                       (GtkMenuItem     *menuitem,
00277                                         gpointer         user_data)
00278 {
00279   /* first figure out which layer in the layer side menu is selected */
00280   gint index=callbacks_get_selected_row_index();
00281   
00282   /* Now save that layer */
00283   if (index >= 0) {
00284     if (!gerbv_save_layer_from_index (mainProject, index, mainProject->file[index]->fullPathname)) {
00285       interface_show_alert_dialog("Gerbv cannot export this file type", 
00286                               NULL,
00287                               FALSE,
00288                               NULL);
00289       mainProject->file[index]->layer_dirty = FALSE;
00290       callbacks_update_layer_tree();
00291       return;
00292     }
00293   }
00294   return;
00295 }
00296 
00297 /* --------------------------------------------------------- */
00298 void
00299 callbacks_generic_save_activate (GtkMenuItem     *menuitem,
00300                                         gpointer         user_data)
00301 {
00302        gchar *filename=NULL;
00303        gint processType = GPOINTER_TO_INT (user_data);
00304        gchar *windowTitle=NULL;
00305        
00306        if (processType == CALLBACKS_SAVE_PROJECT_AS)
00307               windowTitle = g_strdup ("Save project as...");
00308        else if (processType == CALLBACKS_SAVE_FILE_PS)
00309               windowTitle = g_strdup ("Export PS file as...");
00310        else if (processType == CALLBACKS_SAVE_FILE_PDF)
00311               windowTitle = g_strdup ("Export PDF file as...");
00312        else if (processType == CALLBACKS_SAVE_FILE_SVG)
00313               windowTitle = g_strdup ("Export SVG file as...");
00314        else if (processType == CALLBACKS_SAVE_FILE_PNG)
00315               windowTitle = g_strdup ("Export PNG file as...");
00316        else if (processType == CALLBACKS_SAVE_FILE_RS274X)
00317               windowTitle = g_strdup ("Export RS-274X file as...");
00318        else if (processType == CALLBACKS_SAVE_FILE_DRILL)
00319               windowTitle = g_strdup ("Export Excellon drill file as...");
00320        else if (processType == CALLBACKS_SAVE_LAYER_AS)
00321               windowTitle = g_strdup ("Save layer as...");
00322               
00323        screen.win.gerber = 
00324        gtk_file_chooser_dialog_new (windowTitle, NULL,
00325                                  GTK_FILE_CHOOSER_ACTION_SAVE,
00326                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
00327                                  GTK_STOCK_SAVE,   GTK_RESPONSE_ACCEPT,
00328                                  NULL);
00329        g_free (windowTitle);
00330        
00331        gtk_widget_show (screen.win.gerber);
00332        if (gtk_dialog_run ((GtkDialog*)screen.win.gerber) == GTK_RESPONSE_ACCEPT) {
00333               filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (screen.win.gerber));
00334        }
00335        gtk_widget_destroy (screen.win.gerber);
00336 
00337        if (filename) {
00338               if (processType == CALLBACKS_SAVE_PROJECT_AS) {
00339                      main_save_as_project_from_filename (mainProject, filename);
00340                      rename_main_window(filename, NULL);
00341               }
00342               else if (processType == CALLBACKS_SAVE_FILE_PS)
00343                      gerbv_export_postscript_file_from_project (mainProject, &screenRenderInfo, filename);
00344               else if (processType == CALLBACKS_SAVE_FILE_PDF)
00345                      gerbv_export_pdf_file_from_project (mainProject, &screenRenderInfo, filename);
00346               else if (processType == CALLBACKS_SAVE_FILE_SVG)
00347                      gerbv_export_svg_file_from_project (mainProject, &screenRenderInfo, filename);
00348 #ifdef EXPORT_PNG
00349               else if (processType == CALLBACKS_SAVE_FILE_PNG)
00350                      gerbv_export_png_file_from_project (mainProject, &screenRenderInfo, filename);
00351 #endif
00352               else if (processType == CALLBACKS_SAVE_LAYER_AS) {
00353                      gint index=callbacks_get_selected_row_index();
00354                      
00355                      gerbv_save_layer_from_index (mainProject, index, filename);
00356               }
00357               else if (processType == CALLBACKS_SAVE_FILE_RS274X) {
00358                      gint index=callbacks_get_selected_row_index();
00359                      
00360                      gerbv_export_rs274x_file_from_image (filename, mainProject->file[index]->image);
00361               }
00362               else if (processType == CALLBACKS_SAVE_FILE_DRILL) {
00363                      gint index=callbacks_get_selected_row_index();
00364                      
00365                      gerbv_export_drill_file_from_image (filename, mainProject->file[index]->image);
00366               }
00367        }
00368        g_free (filename);
00369        return;
00370 }
00371 
00372 /* --------------------------------------------------------- */
00373 #if GTK_CHECK_VERSION(2,10,0)
00374 
00375 static void
00376 callbacks_begin_print (GtkPrintOperation *operation, GtkPrintContext   *context,
00377               gpointer user_data) {
00378        gtk_print_operation_set_n_pages     (operation, 1);
00379 }
00380 
00381 
00382 /* --------------------------------------------------------- */
00383 static void
00384 callbacks_print_render_page (GtkPrintOperation *operation,
00385            GtkPrintContext   *context,
00386            gint               page_nr,
00387            gpointer           user_data)
00388 {
00389 #ifndef RENDER_USING_GDK
00390        GtkPrintSettings *pSettings = gtk_print_operation_get_print_settings (operation);
00391        gerbv_render_info_t renderInfo = {1.0, 0, 0, 2,
00392               (gint) gtk_print_context_get_width (context),
00393               (gint) gtk_print_context_get_height (context)};
00394        cairo_t *cr;
00395        int i;
00396        
00397        /* have to assume x and y resolutions are the same for now, since we
00398           don't support differing scales in the gerb_render_info_t struct yet */
00399        gdouble xres = gtk_print_context_get_dpi_x (context);
00400        gdouble yres = gtk_print_context_get_dpi_y (context);
00401        gdouble scalePercentage = gtk_print_settings_get_scale (pSettings);
00402        renderInfo.scaleFactorX = scalePercentage / 100 * xres;
00403        renderInfo.scaleFactorY = scalePercentage / 100 * yres;
00404 
00405        gerbv_render_translate_to_fit_display (mainProject, &renderInfo);
00406        cr = gtk_print_context_get_cairo_context (context);
00407        for(i = 0; i < mainProject->max_files; i++) {
00408               if (mainProject->file[i] && mainProject->file[i]->isVisible) {
00409                      //cairo_push_group (cr);
00410                      gerbv_render_layer_to_cairo_target (cr, mainProject->file[i], &renderInfo);
00411                      //cairo_pop_group_to_source (cr);
00412                      //cairo_paint_with_alpha (cr, screen.file[i]->alpha);          
00413               }
00414        }
00415 #endif
00416 }
00417 
00418 /* --------------------------------------------------------- */
00419 void
00420 callbacks_print_activate (GtkMenuItem *menuitem, gpointer user_data)
00421 {
00422        GtkPrintOperation *print;
00423        GtkPrintOperationResult res;
00424 
00425        print = gtk_print_operation_new ();
00426 
00427        g_signal_connect (print, "begin_print", G_CALLBACK (callbacks_begin_print), NULL);
00428        g_signal_connect (print, "draw_page", G_CALLBACK (callbacks_print_render_page), NULL);
00429 
00430        //GtkPrintSettings *pSettings = gtk_print_operation_get_print_settings (print);
00431        
00432        res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
00433                                      (GtkWindow *) screen.win.topLevelWindow , NULL);
00434 
00435        g_object_unref (print);
00436 }
00437 #endif /* GTK_CHECK_VERSION(2,10,0) */
00438 
00439 /* --------------------------------------------------------- */
00440 void
00441 callbacks_zoom_in_activate                    (GtkMenuItem     *menuitem,
00442                                         gpointer         user_data)
00443 {
00444        render_zoom_display (ZOOM_IN, 0, 0, 0);
00445 }
00446 
00447 /* --------------------------------------------------------- */
00448 void
00449 callbacks_zoom_out_activate                   (GtkMenuItem     *menuitem,
00450                                         gpointer         user_data)
00451 {
00452        render_zoom_display (ZOOM_OUT, 0, 0, 0);
00453 }
00454 
00455 /* --------------------------------------------------------- */
00456 void
00457 callbacks_fit_to_window_activate              (GtkMenuItem     *menuitem,
00458                                         gpointer         user_data)
00459 {
00460        gerbv_render_zoom_to_fit_display (mainProject, &screenRenderInfo);
00461        render_refresh_rendered_image_on_screen();
00462 }
00463 
00464 
00465 /* --------------------------------------------------------- */
00472 void
00473 callbacks_analyze_active_gerbers_activate(GtkMenuItem *menuitem, 
00474                              gpointer user_data)
00475 {
00476     gerbv_stats_t *stats_report;
00477     gchar *G_report_string;
00478     gchar *D_report_string;
00479     gchar *M_report_string;
00480     gchar *misc_report_string;
00481     gchar *general_report_string;
00482     gchar *error_report_string;
00483     gerbv_error_list_t *my_error_list;
00484     gchar *error_level = NULL;
00485     gchar *aperture_def_report_string = "";
00486     gchar *aperture_use_report_string = "";
00487     gerbv_aperture_list_t *my_aperture_list;
00488     int idx;
00489 
00490     /* First get a report of stats & errors accumulated from all layers */
00491     stats_report = generate_gerber_analysis();
00492 
00493     /* General info report */
00494     general_report_string = g_strdup_printf("General information\n");
00495     general_report_string = g_strdup_printf("%s  Active layer count = %d\n", 
00496                                        general_report_string, stats_report->layer_count);
00497     general_report_string = g_strdup_printf("%s\n\n%-45s   %-10s\n",
00498                                        general_report_string,
00499                                        "Files processed",
00500                                        "Layer number");
00501     for (idx = 0; idx <= mainProject->max_files-1; idx++) {
00502       if (mainProject->file[idx] &&
00503          mainProject->file[idx]->isVisible &&
00504          (mainProject->file[idx]->image->layertype == GERBV_LAYERTYPE_RS274X) ) {
00505        general_report_string = 
00506          g_strdup_printf("%s  %-45s   %-10d\n", general_report_string, mainProject->file[idx]->name, idx+1);
00507       }
00508     }
00509 
00510     /* Error report (goes into general report tab) */
00511     if (stats_report->layer_count == 0) {
00512         error_report_string = g_strdup_printf("\n\nNo Gerber files loaded!\n");
00513     } else if (stats_report->error_list->error_text == NULL) {
00514        error_report_string = g_strdup_printf("\n\nNo errors found in Gerber file(s)!\n"); 
00515     } else {
00516        error_report_string = g_strdup_printf("\n\nErrors found in Gerber file(s):\n"); 
00517        for(my_error_list = stats_report->error_list; 
00518            my_error_list != NULL; 
00519            my_error_list = my_error_list->next) {
00520            switch(my_error_list->type) {
00521               case GERBV_MESSAGE_FATAL: /* We should never get this one since the 
00522                           * program should terminate first.... */
00523                   error_level = g_strdup_printf("FATAL: ");
00524                   break;
00525               case GERBV_MESSAGE_ERROR:
00526                   error_level = g_strdup_printf("ERROR: ");
00527                   break;
00528               case GERBV_MESSAGE_WARNING:
00529                   error_level = g_strdup_printf("WARNING: ");
00530                   break;
00531               case GERBV_MESSAGE_NOTE:
00532                   error_level = g_strdup_printf("NOTE: ");
00533                   break;
00534            }
00535            error_report_string = g_strdup_printf("%s  Layer %d: %s %s", 
00536                                             error_report_string,
00537                                             my_error_list->layer,
00538                                             error_level,
00539                                             my_error_list->error_text);
00540        }
00541     }
00542 
00543     general_report_string = g_strdup_printf("%s%s", 
00544                                        general_report_string,
00545                                        error_report_string);
00546     g_free(error_report_string);
00547     
00548     /* Now compile stats related to reading G codes */
00549     G_report_string = g_strdup_printf("G code statistics (all active layers)\n");
00550     G_report_string = g_strdup_printf("%s<code> = <number of incidences>\n", G_report_string);
00551     G_report_string = g_strdup_printf("%sG0 = %-6d (%s)\n", 
00552                                   G_report_string, stats_report->G0,
00553                                   "Move");
00554     G_report_string = g_strdup_printf("%sG1 = %-6d (%s)\n", 
00555                                   G_report_string, stats_report->G1,
00556                                   "1X linear interpolation");
00557     G_report_string = g_strdup_printf("%sG2 = %-6d (%s)\n", 
00558                                   G_report_string, stats_report->G2,
00559                                   "CW interpolation");
00560     G_report_string = g_strdup_printf("%sG3 = %-6d (%s)\n", 
00561                                   G_report_string, stats_report->G3,
00562                                   "CCW interpolation");
00563     G_report_string = g_strdup_printf("%sG4 = %-6d (%s)\n", 
00564                                   G_report_string, stats_report->G4,
00565                                   "Comment/ignore block");
00566     G_report_string = g_strdup_printf("%sG10 = %-6d (%s)\n", 
00567                                   G_report_string, stats_report->G10,
00568                                   "10X linear interpolation");
00569     G_report_string = g_strdup_printf("%sG11 = %-6d (%s)\n", 
00570                                   G_report_string, stats_report->G11,
00571                                   "0.1X linear interpolation");
00572     G_report_string = g_strdup_printf("%sG12 = %-6d (%s)\n", 
00573                                   G_report_string, stats_report->G12,
00574                                   "0.01X linear interpolation");
00575     G_report_string = g_strdup_printf("%sG36 = %-6d (%s)\n", 
00576                                   G_report_string, stats_report->G36,
00577                                   "Poly fill on");
00578     G_report_string = g_strdup_printf("%sG37 = %-6d (%s)\n", 
00579                                   G_report_string, stats_report->G37,
00580                                   "Poly fill off");
00581     G_report_string = g_strdup_printf("%sG54 = %-6d (%s)\n", 
00582                                   G_report_string, stats_report->G54,
00583                                   "Tool prepare");
00584     G_report_string = g_strdup_printf("%sG55 = %-6d (%s)\n", 
00585                                   G_report_string, stats_report->G55,
00586                                   "Flash prepare");
00587     G_report_string = g_strdup_printf("%sG70 = %-6d (%s)\n", 
00588                                   G_report_string, stats_report->G70,
00589                                   "Units = inches");
00590     G_report_string = g_strdup_printf("%sG71 = %-6d (%s)\n", 
00591                                   G_report_string, stats_report->G71,
00592                                   "Units = mm");
00593     G_report_string = g_strdup_printf("%sG74 = %-6d (%s)\n", 
00594                                   G_report_string, stats_report->G74,
00595                                   "Disable 360 circ. interpolation");
00596     G_report_string = g_strdup_printf("%sG75 = %-6d (%s)\n", 
00597                                   G_report_string, stats_report->G75,
00598                                   "Enable 360 circ. interpolation");
00599     G_report_string = g_strdup_printf("%sG90 = %-6d (%s)\n", 
00600                                   G_report_string, stats_report->G90,
00601                                   "Absolute units");
00602     G_report_string = g_strdup_printf("%sG91 = %-6d (%s)\n", 
00603                                   G_report_string, stats_report->G91,
00604                                   "Incremental units");
00605     G_report_string = g_strdup_printf("%sUnknown G codes = %d\n", 
00606                                   G_report_string, stats_report->G_unknown);
00607 
00608 
00609     D_report_string = g_strdup_printf("D code statistics (all active layers)\n");
00610     D_report_string = g_strdup_printf("%s<code> = <number of incidences>\n", D_report_string);
00611     D_report_string = g_strdup_printf("%sD1 = %-6d (%s)\n", 
00612                                   D_report_string, stats_report->D1,
00613                                   "Exposure on");
00614     D_report_string = g_strdup_printf("%sD2 = %-6d (%s)\n", 
00615                                   D_report_string, stats_report->D2,
00616                                   "Exposure off");
00617     D_report_string = g_strdup_printf("%sD3 = %-6d (%s)\n", 
00618                                   D_report_string, stats_report->D3,
00619                                   "Flash aperture");
00620     D_report_string = g_strdup_printf("%sUndefined D codes = %d\n", 
00621                                   D_report_string, stats_report->D_unknown);
00622     D_report_string = g_strdup_printf("%sD code Errors = %d\n", 
00623                                   D_report_string, stats_report->D_error);
00624 
00625 
00626     M_report_string = g_strdup_printf("M code statistics (all active layers)\n");
00627     M_report_string = g_strdup_printf("%s<code> = <number of incidences>\n", M_report_string);
00628     M_report_string = g_strdup_printf("%sM0 = %-6d (%s)\n", 
00629                                   M_report_string, stats_report->M0,
00630                                   "Program start");
00631     M_report_string = g_strdup_printf("%sM1 = %-6d (%s)\n", 
00632                                   M_report_string, stats_report->M1,
00633                                   "Program stop");
00634     M_report_string = g_strdup_printf("%sM2 = %-6d (%s)\n", 
00635                                   M_report_string, stats_report->M2,
00636                                   "Program end");
00637     M_report_string = g_strdup_printf("%sUnknown M codes = %d\n", 
00638                                   M_report_string, stats_report->M_unknown);
00639 
00640 
00641     misc_report_string = g_strdup_printf("Misc code statistics (all active layers)\n");
00642     misc_report_string = g_strdup_printf("%s<code> = <number of incidences>\n", misc_report_string);
00643     misc_report_string = g_strdup_printf("%sX = %d\n", misc_report_string, stats_report->X);
00644     misc_report_string = g_strdup_printf("%sY = %d\n", misc_report_string, stats_report->Y);
00645     misc_report_string = g_strdup_printf("%sI = %d\n", misc_report_string, stats_report->I);
00646     misc_report_string = g_strdup_printf("%sJ = %d\n", misc_report_string, stats_report->J);
00647     misc_report_string = g_strdup_printf("%s* = %d\n", misc_report_string, stats_report->star);
00648     misc_report_string = g_strdup_printf("%sUnknown codes = %d\n", 
00649                                   misc_report_string, stats_report->unknown);
00650 
00651     /* Report apertures defined in input files. */
00652 
00653     if (stats_report->aperture_list->number == -1) {
00654        aperture_def_report_string = 
00655            g_strdup_printf("No aperture definitions found in Gerber file(s)!\n"); 
00656     } else {
00657        aperture_def_report_string = 
00658            g_strdup_printf("Apertures defined in Gerber file(s) (by layer)\n"); 
00659        aperture_def_report_string = 
00660            g_strdup_printf("%s %-6s %-8s %12s  %8s %8s %8s\n",
00661                          aperture_def_report_string,
00662                          "Layer",
00663                          "D code",
00664                          "Aperture",
00665                          "Param[0]",
00666                          "Param[1]",
00667                          "Param[2]"
00668               );
00669        for(my_aperture_list = stats_report->aperture_list; 
00670            my_aperture_list != NULL; 
00671            my_aperture_list = my_aperture_list->next) {
00672 
00673            aperture_def_report_string = 
00674               g_strdup_printf("%s %-6d    D%-4d%13s  %8.3f %8.3f %8.3f\n", 
00675                             aperture_def_report_string,
00676                             my_aperture_list->layer,
00677                             my_aperture_list->number,
00678                             ap_names[my_aperture_list->type],
00679                             my_aperture_list->parameter[0],
00680                             my_aperture_list->parameter[1],
00681                             my_aperture_list->parameter[2]
00682                   );
00683        }
00684     }
00685 
00686 
00687     /* Report apertures usage count in input files. */
00688     if (stats_report->D_code_list->number == -1) {
00689        aperture_use_report_string = 
00690            g_strdup_printf("No apertures used in Gerber file(s)!\n"); 
00691     } else {
00692       /* Now add list of user-defined D codes (apertures) */
00693       aperture_use_report_string = 
00694        g_strdup_printf("Apertures used in Gerber file(s) (all active layers)\n"); 
00695       aperture_use_report_string = 
00696        g_strdup_printf("%s<aperture code> = <number of uses>\n",
00697                      aperture_use_report_string);
00698       for (my_aperture_list = stats_report->D_code_list; 
00699           my_aperture_list != NULL; 
00700           my_aperture_list = my_aperture_list->next) {
00701        
00702        aperture_use_report_string = 
00703          g_strdup_printf("%s D%d = %-6d\n",
00704                        aperture_use_report_string,
00705                        my_aperture_list->number,
00706                        my_aperture_list->count
00707                        );
00708       }
00709     }
00710 
00711 
00712     /* Create top level dialog window for report */
00713     GtkWidget *analyze_active_gerbers;
00714     analyze_active_gerbers = gtk_dialog_new_with_buttons("Gerber codes report",
00715                                                  NULL,
00716                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
00717                                                  GTK_STOCK_OK,
00718                                                  GTK_RESPONSE_ACCEPT,
00719                                                  NULL);
00720     gtk_container_set_border_width (GTK_CONTAINER (analyze_active_gerbers), 5);
00721     
00722     gtk_dialog_set_default_response (GTK_DIALOG(analyze_active_gerbers), 
00723                                  GTK_RESPONSE_ACCEPT);
00724     g_signal_connect (G_OBJECT(analyze_active_gerbers),
00725                     "response",
00726                     G_CALLBACK (gtk_widget_destroy), 
00727                     GTK_WIDGET(analyze_active_gerbers));
00728 
00729     /* Use fixed width font for all reports */
00730     PangoFontDescription *font = 
00731        pango_font_description_from_string ("monospace");
00732 
00733     /* Create GtkLabel to hold general report text */
00734     GtkWidget *general_report_label = gtk_label_new (general_report_string);
00735     gtk_misc_set_alignment(GTK_MISC(general_report_label), 0, 0);
00736     gtk_misc_set_padding(GTK_MISC(general_report_label), 13, 13);
00737     gtk_label_set_selectable(GTK_LABEL(general_report_label), TRUE);
00738     gtk_widget_modify_font (GTK_WIDGET(general_report_label),
00739                          font);
00740     g_free(general_report_string);
00741     /* Put general report text into scrolled window */
00742     GtkWidget *general_code_report_window = gtk_scrolled_window_new (NULL, NULL);
00743     /* This throws a warning.  Must find different approach.... */
00744     gtk_widget_set_size_request(GTK_WIDGET(general_code_report_window),
00745                             200,
00746                             300);
00747     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(general_code_report_window),
00748                                      GTK_WIDGET(general_report_label));
00749 
00750     /* Create GtkLabel to hold G code text */
00751     GtkWidget *G_report_label = gtk_label_new (G_report_string);
00752     gtk_misc_set_alignment(GTK_MISC(G_report_label), 0, 0);
00753     gtk_misc_set_padding(GTK_MISC(G_report_label), 13, 13);
00754     gtk_label_set_selectable(GTK_LABEL(G_report_label), TRUE);
00755     gtk_widget_modify_font (GTK_WIDGET(G_report_label),
00756                          font);
00757     g_free(G_report_string);
00758 
00759     /* Create GtkLabel to hold D code text */
00760     GtkWidget *D_report_label = gtk_label_new (D_report_string);
00761     gtk_misc_set_alignment(GTK_MISC(D_report_label), 0, 0);
00762     gtk_misc_set_padding(GTK_MISC(D_report_label), 13, 13);
00763     gtk_label_set_selectable(GTK_LABEL(D_report_label), TRUE);
00764     gtk_widget_modify_font (GTK_WIDGET(D_report_label),
00765                          font);
00766     g_free(D_report_string);
00767 
00768     /* Create GtkLabel to hold M code text */
00769     GtkWidget *M_report_label = gtk_label_new (M_report_string);
00770     gtk_misc_set_alignment(GTK_MISC(M_report_label), 0, 0);
00771     gtk_misc_set_padding(GTK_MISC(M_report_label), 13, 13);
00772     gtk_label_set_selectable(GTK_LABEL(M_report_label), TRUE);
00773     gtk_widget_modify_font (GTK_WIDGET(M_report_label),
00774                          font);
00775     g_free(M_report_string);
00776 
00777     /* Create GtkLabel to hold misc code text */
00778     GtkWidget *misc_report_label = gtk_label_new (misc_report_string);
00779     gtk_misc_set_alignment(GTK_MISC(misc_report_label), 0, 0);
00780     gtk_misc_set_padding(GTK_MISC(misc_report_label), 13, 13);
00781     gtk_label_set_selectable(GTK_LABEL(misc_report_label), TRUE);
00782     gtk_widget_modify_font (GTK_WIDGET(misc_report_label),
00783                          font);
00784     g_free(misc_report_string);
00785 
00786     /* Create GtkLabel to hold aperture defintion text */
00787     GtkWidget *aperture_def_report_label = gtk_label_new (aperture_def_report_string);
00788     gtk_misc_set_alignment(GTK_MISC(aperture_def_report_label), 0, 0);
00789     gtk_misc_set_padding(GTK_MISC(aperture_def_report_label), 13, 13);
00790     gtk_label_set_selectable(GTK_LABEL(aperture_def_report_label), TRUE);
00791     gtk_widget_modify_font (GTK_WIDGET(aperture_def_report_label),
00792                          font);
00793     g_free(aperture_def_report_string);
00794     /* Put aperture definintion text into scrolled window */
00795     GtkWidget *aperture_def_report_window = gtk_scrolled_window_new (NULL, NULL);
00796     /* This throws a warning.  Must find different approach.... */
00797     gtk_widget_set_size_request(GTK_WIDGET(aperture_def_report_window),
00798                             200,
00799                             300);
00800     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(aperture_def_report_window),
00801                                      GTK_WIDGET(aperture_def_report_label));
00802 
00803     /* Create GtkLabel to hold aperture use text */
00804     GtkWidget *aperture_use_report_label = gtk_label_new (aperture_use_report_string);
00805     gtk_misc_set_alignment(GTK_MISC(aperture_use_report_label), 0, 0);
00806     gtk_misc_set_padding(GTK_MISC(aperture_use_report_label), 13, 13);
00807     gtk_label_set_selectable(GTK_LABEL(aperture_use_report_label), TRUE);
00808     gtk_widget_modify_font (GTK_WIDGET(aperture_use_report_label),
00809                          font);
00810     g_free(aperture_use_report_string);
00811     /* Put aperture definintion text into scrolled window */
00812     GtkWidget *aperture_use_report_window = gtk_scrolled_window_new (NULL, NULL);
00813     /* This throws a warning.  Must find different approach.... */
00814     gtk_widget_set_size_request(GTK_WIDGET(aperture_use_report_window),
00815                             200,
00816                             300);
00817     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(aperture_use_report_window),
00818                                      GTK_WIDGET(aperture_use_report_label));
00819 
00820     /* Create tabbed notebook widget and add report label widgets. */
00821     GtkWidget *notebook = gtk_notebook_new();
00822     
00823     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
00824                           GTK_WIDGET(general_code_report_window),
00825                           gtk_label_new("General"));
00826     
00827     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
00828                           GTK_WIDGET(G_report_label),
00829                           gtk_label_new("G codes"));
00830     
00831     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
00832                           GTK_WIDGET(D_report_label),
00833                           gtk_label_new("D codes"));
00834     
00835     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
00836                           GTK_WIDGET(M_report_label),
00837                           gtk_label_new("M codes"));
00838     
00839     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
00840                           GTK_WIDGET(misc_report_label),
00841                           gtk_label_new("Misc. codes"));
00842     
00843     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
00844                           GTK_WIDGET(aperture_def_report_window),
00845                           gtk_label_new("Aperture definitions"));
00846     
00847     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
00848                           GTK_WIDGET(aperture_use_report_window),
00849                           gtk_label_new("Aperture usage"));
00850     
00851     
00852     /* Now put notebook into dialog window and show the whole thing */
00853     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(analyze_active_gerbers)->vbox),
00854                     GTK_WIDGET(notebook));
00855     
00856     gtk_widget_show_all(analyze_active_gerbers);
00857        
00858     return;
00859 
00860 }
00861 
00862 /* --------------------------------------------------------- */
00869 void
00870 callbacks_analyze_active_drill_activate(GtkMenuItem     *menuitem,
00871                                         gpointer         user_data)
00872 {
00873     gerbv_drill_stats_t *stats_report;
00874     gchar *G_report_string;
00875     gchar *M_report_string;
00876     gchar *misc_report_string;
00877     gerbv_drill_list_t *my_drill_list;
00878     gchar *drill_report_string;
00879     gchar *general_report_string;
00880     gchar *error_report_string;
00881     gerbv_error_list_t *my_error_list;
00882     gchar *error_level = NULL;
00883     int idx;
00884 
00885     stats_report = (gerbv_drill_stats_t *) generate_drill_analysis();
00886     
00887     /* General and error window strings */
00888     general_report_string = g_strdup_printf("General information\n");
00889     general_report_string = g_strdup_printf("%s  Active layer count = %d\n", 
00890                                        general_report_string, stats_report->layer_count);
00891 
00892     general_report_string = g_strdup_printf("%s\n\nFiles processed:\n", 
00893                                        general_report_string);
00894     for (idx = mainProject->max_files-1; idx >= 0; idx--) {
00895       if (mainProject->file[idx] &&
00896          mainProject->file[idx]->isVisible &&
00897          (mainProject->file[idx]->image->layertype == GERBV_LAYERTYPE_DRILL) ) {
00898        general_report_string = 
00899          g_strdup_printf("%s  %s\n", general_report_string, mainProject->file[idx]->name);
00900       }
00901     }
00902 
00903 
00904     if (stats_report->layer_count == 0) {
00905         error_report_string = g_strdup_printf("\n\nNo drill files loaded!\n"); 
00906     } else if (stats_report->error_list->error_text == NULL) {
00907        error_report_string = g_strdup_printf("\n\nNo errors found in drill file(s)!\n"); 
00908     } else {
00909        error_report_string = g_strdup_printf("\n\nErrors found in drill file(s):\n"); 
00910        for(my_error_list = stats_report->error_list; 
00911            my_error_list != NULL; 
00912            my_error_list = my_error_list->next) {
00913            switch(my_error_list->type) {
00914               case GERBV_MESSAGE_FATAL: /* We should never get this one since the 
00915                           * program should terminate first.... */
00916                   error_level = g_strdup_printf("FATAL: ");
00917                   break;
00918               case GERBV_MESSAGE_ERROR:
00919                   error_level = g_strdup_printf("ERROR: ");
00920                   break;
00921               case GERBV_MESSAGE_WARNING:
00922                   error_level = g_strdup_printf("WARNING: ");
00923                   break;
00924               case GERBV_MESSAGE_NOTE:
00925                   error_level = g_strdup_printf("NOTE: ");
00926                   break;
00927            }
00928            error_report_string = g_strdup_printf("%s  Layer %d: %s %s", 
00929                                             error_report_string,
00930                                             my_error_list->layer,
00931                                             error_level,
00932                                             my_error_list->error_text);
00933        }
00934     }
00935 
00936     general_report_string = g_strdup_printf("%s%s", 
00937                                        general_report_string,
00938                                        error_report_string);
00939     g_free(error_report_string);
00940 
00941 
00942     /* G code window strings */
00943     G_report_string = g_strdup_printf("G code statistics (all active layers)\n");
00944     G_report_string = g_strdup_printf("%s<code> = <number of incidences>\n", G_report_string);
00945     G_report_string = g_strdup_printf("%sG00 = %-6d (%s)\n", 
00946                                   G_report_string, stats_report->G00,
00947                                   "Rout mode");
00948     G_report_string = g_strdup_printf("%sG01 = %-6d (%s)\n", 
00949                                   G_report_string, stats_report->G01,
00950                                   "1X linear interpolation");
00951     G_report_string = g_strdup_printf("%sG02 = %-6d (%s)\n", 
00952                                   G_report_string, stats_report->G02,
00953                                   "CW interpolation");
00954     G_report_string = g_strdup_printf("%sG03 = %-6d (%s)\n", 
00955                                   G_report_string, stats_report->G03,
00956                                   "CCW interpolation");
00957     G_report_string = g_strdup_printf("%sG04 = %-6d (%s)\n", 
00958                                   G_report_string, stats_report->G04,
00959                                   "Variable dwell");
00960     G_report_string = g_strdup_printf("%sG05 = %-6d (%s)\n", 
00961                                   G_report_string, stats_report->G05,
00962                                   "Drill mode");
00963     G_report_string = g_strdup_printf("%sG90 = %-6d (%s)\n", 
00964                                   G_report_string, stats_report->G90,
00965                                   "Absolute units");
00966     G_report_string = g_strdup_printf("%sG91 = %-6d (%s)\n", 
00967                                   G_report_string, stats_report->G91,
00968                                   "Incremental units");
00969     G_report_string = g_strdup_printf("%sG93 = %-6d (%s)\n", 
00970                                   G_report_string, stats_report->G93,
00971                                   "Zero set");
00972     G_report_string = g_strdup_printf("%sUnknown G codes = %d\n", 
00973                                   G_report_string, stats_report->G_unknown);
00974 
00975     /* M code window strings */
00976     M_report_string = g_strdup_printf("M code statistics (all active layers)\n");
00977     M_report_string = g_strdup_printf("%s<code> = <number of incidences>\n", M_report_string);
00978     M_report_string = g_strdup_printf("%sM00 = %-6d (%s)\n", 
00979                                   M_report_string, stats_report->M00,
00980                                   "End of program");
00981     M_report_string = g_strdup_printf("%sM01 = %-6d (%s)\n", 
00982                                   M_report_string, stats_report->M01,
00983                                   "End of pattern");
00984     M_report_string = g_strdup_printf("%sM18 = %-6d (%s)\n", 
00985                                   M_report_string, stats_report->M18,
00986                                   "Tool tip check");
00987     M_report_string = g_strdup_printf("%sM25 = %-6d (%s)\n", 
00988                                   M_report_string, stats_report->M25,
00989                                   "Begin pattern");
00990     M_report_string = g_strdup_printf("%sM30 = %-6d (%s)\n", 
00991                                   M_report_string, stats_report->M30,
00992                                   "End program rewind");
00993     M_report_string = g_strdup_printf("%sM31 = %-6d (%s)\n", 
00994                                   M_report_string, stats_report->M31,
00995                                   "Begin pattern");
00996     M_report_string = g_strdup_printf("%sM45 = %-6d (%s)\n", 
00997                                   M_report_string, stats_report->M45,
00998                                   "Long message");
00999     M_report_string = g_strdup_printf("%sM47 = %-6d (%s)\n", 
01000                                   M_report_string, stats_report->M47,
01001                                   "Operator message");
01002     M_report_string = g_strdup_printf("%sM48 = %-6d (%s)\n", 
01003                                   M_report_string, stats_report->M48,
01004                                   "Begin program header");
01005     M_report_string = g_strdup_printf("%sM71 = %-6d (%s)\n", 
01006                                   M_report_string, stats_report->M71,
01007                                   "Metric units");
01008     M_report_string = g_strdup_printf("%sM72 = %-6d (%s)\n", 
01009                                   M_report_string, stats_report->M72,
01010                                   "English units");
01011     M_report_string = g_strdup_printf("%sM95 = %-6d (%s)\n", 
01012                                   M_report_string, stats_report->M95,
01013                                   "End program header");
01014     M_report_string = g_strdup_printf("%sM97 = %-6d (%s)\n", 
01015                                   M_report_string, stats_report->M97,
01016                                   "Canned text");
01017     M_report_string = g_strdup_printf("%sM98 = %-6d (%s)\n", 
01018                                   M_report_string, stats_report->M98,
01019                                   "Canned text");
01020     M_report_string = g_strdup_printf("%sUnknown M codes = %d\n", 
01021                                   M_report_string, stats_report->M_unknown);
01022 
01023 
01024     /* misc report strings */
01025     misc_report_string = g_strdup_printf("Misc code statistics (all active layers)\n");
01026     misc_report_string = g_strdup_printf("%s<code> = <number of incidences>\n", misc_report_string);
01027     misc_report_string = g_strdup_printf("%scomments = %d\n", 
01028                                     misc_report_string, stats_report->comment);
01029     misc_report_string = g_strdup_printf("%sUnknown codes = %d\n", 
01030                                     misc_report_string, stats_report->unknown);
01031 
01032     if (stats_report->detect != NULL ) {
01033        misc_report_string = g_strdup_printf("%s\n%s\n", 
01034                                         misc_report_string, stats_report->detect);
01035     }  
01036     /* drill report window strings */
01037     drill_report_string = g_strdup_printf("Drills used (all active layers)\n");
01038     drill_report_string = g_strdup_printf("%s%10s %8s %8s %8s\n", 
01039                                      drill_report_string, "Drill no.", "Dia.", "Units", "Count");
01040     for(my_drill_list = stats_report->drill_list; 
01041        my_drill_list != NULL; 
01042        my_drill_list = my_drill_list->next) {
01043        if (my_drill_list->drill_num == -1) break;  /* No dill list */
01044        drill_report_string = g_strdup_printf("%s%10d %8.3f %8s %8d\n", 
01045                                          drill_report_string,
01046                                          my_drill_list->drill_num,
01047                                          my_drill_list->drill_size,
01048                                          my_drill_list->drill_unit,
01049                                          my_drill_list->drill_count);
01050     }
01051 
01052     /* Use fixed width font for all reports */
01053     PangoFontDescription *font = 
01054        pango_font_description_from_string ("monospace");
01055 
01056     /* Create top level dialog window for report */
01057     GtkWidget *analyze_active_drill;
01058     analyze_active_drill = gtk_dialog_new_with_buttons("Drill file codes report",
01059                                                  NULL,
01060                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
01061                                                  GTK_STOCK_OK,
01062                                                  GTK_RESPONSE_ACCEPT,
01063                                                  NULL);
01064     gtk_container_set_border_width (GTK_CONTAINER (analyze_active_drill), 5);
01065     gtk_dialog_set_default_response (GTK_DIALOG(analyze_active_drill), 
01066                                  GTK_RESPONSE_ACCEPT);
01067     g_signal_connect (G_OBJECT(analyze_active_drill),
01068                     "response",
01069                     G_CALLBACK (gtk_widget_destroy), 
01070                     GTK_WIDGET(analyze_active_drill));
01071 
01072     /* Create GtkLabel to hold general report text */
01073     GtkWidget *general_report_label = gtk_label_new (general_report_string);
01074     gtk_misc_set_alignment(GTK_MISC(general_report_label), 0, 0);
01075     gtk_misc_set_padding(GTK_MISC(general_report_label), 13, 13);
01076     gtk_label_set_selectable(GTK_LABEL(general_report_label), TRUE);
01077     gtk_widget_modify_font (GTK_WIDGET(general_report_label),
01078                          font);
01079     g_free(general_report_string);
01080 
01081     /* Create GtkLabel to hold G code text */
01082     GtkWidget *G_report_label = gtk_label_new (G_report_string);
01083     gtk_misc_set_alignment(GTK_MISC(G_report_label), 0, 0);
01084     gtk_misc_set_padding(GTK_MISC(G_report_label), 13, 13);
01085     gtk_label_set_selectable(GTK_LABEL(G_report_label), TRUE);
01086     gtk_widget_modify_font (GTK_WIDGET(G_report_label),
01087                          font);
01088     g_free(G_report_string);
01089 
01090     /* Create GtkLabel to hold M code text */
01091     GtkWidget *M_report_label = gtk_label_new (M_report_string);
01092     gtk_misc_set_alignment(GTK_MISC(M_report_label), 0, 0);
01093     gtk_misc_set_padding(GTK_MISC(M_report_label), 13, 13);
01094     gtk_label_set_selectable(GTK_LABEL(M_report_label), TRUE);
01095     gtk_widget_modify_font (GTK_WIDGET(M_report_label),
01096                          font);
01097     g_free(M_report_string);
01098 
01099     /* Create GtkLabel to hold misc code text */
01100     GtkWidget *misc_report_label = gtk_label_new (misc_report_string);
01101     gtk_misc_set_alignment(GTK_MISC(misc_report_label), 0, 0);
01102     gtk_misc_set_padding(GTK_MISC(misc_report_label), 13, 13);
01103     gtk_label_set_selectable(GTK_LABEL(misc_report_label), TRUE);
01104     gtk_widget_modify_font (GTK_WIDGET(misc_report_label),
01105                          font);
01106     g_free(misc_report_string);
01107 
01108     /* Create GtkLabel to hold drills used text */
01109     GtkWidget *drill_report_label = gtk_label_new (drill_report_string);
01110     gtk_misc_set_alignment(GTK_MISC(drill_report_label), 0, 0);
01111     gtk_misc_set_padding(GTK_MISC(drill_report_label), 13, 13);
01112     gtk_label_set_selectable(GTK_LABEL(drill_report_label), TRUE);
01113     gtk_widget_modify_font (GTK_WIDGET(drill_report_label),
01114                          font);
01115     g_free(drill_report_string);
01116 
01117     /* Create tabbed notebook widget and add report label widgets. */
01118     GtkWidget *notebook = gtk_notebook_new();
01119     
01120     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
01121                           GTK_WIDGET(general_report_label),
01122                           gtk_label_new("General"));
01123 
01124     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
01125                           GTK_WIDGET(G_report_label),
01126                           gtk_label_new("G codes"));
01127     
01128     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
01129                           GTK_WIDGET(M_report_label),
01130                           gtk_label_new("M codes"));
01131     
01132     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
01133                           GTK_WIDGET(misc_report_label),
01134                           gtk_label_new("Misc. codes"));
01135     
01136     gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
01137                           GTK_WIDGET(drill_report_label),
01138                           gtk_label_new("Drills used"));
01139     
01140     /* Now put notebook into dialog window and show the whole thing */
01141     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(analyze_active_drill)->vbox),
01142                     GTK_WIDGET(notebook));
01143     gtk_widget_show_all(analyze_active_drill);
01144        
01145     return;
01146 }
01147 
01148 /* --------------------------------------------------------- */
01149 void
01150 callbacks_control_gerber_options_activate     (GtkMenuItem     *menuitem,
01151                                         gpointer         user_data)
01152 {
01153 
01154 }
01155 
01156 /* --------------------------------------------------------- */
01157 void
01158 callbacks_online_manual_activate              (GtkMenuItem     *menuitem,
01159                                         gpointer         user_data)
01160 {
01161 
01162 }
01163 
01164 /* --------------------------------------------------------- */
01170 void
01171 callbacks_quit_activate                       (GtkMenuItem     *menuitem,
01172                                         gpointer         user_data)
01173 {
01174   gboolean layers_dirty = FALSE;
01175   gint idx;
01176 
01177   for (idx = 0; idx<=mainProject->last_loaded; idx++) {
01178     if (mainProject->file[idx] == NULL) break;
01179     layers_dirty = layers_dirty || mainProject->file[idx]->layer_dirty;
01180   }
01181 
01182   if (layers_dirty &&
01183       !interface_get_alert_dialog_response(
01184             "Do you want to close all open layers and quit the program?",
01185             "Quitting the program will cause any unsaved changes to be lost.",
01186            FALSE,
01187            NULL)) {
01188     return;
01189   }
01190   gerbv_unload_all_layers (mainProject);
01191   gtk_main_quit();
01192 }
01193 
01194 /* --------------------------------------------------------- */
01200 void
01201 callbacks_about_activate                     (GtkMenuItem     *menuitem,
01202                                         gpointer         user_data)
01203 {
01204        GtkWidget *aboutdialog1;
01205        /* TRANSLATORS: Replace this string with your names, one name per line. */
01206        /* gchar *translators = _("translator-credits"); */
01207 
01208 #ifdef RENDER_USING_GDK
01209 #define RENDERER "gdk"
01210 #else
01211 #define RENDERER "cairo"
01212 #endif
01213        gchar *string = g_strdup_printf ( "gerbv -- a Gerber (RS-274/X) viewer.\n\n"
01214                                      "This is gerbv version %s\n"
01215                                      "Compiled on %s at %s\n"
01216                                      "Renderer (compile time setting):  %s\n"
01217                                      "\n"
01218                                      "gerbv is part of the gEDA Project.\n"
01219                                      "\n"
01220                                      "For more information see:\n"
01221                                      "  gerbv homepage: http://gerbv.sf.net\n"
01222                                      "  gEDA homepage: http://www.geda.seul.org\n"
01223                                      "  gEDA Wiki: http://geda.seul.org/dokuwiki/doku.php?id=geda\n\n",
01224                                      VERSION, __DATE__, __TIME__, RENDERER);
01225 
01226 #undef RENDERER
01227 #if GTK_CHECK_VERSION(2,6,0)
01228        gchar *license = g_strdup_printf("gerbv -- a Gerber (RS-274/X) viewer.\n\n"
01229                                     "Copyright (C) 2000-2007 Stefan Petersen\n\n"
01230                                     "This program is free software: you can redistribute it and/or modify\n"
01231                                     "it under the terms of the GNU General Public License as published by\n"
01232                                     "the Free Software Foundation, either version 2 of the License, or\n"
01233                                     "(at your option) any later version.\n\n"
01234                                     "This program is distributed in the hope that it will be useful,\n"
01235                                     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
01236                                     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
01237                                     "GNU General Public License for more details.\n\n"
01238                                     "You should have received a copy of the GNU General Public License\n"
01239                                     "along with this program.  If not, see <http://www.gnu.org/licenses/>.");
01240 
01241        /* Note:  set_authors works strangely.... */
01242        const gchar *authors[15] = {"Project founder:  Stefan Petersen\n",
01243                                 "Contributors:",
01244                                 "Julian Lamb",
01245                                 "Stuart Brorson",
01246                                 "Dan McMahill",
01247                                 "Joerg Wunsch",
01248                                 "Andreas Andersson aka Pitch",
01249                                 "Anders Eriksson",
01250                                 "Juergen Haas",
01251                                 "Tomasz Motylewski",
01252                                 "Joost Witteveen",
01253                                 "Trevor Blackwell",
01254                                 "David Carr",
01255                                 "... and many others.",
01256                                 NULL};
01257 
01258        aboutdialog1 = gtk_about_dialog_new ();
01259        gtk_container_set_border_width (GTK_CONTAINER (aboutdialog1), 5);
01260        gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (aboutdialog1), VERSION);
01261        gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (aboutdialog1), _("Gerbv"));
01262 
01263        /* gtk_about_dialog_set_translator_credits (GTK_ABOUT_DIALOG (aboutdialog1), translators); */
01264        gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG (aboutdialog1), string);
01265        gtk_about_dialog_set_license(GTK_ABOUT_DIALOG (aboutdialog1), license);
01266        gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG (aboutdialog1), authors);
01267        gtk_about_dialog_set_website(GTK_ABOUT_DIALOG (aboutdialog1), NULL);
01268 
01269        g_signal_connect (G_OBJECT(aboutdialog1),"response",
01270                     G_CALLBACK (gtk_widget_destroy), GTK_WIDGET(aboutdialog1));
01271 
01272        g_free (string);
01273        g_free (license);
01274 #else
01275        aboutdialog1 = gtk_message_dialog_new (   GTK_WINDOW (screen.win.topLevelWindow),
01276                                           GTK_DIALOG_DESTROY_WITH_PARENT,
01277                                           GTK_MESSAGE_INFO,
01278                                           GTK_BUTTONS_CLOSE,
01279                                           string
01280                                           );
01281 
01282        gtk_window_set_title ( GTK_WINDOW (aboutdialog1), _("About Gerbv"));
01283 
01284        /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
01285        g_signal_connect_swapped (aboutdialog1, "response",
01286                               G_CALLBACK (gtk_widget_destroy),
01287                               aboutdialog1);
01288        g_free (string);
01289 #endif
01290 
01291        gtk_widget_show_all(GTK_WIDGET(aboutdialog1));
01292 
01293 }
01294 
01295 /* --------------------------------------------------------- */
01296 gdouble callbacks_calculate_actual_distance (gdouble inputDimension) {
01297        gdouble returnValue = 0.0;
01298        
01299        if (screen.unit == GERBV_MILS) {
01300            returnValue = COORD2MILS(inputDimension);
01301        } else if (screen.unit == GERBV_MMS) {
01302            returnValue = COORD2MMS(inputDimension);
01303        } else {
01304            returnValue = COORD2MILS(inputDimension)/1000;
01305        }
01306        return returnValue;
01307 }
01308 
01309 /* --------------------------------------------------------- */
01310 void callbacks_update_ruler_pointers (void) {
01311        double xPosition, yPosition;
01312        xPosition = screenRenderInfo.lowerLeftX + (screen.last_x / screenRenderInfo.scaleFactorX);
01313        yPosition = screenRenderInfo.lowerLeftY + ((screenRenderInfo.displayHeight - screen.last_y) / screenRenderInfo.scaleFactorY);
01314 
01315        if (!((screen.unit == GERBV_MILS) && ((screenRenderInfo.scaleFactorX < 80)||(screenRenderInfo.scaleFactorY < 80)))) {
01316               xPosition = callbacks_calculate_actual_distance (xPosition);
01317               yPosition = callbacks_calculate_actual_distance (yPosition);
01318        }
01319        g_object_set (G_OBJECT (screen.win.hRuler), "position", xPosition, NULL);
01320        g_object_set (G_OBJECT (screen.win.vRuler), "position", yPosition, NULL);
01321 }
01322 
01323 /* --------------------------------------------------------- */
01324 void callbacks_update_ruler_scales (void) {
01325        double xStart, xEnd, yStart, yEnd;
01326 
01327        xStart = screenRenderInfo.lowerLeftX;
01328        yStart = screenRenderInfo.lowerLeftY;
01329        xEnd = screenRenderInfo.lowerLeftX + (screenRenderInfo.displayWidth / screenRenderInfo.scaleFactorX);
01330        yEnd = screenRenderInfo.lowerLeftY + (screenRenderInfo.displayHeight / screenRenderInfo.scaleFactorY);
01331        /* mils can get super crowded with large boards, but inches are too
01332           large for most boards.  So, we leave mils in for now and just switch
01333           to inches if the scale factor gets too small */
01334        if (!((screen.unit == GERBV_MILS) && ((screenRenderInfo.scaleFactorX < 80)||(screenRenderInfo.scaleFactorY < 80)))) {
01335               xStart = callbacks_calculate_actual_distance (xStart);
01336               xEnd = callbacks_calculate_actual_distance (xEnd);
01337               yStart = callbacks_calculate_actual_distance (yStart);
01338               yEnd = callbacks_calculate_actual_distance (yEnd);
01339        }
01340        /* make sure the widgets actually exist before setting (in case this gets
01341           called before everything is realized */
01342        if (screen.win.hRuler)
01343               gtk_ruler_set_range (GTK_RULER (screen.win.hRuler), xStart, xEnd, 0, xEnd - xStart);
01344        /* reverse y min and max, since the ruler starts at the top */
01345        if (screen.win.vRuler)
01346               gtk_ruler_set_range (GTK_RULER (screen.win.vRuler), yEnd, yStart, 0, yEnd - yStart);
01347 }
01348 
01349 /* --------------------------------------------------------- */
01350 void callbacks_update_scrollbar_limits (void){
01351 #ifdef RENDER_USING_GDK
01352        gerbv_render_info_t tempRenderInfo = {0, 0, 0, 0, 0, screenRenderInfo.displayWidth,
01353                      screenRenderInfo.displayHeight};
01354 #else
01355        gerbv_render_info_t tempRenderInfo = {0, 0, 0, 0, 3, screenRenderInfo.displayWidth,
01356                      screenRenderInfo.displayHeight};
01357 #endif
01358        GtkAdjustment *hAdjust = (GtkAdjustment *)screen.win.hAdjustment;
01359        GtkAdjustment *vAdjust = (GtkAdjustment *)screen.win.vAdjustment;
01360        
01361        gerbv_render_zoom_to_fit_display (mainProject, &tempRenderInfo);
01362        hAdjust->lower = tempRenderInfo.lowerLeftX;
01363        hAdjust->page_increment = hAdjust->page_size;
01364        hAdjust->step_increment = hAdjust->page_size / 10.0;
01365        vAdjust->lower = tempRenderInfo.lowerLeftY;
01366        vAdjust->page_increment = vAdjust->page_size;
01367        vAdjust->step_increment = vAdjust->page_size / 10.0;
01368        hAdjust->upper = tempRenderInfo.lowerLeftX + (tempRenderInfo.displayWidth / tempRenderInfo.scaleFactorX);
01369        hAdjust->page_size = screenRenderInfo.displayWidth / screenRenderInfo.scaleFactorX;
01370        vAdjust->upper = tempRenderInfo.lowerLeftY + (tempRenderInfo.displayHeight / tempRenderInfo.scaleFactorY);
01371        vAdjust->page_size = screenRenderInfo.displayHeight / screenRenderInfo.scaleFactorY;
01372        callbacks_update_scrollbar_positions ();
01373 }
01374 
01375 /* --------------------------------------------------------- */
01376 void callbacks_update_scrollbar_positions (void){
01377        gdouble positionX,positionY;
01378        
01379        positionX = screenRenderInfo.lowerLeftX;
01380        if (positionX < ((GtkAdjustment *)screen.win.hAdjustment)->lower)
01381               positionX = ((GtkAdjustment *)screen.win.hAdjustment)->lower;
01382        if (positionX > (((GtkAdjustment *)screen.win.hAdjustment)->upper - ((GtkAdjustment *)screen.win.hAdjustment)->page_size))
01383               positionX = (((GtkAdjustment *)screen.win.hAdjustment)->upper - ((GtkAdjustment *)screen.win.hAdjustment)->page_size);
01384        
01385        gtk_adjustment_set_value ((GtkAdjustment *)screen.win.hAdjustment, positionX);
01386        positionY = ((GtkAdjustment *)screen.win.vAdjustment)->upper - (screenRenderInfo.lowerLeftY + (screenRenderInfo.displayHeight / screenRenderInfo.scaleFactorY));
01387        if (positionY < ((GtkAdjustment *)screen.win.vAdjustment)->lower)
01388               positionY = ((GtkAdjustment *)screen.win.vAdjustment)->lower;
01389        if (positionY > (((GtkAdjustment *)screen.win.vAdjustment)->upper - ((GtkAdjustment *)screen.win.vAdjustment)->page_size))
01390               positionY = (((GtkAdjustment *)screen.win.vAdjustment)->upper - ((GtkAdjustment *)screen.win.vAdjustment)->page_size);
01391        gtk_adjustment_set_value ((GtkAdjustment *)screen.win.vAdjustment, positionY);
01392 
01393 }
01394 
01395 /* --------------------------------------------------------- */
01396 gboolean
01397 callbacks_scrollbar_button_released (GtkWidget *widget, GdkEventButton *event){
01398        screen.off_x = 0;
01399        screen.off_y = 0;
01400        screen.state = NORMAL;
01401        render_refresh_rendered_image_on_screen();
01402        return FALSE;
01403 }
01404 
01405 /* --------------------------------------------------------- */
01406 gboolean
01407 callbacks_scrollbar_button_pressed (GtkWidget *widget, GdkEventButton *event){
01408        //screen.last_x = ((GtkAdjustment *)screen.win.hAdjustment)->value;
01409        screen.state = SCROLLBAR;
01410        return FALSE;
01411 }
01412 
01413 /* --------------------------------------------------------- */
01414 void callbacks_hadjustment_value_changed (GtkAdjustment *adjustment, gpointer user_data){
01415        /* make sure we're actually using the scrollbar to make sure we don't reset
01416           lowerLeftX during a scrollbar redraw during something else */
01417        if (screen.state == SCROLLBAR) {
01418               screenRenderInfo.lowerLeftX = gtk_adjustment_get_value (adjustment);
01419        }
01420 }
01421 
01422 /* --------------------------------------------------------- */
01423 void callbacks_vadjustment_value_changed (GtkAdjustment *adjustment, gpointer user_data){
01424        /* make sure we're actually using the scrollbar to make sure we don't reset
01425           lowerLeftY during a scrollbar redraw during something else */
01426        if (screen.state == SCROLLBAR) {
01427               screenRenderInfo.lowerLeftY = adjustment->upper - gtk_adjustment_get_value (adjustment) - (screenRenderInfo.displayHeight / screenRenderInfo.scaleFactorY);             
01428        }
01429 }
01430 
01431 /* --------------------------------------------------------- */
01432 void
01433 callbacks_layer_tree_visibility_button_toggled (GtkCellRendererToggle *cell_renderer,
01434                                                         gchar *path,
01435                                                         gpointer user_data){
01436        GtkListStore *list_store = (GtkListStore *) gtk_tree_view_get_model
01437                      ((GtkTreeView *) screen.win.layerTree);
01438        GtkTreeIter iter;
01439        gboolean newVisibility=TRUE;
01440        gint index;
01441        
01442        gtk_tree_model_get_iter_from_string ((GtkTreeModel *)list_store, &iter, path);
01443        
01444        GtkTreePath *treePath = gtk_tree_path_new_from_string (path);
01445        if (gtk_tree_model_get_iter((GtkTreeModel *)list_store, &iter, treePath)) {
01446              gint *indeces;
01447              
01448              indeces = gtk_tree_path_get_indices (treePath);
01449              index = indeces[0];
01450               if (mainProject->file[index]->isVisible)
01451                       newVisibility = FALSE;
01452               mainProject->file[index]->isVisible = newVisibility;
01453 
01454              callbacks_update_layer_tree ();
01455               if (screenRenderInfo.renderType < 2) {
01456                      render_refresh_rendered_image_on_screen();
01457               }
01458 #ifndef RENDER_USING_GDK
01459               else {
01460                      render_recreate_composite_surface (screen.drawing_area);
01461                      callbacks_force_expose_event_for_screen ();
01462               }
01463 #endif 
01464        }
01465 }
01466 
01467 /* --------------------------------------------------------- */
01468 gint
01469 callbacks_get_col_number_from_tree_view_column (GtkTreeViewColumn *col)
01470 {
01471        GList *cols;
01472        gint   num;
01473        
01474        g_return_val_if_fail ( col != NULL, -1 );
01475        g_return_val_if_fail ( col->tree_view != NULL, -1 );
01476        cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(col->tree_view));
01477        num = g_list_index(cols, (gpointer) col);
01478        g_list_free(cols);
01479        return num;
01480 }
01481 
01482 /* --------------------------------------------------------- */
01483 void
01484 callbacks_add_layer_button_clicked  (GtkButton *button, gpointer   user_data) {
01485        callbacks_open_layer_activate (NULL, NULL);
01486 }
01487 
01488 /* --------------------------------------------------------- */
01489 void
01490 callbacks_unselect_all_tool_buttons (void) {
01491 
01492 }
01493 
01494 void
01495 callbacks_switch_to_normal_tool_cursor (gint toolNumber) {
01496        GdkCursor *cursor;
01497 
01498        switch (toolNumber) {
01499               case POINTER:
01500                      gdk_window_set_cursor(GDK_WINDOW(screen.drawing_area->window),
01501                                             GERBV_DEF_CURSOR);
01502                      break;
01503               case PAN:
01504                      cursor = gdk_cursor_new(GDK_FLEUR);
01505                      gdk_window_set_cursor(GDK_WINDOW(screen.drawing_area->window),
01506                                      cursor);
01507                      gdk_cursor_destroy(cursor);
01508                      break;
01509               case ZOOM:
01510                      cursor = gdk_cursor_new(GDK_SIZING);
01511                      gdk_window_set_cursor(GDK_WINDOW(screen.drawing_area->window),
01512                                          cursor);
01513                      gdk_cursor_destroy(cursor);
01514                      break;
01515               case MEASURE:
01516                      cursor = gdk_cursor_new(GDK_CROSSHAIR);
01517                      gdk_window_set_cursor(GDK_WINDOW(screen.drawing_area->window),
01518                                      cursor);
01519                      gdk_cursor_destroy(cursor);
01520                      break;
01521               default:
01522                      break;
01523        }
01524 }
01525 
01526 /* --------------------------------------------------------- */
01527 void
01528 callbacks_switch_to_correct_cursor (void) {
01529        GdkCursor *cursor;
01530 
01531        if (screen.state == IN_MOVE) {
01532               cursor = gdk_cursor_new(GDK_FLEUR);
01533               gdk_window_set_cursor(GDK_WINDOW(screen.drawing_area->window),
01534                               cursor);
01535               gdk_cursor_destroy(cursor);
01536               return;
01537        }
01538        else if (screen.state == IN_ZOOM_OUTLINE) {
01539               cursor = gdk_cursor_new(GDK_SIZING);
01540               gdk_window_set_cursor(GDK_WINDOW(screen.drawing_area->window),
01541                               cursor);
01542               gdk_cursor_destroy(cursor);
01543               return;
01544        }
01545        callbacks_switch_to_normal_tool_cursor (screen.tool);
01546 }
01547 
01548 /* --------------------------------------------------------- */
01549 void
01550 callbacks_change_tool (GtkButton *button, gpointer   user_data) {
01551        gint toolNumber = GPOINTER_TO_INT (user_data);
01552        
01553        /* make sure se don't get caught in endless recursion here */
01554        if (screen.win.updatingTools)
01555               return;
01556        screen.win.updatingTools = TRUE;
01557 #ifndef RENDER_USING_GDK
01558        gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen.win.toolButtonPointer), FALSE);
01559 #endif
01560        gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen.win.toolButtonPan), FALSE);
01561        gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen.win.toolButtonZoom), FALSE);
01562        gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen.win.toolButtonMeasure), FALSE);
01563        switch (toolNumber) {
01564               case POINTER:
01565                      gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen.win.toolButtonPointer), TRUE);
01566                      screen.tool = POINTER;
01567                      screen.state = NORMAL;
01568                      snprintf(screen.statusbar.diststr, MAX_DISTLEN, 
01569                              "Click to select. Middle click and drag to pan.");
01570                      break;
01571               case PAN:
01572                      gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen.win.toolButtonPan), TRUE);
01573                      screen.tool = PAN;
01574                      screen.state = NORMAL;
01575                      snprintf(screen.statusbar.diststr, MAX_DISTLEN, 
01576                              "Click and drag to pan. Right click and drag to zoom.");
01577                      break;
01578               case ZOOM:
01579                      gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen.win.toolButtonZoom), TRUE);
01580                      screen.tool = ZOOM;
01581                      screen.state = NORMAL;
01582                      snprintf(screen.statusbar.diststr, MAX_DISTLEN, 
01583                              "Click and drag to zoom in. Shift+click to zoom out.");
01584                      break;
01585               case MEASURE:
01586                      gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen.win.toolButtonMeasure), TRUE);
01587                      screen.tool = MEASURE;
01588                      screen.state = NORMAL;
01589                      snprintf(screen.statusbar.diststr, MAX_DISTLEN, "Click and drag to measure a distance.");
01590                      break;
01591               default:
01592                      break;
01593        }
01594        callbacks_switch_to_normal_tool_cursor (toolNumber);
01595        callbacks_update_statusbar();
01596        screen.win.updatingTools = FALSE;
01597        callbacks_force_expose_event_for_screen();
01598 }
01599 
01600 /* --------------------------------------------------------- */
01601 void
01602 callbacks_select_row (gint rowIndex) {
01603        GtkTreeSelection *selection;
01604        GtkTreeIter       iter;
01605        GtkListStore *list_store = (GtkListStore *) gtk_tree_view_get_model
01606                      ((GtkTreeView *) screen.win.layerTree);
01607 
01608        selection = gtk_tree_view_get_selection((GtkTreeView *) screen.win.layerTree);
01609        if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, rowIndex)) {
01610               gtk_tree_selection_select_iter (selection, &iter);
01611        }
01612 }
01613 
01614 /* --------------------------------------------------------- */
01620 gint
01621 callbacks_get_selected_row_index  (void) {
01622        GtkTreeSelection *selection;
01623        GtkTreeIter       iter;
01624        GtkListStore *list_store = (GtkListStore *) gtk_tree_view_get_model
01625                      ((GtkTreeView *) screen.win.layerTree);
01626        gint index=-1,i=0;
01627        
01628        /* This will only work in single or browse selection mode! */
01629        selection = gtk_tree_view_get_selection((GtkTreeView *) screen.win.layerTree);
01630        if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
01631               while (gtk_tree_model_iter_nth_child ((GtkTreeModel *)list_store,
01632                             &iter, NULL, i)){
01633                      if (gtk_tree_selection_iter_is_selected (selection, &iter)) {
01634                             return i;
01635                      }
01636                      i++;
01637               }      
01638        }
01639        return index;
01640 }
01641 
01642 /* --------------------------------------------------------- */
01643 void
01644 callbacks_remove_layer_button_clicked  (GtkButton *button, gpointer   user_data) {
01645        gint index=callbacks_get_selected_row_index();
01646        
01647        if ((index >= 0) && (index <= mainProject->last_loaded)) {
01648               gerbv_unload_layer (mainProject, index);
01649              callbacks_update_layer_tree ();
01650              callbacks_select_row (0);
01651 
01652               if (screenRenderInfo.renderType < 2) {
01653                      render_refresh_rendered_image_on_screen();
01654               }
01655 #ifndef RENDER_USING_GDK
01656               else {
01657                      render_recreate_composite_surface (screen.drawing_area);
01658                      callbacks_force_expose_event_for_screen ();
01659               }
01660 #endif 
01661        }
01662 }
01663 
01664 /* --------------------------------------------------------- */
01665 void
01666 callbacks_move_layer_down_button_clicked  (GtkButton *button, gpointer   user_data) {
01667        gint index=callbacks_get_selected_row_index();
01668        
01669        if ((index >= 0) && (index < mainProject->last_loaded)) {
01670               gerbv_change_layer_order (mainProject, index, index + 1);
01671              callbacks_update_layer_tree ();
01672              callbacks_select_row (index + 1);
01673               if (screenRenderInfo.renderType < 2) {
01674                      render_refresh_rendered_image_on_screen();
01675               }
01676 #ifndef RENDER_USING_GDK
01677               else {
01678                      render_recreate_composite_surface (screen.drawing_area);
01679                      callbacks_force_expose_event_for_screen ();
01680               }
01681 #endif 
01682        }
01683 }
01684 
01685 /* --------------------------------------------------------- */
01686 void
01687 callbacks_move_layer_up_clicked  (GtkButton *button, gpointer   user_data) {
01688        gint index=callbacks_get_selected_row_index();
01689        
01690        if (index > 0) {
01691               gerbv_change_layer_order (mainProject, index, index - 1);
01692               callbacks_update_layer_tree ();
01693               callbacks_select_row (index - 1);
01694               if (screenRenderInfo.renderType < 2) {
01695                      render_refresh_rendered_image_on_screen();
01696               }
01697 #ifndef RENDER_USING_GDK
01698               else {
01699                      render_recreate_composite_surface (screen.drawing_area);
01700                      callbacks_force_expose_event_for_screen ();
01701               }
01702 #endif 
01703        }
01704 }
01705 
01706 /* --------------------------------------------------------- */
01707 void callbacks_layer_tree_row_inserted (GtkTreeModel *tree_model, GtkTreePath  *path,
01708                               GtkTreeIter  *oIter, gpointer user_data) {
01709        gint *indeces=NULL,oldPosition,newPosition;
01710       
01711        if ((!screen.win.treeIsUpdating)&&(path != NULL)) {
01712               indeces = gtk_tree_path_get_indices (path);
01713               if (indeces) {
01714                      newPosition = indeces[0];
01715                      oldPosition = callbacks_get_selected_row_index ();
01716                      /* compensate for the fact that the old row has already
01717                         been removed */
01718                      if (oldPosition < newPosition)
01719                             newPosition--;
01720                      else
01721                             oldPosition--;
01722                      gerbv_change_layer_order (mainProject, oldPosition, newPosition);
01723 
01724                      if (screenRenderInfo.renderType < 2) {
01725                             render_refresh_rendered_image_on_screen();
01726                      }
01727 #ifndef RENDER_USING_GDK
01728                      else {
01729                             render_recreate_composite_surface (screen.drawing_area);
01730                             callbacks_force_expose_event_for_screen ();
01731                      }
01732 #endif        
01733                      /* select the new line */
01734                      GtkTreeSelection *selection;
01735                      GtkTreeIter iter;
01736                      GtkListStore *list_store = (GtkListStore *) gtk_tree_view_get_model
01737                             ((GtkTreeView *) screen.win.layerTree);
01738                      
01739                      selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(screen.win.layerTree));
01740                      if (gtk_tree_model_get_iter ((GtkTreeModel *)list_store, &iter, path))
01741                             gtk_tree_selection_select_iter (selection, &iter);
01742               }
01743        }
01744 }
01745 
01746 /* --------------------------------------------------------- */
01747 void
01748 callbacks_show_color_picker_dialog (gint index){
01749        screen.win.colorSelectionDialog = NULL;
01750        GtkColorSelectionDialog *cs= (GtkColorSelectionDialog *) gtk_color_selection_dialog_new ("Select a color");
01751        GtkColorSelection *colorsel = (GtkColorSelection *) cs->colorsel;
01752        
01753        screen.win.colorSelectionDialog = (GtkWidget *) cs;
01754        screen.win.colorSelectionIndex = index;
01755        gtk_color_selection_set_current_color (colorsel, &mainProject->file[index]->color);
01756 #ifndef RENDER_USING_GDK
01757        if (screenRenderInfo.renderType >= 2) {
01758               gtk_color_selection_set_has_opacity_control (colorsel, TRUE);
01759               gtk_color_selection_set_current_alpha (colorsel, mainProject->file[index]->alpha);
01760        }
01761 #endif
01762        gtk_widget_show_all((GtkWidget *)cs);
01763        if (gtk_dialog_run ((GtkDialog*)cs) == GTK_RESPONSE_OK) {
01764               GtkColorSelection *colorsel = (GtkColorSelection *) cs->colorsel;
01765               gint rowIndex = screen.win.colorSelectionIndex;
01766               
01767               gtk_color_selection_get_current_color (colorsel, &mainProject->file[rowIndex]->color);
01768               if (screenRenderInfo.renderType >= 2) {
01769                      mainProject->file[rowIndex]->alpha = gtk_color_selection_get_current_alpha (colorsel);
01770               }
01771               gdk_colormap_alloc_color(gdk_colormap_get_system(), &mainProject->file[rowIndex]->color, FALSE, TRUE);
01772               callbacks_update_layer_tree ();
01773               render_refresh_rendered_image_on_screen();
01774        }
01775        gtk_widget_destroy ((GtkWidget *)cs);
01776        screen.win.colorSelectionDialog = NULL;
01777 }
01778 
01779 /* --------------------------------------------------------- */
01780 void
01781 callbacks_invert_layer_clicked  (GtkButton *button, gpointer   user_data) {
01782        gint index=callbacks_get_selected_row_index();
01783        
01784        mainProject->file[index]->transform.inverted = !mainProject->file[index]->transform.inverted;
01785        render_refresh_rendered_image_on_screen ();
01786        callbacks_update_layer_tree ();
01787 }
01788 
01789 /* --------------------------------------------------------- */
01790 void
01791 callbacks_change_layer_color_clicked  (GtkButton *button, gpointer   user_data) {
01792        gint index=callbacks_get_selected_row_index();
01793 
01794        callbacks_show_color_picker_dialog (index);
01795 }
01796 
01797 /* --------------------------------------------------------------------------- */                               
01798 void
01799 callbacks_reload_layer_clicked  (GtkButton *button, gpointer   user_data) {
01800        gint index = callbacks_get_selected_row_index();
01801        gerbv_revert_file (mainProject, index);
01802        render_refresh_rendered_image_on_screen ();
01803 }
01804 
01805 /* --------------------------------------------------------------------------- */
01806 void
01807 callbacks_change_layer_format_clicked  (GtkButton *button, gpointer   user_data)
01808 {
01809     gerbv_HID_Attribute *attr = NULL;
01810     int n = 0;
01811     int i;
01812     gerbv_HID_Attr_Val * results = NULL;
01813     gint index = callbacks_get_selected_row_index();
01814     gchar *type;
01815 
01816     dprintf ("%s(): index = %d\n", __FUNCTION__, index);
01817     attr = mainProject->file[index]->image->info->attr_list;
01818     n =  mainProject->file[index]->image->info->n_attr;
01819     type =  mainProject->file[index]->image->info->type;
01820     if (type == NULL) 
01821        type = "Unknown";
01822 
01823     if (attr == NULL || n == 0) 
01824        {
01825          interface_show_alert_dialog("This file type does not currently have any editable features", 
01826                                   "Format editing is currently only supported for Excellon drill file formats.",
01827                                   FALSE,
01828                                   NULL);
01829          return;
01830        }
01831 
01832     dprintf ("%s(): n = %d, attr = %p\n", __FUNCTION__, n, attr);
01833     if (n > 0)
01834        {
01835            results = (gerbv_HID_Attr_Val *) malloc (n * sizeof (gerbv_HID_Attr_Val));
01836            if (results == NULL)
01837               {
01838                   fprintf (stderr, "%s() -- malloc failed\n", __FUNCTION__);
01839                   exit (1);
01840               }
01841       
01842            /* non-zero means cancel was picked */
01843            if (attribute_interface_dialog (attr, n, results, 
01844                                        "Edit file format", 
01845                                        type))
01846               {
01847                   return;
01848               }
01849           
01850     }
01851 
01852     dprintf ("%s():  Reloading layer\n", __FUNCTION__);
01853     gerbv_revert_file (mainProject, index);
01854 
01855     for (i = 0; i < n; i++)
01856        {
01857            if (results[i].str_value)
01858               free (results[i].str_value);
01859        }
01860     
01861     if (results)
01862        free (results);
01863     render_refresh_rendered_image_on_screen();
01864 }
01865 
01866 /* --------------------------------------------------------------------------- */
01867 gboolean
01868 callbacks_layer_tree_button_press (GtkWidget *widget, GdkEventButton *event,
01869                                    gpointer user_data) {
01870       GtkTreePath *path;
01871       GtkTreeIter iter;
01872       GtkTreeViewColumn *column;
01873       gint x,y;
01874       gint columnIndex;
01875       
01876       GtkListStore *list_store = (GtkListStore *) gtk_tree_view_get_model
01877                      ((GtkTreeView *) screen.win.layerTree);
01878       if (event->button == 1) {
01879              if (gtk_tree_view_get_path_at_pos  ((GtkTreeView *) widget, event->x, event->y,
01880               &path, &column, &x, &y)) {
01881                     if (gtk_tree_model_get_iter((GtkTreeModel *)list_store, &iter, path)) {
01882                      gint *indeces;
01883                      indeces = gtk_tree_path_get_indices (path);
01884                      if (indeces) {
01885                                    columnIndex = callbacks_get_col_number_from_tree_view_column (column);
01886                                    if ((columnIndex == 1) && (indeces[0] <= mainProject->last_loaded)){
01887                                           callbacks_show_color_picker_dialog (indeces[0]);
01888                                           /* don't propagate the signal, since drag and drop can
01889                                           sometimes activated during color selection */
01890                                           return TRUE;
01891                                    }
01892                             }
01893                      }
01894               }
01895        }
01896        /* don't pop up the menu if we don't have any loaded files */
01897        else if ((event->button == 3)&&(mainProject->last_loaded >= 0)) {
01898               gtk_menu_popup(GTK_MENU(screen.win.layerTreePopupMenu), NULL, NULL, NULL, NULL, 
01899                         event->button, event->time);
01900        }
01901        /* always allow the click to propagate and make sure the line is activated */
01902        return FALSE;
01903 }
01904 
01905 /* --------------------------------------------------------------------------- */
01906 void
01907 callbacks_update_layer_tree (void) {
01908        GtkListStore *list_store = (GtkListStore *) gtk_tree_view_get_model
01909                      ((GtkTreeView *) screen.win.layerTree);
01910        gint idx;
01911        GtkTreeIter iter;
01912        GtkTreeSelection *selection;
01913        gint oldSelectedRow;
01914        
01915        if (!screen.win.treeIsUpdating) {
01916               screen.win.treeIsUpdating = TRUE;
01917               
01918               oldSelectedRow = callbacks_get_selected_row_index();
01919               if (oldSelectedRow < 0)
01920                      oldSelectedRow = 0;
01921               gtk_list_store_clear (list_store);
01922 
01923               for (idx = 0; idx < mainProject->max_files; idx++) {
01924                      if (mainProject->file[idx]) {
01925                             GdkPixbuf    *pixbuf,*blackPixbuf;
01926                             guint32 color;
01927                             
01928                             unsigned char red, green, blue, alpha;
01929                             
01930                             red = (unsigned char) (mainProject->file[idx]->color.red * 255 / G_MAXUINT16) ;
01931                             green = (unsigned char) (mainProject->file[idx]->color.green * 255 / G_MAXUINT16) ;
01932                             blue = (unsigned char) (mainProject->file[idx]->color.blue *255 / G_MAXUINT16) ;
01933                             alpha = (unsigned char) (mainProject->file[idx]->alpha * 255 / G_MAXUINT16) ;
01934                             
01935                             color = (red )* (256*256*256) + (green ) * (256*256) + (blue )* (256) + (alpha );
01936                             pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 20, 15);
01937                             gdk_pixbuf_fill (pixbuf, color);
01938                             
01939                             blackPixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 20, 15);
01940                             color = (100 )* (256*256*256) + (100 ) * (256*256) + (100 )* (256) + (150 );
01941                             gdk_pixbuf_fill (blackPixbuf, color);
01942                             
01943                             /* copy the color area into the black pixbuf */
01944                             gdk_pixbuf_copy_area  (pixbuf, 1, 1, 18, 13, blackPixbuf, 1, 1);
01945                             /* free the color buffer, since we don't need it anymore */
01946                             g_object_unref(pixbuf);
01947                         
01948                             gtk_list_store_append (list_store, &iter);
01949                             
01950                             gchar *modifiedCode;
01951                             if (mainProject->file[idx]->transform.inverted) {
01952                                    modifiedCode = g_strdup ("I");
01953                             }
01954                             else
01955                                    modifiedCode = g_strdup ("");
01956                             
01957                             /* display any unsaved layers differently to show the user they are
01958                                unsaved */
01959                             gchar *layerName;
01960                             if (mainProject->file[idx]->layer_dirty == TRUE) {
01961                               /* The layer has unsaved changes in it. Show layer name in italics. */
01962                               layerName = g_strconcat ("*","<i>",mainProject->file[idx]->name,"</i>",NULL);
01963                             }
01964                             else
01965                               /* layer is clean.  Show layer name using normal font. */
01966                               layerName = g_strdup (mainProject->file[idx]->name);
01967                             
01968                             gtk_list_store_set (list_store, &iter,
01969                                                  0, mainProject->file[idx]->isVisible,
01970                                                  1, blackPixbuf,
01971                                              2, layerName,
01972                                              3, modifiedCode,
01973                                              -1);
01974                            g_free (layerName);
01975                            g_free (modifiedCode);
01976                            /* pixbuf has a refcount of 2 now, as the list store has added its own reference */
01977                            g_object_unref(blackPixbuf);
01978                      }
01979               }
01980               
01981               selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(screen.win.layerTree));
01982               
01983               /* if no line is selected yet, select the first row (if it has data) */
01984               /* or, select the line that was previously selected */
01985               
01986               if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
01987                      if (gtk_tree_model_iter_nth_child ((GtkTreeModel *) list_store,
01988                                                  &iter, NULL, oldSelectedRow)) {
01989                             gtk_tree_selection_select_iter (selection, &iter);
01990                      }
01991               }
01992               screen.win.treeIsUpdating = FALSE;
01993        }
01994 }
01995 
01996 /* --------------------------------------------------------------------------- */
01997 void
01998 callbacks_display_object_properties_clicked (GtkButton *button, gpointer   user_data){
01999        int i;
02000        gchar *layer_name;
02001        gchar *net_label;
02002        gboolean validAperture;
02003 
02004 #ifndef RENDER_USING_GDK
02005 
02006        gint index=callbacks_get_selected_row_index();
02007        if (index < 0)
02008               return;
02009 
02010        for (i=0; i<screen.selectionInfo.selectedNodeArray->len; i++){
02011               gerbv_selection_item_t sItem = g_array_index (screen.selectionInfo.selectedNodeArray,
02012                                             gerbv_selection_item_t, i);
02013 
02014               gerbv_net_t *net = sItem.net;
02015               gerbv_image_t *image = sItem.image;
02016               int ap_type=0;
02017 
02018               /* get the aperture definition for the selected item */
02019               if (net->aperture > 0) {
02020                      ap_type = image->aperture[net->aperture]->type;
02021                      validAperture = TRUE;
02022               }
02023               else {
02024                      validAperture = FALSE;
02025               }
02026 
02027               /* Also get layer name specified in file by %LN directive
02028               * (if it exists).  */
02029               if (net->layer->name == NULL) {
02030                      layer_name = g_strdup("<unnamed layer>");
02031               } else {
02032                      layer_name = g_strdup(net->layer->name);
02033               }
02034 
02035               if (net->label == NULL) {
02036                      net_label = g_strdup("<unlabeled net>");
02037               } else {
02038                      net_label = g_strdup((gchar *)net->label);
02039               }
02040               if (net->interpolation == GERBV_INTERPOLATION_PAREA_START) {
02041                      g_message ("Object type: Polygon\n");
02042               }
02043               else {
02044                      switch (net->aperture_state){
02045                             case GERBV_APERTURE_STATE_OFF:
02046                                    break;
02047                             case GERBV_APERTURE_STATE_ON:
02048                                    if (i!=0) g_message ("\n");  /* Spacing for a pretty display */
02049                                    switch (net->interpolation) {
02050                                           case GERBV_INTERPOLATION_x10 :
02051                                           case GERBV_INTERPOLATION_LINEARx01 :
02052                                           case GERBV_INTERPOLATION_LINEARx001 :
02053                                           case GERBV_INTERPOLATION_LINEARx1 :
02054                                                  g_message ("Object type: Line\n");
02055                                                  break;
02056                                           case GERBV_INTERPOLATION_CW_CIRCULAR :
02057                                           case GERBV_INTERPOLATION_CCW_CIRCULAR :
02058                                                  g_message ("Object type: Arc\n");
02059                                                  break;
02060                                           default :
02061                                                  g_message ("Object type: Unknown\n");
02062                                                  break;
02063                                    }
02064                                    g_message ("    Exposure: On\n");
02065                                    if (validAperture) {
02066                                           g_message ("    Aperture used: D%d\n", net->aperture);
02067                                           g_message ("    Aperture type: %s\n", ap_names[ap_type]);
02068                                    }
02069                                    g_message ("    Start location: (%g, %g)\n", net->start_x, net->start_y);
02070                                    g_message ("    Stop location: (%g, %g)\n", net->stop_x, net->stop_y);
02071                                    g_message ("    Layer name: %s\n", layer_name);
02072                                    g_message ("    Net label: %s\n", net_label);
02073                                    g_message ("    In file: %s\n", mainProject->file[index]->name);
02074                                    break;
02075                             case GERBV_APERTURE_STATE_FLASH:
02076                                    if (i!=0) g_message ("\n");  /* Spacing for a pretty display */
02077                                    g_message ("Object type: Flashed aperture\n");
02078                                    if (validAperture) {
02079                                           g_message ("    Aperture used: D%d\n", net->aperture);
02080                                           g_message ("    Aperture type: %s\n", ap_names[ap_type]);
02081                                    }
02082                                    g_message ("    Location: (%g, %g)\n", net->stop_x, net->stop_y);
02083                                    g_message ("    Layer name: %s\n", layer_name);
02084                                    g_message ("    Net label: %s\n", net_label);
02085                                    g_message ("    In file: %s\n", mainProject->file[index]->name);
02086                                    break;
02087                      }
02088               }
02089               g_free (net_label);
02090               g_free (layer_name);
02091        }
02092        /* Use separator for different report requests */
02093        g_message ("---------------------------------------\n");
02094 #endif
02095 }
02096 
02097 /* --------------------------------------------------------------------------- */
02098 void
02099 callbacks_edit_object_properties_clicked (GtkButton *button, gpointer   user_data){
02100 }
02101 
02102 /* --------------------------------------------------------------------------- */
02103 void
02104 callbacks_move_objects_clicked (GtkButton *button, gpointer   user_data){
02105 #ifndef RENDER_USING_GDK
02106        /* for testing, just hard code in some translations here */
02107        gerbv_image_move_selected_objects (screen.selectionInfo.selectedNodeArray, -0.050, 0.050);
02108        callbacks_update_layer_tree();
02109        render_clear_selection_buffer ();
02110        render_refresh_rendered_image_on_screen ();
02111 #endif
02112 }
02113 
02114 /* --------------------------------------------------------------------------- */
02115 void
02116 callbacks_reduce_object_area_clicked  (GtkButton *button, gpointer user_data){
02117 #ifndef RENDER_USING_GDK
02118        /* for testing, just hard code in some parameters */
02119        gerbv_image_reduce_area_of_selected_objects (screen.selectionInfo.selectedNodeArray, 0.20, 3, 3, 0.01);
02120        render_clear_selection_buffer ();
02121        render_refresh_rendered_image_on_screen ();
02122 #endif
02123 }
02124 
02125 /* --------------------------------------------------------------------------- */
02126 void
02127 callbacks_delete_objects_clicked (GtkButton *button, gpointer   user_data){
02128 #ifndef RENDER_USING_GDK
02129        if (screen.selectionInfo.type == GERBV_SELECTION_EMPTY) {
02130               interface_show_alert_dialog("No object is currently selected",
02131                                       NULL,
02132                                       FALSE,
02133                                       NULL);
02134               return;
02135        }
02136 
02137        gint index=callbacks_get_selected_row_index();
02138        if (index < 0)
02139               return;
02140 
02141        if (mainProject->check_before_delete == TRUE) {
02142               if (!interface_get_alert_dialog_response(
02143                                                "Do you want to permanently delete the selected objects?",
02144                                                "Gerbv currently has no undo function, so this action cannot be undone. This action will not change the saved file unless you save the file afterwards.",
02145                                                TRUE,
02146                                                &(mainProject->check_before_delete)))
02147               return;
02148        }
02149 
02150        gerbv_image_delete_selected_nets (mainProject->file[index]->image,
02151                                 screen.selectionInfo.selectedNodeArray); 
02152        render_refresh_rendered_image_on_screen ();
02153        /* Set layer_dirty flag to TRUE */
02154        mainProject->file[index]->layer_dirty = TRUE;
02155        callbacks_update_layer_tree();
02156 
02157        render_clear_selection_buffer ();
02158 #endif
02159 }
02160 
02161 /* --------------------------------------------------------------------------- */
02162 gboolean
02163 callbacks_drawingarea_configure_event (GtkWidget *widget, GdkEventConfigure *event)
02164 {
02165        GdkDrawable *drawable = widget->window;
02166        
02167        gdk_drawable_get_size (drawable, &screenRenderInfo.displayWidth, &screenRenderInfo.displayHeight);
02168 
02169 #ifndef RENDER_USING_GDK
02170        /* set this up if cairo is compiled, since we may need to switch over to
02171           using the surface at any time */
02172        int x_off=0, y_off=0;
02173        GdkVisual *visual;
02174        
02175        if (GDK_IS_WINDOW(widget->window)) {
02176              /* query the window's backbuffer if it has one */
02177               GdkWindow *window = GDK_WINDOW(widget->window);
02178              gdk_window_get_internal_paint_info (window, &drawable, &x_off, &y_off);
02179        }
02180        visual = gdk_drawable_get_visual (drawable);
02181        if (!screen.windowSurface) {
02182 #ifdef WIN32
02183               cairo_t *cairoTarget = gdk_cairo_create (GDK_WINDOW(widget->window));
02184               
02185               screen.windowSurface = cairo_get_target (cairoTarget);
02186               /* increase surface reference by one so it isn't freed when the cairo_t
02187                  is destroyed next */
02188               screen.windowSurface = cairo_surface_reference (screen.windowSurface);
02189               cairo_destroy (cairoTarget);
02190 #else
02191               screen.windowSurface = (gpointer) cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable),
02192                                                  GDK_DRAWABLE_XID (drawable),
02193                                                  GDK_VISUAL_XVISUAL (visual),
02194                                                  screenRenderInfo.displayWidth,
02195                                                  screenRenderInfo.displayHeight);
02196 #endif
02197 
02198        }
02199 #endif
02200        /* if this is the first time, go ahead and call autoscale even if we don't
02201           have a model loaded */
02202        if ((screenRenderInfo.scaleFactorX < 0.001)||(screenRenderInfo.scaleFactorY < 0.001)) {
02203               gerbv_render_zoom_to_fit_display (mainProject, &screenRenderInfo);
02204        }
02205        render_refresh_rendered_image_on_screen();
02206        return TRUE;
02207 }
02208 
02209 /* --------------------------------------------------------- */
02210 gboolean
02211 callbacks_drawingarea_expose_event (GtkWidget *widget, GdkEventExpose *event)
02212 {
02213        if (screenRenderInfo.renderType < 2) {
02214               GdkPixmap *new_pixmap;
02215               GdkGC *gc = gdk_gc_new(widget->window);
02216 
02217               /*
02218               * Create a pixmap with default background
02219               */
02220               new_pixmap = gdk_pixmap_new(widget->window,
02221                                    widget->allocation.width,
02222                                    widget->allocation.height,
02223                                    -1);
02224 
02225               gdk_gc_set_foreground(gc, &mainProject->background);
02226 
02227               gdk_draw_rectangle(new_pixmap, gc, TRUE, 
02228                             event->area.x, event->area.y,
02229                             event->area.width, event->area.height);
02230 
02231               /*
02232               * Copy gerber pixmap onto background if we have one to copy.
02233               * Do translation at the same time.
02234               */
02235               if (screen.pixmap != NULL) {
02236               gdk_draw_pixmap(new_pixmap,
02237                             widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
02238                             screen.pixmap, 
02239                             event->area.x - screen.off_x, 
02240                             event->area.y - screen.off_y, 
02241                             event->area.x, event->area.y,
02242                             event->area.width, event->area.height);
02243               }
02244 
02245               /*
02246               * Draw the whole thing onto screen
02247               */
02248               gdk_draw_pixmap(widget->window,
02249                          widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
02250                          new_pixmap,
02251                          event->area.x, event->area.y,
02252                          event->area.x, event->area.y,
02253                          event->area.width, event->area.height);
02254 
02255               gdk_pixmap_unref(new_pixmap);
02256               gdk_gc_unref(gc);
02257 
02258               /*
02259               * Draw Zooming outline if we are in that mode
02260               */
02261               if (screen.state == IN_ZOOM_OUTLINE) {
02262                      render_draw_zoom_outline(screen.centered_outline_zoom);
02263               }
02264               else if (screen.state == IN_MEASURE) {
02265                      render_draw_measure_distance();
02266               }
02267 
02268               return FALSE;
02269        }
02270 #ifndef RENDER_USING_GDK
02271 
02272        cairo_t *cr;
02273        int width, height;
02274        int x_off=0, y_off=0;
02275        GdkDrawable *drawable = widget->window;
02276        GdkVisual *visual;
02277 
02278        if (GDK_IS_WINDOW(widget->window)) {
02279              /* query the window's backbuffer if it has one */
02280               GdkWindow *window = GDK_WINDOW(widget->window);
02281              gdk_window_get_internal_paint_info (window,
02282                                                  &drawable, &x_off, &y_off);
02283        }
02284        visual = gdk_drawable_get_visual (drawable);
02285        gdk_drawable_get_size (drawable, &width, &height);
02286 
02287 #ifdef WIN32
02288        /* FIXME */
02289        cr = gdk_cairo_create (GDK_WINDOW(widget->window));
02290 #else      
02291        cairo_surface_t *buffert;
02292        
02293        buffert = (gpointer) cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable),
02294                                                  GDK_DRAWABLE_XID (drawable),
02295                                                  GDK_VISUAL_XVISUAL (visual),
02296                                                  event->area.width, event->area.height);
02297        cr = cairo_create (buffert);
02298 #endif
02299        cairo_translate (cr, -event->area.x + screen.off_x, -event->area.y + screen.off_y);
02300        render_project_to_cairo_target (cr);
02301        cairo_destroy (cr);
02302 #ifndef WIN32
02303        cairo_surface_destroy (buffert);
02304 #endif
02305 
02306 #endif
02307        return FALSE;
02308 }
02309 
02310 /* --------------------------------------------------------- */
02311 void
02312 callbacks_update_statusbar_coordinates (gint x, gint y) {
02313        double X, Y;
02314 
02315        /* make sure we don't divide by zero (which is possible if the gui
02316           isn't displayed yet */
02317        if ((screenRenderInfo.scaleFactorX > 0.001)||(screenRenderInfo.scaleFactorY > 0.001)) {
02318               X = screenRenderInfo.lowerLeftX + (x / screenRenderInfo.scaleFactorX);
02319               Y = screenRenderInfo.lowerLeftY + ((screenRenderInfo.displayHeight - y)
02320                      / screenRenderInfo.scaleFactorY);
02321        }
02322        else {
02323               X = Y = 0.0;
02324        }
02325        if (screen.unit == GERBV_MILS) {
02326            snprintf(screen.statusbar.coordstr, MAX_COORDLEN,
02327                    "(%8.2f, %8.2f)",
02328                    COORD2MILS(X), COORD2MILS(Y));
02329        } else if (screen.unit == GERBV_MMS) {
02330            snprintf(screen.statusbar.coordstr, MAX_COORDLEN,
02331                    "(%8.3f, %8.3f)",
02332                    COORD2MMS(X), COORD2MMS(Y));
02333        } else {
02334            snprintf(screen.statusbar.coordstr, MAX_COORDLEN,
02335                    "(%4.5f, %4.5f)",
02336                    COORD2MILS(X) / 1000.0, COORD2MILS(Y) / 1000.0);
02337        }
02338        callbacks_update_statusbar();
02339 }
02340 
02341 /* --------------------------------------------------------- */
02342 gboolean
02343 callbacks_drawingarea_motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
02344 {
02345        int x, y;
02346        GdkModifierType state;
02347 
02348        if (event->is_hint)
02349               gdk_window_get_pointer (event->window, &x, &y, &state);
02350        else {
02351               x = event->x;
02352               y = event->y;
02353               state = event->state;
02354        }
02355 
02356        switch (screen.state) {
02357               case IN_MOVE: {
02358                   if (screen.last_x != 0 || screen.last_y != 0) {
02359                      /* Move pixmap to get a snappier feel of movement */
02360                      screen.off_x += x - screen.last_x;
02361                      screen.off_y += y - screen.last_y;
02362                   }
02363                   screenRenderInfo.lowerLeftX -= ((x - screen.last_x) / screenRenderInfo.scaleFactorX);
02364                   screenRenderInfo.lowerLeftY += ((y - screen.last_y) / screenRenderInfo.scaleFactorY);
02365                   callbacks_force_expose_event_for_screen ();
02366                   callbacks_update_scrollbar_positions ();
02367                      screen.last_x = x;
02368                      screen.last_y = y;
02369                   break;
02370               }
02371               case IN_ZOOM_OUTLINE: {
02372                      if (screen.last_x || screen.last_y)
02373                             render_draw_zoom_outline(screen.centered_outline_zoom);
02374                      screen.last_x = x;
02375                      screen.last_y = y;
02376                      render_draw_zoom_outline(screen.centered_outline_zoom);
02377                      break;
02378               }
02379               case IN_MEASURE: {
02380                      /* clear the previous drawn line by drawing over it */
02381                      if (screen.last_x || screen.last_y)
02382                             render_draw_measure_distance();
02383                      screen.last_x = x;
02384                      screen.last_y = y;
02385                      /* draw the new line */
02386                      render_draw_measure_distance();
02387                      break;
02388               }
02389               case IN_SELECTION_DRAG: {
02390                      if (screen.last_x || screen.last_y)
02391                             render_draw_selection_box_outline();
02392                      screen.last_x = x;
02393                      screen.last_y = y;
02394                      render_draw_selection_box_outline();
02395                      break;
02396               }
02397               default:
02398                      screen.last_x = x;
02399                      screen.last_y = y;
02400                      break;
02401        }
02402        callbacks_update_statusbar_coordinates (x, y);
02403        callbacks_update_ruler_pointers ();
02404        return TRUE;
02405 } /* motion_notify_event */
02406 
02407 /* --------------------------------------------------------- */
02408 gboolean
02409 callbacks_drawingarea_button_press_event (GtkWidget *widget, GdkEventButton *event)
02410 {
02411        GdkCursor *cursor;
02412        
02413        switch (event->button) {
02414               case 1 :
02415                      if (screen.tool == POINTER) {
02416                             /* select */
02417 #ifndef RENDER_USING_GDK
02418                             /* selection will only work with cairo, so do nothing if it's
02419                                not compiled */
02420                             screen.state = IN_SELECTION_DRAG;
02421                             screen.start_x = event->x;
02422                             screen.start_y = event->y;
02423 #else
02424                             break;
02425 #endif
02426                      }
02427                      else if (screen.tool == PAN) {
02428                             /* Plain panning */
02429                             screen.state = IN_MOVE;
02430                             screen.last_x = event->x;
02431                             screen.last_y = event->y;
02432                      }
02433                      else if (screen.tool == ZOOM) {
02434                             screen.state = IN_ZOOM_OUTLINE;
02435                             /* Zoom outline mode initiated */
02436                             screen.start_x = event->x;
02437                             screen.start_y = event->y;
02438                             screen.centered_outline_zoom = event->state;
02439                      }
02440                      else if (screen.tool == MEASURE) {
02441                             screen.state = IN_MEASURE;
02442                             screen.start_x = event->x;
02443                             screen.start_y = event->y;
02444                             /* force an expose event to clear any previous measure lines */
02445                             callbacks_force_expose_event_for_screen ();
02446                      }
02447                      break;
02448               case 2 :
02449                      screen.state = IN_MOVE;
02450                      screen.last_x = event->x;
02451                      screen.last_y = event->y;
02452                      cursor = gdk_cursor_new(GDK_FLEUR);
02453                      gdk_window_set_cursor(GDK_WINDOW(screen.drawing_area->window),
02454                                      cursor);
02455                      gdk_cursor_destroy(cursor);
02456                      break;
02457               case 3 :
02458                      if (screen.tool == POINTER) {
02459 #ifndef RENDER_USING_GDK
02460                             /* if no items are selected, try and find the item the user
02461                                is pointing at */
02462                             if (screen.selectionInfo.type == GERBV_SELECTION_EMPTY) {
02463                                    gint index=callbacks_get_selected_row_index();
02464                                    if ((index >= 0) && 
02465                                        (index <= mainProject->last_loaded) &&
02466                                        (mainProject->file[index]->isVisible)) {
02467                                      render_fill_selection_buffer_from_mouse_click(event->x,event->y,index,TRUE);
02468                                    } else {
02469                                        render_clear_selection_buffer ();
02470                                        render_refresh_rendered_image_on_screen ();
02471                                    }
02472                             }
02473                             /* only show the popup if we actually have something selected now */
02474                             if (screen.selectionInfo.type != GERBV_SELECTION_EMPTY)
02475                                    gtk_menu_popup(GTK_MENU(screen.win.drawWindowPopupMenu), NULL, NULL, NULL, NULL, 
02476                                           event->button, event->time);
02477 #else
02478                             /* Do nothing if using GDK */
02479 #endif
02480                      } else {
02481                             /* Zoom outline mode initiated */
02482                             screen.state = IN_ZOOM_OUTLINE;
02483                             screen.start_x = event->x;
02484                             screen.start_y = event->y;
02485                             screen.centered_outline_zoom = event->state & GDK_SHIFT_MASK;
02486                             cursor = gdk_cursor_new(GDK_SIZING);
02487                             gdk_window_set_cursor(GDK_WINDOW(screen.drawing_area->window),
02488                                             cursor);
02489                             gdk_cursor_destroy(cursor);
02490                      }
02491                      break;
02492               case 4 : /* Scroll wheel */
02493                      render_zoom_display (ZOOM_IN_CMOUSE, 0, event->x, event->y);
02494                      break;
02495               case 5 :  /* Scroll wheel */
02496                      render_zoom_display (ZOOM_OUT_CMOUSE, 0, event->x, event->y);
02497                      break;
02498               default:
02499                      break;
02500        }
02501        callbacks_switch_to_correct_cursor ();
02502        return TRUE;
02503 }
02504 
02505 /* --------------------------------------------------------- */
02506 gboolean
02507 callbacks_drawingarea_button_release_event (GtkWidget *widget, GdkEventButton *event)
02508 { 
02509        if (event->type == GDK_BUTTON_RELEASE) {
02510               if (screen.state == IN_MOVE) {  
02511                      screen.off_x = 0;
02512                      screen.off_y = 0;
02513                      render_refresh_rendered_image_on_screen();
02514                      callbacks_switch_to_normal_tool_cursor (screen.tool);
02515               }
02516               else if (screen.state == IN_ZOOM_OUTLINE) {
02517                      if ((event->state & GDK_SHIFT_MASK) != 0) {
02518                             render_zoom_display (ZOOM_OUT_CMOUSE, 0, event->x, event->y);
02519                      }
02520                      /* if the user just clicks without dragging, then simply
02521                         zoom in a preset amount */
02522                      else if ((abs(screen.start_x - event->x) < 4) &&
02523                                    (abs(screen.start_y - event->y) < 4)) {
02524                             render_zoom_display (ZOOM_IN_CMOUSE, 0, event->x, event->y);
02525                      }
02526                      else
02527                             render_calculate_zoom_from_outline (widget, event);
02528                      callbacks_switch_to_normal_tool_cursor (screen.tool);
02529               }
02530               else if (screen.state == IN_SELECTION_DRAG) {
02531 #ifndef RENDER_USING_GDK
02532                      /* selection will only work with cairo, so do nothing if it's
02533                         not compiled */
02534                      gint index=callbacks_get_selected_row_index();
02535                      /* determine if this was just a click or a box drag */
02536                      if ((index >= 0) && 
02537                          (mainProject->file[index]->isVisible)) {
02538                             gboolean eraseOldSelection = TRUE;
02539                             if ((event->state & GDK_SHIFT_MASK) ||
02540                                (event->state & GDK_CONTROL_MASK)) {
02541                                    eraseOldSelection = FALSE;
02542                             }
02543                             if ((fabs((double)(screen.last_x - screen.start_x)) < 5) &&
02544                                     (fabs((double)(screen.last_y - screen.start_y)) < 5))
02545                                    render_fill_selection_buffer_from_mouse_click(event->x,event->y,index,eraseOldSelection);
02546                             else
02547                                    render_fill_selection_buffer_from_mouse_drag(event->x,event->y,
02548                                           screen.start_x,screen.start_y,index,eraseOldSelection);
02549                      } else {
02550                          render_clear_selection_buffer ();
02551                          render_refresh_rendered_image_on_screen ();
02552                      }
02553 #endif
02554               }
02555               screen.last_x = screen.last_y = 0;
02556               screen.state = NORMAL;
02557        }
02558        return TRUE;
02559 } /* button_release_event */
02560 
02561 /* --------------------------------------------------------- */
02562 gboolean
02563 callbacks_window_key_press_event (GtkWidget *widget, GdkEventKey *event)
02564 {
02565        //switch (screen.state) {
02566               //case NORMAL:
02567                      switch(event->keyval) {
02568                             case GDK_f:
02569                             case GDK_F:
02570                                    gerbv_render_zoom_to_fit_display (mainProject, &screenRenderInfo);
02571                                    render_refresh_rendered_image_on_screen();
02572                                    break;
02573                             case GDK_z:
02574                                    render_zoom_display (ZOOM_IN, 0, 0, 0);
02575                                    break;
02576                             case GDK_Z:
02577                                    render_zoom_display (ZOOM_OUT, 0, 0, 0);
02578                                    break;
02579                             case GDK_F1:
02580                                    callbacks_change_tool (NULL, (gpointer) 0);
02581                                    break;
02582                             case GDK_F2:
02583                                    callbacks_change_tool (NULL, (gpointer) 1);
02584                                    break;
02585                             case GDK_F3:
02586                                    callbacks_change_tool (NULL, (gpointer) 2);
02587                                    break;
02588                             case GDK_F4:
02589                                    callbacks_change_tool (NULL, (gpointer) 3);
02590                                    break;
02591 #ifndef RENDER_USING_GDK
02592                             case GDK_Delete:
02593                                    callbacks_delete_objects_clicked (NULL, NULL);
02594                                    break;
02595                             case GDK_Escape:
02596                                    render_clear_selection_buffer ();
02597                                    break;
02598 #endif
02599                             default:
02600                                    break;
02601                      }
02602                      //break;
02603               //default:
02604               //     break;
02605        //}
02606            
02607        /* Escape may be used to abort outline zoom and just plain repaint */
02608        if (event->keyval == GDK_Escape) {
02609               screen.state = NORMAL;
02610               render_refresh_rendered_image_on_screen();
02611        }
02612 
02613        return TRUE;
02614 } /* key_press_event */
02615 
02616 /* --------------------------------------------------------- */
02617 gboolean
02618 callbacks_window_key_release_event (GtkWidget *widget, GdkEventKey *event)
02619 {
02620        return TRUE;
02621 } /* key_release_event */
02622 
02623 /* --------------------------------------------------------- */
02624 /* Scroll wheel */
02625 gboolean
02626 callbacks_window_scroll_event(GtkWidget *widget, GdkEventScroll *event)
02627 {
02628        switch (event->direction) {
02629               case GDK_SCROLL_UP:
02630                      render_zoom_display (ZOOM_IN_CMOUSE, 0, event->x, event->y);
02631                      break;
02632               case GDK_SCROLL_DOWN:
02633                      render_zoom_display (ZOOM_OUT_CMOUSE, 0, event->x, event->y);
02634                      break;
02635               case GDK_SCROLL_LEFT: 
02636                      /* Ignore */
02637               case GDK_SCROLL_RIGHT:
02638                      /* Ignore */
02639               default:
02640                      return TRUE;
02641        }
02642        return TRUE;
02643 } /* scroll_event */
02644 
02645 
02646 /* ------------------------------------------------------------------ */
02653 void
02654 callbacks_update_statusbar(void)
02655 {
02656        if ((screen.statusbar.coordstr != NULL)&&(GTK_IS_LABEL(screen.win.statusMessageLeft))) {
02657               gtk_label_set_text(GTK_LABEL(screen.win.statusMessageLeft), screen.statusbar.coordstr);
02658        }
02659        if ((screen.statusbar.diststr != NULL)&&(GTK_IS_LABEL(screen.win.statusMessageRight))) {
02660               gtk_label_set_text(GTK_LABEL(screen.win.statusMessageRight), screen.statusbar.diststr);
02661        }
02662 }
02663 
02664 /* --------------------------------------------------------- */
02665 void
02666 callbacks_update_statusbar_measured_distance (gdouble dx, gdouble dy){
02667        gdouble delta = sqrt(dx*dx + dy*dy);
02668        
02669        if (screen.unit == GERBV_MILS) {
02670            snprintf(screen.statusbar.diststr, MAX_DISTLEN,
02671                    "Measured distance: %8.2f mils (%8.2f x, %8.2f y)",
02672                    COORD2MILS(delta), COORD2MILS(dx), COORD2MILS(dy));
02673        } 
02674        else if (screen.unit == GERBV_MMS) {
02675            snprintf(screen.statusbar.diststr, MAX_DISTLEN,
02676                    "Measured distance: %8.3f mms (%8.3f x, %8.3f y)",
02677                    COORD2MMS(delta), COORD2MMS(dx), COORD2MMS(dy));
02678        }
02679        else {
02680            snprintf(screen.statusbar.diststr, MAX_DISTLEN,
02681                    "Measured distance: %4.5f inches (%4.5f x, %4.5f y)",
02682                    COORD2MILS(delta) / 1000.0, COORD2MILS(dx) / 1000.0,
02683                    COORD2MILS(dy) / 1000.0);
02684        }
02685        callbacks_update_statusbar();
02686 }
02687 
02688 /* --------------------------------------------------------- */
02689 void
02690 callbacks_sidepane_render_type_combo_box_changed (GtkComboBox *widget, gpointer user_data) {
02691        int activeRow = gtk_combo_box_get_active (widget);
02692        
02693        dprintf ("%s():  activeRow = %d\n", __FUNCTION__, activeRow);
02694        screenRenderInfo.renderType = activeRow;
02695        
02696        render_refresh_rendered_image_on_screen();
02697 }
02698 
02699 /* --------------------------------------------------------- */
02700 void
02701 callbacks_statusbar_unit_combo_box_changed (GtkComboBox *widget, gpointer user_data) {
02702        int activeRow = gtk_combo_box_get_active (widget);
02703        
02704        if (activeRow >= 0) {
02705               screen.unit = activeRow;    
02706        }
02707        callbacks_update_ruler_scales();
02708        callbacks_update_statusbar_coordinates (screen.last_x, screen.last_y);
02709        
02710        if (screen.tool == MEASURE)
02711               callbacks_update_statusbar_measured_distance (screen.win.lastMeasuredX,
02712                                                  screen.win.lastMeasuredY);
02713 }
02714 
02715 /* --------------------------------------------------------- */
02716 void
02717 callbacks_clear_messages_button_clicked  (GtkButton *button, gpointer   user_data) {
02718        GtkTextBuffer *textbuffer;
02719        GtkTextIter start, end;
02720 
02721        textbuffer = gtk_text_view_get_buffer((GtkTextView*)screen.win.messageTextView);
02722        gtk_text_buffer_get_start_iter(textbuffer, &start);
02723        gtk_text_buffer_get_end_iter(textbuffer, &end);
02724        gtk_text_buffer_delete (textbuffer, &start, &end);
02725 }
02726             
02727 /* --------------------------------------------------------- */
02728 void
02729 callbacks_handle_log_messages(const gchar *log_domain, GLogLevelFlags log_level,
02730                     const gchar *message, gpointer user_data) {
02731        GtkTextBuffer *textbuffer = NULL;
02732        GtkTextIter iter;
02733        GtkTextTag *tag;
02734        GtkTextMark *StartMark = NULL, *StopMark = NULL;
02735        GtkTextIter StartIter, StopIter;
02736 
02737        if (!screen.win.messageTextView)
02738               return;
02739               
02740        textbuffer = gtk_text_view_get_buffer((GtkTextView*)screen.win.messageTextView);
02741 
02742        /* create a mark for the end of the text. */
02743        gtk_text_buffer_get_end_iter(textbuffer, &iter);
02744 
02745        /* get the current end position of the text (it will be the
02746              start of the new text. */
02747        StartMark = gtk_text_buffer_create_mark(textbuffer,
02748                                        "NewTextStart", &iter, TRUE);
02749 
02750        tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
02751                                      "blue_foreground");
02752        /* the tag does not exist: create it and let them exist in the tag table.*/
02753        if (tag == NULL)    {
02754               tag = gtk_text_buffer_create_tag(textbuffer, "black_foreground",
02755                                             "foreground", "black", NULL);
02756               tag = gtk_text_buffer_create_tag(textbuffer, "blue_foreground",
02757                                             "foreground", "blue", NULL);
02758               tag = gtk_text_buffer_create_tag(textbuffer, "red_foreground",
02759                                             "foreground", "red", NULL);
02760               tag = gtk_text_buffer_create_tag(textbuffer, "darkred_foreground",
02761                                             "foreground", "darkred", NULL);
02762               tag = gtk_text_buffer_create_tag(textbuffer, "darkblue_foreground",
02763                                             "foreground", "darkblue", NULL);
02764               tag = gtk_text_buffer_create_tag (textbuffer, "darkgreen_foreground",
02765                                             "foreground", "darkgreen", NULL);
02766               tag = gtk_text_buffer_create_tag (textbuffer,
02767                                             "saddlebrown_foreground",
02768                                             "foreground", "saddlebrown", NULL);
02769        }
02770 
02771        /* 
02772        * See rgb.txt for the color names definition 
02773        * (on my PC it is on /usr/X11R6/lib/X11/rgb.txt)
02774        */
02775        switch (log_level & G_LOG_LEVEL_MASK) {
02776        case G_LOG_LEVEL_ERROR:
02777        /* a message of this kind aborts the application calling abort() */
02778              tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
02779                                            "red_foreground");
02780              gtk_notebook_set_current_page(GTK_NOTEBOOK(screen.win.sidepane_notebook), 1);
02781              gtk_widget_show(screen.win.sidepane_notebook);
02782               break;
02783        case G_LOG_LEVEL_CRITICAL:
02784              tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
02785                                            "red_foreground");
02786              gtk_notebook_set_current_page(GTK_NOTEBOOK(screen.win.sidepane_notebook), 1);
02787              gtk_widget_show(screen.win.sidepane_notebook);
02788               break;
02789        case G_LOG_LEVEL_WARNING:
02790              tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
02791                                            "darkred_foreground");
02792              gtk_notebook_set_current_page(GTK_NOTEBOOK(screen.win.sidepane_notebook), 1);
02793              gtk_widget_show(screen.win.sidepane_notebook);
02794               break;
02795        case G_LOG_LEVEL_MESSAGE:
02796              tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
02797                                            "darkblue_foreground");
02798              gtk_notebook_set_current_page(GTK_NOTEBOOK(screen.win.sidepane_notebook), 1);
02799              gtk_widget_show(screen.win.sidepane_notebook);
02800               break;
02801        case G_LOG_LEVEL_INFO:
02802              tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
02803                                            "darkgreen_foreground");
02804               break;
02805        case G_LOG_LEVEL_DEBUG:
02806               tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
02807                                    "saddlebrown_foreground");
02808               break;
02809        default:
02810              tag = gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table(textbuffer),
02811                                            "black_foreground");
02812               break;
02813        }
02814 
02815        /*
02816        * Fatal aborts application. We will try to get the message out anyhow.
02817        */
02818        if (log_level & G_LOG_FLAG_FATAL)
02819               fprintf(stderr, "Fatal error : %s\n", message);
02820 
02821        gtk_text_buffer_insert(textbuffer, &iter, message, -1);
02822 
02823        gtk_text_buffer_get_end_iter(textbuffer, &iter);
02824 
02825        StopMark = gtk_text_buffer_create_mark(textbuffer,
02826                                       "NewTextStop", &iter, TRUE);
02827 
02828        gtk_text_buffer_get_iter_at_mark(textbuffer, &StartIter, StartMark);
02829        gtk_text_buffer_get_iter_at_mark(textbuffer, &StopIter, StopMark);
02830 
02831        gtk_text_buffer_apply_tag(textbuffer, tag, &StartIter, &StopIter);
02832 }
02833 
02834 /* --------------------------------------------------------- */
02835 void callbacks_force_expose_event_for_screen (void){
02836 
02837        GdkRectangle update_rect;
02838        
02839        update_rect.x = 0;
02840        update_rect.y = 0;
02841        update_rect.width = screenRenderInfo.displayWidth;
02842        update_rect.height = screenRenderInfo.displayHeight;
02843 
02844        /* Calls expose_event */
02845        gdk_window_invalidate_rect (screen.drawing_area->window, &update_rect, FALSE);
02846        
02847        /* update other gui things that could have changed */
02848        callbacks_update_ruler_scales();
02849        callbacks_update_scrollbar_limits();
02850        callbacks_update_scrollbar_positions();
02851 }
02852 

Generated on Tue Aug 19 00:14:48 2008 for gerbv by  doxygen 1.5.6