/* Select on the layout the current net treeview selection */ static void netlist_select_cb (GtkWidget * widget, gpointer data) { LibraryEntryType *entry; ConnectionType conn; gint i; gboolean select_flag = GPOINTER_TO_INT (data); if (!selected_net) return; if (selected_net == node_selected_net) node_selected_net = NULL; InitConnectionLookup (); ResetConnections (true); for (i = selected_net->EntryN, entry = selected_net->Entry; i; i--, entry++) if (SeekPad (entry, &conn, false)) RatFindHook (conn.type, conn.ptr1, conn.ptr2, conn.ptr2, true, true); SelectConnection (select_flag); ResetConnections (false); FreeConnectionLookupMemory (); IncrementUndoSerialNumber (); Draw (); }
static void toggle_pin_selected (LibraryEntryType *entry) { ConnectionType conn; if (!SeekPad (entry, &conn, false)) return; AddObjectToFlagUndoList (conn.type, conn.ptr1, conn.ptr2, conn.ptr2); TOGGLE_FLAG (SELECTEDFLAG, (AnyObjectType *)conn.ptr2); DrawObject (conn.type, conn.ptr1, conn.ptr2); }
/* --------------------------------------------------------------------------- * toggle selection of pin * This SelectPin function was moved to here from the original netlist.c * as part of the gui code separation for the Gtk port. SelectPin() is * written by and is Copyright (C) 1998, 1999, 2000, 2001 harry eaton */ void SelectPin (LibraryEntryTypePtr entry, bool toggle) { ConnectionType conn; if (SeekPad (entry, &conn, false)) { switch (conn.type) { case PIN_TYPE: { PinTypePtr pin = (PinTypePtr) conn.ptr2; AddObjectToFlagUndoList (PIN_TYPE, conn.ptr1, conn.ptr2, conn.ptr2); if (toggle) { TOGGLE_FLAG (SELECTEDFLAG, pin); CenterDisplay (pin->X, pin->Y, false); } else SET_FLAG (SELECTEDFLAG, pin); DrawPin (pin, 0); break; } case PAD_TYPE: { PadTypePtr pad = (PadTypePtr) conn.ptr2; AddObjectToFlagUndoList (PAD_TYPE, conn.ptr1, conn.ptr2, conn.ptr2); if (toggle) { TOGGLE_FLAG (SELECTEDFLAG, pad); CenterDisplay (pad->Point1.X, pad->Point1.Y, false); } else SET_FLAG (SELECTEDFLAG, pad); DrawPad (pad, 0); break; } } } }
static int pin_name_to_xy (LibraryEntryType * pin, int *x, int *y) { ConnectionType conn; if (!SeekPad (pin, &conn, false)) return 1; switch (conn.type) { case PIN_TYPE: *x = ((PinType *) (conn.ptr2))->X; *y = ((PinType *) (conn.ptr2))->Y; return 0; case PAD_TYPE: *x = ((PadType *) (conn.ptr2))->Point1.X; *y = ((PadType *) (conn.ptr2))->Point1.Y; return 0; } return 1; }
/* Select on the layout the current net treeview selection */ static void nbcb_select_common (LibraryMenuTypePtr net, int pos, int select_flag) { LibraryEntryType *entry; ConnectionType conn; int i; InitConnectionLookup (); ResetConnections (true); for (i = net->EntryN, entry = net->Entry; i; i--, entry++) if (SeekPad (entry, &conn, false)) RatFindHook (conn.type, conn.ptr1, conn.ptr2, conn.ptr2, true, true); SelectConnection (select_flag); ResetConnections (false); FreeConnectionLookupMemory (); IncrementUndoSerialNumber (); Draw (); }
static int ReportNetLengthByName (char *tofind, int x, int y) { int result; char *netname = 0; Coord length = 0; int found = 0; int i; LibraryMenuType *net; ConnectionType conn; int net_found = 0; #if defined(USE_RE) int use_re = 0; #endif #if defined(HAVE_REGCOMP) regex_t elt_pattern; regmatch_t match; #endif #if defined(HAVE_RE_COMP) char *elt_pattern; #endif if (!PCB) return 1; if (!tofind) return 1; #if defined(USE_RE) use_re = 1; for (i = 0; i < PCB->NetlistLib.MenuN; i++) { net = PCB->NetlistLib.Menu + i; if (strcasecmp (tofind, net->Name + 2) == 0) use_re = 0; } if (use_re) { #if defined(HAVE_REGCOMP) result = regcomp (&elt_pattern, tofind, REG_EXTENDED | REG_ICASE | REG_NOSUB); if (result) { char errorstring[128]; regerror (result, &elt_pattern, errorstring, 128); Message (_("regexp error: %s\n"), errorstring); regfree (&elt_pattern); return (1); } #endif #if defined(HAVE_RE_COMP) if ((elt_pattern = re_comp (tofind)) != NULL) { Message (_("re_comp error: %s\n"), elt_pattern); return (1); } #endif } #endif for (i = 0; i < PCB->NetlistLib.MenuN; i++) { net = PCB->NetlistLib.Menu + i; #if defined(USE_RE) if (use_re) { #if defined(HAVE_REGCOMP) if (regexec (&elt_pattern, net->Name + 2, 1, &match, 0) != 0) continue; #endif #if defined(HAVE_RE_COMP) if (re_exec (net->Name + 2) != 1) continue; #endif } else #endif if (strcasecmp (net->Name + 2, tofind)) continue; if (SeekPad (net->Entry, &conn, false)) { switch (conn.type) { case PIN_TYPE: x = ((PinType *) (conn.ptr2))->X; y = ((PinType *) (conn.ptr2))->Y; net_found=1; break; case PAD_TYPE: x = ((PadType *) (conn.ptr2))->Point1.X; y = ((PadType *) (conn.ptr2))->Point1.Y; net_found=1; break; } if (net_found) break; } } if (!net_found) { gui->log (_("No net named %s\n"), tofind); return 1; } #ifdef HAVE_REGCOMP if (use_re) regfree (&elt_pattern); #endif /* Reset all connection flags and save an undo-state to get back * to the state the board was in when we started. * * After this, we don't add any changes to the undo system, but * ensure we get back to a point where we can Undo() our changes * by resetting the connections with ClearFlagOnAllObjects() before * calling Undo() when we are finished. */ ClearFlagOnAllObjects (true, FOUNDFLAG); IncrementUndoSerialNumber (); length = XYtoNetLength (x, y, &found); netname = net->Name + 2; ClearFlagOnAllObjects (false, FOUNDFLAG); Undo (true); if (!found) { if (net_found) gui->log (_("Net found, but no lines or arcs were flagged.\n")); else gui->log (_("Net not found.\n")); return 1; } { char buf[50]; pcb_snprintf(buf, 50, _("%$m*"), Settings.grid_unit->suffix, length); if (netname) gui->log (_("Net \"%s\" length: %s\n"), netname, buf); else gui->log (_("Net length: %s\n"), buf); } return 0; }
/* Callback when the user clicks on a PCB node in the right node treeview. */ static void node_selection_changed_cb (GtkTreeSelection * selection, gpointer data) { GtkTreeIter iter; GtkTreeModel *model; LibraryMenuType *node_net; LibraryEntryType *node; ConnectionType conn; Coord x, y; static gchar *node_name; if (selection_holdoff) /* PCB is highlighting, user is not selecting */ return; /* Toggle off the previous selection. Look up node_name to make sure | it still exists. This toggling can get out of sync if a node is | toggled selected, then the net that includes the node is selected | then unselected. */ if ((node = node_get_node_from_name (node_name, &node_net)) != NULL) { /* If net node belongs to has been highlighted/unhighighed, toggling | if off here will get our on/off toggling out of sync. */ if (node_net == node_selected_net) { toggle_pin_selected (node); ghid_cancel_lead_user (); } g_free (node_name); node_name = NULL; } /* Get the selected treeview row. */ if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { if (node) ghid_invalidate_all (); return; } /* From the treeview row, extract the node pointer stored there and | we've got a pointer to the LibraryEntryType (node) the row | represents. */ gtk_tree_model_get (model, &iter, NODE_LIBRARY_COLUMN, &node, -1); dup_string (&node_name, node->ListEntry); node_selected_net = selected_net; /* Now just toggle a select of the node on the layout */ toggle_pin_selected (node); IncrementUndoSerialNumber (); /* And lead the user to the location */ if (SeekPad (node, &conn, false)) switch (conn.type) { case PIN_TYPE: { PinType *pin = (PinType *) conn.ptr2; x = pin->X; y = pin->Y; gui->set_crosshair (x, y, 0); ghid_lead_user_to_location (x, y); break; } case PAD_TYPE: { PadType *pad = (PadType *) conn.ptr2; x = pad->Point1.X + (pad->Point2.X - pad->Point1.X) / 2; y = pad->Point1.Y + (pad->Point2.Y - pad->Point1.Y) / 2; gui->set_crosshair (x, y, 0); ghid_lead_user_to_location (x, y); break; } } }
/*! * \brief Read the library-netlist build a true Netlist structure. */ NetListType * ProcNetlist (LibraryType *net_menu) { ConnectionType *connection; ConnectionType LastPoint; NetType *net; static NetListType *Wantlist = NULL; if (!net_menu->MenuN) return (NULL); FreeNetListMemory (Wantlist); free (Wantlist); badnet = false; /* find layer groups of the component side and solder side */ bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE); top_group = GetLayerGroupNumberBySide (TOP_SIDE); Wantlist = (NetListType *)calloc (1, sizeof (NetListType)); if (Wantlist) { ALLPIN_LOOP (PCB->Data); { pin->Spare = NULL; CLEAR_FLAG (DRCFLAG, pin); } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { pad->Spare = NULL; CLEAR_FLAG (DRCFLAG, pad); } ENDALL_LOOP; MENU_LOOP (net_menu); { if (menu->Name[0] == '*' || menu->flag == 0) { badnet = true; continue; } net = GetNetMemory (Wantlist); if (menu->Style) { STYLE_LOOP (PCB); { if (style->Name && !NSTRCMP (style->Name, menu->Style)) { net->Style = style; break; } } END_LOOP; } else /* default to NULL if none found */ net->Style = NULL; ENTRY_LOOP (menu); { if (SeekPad (entry, &LastPoint, false)) { if (TEST_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2)) Message (_ ("Error! Element %s pin %s appears multiple times in the netlist file.\n"), NAMEONPCB_NAME ((ElementType *) LastPoint.ptr1), (LastPoint.type == PIN_TYPE) ? ((PinType *) LastPoint.ptr2)-> Number : ((PadType *) LastPoint.ptr2)->Number); else { connection = GetConnectionMemory (net); *connection = LastPoint; /* indicate expect net */ connection->menu = menu; /* mark as visited */ SET_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2); if (LastPoint.type == PIN_TYPE) ((PinType *) LastPoint.ptr2)->Spare = (void *) menu; else ((PadType *) LastPoint.ptr2)->Spare = (void *) menu; } } else badnet = true; /* check for more pins with the same number */ for (; SeekPad (entry, &LastPoint, true);) { connection = GetConnectionMemory (net); *connection = LastPoint; /* indicate expect net */ connection->menu = menu; /* mark as visited */ SET_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2); if (LastPoint.type == PIN_TYPE) ((PinType *) LastPoint.ptr2)->Spare = (void *) menu; else ((PadType *) LastPoint.ptr2)->Spare = (void *) menu; } } END_LOOP; } END_LOOP; } /* clear all visit marks */ ALLPIN_LOOP (PCB->Data); { CLEAR_FLAG (DRCFLAG, pin); } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { CLEAR_FLAG (DRCFLAG, pad); } ENDALL_LOOP; return (Wantlist); }