[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: gEDA-user: DRC-GUI
On Thu, 2009-04-02 at 18:23 +0200, Bert Timmerman wrote:
> Hi Peter,
>
> On Thu, 2009-04-02 at 03:34 +0100, Peter Clifton wrote:
> > More eye-candy.. again, a real screen-shot, not a mockup.
> >
> > http://www2.eng.cam.ac.uk/~pcjc2/geda/drc_for_real2.png
> >
>
> Totally awesome !
>
> Now to double-click on the thumbnail image to move the cursor on the
> spot would be the icing on top of the cake :)
Good idea. (Currently, the code just jumps the mouse cursor as soon as
you select a particular violation).
> I'm looking forward for your patches / git fork.
It is in my git repository under the "better_drc" branch.
It is based on top of my local customisation patches, and the
"before_pours" PCB+GL branch. The relevant patches could probably just
be applied on top of the "before_pours" branch. (I've attached them).
Beware that the GL code seems to cause an X server crash occasionally on
my box. Something wrong there.. not sure if its something I'm doing
wrong, or just a bug I'm inadvertently triggering.
It shouldn't be too hard to modify src/hid/gtk/gui-pixmap-render.c to
render the preview images to a pixmap using the old GDK code either.
Currently I'm just testing with GL.
It works in the same way as the pinout / footprint preview widget, by
temporarily diverting the GUI's zoom and rendering target. A bit of a
kludge perhaps, but it works. (I must get round to refactoring out the
common GL setup code though, it's in 3 places now!).
Thanks for the feedback!
--
Peter Clifton
Electrical Engineering Division,
Engineering Department,
University of Cambridge,
9, JJ Thomson Avenue,
Cambridge
CB3 0FA
Tel: +44 (0)7729 980173 - (No signal in the lab!)
From b2e8f90bdd4583ec3c1516604b2323b1a1363d31 Mon Sep 17 00:00:00 2001
From: Peter Clifton <pcjc2@xxxxxxxxx>
Date: Wed, 1 Apr 2009 13:45:12 +0100
Subject: [PATCH] Improve reporting of DRC errors to the GUI
---
src/Makefile.am | 1 +
src/find.c | 464 ++++++++++++++++++++----
src/hid.h | 20 +-
src/hid/gtk/gtkhid-main.c | 3 +-
src/hid/gtk/gui-drc-window.c | 840 ++++++++++++++++++++++++++++++++++++++++--
src/hid/gtk/gui-drc-window.h | 111 ++++++
src/hid/gtk/gui.h | 1 +
7 files changed, 1351 insertions(+), 89 deletions(-)
create mode 100644 src/hid/gtk/gui-drc-window.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 77e4467..f35a45f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -242,6 +242,7 @@ LIBGTK_SRCS = \
hid/gtk/gui-dialog-size.c \
hid/gtk/gui-dialog.c \
hid/gtk/gui-drc-window.c \
+ hid/gtk/gui-drc-window.h \
hid/gtk/gui-keyref-window.c \
hid/gtk/gui-library-window.c \
hid/gtk/gui-library-window.h \
diff --git a/src/find.c b/src/find.c
index 748d389..8f3ebb8 100644
--- a/src/find.c
+++ b/src/find.c
@@ -157,6 +157,52 @@ RCSID ("$Id$");
#define IS_PV_ON_PAD(PV,Pad) \
( IsPointInPad((PV)->X, (PV)->Y, MAX((PV)->Thickness/2 +Bloat,0), (Pad)))
+#define LENGTH_TO_HUMAN(value) (Settings.grid_units_mm ? ((value) / 100000.0 * 25.4) : ((value) / 100.0))
+#define LENGTH_DIGITS (Settings.grid_units_mm ? 4 : 2)
+#define LENGTH_UNITS_STRING (Settings.grid_units_mm ? "mm" : "mils")
+
+
+static DRC_VIOLATION
+*pcb_drc_violation_new (char *title,
+ char *explanation,
+ int x, int y,
+ int angle,
+ int have_measured,
+ double measured_value,
+ double required_value,
+ int value_digits,
+ const char *value_units,
+ int object_count,
+ long int *object_id_list,
+ int *object_type_list)
+{
+ DRC_VIOLATION *violation = malloc (sizeof (DRC_VIOLATION));
+
+ violation->title = strdup (title);
+ violation->explanation = strdup (explanation);
+ violation->x = x;
+ violation->y = y;
+ violation->angle = angle;
+ violation->have_measured = have_measured;
+ violation->measured_value = measured_value;
+ violation->required_value = required_value;
+ violation->value_digits = value_digits;
+ violation->value_units = value_units;
+ violation->object_count = object_count;
+ violation->object_id_list = object_id_list;
+ violation->object_type_list = object_type_list;
+
+ return violation;
+}
+
+static void
+pcb_drc_violation_free (DRC_VIOLATION *violation)
+{
+ free (violation->title);
+ free (violation->explanation);
+ free (violation);
+}
+
static char drc_dialog_message[289] = {0,};
static void
reset_drc_dialog_message(void)
@@ -184,7 +230,8 @@ append_drc_dialog_message(const char *fmt, ...)
if (gui->drc_gui != NULL)
{
- gui->drc_gui->append_drc_dialog_messagev (fmt, ap);
+ printf ("FUBAR\n");
+ //gui->drc_gui->append_drc_dialog_messagev (fmt, ap);
}
else
{
@@ -200,6 +247,18 @@ append_drc_dialog_message(const char *fmt, ...)
va_end (ap);
}
+static void
+append_drc_violation (DRC_VIOLATION *violation)
+{
+ if (gui->drc_gui != NULL)
+ {
+ gui->drc_gui->append_drc_violation (violation);
+ }
+ else
+ {
+ /* FALLBACK TO THE OLD WAY? */
+ }
+}
/*
* message when asked about continuing DRC checks after next
* violation is found.
@@ -216,7 +275,7 @@ throw_drc_dialog(void)
if (gui->drc_gui != NULL)
{
r = gui->drc_gui->throw_drc_dialog ();
- gui->drc_gui->reset_drc_dialog_message ();
+// gui->drc_gui->reset_drc_dialog_message ();
}
else
{
@@ -288,6 +347,8 @@ static Boolean PrintAndSelectUnusedPinsAndPadsOfElement (ElementTypePtr,
static void DrawNewConnections (void);
static void ResetConnections (Boolean);
static void DumpList (void);
+static void LocateError (LocationType *, LocationType *);
+static void BuildObjectList (int *, long int **, int **);
static void GotoError (void);
static Boolean DRCFind (int, void *, void *, void *);
static Boolean ListStart (int, void *, void *, void *);
@@ -3494,6 +3555,12 @@ DumpList (void)
static Boolean
DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
{
+ LocationType x, y;
+ int object_count;
+ long int *object_id_list;
+ int *object_type_list;
+ DRC_VIOLATION *violation;
+
// reset_drc_dialog_message();
if (PCB->Shrink != 0)
{
@@ -3515,7 +3582,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
Message
(_
("WARNING!! Design Rule Error - potential for broken trace!\n"));
- append_drc_dialog_message(_("potential for broken trace\n"));
/* make the flag changes undoable */
TheFlag = FOUNDFLAG | SELECTEDFLAG;
ResetConnections (False);
@@ -3538,7 +3604,26 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
User = False;
drc = False;
drcerr_count++;
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Potential for broken trace"),
+ _("Insufficient overlap between objects can lead to broken tracks\n"
+ "due to registration errors with old wheel style photo-plotters."),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ FALSE, /* MEASUREMENT OF ERROR UNKNOWN */
+ 0, /* MAGNITUDE OF ERROR UNKNOWN */
+ LENGTH_TO_HUMAN(PCB->Shrink),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
+
if (!throw_drc_dialog())
return (True);
IncrementUndoSerialNumber ();
@@ -3558,7 +3643,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
{
DumpList ();
Message (_("WARNING! Design Rule error - copper areas too close!\n"));
- append_drc_dialog_message(_("copper areas too close\n"));
/* make the flag changes undoable */
TheFlag = FOUNDFLAG | SELECTEDFLAG;
ResetConnections (False);
@@ -3579,7 +3663,25 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
DoIt (True, True);
DumpList ();
drcerr_count++;
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Copper areas too close"),
+ _("Circuits that are too close may bridge during imaging, etching,\n"
+ "plating, or soldering processes resulting in a direct short."),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ FALSE, /* MEASUREMENT OF ERROR UNKNOWN */
+ 0, /* MAGNITUDE OF ERROR UNKNOWN */
+ LENGTH_TO_HUMAN(PCB->Bloat),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
User = False;
drc = False;
if (!throw_drc_dialog())
@@ -3630,6 +3732,13 @@ static int
drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
int type, void *ptr1, void *ptr2)
{
+ char *message;
+ LocationType x, y;
+ int object_count;
+ long int *object_id_list;
+ int *object_type_list;
+ DRC_VIOLATION *violation;
+
LineTypePtr line = (LineTypePtr) ptr2;
ArcTypePtr arc = (ArcTypePtr) ptr2;
PinTypePtr pin = (PinTypePtr) ptr2;
@@ -3646,9 +3755,8 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
{
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, line);
- Message (_("Line with insufficient clearance inside polygon\n"));
- append_drc_dialog_message(_("line inside polygon\n"
- "with insufficient clearance\n"));
+ message = _("Line with insufficient clearance inside polygon\n");
+ Message (message);
goto doIsBad;
}
break;
@@ -3657,9 +3765,8 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
{
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, arc);
- Message (_("Arc with insufficient clearance inside polygon\n"));
- append_drc_dialog_message(_("arc inside polygon\n"
- "with insufficient clearance\n"));
+ message = _("Arc with insufficient clearance inside polygon\n");
+ Message (message);
goto doIsBad;
}
break;
@@ -3669,9 +3776,8 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
{
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, pad);
- Message (_("Pad with insufficient clearance inside polygon\n"));
- append_drc_dialog_message(_("pad inside polygon\n"
- "with insufficient clearance\n"));
+ message = _("Pad with insufficient clearance inside polygon\n");
+ Message (message);
goto doIsBad;
}
break;
@@ -3680,9 +3786,8 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
{
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, pin);
- Message (_("Pin with insufficient clearance inside polygon\n"));
- append_drc_dialog_message(_("pin inside polygon\n"
- "with insufficient clearance\n"));
+ message = _("Pin with insufficient clearance inside polygon\n");
+ Message (message);
goto doIsBad;
}
break;
@@ -3691,16 +3796,15 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
{
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, pin);
- Message (_("Via with insufficient clearance inside polygon\n"));
- append_drc_dialog_message(_("via inside polygon\n"
- "with insufficient clearance\n"));
+ message = _("Via with insufficient clearance inside polygon\n");
+ Message (message);
goto doIsBad;
}
break;
default:
Message ("hace: Bad Plow object in callback\n");
- append_drc_dialog_message(_("wrong object inside polygon\n"
- "with insufficient clearance\n"));
+// append_drc_dialog_message(_("wrong object inside polygon\n"
+// "with insufficient clearance\n"));
}
return 0;
@@ -3710,7 +3814,25 @@ doIsBad:
DrawPolygon (layer, polygon, 0);
DrawObject (type, ptr1, ptr2, 0);
drcerr_count++;
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (message,
+ _("Circuits that are too close may bridge during imaging, etching,\n"
+ "plating, or soldering processes resulting in a direct short."),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ FALSE, /* MEASUREMENT OF ERROR UNKNOWN */
+ 0, /* MAGNITUDE OF ERROR UNKNOWN */
+ LENGTH_TO_HUMAN(PCB->Bloat),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -3728,9 +3850,16 @@ doIsBad:
int
DRCAll (void)
{
+ LocationType x, y;
+ int object_count;
+ long int *object_id_list;
+ int *object_type_list;
+ DRC_VIOLATION *violation;
int tmpcnt;
int nopastecnt = 0;
+ reset_drc_dialog_message();
+
IsBad = False;
drcerr_count = 0;
SaveStackAndVisibility ();
@@ -3806,11 +3935,28 @@ DRCAll (void)
AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
SET_FLAG (TheFlag, line);
Message (_("Line is too thin\n"));
- append_drc_dialog_message(_("too thin line\n"));
DrawLine (layer, line, 0);
drcerr_count++;
SetThing (LINE_TYPE, layer, line, line);
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Line width is too thin"),
+ _("Process specifications dictate a minimum feature-width\n"
+ "that can reliably be reproduced"),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ TRUE, /* MEASUREMENT OF ERROR KNOWN */
+ LENGTH_TO_HUMAN(line->Thickness),
+ LENGTH_TO_HUMAN(PCB->minWid),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -3834,11 +3980,28 @@ DRCAll (void)
AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
SET_FLAG (TheFlag, arc);
Message (_("Arc is too thin\n"));
- append_drc_dialog_message(_("too thin arc\n"));
DrawArc (layer, arc, 0);
drcerr_count++;
SetThing (ARC_TYPE, layer, arc, arc);
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Arc width is too thin"),
+ _("Process specifications dictate a minimum feature-width\n"
+ "that can reliably be reproduced"),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ TRUE, /* MEASUREMENT OF ERROR KNOWN */
+ LENGTH_TO_HUMAN(arc->Thickness),
+ LENGTH_TO_HUMAN(PCB->minWid),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -3864,11 +4027,28 @@ DRCAll (void)
SET_FLAG (TheFlag, pin);
Message (_
("Pin annular ring is too small based on minimum annular ring\n"));
- append_drc_dialog_message(_("pin ring thinner\nthan min annular ring\n"));
DrawPin (pin, 0);
drcerr_count++;
SetThing (PIN_TYPE, element, pin, pin);
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Pin annular ring too small"),
+ _("Annular rings that are too small may erode during etching,\n"
+ "resulting in a broken connection"),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ TRUE, /* MEASUREMENT OF ERROR KNOWN */
+ LENGTH_TO_HUMAN((pin->Thickness - pin->DrillingHole) / 2),
+ LENGTH_TO_HUMAN(PCB->minRing),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -3882,11 +4062,27 @@ DRCAll (void)
AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
SET_FLAG (TheFlag, pin);
Message (_("Pin drill size is too small\n"));
- append_drc_dialog_message(_("too small pin drill\n"));
DrawPin (pin, 0);
drcerr_count++;
SetThing (PIN_TYPE, element, pin, pin);
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Pin drill size is too small"),
+ _("Process rules dictate the minimum drill size which can be used"),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ TRUE, /* MEASUREMENT OF ERROR KNOWN */
+ LENGTH_TO_HUMAN(pin->DrillingHole),
+ LENGTH_TO_HUMAN(PCB->minDrill),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -3910,11 +4106,28 @@ DRCAll (void)
AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
SET_FLAG (TheFlag, pad);
Message (_("Pad is too thin\n"));
- append_drc_dialog_message(_("too thin pad\n"));
DrawPad (pad, 0);
drcerr_count++;
SetThing (PAD_TYPE, element, pad, pad);
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Pad is too thin"),
+ _("Pads which are too thin may erode during etching,\n"
+ "resulting in a broken or unreliable connection"),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ TRUE, /* MEASUREMENT OF ERROR KNOWN */
+ LENGTH_TO_HUMAN(pad->Thickness),
+ LENGTH_TO_HUMAN(PCB->minWid),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -3940,11 +4153,28 @@ DRCAll (void)
SET_FLAG (TheFlag, via);
Message (_
("Via annular ring is too small based on minimum annular ring\n"));
- append_drc_dialog_message(_("via ring thinner\nthan min annular ring\n"));
DrawVia (via, 0);
drcerr_count++;
SetThing (VIA_TYPE, via, via, via);
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Via annular ring too small"),
+ _("Annular rings that are too small may erode during etching,\n"
+ "resulting in a broken connection"),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ TRUE, /* MEASUREMENT OF ERROR KNOWN */
+ LENGTH_TO_HUMAN((via->Thickness - via->DrillingHole) / 2),
+ LENGTH_TO_HUMAN(PCB->minRing),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -3958,11 +4188,27 @@ DRCAll (void)
AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
SET_FLAG (TheFlag, via);
Message (_("Via drill size is too small\n"));
- append_drc_dialog_message(_("too small via drill\n"));
DrawVia (via, 0);
drcerr_count++;
SetThing (VIA_TYPE, via, via, via);
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Via drill size is too small"),
+ _("Process rules dictate the minimum drill size which can be used"),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ TRUE, /* MEASUREMENT OF ERROR KNOWN */
+ LENGTH_TO_HUMAN(via->DrillingHole),
+ LENGTH_TO_HUMAN(PCB->minDrill),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -3991,11 +4237,28 @@ DRCAll (void)
{
SET_FLAG (TheFlag, line);
Message (_("Silk line is too thin\n"));
- append_drc_dialog_message(_("too thin silk line\n"));
DrawLine (layer, line, 0);
drcerr_count++;
SetThing (LINE_TYPE, layer, line, line);
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+ violation = pcb_drc_violation_new (_("Silk line is too thin"),
+ _("Process specifications dictate a minimum silkscreen feature-width\n"
+ "that can reliably be reproduced"),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ TRUE, /* MEASUREMENT OF ERROR KNOWN */
+ LENGTH_TO_HUMAN(line->Thickness),
+ LENGTH_TO_HUMAN(PCB->minSlk),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -4022,16 +4285,51 @@ DRCAll (void)
END_LOOP;
if (tmpcnt > 0)
{
+ char *title;
+ char *name;
+ char *buffer;
+ int buflen;
+
SET_FLAG (TheFlag, element);
Message (_("Element %s has %d silk lines which are too thin\n"),
UNKNOWN (NAMEONPCB_NAME (element)), tmpcnt);
- append_drc_dialog_message (_
- ("%i silk lines\n of element %s\nare too thin\n"),
- tmpcnt, UNKNOWN (NAMEONPCB_NAME (element)));
+// append_drc_dialog_message (_
+// ("%i silk lines\n of element %s\nare too thin\n"),
+// tmpcnt, UNKNOWN (NAMEONPCB_NAME (element)));
DrawElement (element, 0);
drcerr_count++;
SetThing (ELEMENT_TYPE, element, element, element);
- GotoError ();
+ LocateError (&x, &y);
+ BuildObjectList (&object_count, &object_id_list, &object_type_list);
+
+ title = _("Element %s has %i silk lines which are too thin");
+ name = UNKNOWN (NAMEONPCB_NAME (element));
+
+ /* -4 is for the %s and %i place-holders */
+ /* +11 is the max printed length for a 32 bit integer */
+ /* +1 is for the \0 termination */
+ buflen = strlen (title) - 4 + strlen (name) + 11 + 1;
+ buffer = malloc (buflen);
+ snprintf (buffer, buflen, title, name, tmpcnt);
+
+ violation = pcb_drc_violation_new (buffer,
+ _("Process specifications dictate a minimum silkscreen\n"
+ "feature-width that can reliably be reproduced"),
+ x, y,
+ 0, /* ANGLE OF ERROR UNKNOWN */
+ 0, /* MINIMUM OFFENDING WIDTH UNKNOWN */
+ TRUE, /* MEASUREMENT OF ERROR KNOWN */
+ LENGTH_TO_HUMAN(PCB->minSlk),
+ LENGTH_DIGITS,
+ LENGTH_UNITS_STRING,
+ object_count,
+ object_id_list,
+ object_type_list);
+ free (buffer);
+ append_drc_violation (violation);
+ pcb_drc_violation_free (violation);
+ free (object_id_list);
+ free (object_type_list);
if (!throw_drc_dialog())
{
IsBad = True;
@@ -4063,36 +4361,34 @@ DRCAll (void)
}
/*----------------------------------------------------------------------------
- * center the display to show the offending item (thing)
+ * Locate the coordinatates of offending item (thing)
*/
static void
-GotoError (void)
+LocateError (LocationType *x, LocationType *y)
{
- LocationType X, Y;
-
switch (thing_type)
{
case LINE_TYPE:
{
LineTypePtr line = (LineTypePtr) thing_ptr3;
- X = (line->Point1.X + line->Point2.X) / 2;
- Y = (line->Point1.Y + line->Point2.Y) / 2;
+ *x = (line->Point1.X + line->Point2.X) / 2;
+ *y = (line->Point1.Y + line->Point2.Y) / 2;
break;
}
case ARC_TYPE:
{
ArcTypePtr arc = (ArcTypePtr) thing_ptr3;
- X = arc->X;
- Y = arc->Y;
+ *x = arc->X;
+ *y = arc->Y;
break;
}
case POLYGON_TYPE:
{
PolygonTypePtr polygon = (PolygonTypePtr) thing_ptr3;
- X =
+ *x =
(polygon->Clipped->contours->xmin +
polygon->Clipped->contours->xmax) / 2;
- Y =
+ *y =
(polygon->Clipped->contours->ymin +
polygon->Clipped->contours->ymax) / 2;
break;
@@ -4101,33 +4397,75 @@ GotoError (void)
case VIA_TYPE:
{
PinTypePtr pin = (PinTypePtr) thing_ptr3;
- X = pin->X;
- Y = pin->Y;
+ *x = pin->X;
+ *y = pin->Y;
break;
}
case PAD_TYPE:
{
PadTypePtr pad = (PadTypePtr) thing_ptr3;
- X = (pad->Point1.X + pad->Point2.X) / 2;
- Y = (pad->Point1.Y + pad->Point2.Y) / 2;
+ *x = (pad->Point1.X + pad->Point2.X) / 2;
+ *y = (pad->Point1.Y + pad->Point2.Y) / 2;
break;
}
case ELEMENT_TYPE:
{
ElementTypePtr element = (ElementTypePtr) thing_ptr3;
- X = element->MarkX;
- Y = element->MarkY;
+ *x = element->MarkX;
+ *y = element->MarkY;
break;
}
default:
return;
}
+}
+
+
+/*----------------------------------------------------------------------------
+ * Build a list of the of offending items by ID. (Currently just "thing")
+ */
+static void
+BuildObjectList (int *object_count, long int **object_id_list, int **object_type_list)
+{
+ *object_count = 0;
+ *object_id_list = NULL;
+
+ switch (thing_type)
+ {
+ case LINE_TYPE:
+ case ARC_TYPE:
+ case POLYGON_TYPE:
+ case PIN_TYPE:
+ case VIA_TYPE:
+ case PAD_TYPE:
+ case ELEMENT_TYPE:
+ *object_count = 1;
+ *object_id_list = malloc (sizeof (long int));
+ *object_type_list = malloc (sizeof (int));
+ **object_id_list = ((AnyObjectType *)thing_ptr3)->ID;
+ **object_type_list = thing_type;
+ return;
+
+ default:
+ return;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ * center the display to show the offending item (thing)
+ */
+static void
+GotoError (void)
+{
+ LocationType X, Y;
+
+ LocateError (&X, &Y);
+
{
- int digits = Settings.grid_units_mm ? 4: 2;
double scale = Settings.grid_units_mm ? COOR_TO_MM : 1./100,
x = X * scale, y = Y * scale;
- Message (_("near location (%.*f,%.*f)\n"), digits, x, digits, y);
- append_drc_dialog_message("near (%.*f,%.*f)\n", digits, x, digits, y);
+ Message (_("near location (%.*f,%.*f)\n"), LENGTH_DIGITS, x, LENGTH_DIGITS, y);
}
switch (thing_type)
{
diff --git a/src/hid.h b/src/hid.h
index ee62369..2bbe9fd 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -229,11 +229,29 @@ typedef enum
PCB_WATCH_HANGUP = 1 << 3 /**< As in POLLHUP */
} PCBWatchFlags;
+typedef struct
+{
+ char *title;
+ char *explanation;
+ int x;
+ int y;
+ int angle;
+ int have_measured;
+ double measured_value;
+ double required_value;
+ int value_digits;
+ const char *value_units;
+ int object_count;
+ long int *object_id_list;
+ int *object_type_list;
+} DRC_VIOLATION;
+
/* DRC GUI Hooks */
typedef struct
{
void (*reset_drc_dialog_message) (void);
- void (*append_drc_dialog_messagev) (const char *fmt, va_list va);
+ void (*append_drc_violation) (DRC_VIOLATION *violation);
+// void (*append_drc_dialog_messagev) (const char *fmt, va_list va);
int (*throw_drc_dialog) (void);
} HID_DRC_GUI;
diff --git a/src/hid/gtk/gtkhid-main.c b/src/hid/gtk/gtkhid-main.c
index bb5b3d7..4653335 100644
--- a/src/hid/gtk/gtkhid-main.c
+++ b/src/hid/gtk/gtkhid-main.c
@@ -1476,7 +1476,8 @@ ghid_progress (int so_far, int total, const char *message)
/* ---------------------------------------------------------------------- */
HID_DRC_GUI ghid_drc_gui = {
ghid_drc_window_reset_message,
- ghid_drc_window_append_messagev,
+ ghid_drc_window_append_violation,
+// ghid_drc_window_append_messagev,
ghid_drc_window_throw_dialog
};
diff --git a/src/hid/gtk/gui-drc-window.c b/src/hid/gtk/gui-drc-window.c
index 9298729..b443a0d 100644
--- a/src/hid/gtk/gui-drc-window.c
+++ b/src/hid/gtk/gui-drc-window.c
@@ -30,7 +30,13 @@
#include "config.h"
#endif
+#include "error.h"
+#include "search.h"
+#include "draw.h"
+#include "undo.h"
+#include "set.h"
#include "gui.h"
+#include "gui-drc-window.h"
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
@@ -39,7 +45,8 @@
RCSID ("$Id$");
static GtkWidget *drc_window, *drc_list;
-
+static GtkListStore *drc_list_model = NULL;
+static int num_violations = 0;
/* Remember user window resizes. */
static gint
@@ -66,10 +73,720 @@ drc_destroy_cb (GtkWidget * widget, gpointer data)
drc_window = NULL;
}
+enum {
+ DRC_VIOLATION_NUM_COL = 0,
+ DRC_VIOLATION_OBJ_COL,
+ DRC_OBJECT_COUNT_COL,
+ DRC_OBJECT_ID_LIST_COL,
+ DRC_OBJECT_TYPE_LIST_COL,
+ NUM_DRC_COLUMNS
+};
+
+
+#warning NASTY, DOESNT USE UNDO PROPERLY
+static void
+unset_found_flags (int AndDraw)
+{
+ int flag = FOUNDFLAG;
+ int change = 0;
+
+ VIA_LOOP (PCB->Data);
+ {
+ if (TEST_FLAG (flag, via))
+ {
+ if (AndDraw)
+ AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
+ CLEAR_FLAG (flag, via);
+ if (AndDraw)
+ DrawVia (via, 0);
+ change = True;
+ }
+ }
+ END_LOOP;
+ ELEMENT_LOOP (PCB->Data);
+ {
+ PIN_LOOP (element);
+ {
+ if (TEST_FLAG (flag, pin))
+ {
+ if (AndDraw)
+ AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
+ CLEAR_FLAG (flag, pin);
+ if (AndDraw)
+ DrawPin (pin, 0);
+ change = True;
+ }
+ }
+ END_LOOP;
+ PAD_LOOP (element);
+ {
+ if (TEST_FLAG (flag, pad))
+ {
+ if (AndDraw)
+ AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
+ CLEAR_FLAG (flag, pad);
+ if (AndDraw)
+ DrawPad (pad, 0);
+ change = True;
+ }
+ }
+ END_LOOP;
+ }
+ END_LOOP;
+ RAT_LOOP (PCB->Data);
+ {
+ if (TEST_FLAG (flag, line))
+ {
+ if (AndDraw)
+ AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
+ CLEAR_FLAG (flag, line);
+ if (AndDraw)
+ DrawRat (line, 0);
+ change = True;
+ }
+ }
+ END_LOOP;
+ COPPERLINE_LOOP (PCB->Data);
+ {
+ if (TEST_FLAG (flag, line))
+ {
+ if (AndDraw)
+ AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
+ CLEAR_FLAG (flag, line);
+ if (AndDraw)
+ DrawLine (layer, line, 0);
+ change = True;
+ }
+ }
+ ENDALL_LOOP;
+ COPPERARC_LOOP (PCB->Data);
+ {
+ if (TEST_FLAG (flag, arc))
+ {
+ if (AndDraw)
+ AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
+ CLEAR_FLAG (flag, arc);
+ if (AndDraw)
+ DrawArc (layer, arc, 0);
+ change = True;
+ }
+ }
+ ENDALL_LOOP;
+ COPPERPOLYGON_LOOP (PCB->Data);
+ {
+ if (TEST_FLAG (flag, polygon))
+ {
+ if (AndDraw)
+ AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
+ CLEAR_FLAG (flag, polygon);
+ if (AndDraw)
+ DrawPolygon (layer, polygon, 0);
+ change = True;
+ }
+ }
+ ENDALL_LOOP;
+ if (change)
+ {
+ SetChangedFlag (True);
+ if (AndDraw)
+ {
+ IncrementUndoSerialNumber ();
+ Draw ();
+ }
+ }
+}
+
+static void
+selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GhidDrcViolation *violation;
+ int object_count;
+#if 0
+ long int *object_id_list;
+ int *object_type_list;
+#else
+ long int object_id;
+ int object_type;
+#endif
+ int i;
+
+#warning CHEATING HERE!
+ /* I happen to know I'm only putting 0 or 1 items in the lists of objects.
+ To do this properly requires some memory allocation and tracking to
+ avoid leaks! */
+
+ /* Check there is anything selected, if not; return */
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ /* Unflag objects */
+ unset_found_flags (True);
+ return;
+ }
+
+ /* Check the selected node has children, if so; return. */
+ if (gtk_tree_model_iter_has_child (model, &iter))
+ return;
+
+ gtk_tree_model_get (model, &iter,
+ DRC_VIOLATION_OBJ_COL, &violation,
+ DRC_OBJECT_COUNT_COL, &object_count,
+#if 0
+ DRC_OBJECT_ID_LIST_COL, &object_id_list,
+ DRC_OBJECT_TYPE_LIST_COL, &object_type_list,
+#else
+ DRC_OBJECT_ID_LIST_COL, &object_id,
+ DRC_OBJECT_TYPE_LIST_COL, &object_type,
+#endif
+ -1);
+
+ unset_found_flags (False);
+
+ if (violation == NULL)
+ return;
+
+ /* Flag the objects listed against this DRC violation */
+ for (i = 0; i < object_count; i++)
+ {
+ int found_type;
+ void *ptr1, *ptr2, *ptr3;
+
+ found_type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3,
+ object_id, object_type);
+ if (found_type == NO_TYPE)
+ {
+ Message (_("Object ID %i identified during DRC was not found. Stale DRC window?\n"),
+ object_id);
+ continue;
+ }
+ SET_FLAG (FOUNDFLAG, (AnyObjectType *)ptr2);
+ switch (object_type)
+ {
+ case LINE_TYPE:
+ case ARC_TYPE:
+ case POLYGON_TYPE:
+ ChangeGroupVisibility (GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1), True, True);
+ }
+ DrawObject (object_type, ptr1, ptr2, 0);
+ }
+ Draw();
+ CenterDisplay (violation->x_coord, violation->y_coord, False);
+}
+
+
+enum
+{
+ PROP_TITLE = 1,
+ PROP_EXPLANATION,
+ PROP_X_COORD,
+ PROP_Y_COORD,
+ PROP_ANGLE,
+ PROP_HAVE_MEASURED,
+ PROP_MEASURED_VALUE,
+ PROP_REQUIRED_VALUE,
+ PROP_VALUE_DIGITS,
+ PROP_VALUE_UNITS
+};
+
+
+static GObjectClass *ghid_drc_violation_parent_class = NULL;
+
+
+/*! \brief GObject finalise handler
+ *
+ * \par Function Description
+ * Just before the GhidDrcViolation GObject is finalized, free our
+ * allocated data, and then chain up to the parent's finalize handler.
+ *
+ * \param [in] widget The GObject being finalized.
+ */
+static void
+ghid_drc_violation_finalize (GObject * object)
+{
+ GhidDrcViolation *violation = GHID_DRC_VIOLATION (object);
+
+ g_free (violation->title);
+ g_free (violation->explanation);
+ g_free (violation->value_units);
+
+ G_OBJECT_CLASS (ghid_drc_violation_parent_class)->finalize (object);
+}
+
+/*! \brief GObject property setter function
+ *
+ * \par Function Description
+ * Setter function for GhidDrcViolation's GObject properties,
+ * "settings-name" and "toplevel"
+ *
+ * \param [in] object The GObject whose properties we are setting
+ * \param [in] property_id The numeric id. under which the property was
+ * registered with g_object_class_install_property()
+ * \param [in] value The GValue the property is being set from
+ * \param [in] pspec A GParamSpec describing the property being set
+ */
+static void
+ghid_drc_violation_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GhidDrcViolation *violation = GHID_DRC_VIOLATION (object);
+
+ switch (property_id)
+ {
+ case PROP_TITLE:
+ g_free (violation->title);
+ violation->title = g_value_dup_string (value);
+ break;
+ case PROP_EXPLANATION:
+ g_free (violation->explanation);
+ violation->explanation = g_value_dup_string (value);
+ break;
+ case PROP_X_COORD:
+ violation->x_coord = g_value_get_int (value);
+ break;
+ case PROP_Y_COORD:
+ violation->y_coord = g_value_get_int (value);
+ break;
+ case PROP_ANGLE:
+ violation->angle = g_value_get_int (value);
+ break;
+ case PROP_HAVE_MEASURED:
+ violation->have_measured = g_value_get_int (value);
+ break;
+ case PROP_MEASURED_VALUE:
+ violation->measured_value = g_value_get_double (value);
+ break;
+ case PROP_REQUIRED_VALUE:
+ violation->required_value = g_value_get_double (value);
+ break;
+ case PROP_VALUE_DIGITS:
+ violation->value_digits = g_value_get_int (value);
+ break;
+ case PROP_VALUE_UNITS:
+ g_free (violation->value_units);
+ violation->value_units = g_value_dup_string (value);
+ break;
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ return;
+ }
+}
+
+
+/*! \brief GObject property getter function
+ *
+ * \par Function Description
+ * Getter function for GhidDrcViolation's GObject properties,
+ * "settings-name" and "toplevel".
+ *
+ * \param [in] object The GObject whose properties we are getting
+ * \param [in] property_id The numeric id. under which the property was
+ * registered with g_object_class_install_property()
+ * \param [out] value The GValue in which to return the value of the property
+ * \param [in] pspec A GParamSpec describing the property being got
+ */
+static void
+ghid_drc_violation_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+
+}
+
+
+/*! \brief GType class initialiser for GhidDrcViolation
+ *
+ * \par Function Description
+ * GType class initialiser for GhidDrcViolation. We override our parent
+ * virtual class methods as needed and register our GObject properties.
+ *
+ * \param [in] klass The GhidDrcViolationClass we are initialising
+ */
+static void
+ghid_drc_violation_class_init (GhidViolationRendererClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = ghid_drc_violation_finalize;
+ gobject_class->set_property = ghid_drc_violation_set_property;
+ gobject_class->get_property = ghid_drc_violation_get_property;
+
+ ghid_drc_violation_parent_class = g_type_class_peek_parent (klass);
+
+ g_object_class_install_property (gobject_class, PROP_TITLE,
+ g_param_spec_string ("title",
+ "",
+ "",
+ "",
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_EXPLANATION,
+ g_param_spec_string ("explanation",
+ "",
+ "",
+ "",
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_X_COORD,
+ g_param_spec_int ("x-coord",
+ "",
+ "",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_Y_COORD,
+ g_param_spec_int ("y-coord",
+ "",
+ "",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_ANGLE,
+ g_param_spec_int ("angle",
+ "",
+ "",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_HAVE_MEASURED,
+ g_param_spec_int ("have-measured",
+ "",
+ "",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_MEASURED_VALUE,
+ g_param_spec_double ("measured-value",
+ "",
+ "",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0.,
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_REQUIRED_VALUE,
+ g_param_spec_double ("required-value",
+ "",
+ "",
+ -G_MINDOUBLE,
+ G_MAXDOUBLE,
+ 0.,
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_VALUE_DIGITS,
+ g_param_spec_int ("value-digits",
+ "",
+ "",
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_VALUE_UNITS,
+ g_param_spec_string ("value-units",
+ "",
+ "",
+ "",
+ G_PARAM_WRITABLE));
+}
+
+
+
+/*! \brief Function to retrieve GhidViolationRenderer's GType identifier.
+ *
+ * \par Function Description
+ * Function to retrieve GhidViolationRenderer's GType identifier.
+ * Upon first call, this registers the GhidViolationRenderer in the GType system.
+ * Subsequently it returns the saved value from its first execution.
+ *
+ * \return the GType identifier associated with GhidViolationRenderer.
+ */
+GType
+ghid_drc_violation_get_type ()
+{
+ static GType ghid_drc_violation_type = 0;
+
+ if (!ghid_drc_violation_type)
+ {
+ static const GTypeInfo ghid_drc_violation_info = {
+ sizeof (GhidDrcViolationClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) ghid_drc_violation_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GhidDrcViolation),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ };
+
+ ghid_drc_violation_type =
+ g_type_register_static (G_TYPE_OBJECT, "GhidDrcViolation",
+ &ghid_drc_violation_info, 0);
+ }
+
+ return ghid_drc_violation_type;
+}
+
+
+GhidDrcViolation *ghid_drc_violation_new (char *title,
+ char *explanation,
+ int x_coord,
+ int y_coord,
+ int angle,
+ int have_measured,
+ double measured_value,
+ double required_value,
+ int value_digits,
+ const char *value_units,
+ int object_count,
+ long int object_id,
+ int object_type)
+{
+ GhidDrcViolation *violation = g_object_new (GHID_TYPE_DRC_VIOLATION,
+ "title", title,
+ "explanation", explanation,
+ "x-coord", x_coord,
+ "y-coord", y_coord,
+ "angle", angle,
+ "have-measured", have_measured,
+ "measured-value", measured_value,
+ "required-value", required_value,
+ "value-digits", value_digits,
+ "value-units", value_units,
+ NULL);
+// violation->object_count = object_count;
+// violation->object_id = object_id;
+// violation->object_type = object_type;
+ return violation;
+}
+
+enum
+{
+ PROP_VIOLATION = 1,
+};
+
+
+static GObjectClass *ghid_violation_renderer_parent_class = NULL;
+
+
+/*! \brief GObject finalise handler
+ *
+ * \par Function Description
+ * Just before the GhidViolationRenderer GObject is finalized, free our
+ * allocated data, and then chain up to the parent's finalize handler.
+ *
+ * \param [in] widget The GObject being finalized.
+ */
+static void
+ghid_violation_renderer_finalize (GObject * object)
+{
+ GhidViolationRenderer *renderer = GHID_VIOLATION_RENDERER (object);
+
+ if (renderer->violation != NULL)
+ g_object_unref (renderer->violation);
+
+ G_OBJECT_CLASS (ghid_violation_renderer_parent_class)->finalize (object);
+}
+
+
+/*! \brief GObject property setter function
+ *
+ * \par Function Description
+ * Setter function for GhidViolationRenderer's GObject properties,
+ * "settings-name" and "toplevel".
+ *
+ * \param [in] object The GObject whose properties we are setting
+ * \param [in] property_id The numeric id. under which the property was
+ * registered with g_object_class_install_property()
+ * \param [in] value The GValue the property is being set from
+ * \param [in] pspec A GParamSpec describing the property being set
+ */
+static void
+ghid_violation_renderer_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GhidViolationRenderer *renderer = GHID_VIOLATION_RENDERER (object);
+ char *markup;
+
+ switch (property_id)
+ {
+ case PROP_VIOLATION:
+ if (renderer->violation != NULL)
+ g_object_unref (renderer->violation);
+ renderer->violation = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ return;
+ }
+
+ if (renderer->violation == NULL)
+ return;
+
+ if (renderer->violation->have_measured)
+ {
+ markup = g_strdup_printf ("<b>%s (%.*f %s)</b>\n"
+ "<span font_size='1024'> </span>\n"
+ "<small>"
+ "<i>%s</i>\n"
+ "<span font_size='5120'> </span>\n"
+ "Required: %.*f %s"
+ "</small>",
+ renderer->violation->title,
+ renderer->violation->value_digits,
+ renderer->violation->measured_value,
+ renderer->violation->value_units,
+
+ renderer->violation->explanation,
+
+ renderer->violation->value_digits,
+ renderer->violation->required_value,
+ renderer->violation->value_units);
+ }
+ else
+ {
+ markup = g_strdup_printf ("<b>%s</b>\n"
+ "<span font_size='1024'> </span>\n"
+ "<small>"
+ "<i>%s</i>\n"
+ "<span font_size='5120'> </span>\n"
+ "Required: %.*f %s"
+ "</small>",
+ renderer->violation->title,
+
+ renderer->violation->explanation,
+
+ renderer->violation->value_digits,
+ renderer->violation->required_value,
+ renderer->violation->value_units);
+ }
+
+ /* FIXME: Doing this for every property change along the way is going to be slow! */
+ g_object_set (object, "markup", markup, NULL);
+ g_free (markup);
+}
+
+
+/*! \brief GObject property getter function
+ *
+ * \par Function Description
+ * Getter function for GhidViolationRenderer's GObject properties,
+ * "settings-name" and "toplevel".
+ *
+ * \param [in] object The GObject whose properties we are getting
+ * \param [in] property_id The numeric id. under which the property was
+ * registered with g_object_class_install_property()
+ * \param [out] value The GValue in which to return the value of the property
+ * \param [in] pspec A GParamSpec describing the property being got
+ */
+static void
+ghid_violation_renderer_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+
+}
+
+
+/*! \brief GType class initialiser for GhidViolationRenderer
+ *
+ * \par Function Description
+ * GType class initialiser for GhidViolationRenderer. We override our parent
+ * virtual class methods as needed and register our GObject properties.
+ *
+ * \param [in] klass The GhidViolationRendererClass we are initialising
+ */
+static void
+ghid_violation_renderer_class_init (GhidViolationRendererClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = ghid_violation_renderer_finalize;
+ gobject_class->set_property = ghid_violation_renderer_set_property;
+ gobject_class->get_property = ghid_violation_renderer_get_property;
+
+ ghid_violation_renderer_parent_class = g_type_class_peek_parent (klass);
+
+ g_object_class_install_property (gobject_class, PROP_VIOLATION,
+ g_param_spec_object ("violation",
+ "",
+ "",
+ GHID_TYPE_DRC_VIOLATION,
+ G_PARAM_WRITABLE));
+}
+
+
+/*! \brief Function to retrieve GhidViolationRenderer's GType identifier.
+ *
+ * \par Function Description
+ * Function to retrieve GhidViolationRenderer's GType identifier.
+ * Upon first call, this registers the GhidViolationRenderer in the GType system.
+ * Subsequently it returns the saved value from its first execution.
+ *
+ * \return the GType identifier associated with GhidViolationRenderer.
+ */
+GType
+ghid_violation_renderer_get_type ()
+{
+ static GType ghid_violation_renderer_type = 0;
+
+ if (!ghid_violation_renderer_type)
+ {
+ static const GTypeInfo ghid_violation_renderer_info = {
+ sizeof (GhidViolationRendererClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) ghid_violation_renderer_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GhidViolationRenderer),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ };
+
+ ghid_violation_renderer_type =
+ g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT, "GhidViolationRenderer",
+ &ghid_violation_renderer_info, 0);
+ }
+
+ return ghid_violation_renderer_type;
+}
+
+
+/*! \brief Convenience function to create a new violation renderer
+ *
+ * \par Function Description
+ * Convenience function which creates a GhidViolationRenderer.
+ *
+ * \return The GhidViolationRenderer created.
+ */
+GtkCellRenderer *
+ghid_violation_renderer_new (void)
+{
+ GhidViolationRenderer *renderer;
+
+ renderer = g_object_new (GHID_TYPE_VIOLATION_RENDERER,
+ "ypad", 6,
+ NULL);
+
+ return GTK_CELL_RENDERER (renderer);
+}
+
+
void
ghid_drc_window_show (gboolean raise)
{
- GtkWidget *vbox, *hbox, *button;
+ GtkWidget *vbox, *hbox, *button, *scrolled_window;
+ GtkCellRenderer *violation_renderer;
if (drc_window)
{
@@ -78,7 +795,7 @@ ghid_drc_window_show (gboolean raise)
return;
}
- drc_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ drc_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (drc_window), "destroy",
G_CALLBACK (drc_destroy_cb), NULL);
g_signal_connect (G_OBJECT (drc_window), "configure_event",
@@ -93,9 +810,51 @@ ghid_drc_window_show (gboolean raise)
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_container_add (GTK_CONTAINER (drc_window), vbox);
- drc_list = ghid_scrolled_text_view (vbox, NULL,
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
+ drc_list_model = gtk_list_store_new (NUM_DRC_COLUMNS,
+ G_TYPE_INT, /* DRC_VIOLATION_NUM_COL */
+ G_TYPE_OBJECT, /* DRC_VIOLATION_OBJ_COL */
+ G_TYPE_INT, /* DRC_OBJECT_COUNT_COL */
+#warning CHEATING HERE!
+ /* I happen to know I'm only putting 0 or 1 items in the lists of objects.
+ To do this properly requires some memory allocation and tracking to
+ avoid leaks! */
+#if 0
+ G_TYPE_POINTER, /* DRC_OBJECT_ID_LIST_COL */
+ G_TYPE_POINTER); /* DRC_OBJECT_TYPE_LIST_COL */
+#else
+ G_TYPE_LONG, /* DRC_OBJECT_ID_LIST_COL */
+ G_TYPE_INT); /* DRC_OBJECT_TYPE_LIST_COL */
+#endif
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_box_pack_start (GTK_BOX (vbox), scrolled_window,
+ TRUE /* EXPAND */, TRUE /* FILL */, 0 /* PADDING */);
+
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ drc_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (drc_list_model));
+ gtk_container_add (GTK_CONTAINER (scrolled_window), drc_list);
+
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (drc_list), TRUE);
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (drc_list)), "changed",
+ G_CALLBACK (selection_changed_cb), NULL);
+
+ violation_renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (drc_list),
+ -1, /* APPEND */
+ _("No."), /* TITLE */
+ violation_renderer,
+ "text", DRC_VIOLATION_NUM_COL,
+ NULL);
+
+ violation_renderer = ghid_violation_renderer_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (drc_list),
+ -1, /* APPEND */
+ _("Violation details"), /* TITLE */
+ violation_renderer,
+ "violation", DRC_VIOLATION_OBJ_COL,
+ NULL);
hbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
@@ -111,35 +870,68 @@ ghid_drc_window_show (gboolean raise)
gtk_widget_show_all (drc_window);
}
-static void
-ghid_drc_append_violation (gchar * s)
+#define UNIT1(value) (Settings.grid_units_mm ? ((value) / 100000.0 * 25.4) : ((value) / 100.0))
+#define UNIT(value) UNIT1(value) , (Settings.grid_units_mm ? "mm" : "mils")
+
+void ghid_drc_window_append_violation (DRC_VIOLATION *violation)
{
+ GhidDrcViolation *violation_obj;
+ GtkTreeIter iter;
+ long int ID = 0;
+ int type = NO_TYPE;
+
+ /* Ensure the required structures are setup */
ghid_drc_window_show (FALSE);
-}
-void ghid_drc_window_reset_message (void)
-{
- printf ("RESET DRC WINDOW\n");
-}
+ num_violations++;
-#if 0
-void ghid_drc_window_append_message (const char *fmt, ...)
-{
- va_list va;
- va_start (va, fmt);
- vprintf (fmt, va);
- va_end (va);
+ /* Copy the violating object lists */
+#warning CHEATING HERE!
+ /* I happen to know I'm only putting 0 or 1 items in the lists of objects.
+ To do this properly requires some memory allocation and tracking to
+ avoid leaks! */
+ if (violation->object_count > 0)
+ {
+ ID = violation->object_id_list[0];
+ type = violation->object_type_list[0];
+ }
+
+ violation_obj = ghid_drc_violation_new (violation->title,
+ violation->explanation,
+ violation->x,
+ violation->y,
+ violation->angle,
+ violation->have_measured,
+ violation->measured_value,
+ violation->required_value,
+ violation->value_digits,
+ violation->value_units,
+ violation->object_count,
+ ID, /* violation->object_id_list */
+ type); /* violation->object_type_list */
+
+ gtk_list_store_append (drc_list_model, &iter);
+ gtk_list_store_set (drc_list_model, &iter,
+ DRC_VIOLATION_NUM_COL, num_violations,
+ DRC_VIOLATION_OBJ_COL, violation_obj,
+ DRC_OBJECT_COUNT_COL, violation->object_count,
+ DRC_OBJECT_ID_LIST_COL, ID, /* violation->object_id_list, */
+ DRC_OBJECT_TYPE_LIST_COL, type, /* violation->object_type_list, */
+ -1);
+
+ g_object_unref (violation_obj);
}
-#endif
-void ghid_drc_window_append_messagev (const char *fmt, va_list va)
+void ghid_drc_window_reset_message (void)
{
- vprintf (fmt, va);
+ if (drc_list_model != NULL)
+ gtk_list_store_clear (drc_list_model);
+ num_violations = 0;
}
int ghid_drc_window_throw_dialog (void)
{
- printf ("THROW DRC WINDOW\n");
ghid_drc_window_show (TRUE);
+ return 1;
}
diff --git a/src/hid/gtk/gui-drc-window.h b/src/hid/gtk/gui-drc-window.h
new file mode 100644
index 0000000..56e8769
--- /dev/null
+++ b/src/hid/gtk/gui-drc-window.h
@@ -0,0 +1,111 @@
+/* $Id$ */
+
+/*
+ * COPYRIGHT
+ *
+ * PCB, interactive printed circuit board design
+ * Copyright (C) 1994,1995,1996 Thomas Nau
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Contact addresses for paper mail and Email:
+ * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
+ * Thomas.Nau@xxxxxxxxxxxxx
+ *
+ */
+
+/* This file written by Peter Clifton */
+
+#ifndef __GUI_DRC_WINDOW_H__
+#define __GUI_DRC_WINDOW_H__
+
+
+#define GHID_TYPE_DRC_VIOLATION (ghid_drc_violation_get_type())
+#define GHID_DRC_VIOLATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GHID_TYPE_DRC_VIOLATION, GhidDrcViolation))
+#define GHID_DRC_VIOLATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GHID_TYPE_DRC_VIOLATION, GhidDrcViolationClass))
+#define GHID_IS_DRC_VIOLATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GHID_TYPE_DRC_VIOLATION))
+#define GHID_DRC_VIOLATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GHID_TYPE_DRC_VIOLATION, GhidDrcViolationClass))
+
+typedef struct _GhidDrcViolationClass GhidDrcViolationClass;
+typedef struct _GhidDrcViolation GhidDrcViolation;
+
+
+struct _GhidDrcViolationClass
+{
+ GObjectClass parent_class;
+};
+
+struct _GhidDrcViolation
+{
+ GObject parent_instance;
+
+ char *title;
+ char *explanation;
+ int x_coord;
+ int y_coord;
+ int angle;
+ int have_measured;
+ double measured_value;
+ double required_value;
+ int value_digits;
+ char *value_units;
+};
+
+
+GType ghid_drc_violation_get_type (void);
+
+GhidDrcViolation *ghid_drc_violation_new (char *title,
+ char *explanation,
+ int x_coord,
+ int y_coord,
+ int angle,
+ int have_measured,
+ double measured_value,
+ double required_value,
+ int value_digits,
+ const char *value_units,
+ int object_count,
+ long int object_id,
+ int object_type);
+
+
+#define GHID_TYPE_VIOLATION_RENDERER (ghid_violation_renderer_get_type())
+#define GHID_VIOLATION_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GHID_TYPE_VIOLATION_RENDERER, GhidViolationRenderer))
+#define GHID_VIOLATION_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GHID_TYPE_VIOLATION_RENDERER, GhidViolationRendererClass))
+#define GHID_IS_VIOLATION_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GHID_TYPE_VIOLATION_RENDERER))
+#define GHID_VIOLATION_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GHID_TYPE_VIOLATION_RENDERER, GhidViolationRendererClass))
+
+typedef struct _GhidViolationRendererClass GhidViolationRendererClass;
+typedef struct _GhidViolationRenderer GhidViolationRenderer;
+
+
+struct _GhidViolationRendererClass
+{
+ GtkCellRendererTextClass parent_class;
+};
+
+struct _GhidViolationRenderer
+{
+ GtkCellRendererText parent_instance;
+
+ GhidDrcViolation *violation;
+};
+
+
+GType ghid_violation_renderer_get_type (void);
+
+GtkCellRenderer *ghid_violation_renderer_new (void);
+
+#endif /* __GUI_DRC_WINDOW_H__ */
diff --git a/src/hid/gtk/gui.h b/src/hid/gtk/gui.h
index 734d923..f76e3b3 100644
--- a/src/hid/gtk/gui.h
+++ b/src/hid/gtk/gui.h
@@ -407,6 +407,7 @@ int ghid_attribute_dialog (HID_Attribute *, int, HID_Attr_Val *, const char *, c
/* gui-drc-window.c */
void ghid_drc_window_show (gboolean raise);
void ghid_drc_window_reset_message (void);
+void ghid_drc_window_append_violation (DRC_VIOLATION *violation);
//void ghid_drc_window_append_mesage (const char *fmt, ...);
void ghid_drc_window_append_messagev (const char *fmt, va_list va);
int ghid_drc_window_throw_dialog (void);
--
1.6.0.4
From 52b4fe59449f15df0611a410ff68b54b69a7137a Mon Sep 17 00:00:00 2001
From: Peter Clifton <pcjc2@xxxxxxxxx>
Date: Thu, 2 Apr 2009 17:26:42 +0100
Subject: [PATCH] Remove log messages for individual design rule violatons
---
src/find.c | 21 ---------------------
src/hid/gtk/gui-drc-window.c | 10 +++++-----
2 files changed, 5 insertions(+), 26 deletions(-)
diff --git a/src/find.c b/src/find.c
index 8f3ebb8..d224409 100644
--- a/src/find.c
+++ b/src/find.c
@@ -3579,9 +3579,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
if (DoIt (True, False))
{
DumpList ();
- Message
- (_
- ("WARNING!! Design Rule Error - potential for broken trace!\n"));
/* make the flag changes undoable */
TheFlag = FOUNDFLAG | SELECTEDFLAG;
ResetConnections (False);
@@ -3642,7 +3639,6 @@ DRCFind (int What, void *ptr1, void *ptr2, void *ptr3)
while (DoIt (True, False))
{
DumpList ();
- Message (_("WARNING! Design Rule error - copper areas too close!\n"));
/* make the flag changes undoable */
TheFlag = FOUNDFLAG | SELECTEDFLAG;
ResetConnections (False);
@@ -3756,7 +3752,6 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, line);
message = _("Line with insufficient clearance inside polygon\n");
- Message (message);
goto doIsBad;
}
break;
@@ -3766,7 +3761,6 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, arc);
message = _("Arc with insufficient clearance inside polygon\n");
- Message (message);
goto doIsBad;
}
break;
@@ -3777,7 +3771,6 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, pad);
message = _("Pad with insufficient clearance inside polygon\n");
- Message (message);
goto doIsBad;
}
break;
@@ -3787,7 +3780,6 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, pin);
message = _("Pin with insufficient clearance inside polygon\n");
- Message (message);
goto doIsBad;
}
break;
@@ -3797,7 +3789,6 @@ drc_callback (DataTypePtr data, LayerTypePtr layer, PolygonTypePtr polygon,
AddObjectToFlagUndoList (type, ptr1, ptr2, ptr2);
SET_FLAG (TheFlag, pin);
message = _("Via with insufficient clearance inside polygon\n");
- Message (message);
goto doIsBad;
}
break;
@@ -3934,7 +3925,6 @@ DRCAll (void)
{
AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
SET_FLAG (TheFlag, line);
- Message (_("Line is too thin\n"));
DrawLine (layer, line, 0);
drcerr_count++;
SetThing (LINE_TYPE, layer, line, line);
@@ -3979,7 +3969,6 @@ DRCAll (void)
{
AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
SET_FLAG (TheFlag, arc);
- Message (_("Arc is too thin\n"));
DrawArc (layer, arc, 0);
drcerr_count++;
SetThing (ARC_TYPE, layer, arc, arc);
@@ -4025,8 +4014,6 @@ DRCAll (void)
{
AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
SET_FLAG (TheFlag, pin);
- Message (_
- ("Pin annular ring is too small based on minimum annular ring\n"));
DrawPin (pin, 0);
drcerr_count++;
SetThing (PIN_TYPE, element, pin, pin);
@@ -4061,7 +4048,6 @@ DRCAll (void)
{
AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
SET_FLAG (TheFlag, pin);
- Message (_("Pin drill size is too small\n"));
DrawPin (pin, 0);
drcerr_count++;
SetThing (PIN_TYPE, element, pin, pin);
@@ -4105,7 +4091,6 @@ DRCAll (void)
{
AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
SET_FLAG (TheFlag, pad);
- Message (_("Pad is too thin\n"));
DrawPad (pad, 0);
drcerr_count++;
SetThing (PAD_TYPE, element, pad, pad);
@@ -4151,8 +4136,6 @@ DRCAll (void)
{
AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
SET_FLAG (TheFlag, via);
- Message (_
- ("Via annular ring is too small based on minimum annular ring\n"));
DrawVia (via, 0);
drcerr_count++;
SetThing (VIA_TYPE, via, via, via);
@@ -4187,7 +4170,6 @@ DRCAll (void)
{
AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
SET_FLAG (TheFlag, via);
- Message (_("Via drill size is too small\n"));
DrawVia (via, 0);
drcerr_count++;
SetThing (VIA_TYPE, via, via, via);
@@ -4236,7 +4218,6 @@ DRCAll (void)
if (line->Thickness < PCB->minSlk)
{
SET_FLAG (TheFlag, line);
- Message (_("Silk line is too thin\n"));
DrawLine (layer, line, 0);
drcerr_count++;
SetThing (LINE_TYPE, layer, line, line);
@@ -4291,8 +4272,6 @@ DRCAll (void)
int buflen;
SET_FLAG (TheFlag, element);
- Message (_("Element %s has %d silk lines which are too thin\n"),
- UNKNOWN (NAMEONPCB_NAME (element)), tmpcnt);
// append_drc_dialog_message (_
// ("%i silk lines\n of element %s\nare too thin\n"),
// tmpcnt, UNKNOWN (NAMEONPCB_NAME (element)));
diff --git a/src/hid/gtk/gui-drc-window.c b/src/hid/gtk/gui-drc-window.c
index b443a0d..620c272 100644
--- a/src/hid/gtk/gui-drc-window.c
+++ b/src/hid/gtk/gui-drc-window.c
@@ -845,8 +845,8 @@ ghid_drc_window_show (gboolean raise)
-1, /* APPEND */
_("No."), /* TITLE */
violation_renderer,
- "text", DRC_VIOLATION_NUM_COL,
- NULL);
+ "text", DRC_VIOLATION_NUM_COL,
+ NULL);
violation_renderer = ghid_violation_renderer_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (drc_list),
@@ -854,7 +854,7 @@ ghid_drc_window_show (gboolean raise)
_("Violation details"), /* TITLE */
violation_renderer,
"violation", DRC_VIOLATION_OBJ_COL,
- NULL);
+ NULL);
hbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
@@ -907,7 +907,7 @@ void ghid_drc_window_append_violation (DRC_VIOLATION *violation)
violation->value_digits,
violation->value_units,
violation->object_count,
- ID, /* violation->object_id_list */
+ ID, /* violation->object_id_list */
type); /* violation->object_type_list */
gtk_list_store_append (drc_list_model, &iter);
@@ -915,7 +915,7 @@ void ghid_drc_window_append_violation (DRC_VIOLATION *violation)
DRC_VIOLATION_NUM_COL, num_violations,
DRC_VIOLATION_OBJ_COL, violation_obj,
DRC_OBJECT_COUNT_COL, violation->object_count,
- DRC_OBJECT_ID_LIST_COL, ID, /* violation->object_id_list, */
+ DRC_OBJECT_ID_LIST_COL, ID, /* violation->object_id_list, */
DRC_OBJECT_TYPE_LIST_COL, type, /* violation->object_type_list, */
-1);
--
1.6.0.4
From 0400258cdada2fef4333c2c267b2f5c2f1a63cef Mon Sep 17 00:00:00 2001
From: Peter Clifton <pcjc2@xxxxxxxxx>
Date: Thu, 2 Apr 2009 17:26:43 +0100
Subject: [PATCH] Attempt to preview the drc violations on the board
---
src/Makefile.am | 1 +
src/hid/gtk/gui-drc-window.c | 103 ++++++++++++++++++++++++-
src/hid/gtk/gui-drc-window.h | 4 +-
src/hid/gtk/gui-pixmap-render.c | 159 +++++++++++++++++++++++++++++++++++++++
4 files changed, 263 insertions(+), 4 deletions(-)
create mode 100644 src/hid/gtk/gui-pixmap-render.c
diff --git a/src/Makefile.am b/src/Makefile.am
index f35a45f..3ce2fc1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -253,6 +253,7 @@ LIBGTK_SRCS = \
hid/gtk/gui-pinout-preview.c \
hid/gtk/gui-pinout-preview.h \
hid/gtk/gui-pinout-window.c \
+ hid/gtk/gui-pixmap-render.c \
hid/gtk/gui-top-window.c \
hid/gtk/gui-utils.c \
hid/gtk/snavi.c \
diff --git a/src/hid/gtk/gui-drc-window.c b/src/hid/gtk/gui-drc-window.c
index 620c272..e6c3e2f 100644
--- a/src/hid/gtk/gui-drc-window.c
+++ b/src/hid/gtk/gui-drc-window.c
@@ -42,6 +42,9 @@
#include <dmalloc.h>
#endif
+#define VIOLATION_PIXMAP_SIZE 100
+#define VIOLATION_PIXMAP_BORDER 5
+
RCSID ("$Id$");
static GtkWidget *drc_window, *drc_list;
@@ -286,7 +289,8 @@ enum
PROP_MEASURED_VALUE,
PROP_REQUIRED_VALUE,
PROP_VALUE_DIGITS,
- PROP_VALUE_UNITS
+ PROP_VALUE_UNITS,
+ PROP_PIXMAP
};
@@ -309,6 +313,8 @@ ghid_drc_violation_finalize (GObject * object)
g_free (violation->title);
g_free (violation->explanation);
g_free (violation->value_units);
+ if (violation->pixmap != NULL)
+ g_object_unref (violation->pixmap);
G_OBJECT_CLASS (ghid_drc_violation_parent_class)->finalize (object);
}
@@ -366,6 +372,10 @@ ghid_drc_violation_set_property (GObject * object, guint property_id,
g_free (violation->value_units);
violation->value_units = g_value_dup_string (value);
break;
+ case PROP_PIXMAP:
+ if (violation->pixmap)
+ g_object_unref (violation->pixmap); /* Frees our old reference */
+ violation->pixmap = g_value_dup_object (value); /* Takes a new reference */
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -492,6 +502,12 @@ ghid_drc_violation_class_init (GhidViolationRendererClass * klass)
"",
"",
G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, PROP_PIXMAP,
+ g_param_spec_object ("pixmap",
+ "",
+ "",
+ GDK_TYPE_DRAWABLE,
+ G_PARAM_WRITABLE));
}
@@ -545,7 +561,8 @@ GhidDrcViolation *ghid_drc_violation_new (char *title,
const char *value_units,
int object_count,
long int object_id,
- int object_type)
+ int object_type,
+ GdkDrawable *pixmap)
{
GhidDrcViolation *violation = g_object_new (GHID_TYPE_DRC_VIOLATION,
"title", title,
@@ -558,6 +575,7 @@ GhidDrcViolation *ghid_drc_violation_new (char *title,
"required-value", required_value,
"value-digits", value_digits,
"value-units", value_units,
+ "pixmap", pixmap,
NULL);
// violation->object_count = object_count;
// violation->object_id = object_id;
@@ -565,6 +583,7 @@ GhidDrcViolation *ghid_drc_violation_new (char *title,
return violation;
}
+
enum
{
PROP_VIOLATION = 1,
@@ -696,6 +715,79 @@ ghid_violation_renderer_get_property (GObject * object, guint property_id,
}
+static void
+ghid_violation_renderer_get_size (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ GdkRectangle *cell_area,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height)
+{
+ GTK_CELL_RENDERER_CLASS (ghid_violation_renderer_parent_class)->get_size (cell,
+ widget,
+ cell_area,
+ x_offset,
+ y_offset,
+ width,
+ height);
+ if (width != NULL)
+ *width += VIOLATION_PIXMAP_SIZE;
+ if (height != NULL)
+ *height = MAX (*height, VIOLATION_PIXMAP_SIZE);
+}
+
+extern GdkPixmap *pixmap_render (int cx, int cy, double zoom, int width, int height);
+
+static void
+ghid_violation_renderer_render (GtkCellRenderer *cell,
+ GdkDrawable *window,
+ GtkWidget *widget,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ GtkCellRendererState flags)
+{
+ GdkGC *gc;
+ GdkDrawable *mydrawable;
+ GhidViolationRenderer *renderer = GHID_VIOLATION_RENDERER (cell);
+ GhidDrcViolation *violation = renderer->violation;
+ int pixmap_size = VIOLATION_PIXMAP_SIZE - 2 * VIOLATION_PIXMAP_BORDER;
+
+ cell_area->width -= VIOLATION_PIXMAP_SIZE;
+ GTK_CELL_RENDERER_CLASS (ghid_violation_renderer_parent_class)->render (cell,
+ window,
+ widget,
+ background_area,
+ cell_area,
+ expose_area,
+ flags);
+
+ if (violation == NULL)
+ return;
+
+ if (violation->pixmap == NULL)
+ {
+ GdkPixmap *pixmap = pixmap_render (violation->x_coord,
+ violation->y_coord,
+ 10000 / pixmap_size,
+ pixmap_size, pixmap_size);
+ g_object_set (violation, "pixmap", pixmap, NULL);
+ g_object_unref (pixmap);
+ }
+
+ if (violation->pixmap == NULL)
+ return;
+
+ mydrawable = GDK_DRAWABLE (violation->pixmap);
+
+ gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
+ gdk_draw_drawable (window, gc, mydrawable,
+ 0, 0,
+ cell_area->x + cell_area->width + VIOLATION_PIXMAP_BORDER,
+ cell_area->y + VIOLATION_PIXMAP_BORDER, -1, -1);
+}
+
/*! \brief GType class initialiser for GhidViolationRenderer
*
@@ -709,11 +801,15 @@ static void
ghid_violation_renderer_class_init (GhidViolationRendererClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkCellRendererClass *cellrenderer_class = GTK_CELL_RENDERER_CLASS (klass);
gobject_class->finalize = ghid_violation_renderer_finalize;
gobject_class->set_property = ghid_violation_renderer_set_property;
gobject_class->get_property = ghid_violation_renderer_get_property;
+ cellrenderer_class->get_size = ghid_violation_renderer_get_size;
+ cellrenderer_class->render = ghid_violation_renderer_render;
+
ghid_violation_renderer_parent_class = g_type_class_peek_parent (klass);
g_object_class_install_property (gobject_class, PROP_VIOLATION,
@@ -908,7 +1004,8 @@ void ghid_drc_window_append_violation (DRC_VIOLATION *violation)
violation->value_units,
violation->object_count,
ID, /* violation->object_id_list */
- type); /* violation->object_type_list */
+ type, /* violation->object_type_list */
+ NULL); /* pixmap */
gtk_list_store_append (drc_list_model, &iter);
gtk_list_store_set (drc_list_model, &iter,
diff --git a/src/hid/gtk/gui-drc-window.h b/src/hid/gtk/gui-drc-window.h
index 56e8769..9998d18 100644
--- a/src/hid/gtk/gui-drc-window.h
+++ b/src/hid/gtk/gui-drc-window.h
@@ -61,6 +61,7 @@ struct _GhidDrcViolation
double required_value;
int value_digits;
char *value_units;
+ GdkDrawable *pixmap;
};
@@ -78,7 +79,8 @@ GhidDrcViolation *ghid_drc_violation_new (char *title,
const char *value_units,
int object_count,
long int object_id,
- int object_type);
+ int object_type,
+ GdkDrawable *pixmap);
#define GHID_TYPE_VIOLATION_RENDERER (ghid_violation_renderer_get_type())
diff --git a/src/hid/gtk/gui-pixmap-render.c b/src/hid/gtk/gui-pixmap-render.c
new file mode 100644
index 0000000..7fc58d1
--- /dev/null
+++ b/src/hid/gtk/gui-pixmap-render.c
@@ -0,0 +1,159 @@
+/* $Id$ */
+
+/*
+ * COPYRIGHT
+ *
+ * PCB, interactive printed circuit board design
+ * Copyright (C) 1994,1995,1996 Thomas Nau
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Contact addresses for paper mail and Email:
+ * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
+ * Thomas.Nau@xxxxxxxxxxxxx
+ *
+ */
+
+/* This file written by Peter Clifton, starting from
+ * gui-pinout-preview.c */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "global.h"
+
+#include "gui.h"
+
+#include "copy.h"
+#include "data.h"
+#include "draw.h"
+#include "mymem.h"
+
+#ifdef HAVE_LIBDMALLOC
+#include <dmalloc.h>
+#endif
+
+RCSID ("$Id$");
+
+
+#define Z_NEAR 3.0
+
+GdkPixmap *
+pixmap_render (int cx, int cy, double zoom, int width, int height)
+{
+ extern HID ghid_hid;
+ GdkGLConfig *glconfig;
+ GdkPixmap *pixmap;
+ GdkGLPixmap *glpixmap;
+ GdkGLContext* glcontext;
+ GdkGLDrawable* gldrawable;
+ double save_zoom;
+ int save_left, save_top;
+ int save_width, save_height;
+ int save_view_width, save_view_height;
+
+ save_zoom = gport->zoom;
+ save_width = gport->width;
+ save_height = gport->height;
+ save_left = gport->view_x0;
+ save_top = gport->view_y0;
+ save_view_width = gport->view_width;
+ save_view_height = gport->view_height;
+
+
+ /* Try single-buffered visual */
+ glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
+ GDK_GL_MODE_STENCIL |
+// GDK_GL_MODE_DEPTH |
+ GDK_GL_MODE_SINGLE);
+
+ pixmap = gdk_pixmap_new (NULL, width, height, 24); /* FIXME HARDCODING 24 */
+ glpixmap = gdk_pixmap_set_gl_capability (pixmap, glconfig, NULL);
+ gldrawable = GDK_GL_DRAWABLE (glpixmap);
+ glcontext = gdk_gl_context_new (gldrawable, NULL, FALSE, GDK_GL_RGBA_TYPE);
+
+ /* Setup zoom factor for drawing routines */
+
+ gport->zoom = zoom;
+ gport->width = width; // Pixels
+ gport->height = height; // Pixels
+ gport->view_width = width * gport->zoom; // PCB Units
+ gport->view_height = height * gport->zoom; // PCB Units
+ gport->view_x0 = cx - gport->view_height / 2; // PCB Units
+ gport->view_y0 = cy - gport->view_width / 2; // PCB Units
+
+ /* make GL-context "current" */
+ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) {
+ return FALSE;
+ }
+
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glViewport (0, 0, width, height);
+
+// glEnable (GL_SCISSOR_TEST);
+// glScissor (0, 0, width, height);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho (0, width, height, 0, 0, 100);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glTranslatef (0.0f, 0.0f, -Z_NEAR);
+
+ glClearColor (gport->bg_color.red / 65535.,
+ gport->bg_color.green / 65535.,
+ gport->bg_color.blue / 65535.,
+ 1.);
+ glClearStencil (0);
+ glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ /* call the drawing routine */
+ hidgl_init_triangle_array (&buffer);
+ ghid_invalidate_current_gc ();
+ glPushMatrix ();
+ glScalef ((ghid_flip_x ? -1. : 1.) / gport->zoom,
+ (ghid_flip_y ? -1. : 1.) / gport->zoom, 1);
+ glTranslatef (ghid_flip_x ? gport->view_x0 - PCB->MaxWidth :
+ -gport->view_x0,
+ ghid_flip_y ? gport->view_y0 - PCB->MaxHeight :
+ -gport->view_y0, 0);
+ hid_expose_callback (&ghid_hid, NULL, NULL);
+ hidgl_flush_triangles (&buffer);
+ glPopMatrix ();
+
+ glFlush ();
+
+ /* end drawing to current GL-context */
+ gdk_gl_drawable_gl_end (gldrawable);
+// gdk_gl_context_destroy (glcontext);
+
+ gdk_pixmap_unset_gl_capability (pixmap);
+
+ g_object_unref (glconfig);
+ g_object_unref (glcontext);
+
+ gport->zoom = save_zoom;
+ gport->width = save_width;
+ gport->height = save_height;
+ gport->view_x0 = save_left;
+ gport->view_y0 = save_top;
+ gport->view_width = save_view_width;
+ gport->view_height = save_view_height;
+
+ return pixmap;
+}
--
1.6.0.4
_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user