pcb 4.1.1
An interactive printed circuit board layout editor.

gui-drc-window.c

Go to the documentation of this file.
00001 /*
00002  *                            COPYRIGHT
00003  *
00004  *  PCB, interactive printed circuit board design
00005  *  Copyright (C) 1994,1995,1996 Thomas Nau
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License along
00018  *  with this program; if not, write to the Free Software Foundation, Inc.,
00019  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00020  *
00021  *  Contact addresses for paper mail and Email:
00022  *  Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
00023  *  Thomas.Nau@rz.uni-ulm.de
00024  *
00025  */
00026 
00027 #ifdef HAVE_CONFIG_H
00028 #include "config.h"
00029 #endif
00030 
00031 #include "error.h"
00032 #include "search.h"
00033 #include "draw.h"
00034 #include "find.h"
00035 #include "pcb-printf.h"
00036 #include "undo.h"
00037 #include "set.h"
00038 #include "gui.h"
00039 #include "gui-drc-window.h"
00040 
00041 #ifdef HAVE_LIBDMALLOC
00042 #include <dmalloc.h>
00043 #endif
00044 
00045 #define VIOLATION_PIXMAP_PIXEL_SIZE   100
00046 #define VIOLATION_PIXMAP_PIXEL_BORDER 5
00047 #define VIOLATION_PIXMAP_PCB_SIZE     MIL_TO_COORD (100)
00048 
00049 static GtkWidget *drc_window, *drc_list;
00050 static GtkListStore *drc_list_model = NULL;
00051 static int num_violations = 0;
00052 
00053 /* Remember user window resizes. */
00054 static gint
00055 drc_window_configure_event_cb (GtkWidget * widget,
00056                                GdkEventConfigure * ev, gpointer data)
00057 {
00058   GtkAllocation allocation;
00059 
00060   gtk_widget_get_allocation (widget, &allocation);
00061   ghidgui->drc_window_width = allocation.width;
00062   ghidgui->drc_window_height = allocation.height;
00063   ghidgui->config_modified = TRUE;
00064 
00065   return FALSE;
00066 }
00067 
00068 static void
00069 drc_close_cb (gpointer data)
00070 {
00071   gtk_widget_destroy (drc_window);
00072   drc_window = NULL;
00073 }
00074 
00075 static void
00076 drc_refresh_cb (gpointer data)
00077 {
00078   hid_actionl ("DRC", NULL);
00079 }
00080 
00081 static void
00082 drc_destroy_cb (GtkWidget * widget, gpointer data)
00083 {
00084   drc_window = NULL;
00085 }
00086 
00087 enum {
00088   DRC_VIOLATION_NUM_COL = 0,
00089   DRC_VIOLATION_OBJ_COL,
00090   NUM_DRC_COLUMNS
00091 };
00092 
00093 
00094 static void
00095 selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
00096 {
00097   GtkTreeModel *model;
00098   GtkTreeIter iter;
00099   GhidDrcViolation *violation;
00100   int i;
00101 
00102   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
00103     {
00104       if (ClearFlagOnAllObjects (true, FOUNDFLAG))
00105         {
00106           IncrementUndoSerialNumber ();
00107           Draw ();
00108         }
00109       return;
00110     }
00111 
00112   /* Check the selected node has children, if so; return. */
00113   if (gtk_tree_model_iter_has_child (model, &iter))
00114     return;
00115 
00116   gtk_tree_model_get (model, &iter, DRC_VIOLATION_OBJ_COL, &violation, -1);
00117 
00118   ClearFlagOnAllObjects (true, FOUNDFLAG);
00119 
00120   if (violation == NULL)
00121     return;
00122 
00123   /* Flag the objects listed against this DRC violation */
00124   for (i = 0; i < violation->object_count; i++)
00125     {
00126       int object_id = violation->object_id_list[i];
00127       int object_type = violation->object_type_list[i];
00128       int found_type;
00129       void *ptr1, *ptr2, *ptr3;
00130 
00131       found_type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3,
00132                                      object_id, object_type);
00133       if (found_type == NO_TYPE)
00134         {
00135           Message (_("Object ID %i identified during DRC was not found. Stale DRC window?\n"),
00136                    object_id);
00137           continue;
00138         }
00139       AddObjectToFlagUndoList (object_type, ptr1, ptr2, ptr3);
00140       SET_FLAG (FOUNDFLAG, (AnyObjectType *)ptr2);
00141       switch (violation->object_type_list[i])
00142         {
00143         case LINE_TYPE:
00144         case ARC_TYPE:
00145         case POLYGON_TYPE:
00146           ChangeGroupVisibility (GetLayerNumber (PCB->Data, (LayerType *) ptr1), true, true);
00147         }
00148       DrawObject (object_type, ptr1, ptr2);
00149     }
00150   SetChangedFlag (true);
00151   IncrementUndoSerialNumber ();
00152   Draw();
00153 
00154   CenterDisplay (violation->x_coord, violation->y_coord, false);
00155 }
00156 
00157 static void
00158 row_activated_cb (GtkTreeView *view, GtkTreePath *path,
00159                   GtkTreeViewColumn *column, gpointer user_data)
00160 {
00161   GtkTreeModel *model = gtk_tree_view_get_model (view);
00162   GtkTreeIter iter;
00163   GhidDrcViolation *violation;
00164 
00165   gtk_tree_model_get_iter (model, &iter, path);
00166 
00167   gtk_tree_model_get (model, &iter, DRC_VIOLATION_OBJ_COL, &violation, -1);
00168 
00169   if (violation == NULL)
00170     return;
00171 
00172   CenterDisplay (violation->x_coord, violation->y_coord, true);
00173   gtk_window_present (GTK_WINDOW (gport->top_window));
00174 }
00175 
00176 enum
00177 {
00178   PROP_TITLE = 1,
00179   PROP_EXPLANATION,
00180   PROP_X_COORD,
00181   PROP_Y_COORD,
00182   PROP_ANGLE,
00183   PROP_HAVE_MEASURED,
00184   PROP_MEASURED_VALUE,
00185   PROP_REQUIRED_VALUE,
00186   PROP_OBJECT_LIST,
00187   PROP_PIXMAP
00188 };
00189 
00190 
00191 static GObjectClass *ghid_drc_violation_parent_class = NULL;
00192 
00193 
00202 static void
00203 ghid_drc_violation_finalize (GObject * object)
00204 {
00205   GhidDrcViolation *violation = GHID_DRC_VIOLATION (object);
00206 
00207   g_free (violation->title);
00208   g_free (violation->explanation);
00209   g_free (violation->object_id_list);
00210   g_free (violation->object_type_list);
00211   if (violation->pixmap != NULL)
00212     g_object_unref (violation->pixmap);
00213 
00214   G_OBJECT_CLASS (ghid_drc_violation_parent_class)->finalize (object);
00215 }
00216 
00217 typedef struct object_list
00218 {
00219   int count;
00220   long int *id_list;
00221   int *type_list;
00222 } object_list;
00223 
00236 static void
00237 ghid_drc_violation_set_property (GObject * object, guint property_id,
00238                                   const GValue * value, GParamSpec * pspec)
00239 {
00240   GhidDrcViolation *violation = GHID_DRC_VIOLATION (object);
00241   object_list *obj_list;
00242 
00243   switch (property_id)
00244     {
00245     case PROP_TITLE:
00246       g_free (violation->title);
00247       violation->title = g_value_dup_string (value);
00248       break;
00249     case PROP_EXPLANATION:
00250       g_free (violation->explanation);
00251       violation->explanation = g_value_dup_string (value);
00252       break;
00253     case PROP_X_COORD:
00254       violation->x_coord = g_value_get_int (value);
00255       break;
00256     case PROP_Y_COORD:
00257       violation->y_coord = g_value_get_int (value);
00258       break;
00259     case PROP_ANGLE:
00260       violation->angle = g_value_get_double (value);
00261       break;
00262     case PROP_HAVE_MEASURED:
00263       violation->have_measured = g_value_get_boolean (value);
00264       break;
00265     case PROP_MEASURED_VALUE:
00266       violation->measured_value = g_value_get_int (value);
00267       break;
00268     case PROP_REQUIRED_VALUE:
00269       violation->required_value = g_value_get_int (value);
00270       break;
00271     case PROP_OBJECT_LIST:
00272       /* Copy the passed data to make new lists */
00273       g_free (violation->object_id_list);
00274       g_free (violation->object_type_list);
00275       obj_list = (object_list *)g_value_get_pointer (value);
00276       violation->object_count = obj_list->count;
00277       violation->object_id_list   = g_new (long int, obj_list->count);
00278       violation->object_type_list = g_new (int,      obj_list->count);
00279       memcpy (violation->object_id_list, obj_list->id_list,
00280               sizeof (long int) * obj_list->count);
00281       memcpy (violation->object_type_list, obj_list->type_list,
00282               sizeof (int)      * obj_list->count);
00283       break;
00284     case PROP_PIXMAP:
00285       if (violation->pixmap)
00286         g_object_unref (violation->pixmap);           /* Frees our old reference */
00287       violation->pixmap = (GdkDrawable *)g_value_dup_object (value); /* Takes a new reference */
00288       break;
00289     default:
00290       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
00291       return;
00292     }
00293 }
00294 
00295 
00308 static void
00309 ghid_drc_violation_get_property (GObject * object, guint property_id,
00310                                  GValue * value, GParamSpec * pspec)
00311 {
00312   switch (property_id)
00313     {
00314     default:
00315       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
00316     }
00317 
00318 }
00319 
00320 
00329 static void
00330 ghid_drc_violation_class_init (GhidViolationRendererClass * klass)
00331 {
00332   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
00333 
00334   gobject_class->finalize = ghid_drc_violation_finalize;
00335   gobject_class->set_property = ghid_drc_violation_set_property;
00336   gobject_class->get_property = ghid_drc_violation_get_property;
00337 
00338   ghid_drc_violation_parent_class = (GObjectClass *)g_type_class_peek_parent (klass);
00339 
00340   g_object_class_install_property (gobject_class, PROP_TITLE,
00341                                    g_param_spec_string ("title",
00342                                                         "",
00343                                                         "",
00344                                                         "",
00345                                                         G_PARAM_WRITABLE));
00346   g_object_class_install_property (gobject_class, PROP_EXPLANATION,
00347                                    g_param_spec_string ("explanation",
00348                                                         "",
00349                                                         "",
00350                                                         "",
00351                                                         G_PARAM_WRITABLE));
00352   g_object_class_install_property (gobject_class, PROP_X_COORD,
00353                                    g_param_spec_int ("x-coord",
00354                                                      "",
00355                                                      "",
00356                                                      G_MININT,
00357                                                      G_MAXINT,
00358                                                      0,
00359                                                      G_PARAM_WRITABLE));
00360   g_object_class_install_property (gobject_class, PROP_Y_COORD,
00361                                    g_param_spec_int ("y-coord",
00362                                                      "",
00363                                                      "",
00364                                                      G_MININT,
00365                                                      G_MAXINT,
00366                                                      0,
00367                                                      G_PARAM_WRITABLE));
00368   g_object_class_install_property (gobject_class, PROP_ANGLE,
00369                                    g_param_spec_double ("angle",
00370                                                      "",
00371                                                      "",
00372                                                      G_MININT,
00373                                                      G_MAXINT,
00374                                                      0,
00375                                                      G_PARAM_WRITABLE));
00376   g_object_class_install_property (gobject_class, PROP_HAVE_MEASURED,
00377                                    g_param_spec_boolean ("have-measured",
00378                                                      "",
00379                                                      "",
00380                                                      0,
00381                                                      G_PARAM_WRITABLE));
00382   g_object_class_install_property (gobject_class, PROP_MEASURED_VALUE,
00383                                    g_param_spec_int ("measured-value",
00384                                                      "",
00385                                                      "",
00386                                                      G_MININT,
00387                                                      G_MAXINT,
00388                                                      0.,
00389                                                      G_PARAM_WRITABLE));
00390   g_object_class_install_property (gobject_class, PROP_REQUIRED_VALUE,
00391                                    g_param_spec_int ("required-value",
00392                                                      "",
00393                                                      "",
00394                                                      G_MININT,
00395                                                      G_MAXINT,
00396                                                      0.,
00397                                                      G_PARAM_WRITABLE));
00398   g_object_class_install_property (gobject_class, PROP_OBJECT_LIST,
00399                                    g_param_spec_pointer ("object-list",
00400                                                          "",
00401                                                          "",
00402                                                          G_PARAM_WRITABLE));
00403   g_object_class_install_property (gobject_class, PROP_PIXMAP,
00404                                    g_param_spec_object ("pixmap",
00405                                                         "",
00406                                                         "",
00407                                                         GDK_TYPE_DRAWABLE,
00408                                                         G_PARAM_WRITABLE));
00409 }
00410 
00411 
00412 
00422 GType
00423 ghid_drc_violation_get_type ()
00424 {
00425   static GType ghid_drc_violation_type = 0;
00426 
00427   if (!ghid_drc_violation_type)
00428     {
00429       static const GTypeInfo ghid_drc_violation_info = {
00430         sizeof (GhidDrcViolationClass),
00431         NULL,                   /* base_init */
00432         NULL,                   /* base_finalize */
00433         (GClassInitFunc) ghid_drc_violation_class_init,
00434         NULL,                   /* class_finalize */
00435         NULL,                   /* class_data */
00436         sizeof (GhidDrcViolation),
00437         0,                      /* n_preallocs */
00438         NULL,                   /* instance_init */
00439       };
00440 
00441       ghid_drc_violation_type =
00442         g_type_register_static (G_TYPE_OBJECT, "GhidDrcViolation",
00443                                 &ghid_drc_violation_info, (GTypeFlags)0);
00444     }
00445 
00446   return ghid_drc_violation_type;
00447 }
00448 
00449 
00450 GhidDrcViolation *ghid_drc_violation_new (DrcViolationType *violation,
00451                                           GdkDrawable *pixmap)
00452 {
00453   object_list obj_list;
00454 
00455   obj_list.count = violation->object_count;
00456   obj_list.id_list = violation->object_id_list;
00457   obj_list.type_list = violation->object_type_list;
00458 
00459   return (GhidDrcViolation *)g_object_new (GHID_TYPE_DRC_VIOLATION,
00460                        "title",            violation->title,
00461                        "explanation",      violation->explanation,
00462                        "x-coord",          violation->x,
00463                        "y-coord",          violation->y,
00464                        "angle",            violation->angle,
00465                        "have-measured",    violation->have_measured,
00466                        "measured-value",   violation->measured_value,
00467                        "required-value",   violation->required_value,
00468                        "object-list",      &obj_list,
00469                        "pixmap",           pixmap,
00470                        NULL);
00471 }
00472 
00473 enum
00474 {
00475   PROP_VIOLATION = 1,
00476 };
00477 
00478 
00479 static GObjectClass *ghid_violation_renderer_parent_class = NULL;
00480 
00481 
00490 static void
00491 ghid_violation_renderer_finalize (GObject * object)
00492 {
00493   GhidViolationRenderer *renderer = GHID_VIOLATION_RENDERER (object);
00494 
00495   if (renderer->violation != NULL)
00496     g_object_unref (renderer->violation);
00497 
00498   G_OBJECT_CLASS (ghid_violation_renderer_parent_class)->finalize (object);
00499 }
00500 
00501 
00514 static void
00515 ghid_violation_renderer_set_property (GObject * object, guint property_id,
00516                                   const GValue * value, GParamSpec * pspec)
00517 {
00518   GhidViolationRenderer *renderer = GHID_VIOLATION_RENDERER (object);
00519   char *markup;
00520 
00521   switch (property_id)
00522     {
00523     case PROP_VIOLATION:
00524       if (renderer->violation != NULL)
00525         g_object_unref (renderer->violation);
00526       renderer->violation = (GhidDrcViolation *)g_value_dup_object (value);
00527       break;
00528     default:
00529       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
00530       return;
00531     }
00532 
00533   if (renderer->violation == NULL)
00534     return;
00535 
00536   if (renderer->violation->have_measured)
00537     {
00538       markup = pcb_g_strdup_printf (_("%m+<b>%s (%$mS)</b>\n"
00539                                 "<span size='1024'> </span>\n"
00540                                 "<small>"
00541                                   "<i>%s</i>\n"
00542                                   "<span size='5120'> </span>\n"
00543                                   "Required: %$mS"
00544                                 "</small>"),
00545                                 Settings.grid_unit->allow,
00546                                 renderer->violation->title,
00547                                 renderer->violation->measured_value,
00548                                 renderer->violation->explanation,
00549                                 renderer->violation->required_value);
00550     }
00551   else
00552     {
00553       markup = pcb_g_strdup_printf (_("%m+<b>%s</b>\n"
00554                                 "<span size='1024'> </span>\n"
00555                                 "<small>"
00556                                   "<i>%s</i>\n"
00557                                   "<span size='5120'> </span>\n"
00558                                   "Required: %$mS"
00559                                 "</small>"),
00560                                 Settings.grid_unit->allow,
00561                                 renderer->violation->title,
00562                                 renderer->violation->explanation,
00563                                 renderer->violation->required_value);
00564     }
00565 
00566   g_object_set (object, "markup", markup, NULL);
00567   g_free (markup);
00568 }
00569 
00570 
00582 static void
00583 ghid_violation_renderer_get_property (GObject * object, guint property_id,
00584                                   GValue * value, GParamSpec * pspec)
00585 {
00586   switch (property_id)
00587     {
00588     default:
00589       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
00590     }
00591 
00592 }
00593 
00594 static void
00595 ghid_violation_renderer_get_size (GtkCellRenderer      *cell,
00596                                   GtkWidget            *widget,
00597                                   GdkRectangle         *cell_area,
00598                                   gint                 *x_offset,
00599                                   gint                 *y_offset,
00600                                   gint                 *width,
00601                                   gint                 *height)
00602 {
00603   GTK_CELL_RENDERER_CLASS (ghid_violation_renderer_parent_class)->get_size (cell,
00604                                                                             widget,
00605                                                                             cell_area,
00606                                                                             x_offset,
00607                                                                             y_offset,
00608                                                                             width,
00609                                                                             height);
00610   if (width != NULL)
00611     *width += VIOLATION_PIXMAP_PIXEL_SIZE;
00612   if (height != NULL)
00613     *height = MAX (*height, VIOLATION_PIXMAP_PIXEL_SIZE);
00614 }
00615 
00616 
00617 static void
00618 ghid_violation_renderer_render (GtkCellRenderer      *cell,
00619                                 GdkDrawable          *window,
00620                                 GtkWidget            *widget,
00621                                 GdkRectangle         *background_area,
00622                                 GdkRectangle         *cell_area,
00623                                 GdkRectangle         *expose_area,
00624                                 GtkCellRendererState  flags)
00625 {
00626   GdkDrawable *mydrawable;
00627   GtkStyle *style = gtk_widget_get_style (widget);
00628   GhidViolationRenderer *renderer = GHID_VIOLATION_RENDERER (cell);
00629   GhidDrcViolation *violation = renderer->violation;
00630   int pixmap_size = VIOLATION_PIXMAP_PIXEL_SIZE - 2 * VIOLATION_PIXMAP_PIXEL_BORDER;
00631 
00632   cell_area->width -= VIOLATION_PIXMAP_PIXEL_SIZE;
00633   GTK_CELL_RENDERER_CLASS (ghid_violation_renderer_parent_class)->render (cell,
00634                                                                           window,
00635                                                                           widget,
00636                                                                           background_area,
00637                                                                           cell_area,
00638                                                                           expose_area,
00639                                                                           flags);
00640 
00641   if (violation == NULL)
00642     return;
00643 
00644   if (violation->pixmap == NULL)
00645     {
00646       GdkPixmap *pixmap = ghid_render_pixmap (violation->x_coord,
00647                                               violation->y_coord,
00648                                               VIOLATION_PIXMAP_PCB_SIZE / pixmap_size,
00649                                               pixmap_size, pixmap_size,
00650                                               gdk_drawable_get_depth (window));
00651       g_object_set (violation, "pixmap", pixmap, NULL);
00652       g_object_unref (pixmap);
00653     }
00654 
00655   if (violation->pixmap == NULL)
00656     return;
00657 
00658   mydrawable = GDK_DRAWABLE (violation->pixmap);
00659 
00660   gdk_draw_drawable (window, style->fg_gc[gtk_widget_get_state (widget)],
00661                      mydrawable, 0, 0,
00662                      cell_area->x + cell_area->width + VIOLATION_PIXMAP_PIXEL_BORDER,
00663                      cell_area->y + VIOLATION_PIXMAP_PIXEL_BORDER, -1, -1);
00664 }
00665 
00666 
00675 static void
00676 ghid_violation_renderer_class_init (GhidViolationRendererClass * klass)
00677 {
00678   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
00679   GtkCellRendererClass *cellrenderer_class = GTK_CELL_RENDERER_CLASS (klass);
00680 
00681   gobject_class->finalize = ghid_violation_renderer_finalize;
00682   gobject_class->set_property = ghid_violation_renderer_set_property;
00683   gobject_class->get_property = ghid_violation_renderer_get_property;
00684 
00685   cellrenderer_class->get_size = ghid_violation_renderer_get_size;
00686   cellrenderer_class->render = ghid_violation_renderer_render;
00687 
00688   ghid_violation_renderer_parent_class = (GObjectClass *)g_type_class_peek_parent (klass);
00689 
00690   g_object_class_install_property (gobject_class, PROP_VIOLATION,
00691                                    g_param_spec_object ("violation",
00692                                                         "",
00693                                                         "",
00694                                                         GHID_TYPE_DRC_VIOLATION,
00695                                                         G_PARAM_WRITABLE));
00696 }
00697 
00698 
00708 GType
00709 ghid_violation_renderer_get_type ()
00710 {
00711   static GType ghid_violation_renderer_type = 0;
00712 
00713   if (!ghid_violation_renderer_type)
00714     {
00715       static const GTypeInfo ghid_violation_renderer_info = {
00716         sizeof (GhidViolationRendererClass),
00717         NULL,                   /* base_init */
00718         NULL,                   /* base_finalize */
00719         (GClassInitFunc) ghid_violation_renderer_class_init,
00720         NULL,                   /* class_finalize */
00721         NULL,                   /* class_data */
00722         sizeof (GhidViolationRenderer),
00723         0,                      /* n_preallocs */
00724         NULL,                   /* instance_init */
00725       };
00726 
00727       ghid_violation_renderer_type =
00728         g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT, "GhidViolationRenderer",
00729                                 &ghid_violation_renderer_info, (GTypeFlags)0);
00730     }
00731 
00732   return ghid_violation_renderer_type;
00733 }
00734 
00735 
00743 GtkCellRenderer *
00744 ghid_violation_renderer_new (void)
00745 {
00746   GhidViolationRenderer *renderer;
00747 
00748   renderer = (GhidViolationRenderer *)g_object_new (GHID_TYPE_VIOLATION_RENDERER,
00749                            "ypad", 6,
00750                            NULL);
00751 
00752   return GTK_CELL_RENDERER (renderer);
00753 }
00754 
00755 
00756 void
00757 ghid_drc_window_show (gboolean raise)
00758 {
00759   GtkWidget *vbox, *hbox, *button, *scrolled_window;
00760   GtkCellRenderer *violation_renderer;
00761 
00762   if (drc_window)
00763     {
00764       if (raise)
00765         gtk_window_present(GTK_WINDOW(drc_window));
00766       return;
00767     }
00768 
00769  drc_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00770   g_signal_connect (G_OBJECT (drc_window), "destroy",
00771                     G_CALLBACK (drc_destroy_cb), NULL);
00772   g_signal_connect (G_OBJECT (drc_window), "configure_event",
00773                     G_CALLBACK (drc_window_configure_event_cb), NULL);
00774   gtk_window_set_title (GTK_WINDOW (drc_window), _("PCB DRC"));
00775   gtk_window_set_wmclass (GTK_WINDOW (drc_window), "PCB_DRC", "PCB");
00776   gtk_window_resize (GTK_WINDOW (drc_window),
00777                      ghidgui->drc_window_width, ghidgui->drc_window_height);
00778 
00779   vbox = gtk_vbox_new (FALSE, 0);
00780   gtk_container_add (GTK_CONTAINER (drc_window), vbox);
00781   gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
00782   gtk_box_set_spacing (GTK_BOX (vbox), 6);
00783 
00784   drc_list_model = gtk_list_store_new (NUM_DRC_COLUMNS,
00785                                        G_TYPE_INT,      /* DRC_VIOLATION_NUM_COL */
00786                                        G_TYPE_OBJECT);  /* DRC_VIOLATION_OBJ_COL */
00787 
00788   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
00789   gtk_box_pack_start (GTK_BOX (vbox), scrolled_window,
00790                       TRUE /* EXPAND */, TRUE /* FILL */, 0 /* PADDING */);
00791 
00792   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
00793                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
00794 
00795   drc_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (drc_list_model));
00796   gtk_container_add (GTK_CONTAINER (scrolled_window), drc_list);
00797 
00798   gtk_widget_set_tooltip_text (drc_list,
00799                                "Single-click to locate the violation,\n"
00800                                "double-click to also warp the mouse\n"
00801                                "pointer there.");
00802 
00803   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (drc_list), TRUE);
00804   g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (drc_list)), "changed",
00805                     G_CALLBACK (selection_changed_cb), NULL);
00806   g_signal_connect (drc_list, "row-activated",
00807                     G_CALLBACK (row_activated_cb), NULL);
00808 
00809   violation_renderer = gtk_cell_renderer_text_new ();
00810   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (drc_list),
00811                                                -1, /* APPEND */
00812                                                _("No."), /* TITLE */
00813                                                violation_renderer,
00814                                                "text", DRC_VIOLATION_NUM_COL,
00815                                                NULL);
00816 
00817   violation_renderer = ghid_violation_renderer_new ();
00818   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (drc_list),
00819                                                -1, /* APPEND */
00820                                                _("Violation details"), /* TITLE */
00821                                                violation_renderer,
00822                                                "violation", DRC_VIOLATION_OBJ_COL,
00823                                                NULL);
00824 
00825   hbox = gtk_hbutton_box_new ();
00826   gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
00827   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
00828 
00829   gtk_box_set_spacing (GTK_BOX (hbox), 6);
00830 
00831   button = gtk_button_new_from_stock (GTK_STOCK_REFRESH);
00832   g_signal_connect (G_OBJECT (button), "clicked",
00833                     G_CALLBACK (drc_refresh_cb), NULL);
00834   gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
00835 
00836   button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
00837   g_signal_connect (G_OBJECT (button), "clicked",
00838                     G_CALLBACK (drc_close_cb), NULL);
00839   gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
00840 
00841   gtk_widget_realize (drc_window);
00842   if (Settings.AutoPlace)
00843     gtk_window_move (GTK_WINDOW (drc_window), 10, 10);
00844   gtk_widget_show_all (drc_window);
00845 }
00846 
00847 void ghid_drc_window_append_violation (DrcViolationType *violation)
00848 {
00849   GhidDrcViolation *violation_obj;
00850   GtkTreeIter iter;
00851 
00852   /* Ensure the required structures are setup */
00853   ghid_drc_window_show (FALSE);
00854 
00855   num_violations++;
00856 
00857   violation_obj = ghid_drc_violation_new (violation, /* pixmap */ NULL);
00858 
00859   gtk_list_store_append (drc_list_model, &iter);
00860   gtk_list_store_set (drc_list_model, &iter,
00861                       DRC_VIOLATION_NUM_COL, num_violations,
00862                       DRC_VIOLATION_OBJ_COL, violation_obj,
00863                       -1);
00864 
00865   g_object_unref (violation_obj); /* The list store takes its own reference */
00866 }
00867 
00868 void ghid_drc_window_reset_message (void)
00869 {
00870   if (drc_list_model != NULL)
00871     gtk_list_store_clear (drc_list_model);
00872   num_violations = 0;
00873 }
00874 
00875 int ghid_drc_window_throw_dialog (void)
00876 {
00877   ghid_drc_window_show (TRUE);
00878   return 1;
00879 }