Rename ResetFound{LinesAndPolygons,PinsViasAndPads} and ResetConnections
[geda-pcb/pcjc2.git] / src / hid / lesstif / netlist.c
blob598d106ef7edfa17d258a8b15e32a6b3059d6d9d
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
5 #include <stdio.h>
6 #include <stdarg.h>
7 #include <stdlib.h>
8 #include <string.h>
10 #include "xincludes.h"
12 #include "compat.h"
13 #include "global.h"
14 #include "data.h"
16 #include "find.h"
17 #include "rats.h"
18 #include "select.h"
19 #include "undo.h"
20 #include "remove.h"
21 #include "crosshair.h"
22 #include "draw.h"
24 #include "hid.h"
25 #include "../hidint.h"
26 #include "lesstif.h"
28 #ifdef HAVE_LIBDMALLOC
29 #include <dmalloc.h>
30 #endif
32 static Arg args[30];
33 static int n;
34 #define stdarg(t,v) XtSetArg(args[n], t, v); n++
36 static Widget netlist_dialog = 0;
37 static Widget netlist_list, netnode_list;
39 static XmString *netlist_strings = 0;
40 static XmString *netnode_strings = 0;
41 static int n_netnode_strings;
42 static int last_pick = -1;
44 static int LesstifNetlistChanged (int argc, char **argv, Coord x, Coord y);
46 static void
47 pick_net (int pick)
49 LibraryMenuType *menu = PCB->NetlistLib.Menu + pick;
50 int i;
52 if (pick == last_pick)
53 return;
54 last_pick = pick;
56 if (netnode_strings)
57 free (netnode_strings); /* XXX leaked all XmStrings??? */
58 n_netnode_strings = menu->EntryN;
59 netnode_strings = (XmString *) malloc (menu->EntryN * sizeof (XmString));
60 for (i = 0; i < menu->EntryN; i++)
61 netnode_strings[i] = XmStringCreatePCB (menu->Entry[i].ListEntry);
62 n = 0;
63 stdarg (XmNitems, netnode_strings);
64 stdarg (XmNitemCount, menu->EntryN);
65 XtSetValues (netnode_list, args, n);
68 static void
69 netlist_select (Widget w, void *v, XmListCallbackStruct * cbs)
71 XmString str;
72 int pos = cbs->item_position;
73 LibraryMenuType *net = & (PCB->NetlistLib.Menu[pos - 1]);
74 char *name = net->Name;
75 if (name[0] == ' ')
77 name[0] = '*';
78 net->flag = 0;
80 else
82 name[0] = ' ';
83 net->flag = 1;
86 str = XmStringCreatePCB (name);
87 XmListReplaceItemsPos (netlist_list, &str, 1, pos);
88 XmStringFree (str);
89 XmListSelectPos (netlist_list, pos, False);
92 static void
93 netlist_extend (Widget w, void *v, XmListCallbackStruct * cbs)
95 if (cbs->selected_item_count == 1)
96 pick_net (cbs->item_position - 1);
99 typedef void (*Std_Nbcb_Func)(LibraryMenuType *, int);
101 static void
102 nbcb_rat_on (LibraryMenuType *net, int pos)
104 XmString str;
105 char *name = net->Name;
106 name[0] = ' ';
107 net->flag = 1;
108 str = XmStringCreatePCB (name);
109 XmListReplaceItemsPos (netlist_list, &str, 1, pos);
110 XmStringFree (str);
113 static void
114 nbcb_rat_off (LibraryMenuType *net, int pos)
116 XmString str;
117 char *name = net->Name;
118 name[0] = '*';
119 net->flag = 0;
120 str = XmStringCreatePCB (name);
121 XmListReplaceItemsPos (netlist_list, &str, 1, pos);
122 XmStringFree (str);
126 /* Select on the layout the current net treeview selection
128 static void
129 nbcb_select_common (LibraryMenuType *net, int pos, int select_flag)
131 LibraryEntryType *entry;
132 ConnectionType conn;
133 int i;
135 InitConnectionLookup ();
136 ClearFlagOnAllObjects (true, FOUNDFLAG);
138 for (i = net->EntryN, entry = net->Entry; i; i--, entry++)
139 if (SeekPad (entry, &conn, false))
140 RatFindHook (conn.type, conn.ptr1, conn.ptr2, conn.ptr2, true, FOUNDFLAG, true);
142 SelectByFlag (FOUNDFLAG, select_flag);
143 ClearFlagOnAllObjects (false, FOUNDFLAG);
144 FreeConnectionLookupMemory ();
145 IncrementUndoSerialNumber ();
146 Draw ();
149 static void
150 nbcb_select (LibraryMenuType *net, int pos)
152 nbcb_select_common (net, pos, 1);
155 static void
156 nbcb_deselect (LibraryMenuType *net, int pos)
158 nbcb_select_common (net, pos, 0);
161 static void
162 nbcb_find (LibraryMenuType *net, int pos)
164 char *name = net->Name + 2;
165 hid_actionl ("netlist", "find", name, NULL);
168 static void
169 nbcb_std_callback (Widget w, Std_Nbcb_Func v, XmPushButtonCallbackStruct * cbs)
171 int *posl, posc, i;
172 XmString **items, **selected;
173 if (XmListGetSelectedPos (netlist_list, &posl, &posc) == False)
174 return;
175 if (v == nbcb_find)
176 hid_actionl ("connection", "reset", NULL);
177 for (i=0; i<posc; i++)
179 LibraryMenuType *net = & (PCB->NetlistLib.Menu[posl[i] - 1]);
180 v(net, posl[i]);
182 n = 0;
183 stdarg (XmNitems, &items);
184 XtGetValues (netlist_list, args, n);
185 selected = (XmString **) malloc (posc * sizeof (XmString *));
186 for (i=0; i<posc; i++)
187 selected[i] = items[posl[i]-1];
189 n = 0;
190 stdarg (XmNselectedItems, selected);
191 XtSetValues (netlist_list, args, n);
194 static void
195 nbcb_ripup (Widget w, Std_Nbcb_Func v, XmPushButtonCallbackStruct * cbs)
197 nbcb_std_callback (w, nbcb_find, cbs);
199 VISIBLELINE_LOOP (PCB->Data);
201 if (TEST_FLAG (FOUNDFLAG, line) && !TEST_FLAG (LOCKFLAG, line))
202 RemoveObject (LINE_TYPE, layer, line, line);
204 ENDALL_LOOP;
206 VISIBLEARC_LOOP (PCB->Data);
208 if (TEST_FLAG (FOUNDFLAG, arc) && !TEST_FLAG (LOCKFLAG, arc))
209 RemoveObject (ARC_TYPE, layer, arc, arc);
211 ENDALL_LOOP;
213 if (PCB->ViaOn)
214 VIA_LOOP (PCB->Data);
216 if (TEST_FLAG (FOUNDFLAG, via) && !TEST_FLAG (LOCKFLAG, via))
217 RemoveObject (VIA_TYPE, via, via, via);
219 END_LOOP;
222 static void
223 netnode_browse (Widget w, XtPointer v, XmListCallbackStruct * cbs)
225 LibraryMenuType *menu = PCB->NetlistLib.Menu + last_pick;
226 char *name = menu->Entry[cbs->item_position - 1].ListEntry;
227 char *ename, *pname;
229 ename = strdup (name);
230 pname = strchr (ename, '-');
231 if (! pname)
233 free (ename);
234 return;
236 *pname++ = 0;
238 ELEMENT_LOOP (PCB->Data);
240 char *es = element->Name[NAMEONPCB_INDEX].TextString;
241 if (es && strcmp (es, ename) == 0)
243 PIN_LOOP (element);
245 if (strcmp (pin->Number, pname) == 0)
247 MoveCrosshairAbsolute (pin->X, pin->Y);
248 free (ename);
249 return;
252 END_LOOP;
253 PAD_LOOP (element);
255 if (strcmp (pad->Number, pname) == 0)
257 int x = (pad->Point1.X + pad->Point2.X) / 2;
258 int y = (pad->Point1.Y + pad->Point2.Y) / 2;
259 gui->set_crosshair (x, y, HID_SC_PAN_VIEWPORT);
260 free (ename);
261 return;
264 END_LOOP;
267 END_LOOP;
268 free (ename);
271 #define NLB_FORM ((Widget)(~0))
272 static Widget
273 netlist_button (Widget parent, char *name, char *string,
274 Widget top, Widget bottom, Widget left, Widget right,
275 XtCallbackProc callback, void *user_data)
277 Widget rv;
278 XmString str;
280 #define NLB_W(w) if (w == NLB_FORM) { stdarg(XmN ## w ## Attachment, XmATTACH_FORM); } \
281 else if (w) { stdarg(XmN ## w ## Attachment, XmATTACH_WIDGET); \
282 stdarg (XmN ## w ## Widget, w); }
284 NLB_W (top);
285 NLB_W (bottom);
286 NLB_W (left);
287 NLB_W (right);
288 str = XmStringCreatePCB (string);
289 stdarg(XmNlabelString, str);
290 rv = XmCreatePushButton (parent, name, args, n);
291 XtManageChild (rv);
292 if (callback)
293 XtAddCallback (rv, XmNactivateCallback, callback, (XtPointer)user_data);
294 XmStringFree(str);
295 return rv;
298 static int
299 build_netlist_dialog ()
301 Widget b_sel, b_unsel, b_find, b_ripup, b_rat_on, b_rat_off, l_ops;
302 XmString ops_str;
304 if (!mainwind)
305 return 1;
306 if (netlist_dialog)
307 return 0;
309 n = 0;
310 stdarg (XmNresizePolicy, XmRESIZE_GROW);
311 stdarg (XmNtitle, "Netlists");
312 stdarg (XmNautoUnmanage, False);
313 netlist_dialog = XmCreateFormDialog (mainwind, "netlist", args, n);
315 n = 0;
316 b_rat_on = netlist_button (netlist_dialog, "rat_on", "Enable for rats",
317 0, NLB_FORM, NLB_FORM, 0,
318 (XtCallbackProc)nbcb_std_callback, (void *)nbcb_rat_on);
320 n = 0;
321 b_rat_off = netlist_button (netlist_dialog, "rat_off", "Disable for rats",
322 0, NLB_FORM, b_rat_on, 0,
323 (XtCallbackProc)nbcb_std_callback, (void *)nbcb_rat_off);
325 n = 0;
326 b_sel = netlist_button (netlist_dialog, "select", "Select",
327 0, b_rat_on, NLB_FORM, 0,
328 (XtCallbackProc)nbcb_std_callback, (void *)nbcb_select);
330 n = 0;
331 b_unsel = netlist_button (netlist_dialog, "deselect", "Deselect",
332 0, b_rat_on, b_sel, 0,
333 (XtCallbackProc)nbcb_std_callback, (void *)nbcb_deselect);
335 n = 0;
336 b_find = netlist_button (netlist_dialog, "find", "Find",
337 0, b_rat_on, b_unsel, 0,
338 (XtCallbackProc)nbcb_std_callback, (void *)nbcb_find);
341 n = 0;
342 b_ripup = netlist_button (netlist_dialog, "ripup", "Rip Up",
343 0, b_rat_on, b_find, 0,
344 (XtCallbackProc)nbcb_ripup, 0);
346 n = 0;
347 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
348 stdarg (XmNbottomWidget, b_sel);
349 stdarg (XmNleftAttachment, XmATTACH_FORM);
350 ops_str = XmStringCreatePCB ("Operations on selected net names:");
351 stdarg (XmNlabelString, ops_str);
352 l_ops = XmCreateLabel (netlist_dialog, "ops", args, n);
353 XtManageChild (l_ops);
355 n = 0;
356 stdarg (XmNtopAttachment, XmATTACH_FORM);
357 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
358 stdarg (XmNbottomWidget, l_ops);
359 stdarg (XmNleftAttachment, XmATTACH_FORM);
360 stdarg (XmNrightAttachment, XmATTACH_POSITION);
361 stdarg (XmNrightPosition, 50);
362 stdarg (XmNvisibleItemCount, 10);
363 stdarg (XmNselectionPolicy, XmEXTENDED_SELECT);
364 netlist_list = XmCreateScrolledList (netlist_dialog, "nets", args, n);
365 XtManageChild (netlist_list);
366 XtAddCallback (netlist_list, XmNdefaultActionCallback, (XtCallbackProc)netlist_select, 0);
367 XtAddCallback (netlist_list, XmNextendedSelectionCallback, (XtCallbackProc)netlist_extend, 0);
369 n = 0;
370 stdarg (XmNtopAttachment, XmATTACH_FORM);
371 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
372 stdarg (XmNbottomWidget, l_ops);
373 stdarg (XmNrightAttachment, XmATTACH_FORM);
374 stdarg (XmNleftAttachment, XmATTACH_POSITION);
375 stdarg (XmNleftPosition, 50);
376 netnode_list = XmCreateScrolledList (netlist_dialog, "nodes", args, n);
377 XtManageChild (netnode_list);
378 XtAddCallback (netnode_list, XmNbrowseSelectionCallback, (XtCallbackProc)netnode_browse, 0);
380 return 0;
383 static int
384 LesstifNetlistChanged (int argc, char **argv, Coord x, Coord y)
386 int i;
387 if (!PCB->NetlistLib.MenuN)
388 return 0;
389 if (build_netlist_dialog ())
390 return 0;
391 last_pick = -1;
392 if (netlist_strings)
393 free (netlist_strings);
394 netlist_strings =
395 (XmString *) malloc (PCB->NetlistLib.MenuN * sizeof (XmString));
396 for (i = 0; i < PCB->NetlistLib.MenuN; i++)
397 netlist_strings[i] =
398 XmStringCreatePCB (PCB->NetlistLib.Menu[i].Name);
399 n = 0;
400 stdarg (XmNitems, netlist_strings);
401 stdarg (XmNitemCount, PCB->NetlistLib.MenuN);
402 XtSetValues (netlist_list, args, n);
403 pick_net (0);
404 return 0;
407 static const char netlistshow_syntax[] =
408 "NetlistShow(pinname|netname)";
410 static const char netlistshow_help[] =
411 "Selects the given pinname or netname in the netlist window.";
413 /* %start-doc actions NetlistShow
415 %end-doc */
417 static int
418 LesstifNetlistShow (int argc, char **argv, Coord x, Coord y)
420 if (build_netlist_dialog ())
421 return 0;
423 if (argc == 1)
425 LibraryMenuType *net;
427 net = netnode_to_netname(argv[0]);
428 if (net)
430 XmString item;
431 int vis = 0;
433 /* Select net first, 'True' causes pick_net() to be invoked */
434 item = XmStringCreatePCB (net->Name);
435 XmListSelectItem (netlist_list, item, True);
436 XmListSetItem (netlist_list, item);
437 XmStringFree (item);
439 /* Now the netnode_list has the right contents */
440 item = XmStringCreatePCB (argv[0]);
441 XmListSelectItem (netnode_list, item, False);
444 * Only force the item to the top if there are enough to scroll.
445 * A bug (?) in lesstif will cause the window to get ever wider
446 * if an XmList that doesn't require a scrollbar is forced to
447 * have one (when the top item is not the first item).
449 n = 0;
450 stdarg (XmNvisibleItemCount, &vis);
451 XtGetValues (netnode_list, args, n);
452 if (n_netnode_strings > vis)
454 XmListSetItem (netnode_list, item);
456 XmStringFree (item);
458 else
460 /* Try the argument as a netname */
461 net = netname_to_netname(argv[0]);
462 if (net)
464 XmString item;
466 item = XmStringCreatePCB (net->Name);
467 XmListSetItem (netlist_list, item);
468 XmListSelectItem (netlist_list, item, True);
469 XmStringFree (item);
473 return 0;
476 void
477 lesstif_show_netlist ()
479 build_netlist_dialog ();
480 XtManageChild (netlist_dialog);
483 HID_Action lesstif_netlist_action_list[] = {
484 {"NetlistChanged", 0, LesstifNetlistChanged,
485 netlistchanged_help, netlistchanged_syntax},
486 {"NetlistShow", 0, LesstifNetlistShow,
487 netlistshow_help, netlistshow_syntax}
490 REGISTER_ACTIONS (lesstif_netlist_action_list)