Merge the usermenu branch. This reworks how the menus and hotkeys
[geda-pcb/leaky.git] / src / hid / lesstif / netlist.c
blob8a45894fbd036bc848b31b17bd63e18d55edfccf
1 /* $Id$ */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <stdio.h>
8 #include <stdarg.h>
9 #include <stdlib.h>
10 #include <string.h>
12 #include "xincludes.h"
14 #include "compat.h"
15 #include "global.h"
16 #include "data.h"
18 #include "find.h"
19 #include "rats.h"
20 #include "select.h"
21 #include "undo.h"
22 #include "remove.h"
23 #include "crosshair.h"
25 #include "hid.h"
26 #include "../hidint.h"
27 #include "lesstif.h"
29 #ifdef HAVE_LIBDMALLOC
30 #include <dmalloc.h>
31 #endif
33 RCSID ("$Id$");
35 static Arg args[30];
36 static int n;
37 #define stdarg(t,v) XtSetArg(args[n], t, v); n++
39 static Widget netlist_dialog = 0;
40 static Widget netlist_list, netnode_list;
42 static XmString *netlist_strings = 0;
43 static XmString *netnode_strings = 0;
44 static int last_pick = -1;
46 static int NetlistChanged (int argc, char **argv, int x, int y);
48 static void
49 pick_net (int pick)
51 LibraryMenuType *menu = PCB->NetlistLib.Menu + pick;
52 int i;
54 if (pick == last_pick)
55 return;
56 last_pick = pick;
58 if (netnode_strings)
59 free (netnode_strings);
60 netnode_strings = (XmString *) malloc (menu->EntryN * sizeof (XmString));
61 for (i = 0; i < menu->EntryN; i++)
62 netnode_strings[i] = XmStringCreateLocalized (menu->Entry[i].ListEntry);
63 n = 0;
64 stdarg (XmNitems, netnode_strings);
65 stdarg (XmNitemCount, menu->EntryN);
66 XtSetValues (netnode_list, args, n);
69 static void
70 netlist_select (Widget w, void *v, XmListCallbackStruct * cbs)
72 XmString str;
73 int pos = cbs->item_position;
74 LibraryMenuTypePtr net = & (PCB->NetlistLib.Menu[pos - 1]);
75 char *name = net->Name;
76 if (name[0] == ' ')
78 name[0] = '*';
79 net->flag = 0;
81 else
83 name[0] = ' ';
84 net->flag = 1;
87 str = XmStringCreateLocalized (name);
88 XmListReplaceItemsPos (netlist_list, &str, 1, pos);
89 XmStringFree (str);
90 XmListSelectPos (netlist_list, pos, False);
93 static void
94 netlist_extend (Widget w, void *v, XmListCallbackStruct * cbs)
96 if (cbs->selected_item_count == 1)
97 pick_net (cbs->item_position - 1);
100 typedef void (*Std_Nbcb_Func)(LibraryMenuTypePtr, int);
102 static void
103 nbcb_rat_on (LibraryMenuTypePtr net, int pos)
105 XmString str;
106 char *name = net->Name;
107 name[0] = ' ';
108 net->flag = 1;
109 str = XmStringCreateLocalized (name);
110 XmListReplaceItemsPos (netlist_list, &str, 1, pos);
111 XmStringFree (str);
114 static void
115 nbcb_rat_off (LibraryMenuTypePtr net, int pos)
117 XmString str;
118 char *name = net->Name;
119 name[0] = '*';
120 net->flag = 0;
121 str = XmStringCreateLocalized (name);
122 XmListReplaceItemsPos (netlist_list, &str, 1, pos);
123 XmStringFree (str);
127 /* Select on the layout the current net treeview selection
129 static void
130 nbcb_select_common (LibraryMenuTypePtr net, int pos, int select_flag)
132 LibraryEntryType *entry;
133 ConnectionType conn;
134 int i;
136 InitConnectionLookup ();
137 ResetFoundPinsViasAndPads (False);
138 ResetFoundLinesAndPolygons (False);
139 SaveUndoSerialNumber ();
141 for (i = net->EntryN, entry = net->Entry; i; i--, entry++)
142 if (SeekPad (entry, &conn, False))
143 RatFindHook (conn.type, conn.ptr1, conn.ptr2, conn.ptr2, True, True);
144 RestoreUndoSerialNumber ();
145 SelectConnection (select_flag);
146 ResetFoundPinsViasAndPads (False);
147 ResetFoundLinesAndPolygons (False);
148 FreeConnectionLookupMemory ();
149 IncrementUndoSerialNumber ();
152 static void
153 nbcb_select (LibraryMenuTypePtr net, int pos)
155 nbcb_select_common (net, pos, 1);
158 static void
159 nbcb_deselect (LibraryMenuTypePtr net, int pos)
161 nbcb_select_common (net, pos, 0);
164 static void
165 nbcb_find (LibraryMenuTypePtr net, int pos)
167 char *name = net->Name + 2;
168 hid_actionl ("netlist", "find", name, NULL);
171 static void
172 nbcb_std_callback (Widget w, Std_Nbcb_Func v, XmPushButtonCallbackStruct * cbs)
174 int *posl, posc, i;
175 XmString **items, **selected;
176 if (XmListGetSelectedPos (netlist_list, &posl, &posc) == False)
177 return;
178 if (v == nbcb_find)
179 hid_actionl ("connection", "reset", NULL);
180 for (i=0; i<posc; i++)
182 LibraryMenuTypePtr net = & (PCB->NetlistLib.Menu[posl[i] - 1]);
183 v(net, posl[i]);
185 n = 0;
186 stdarg (XmNitems, &items);
187 XtGetValues (netlist_list, args, n);
188 selected = (XmString **) malloc (posc * sizeof (XmString *));
189 for (i=0; i<posc; i++)
190 selected[i] = items[posl[i]-1];
192 n = 0;
193 stdarg (XmNselectedItems, selected);
194 XtSetValues (netlist_list, args, n);
197 static void
198 nbcb_ripup (Widget w, Std_Nbcb_Func v, XmPushButtonCallbackStruct * cbs)
200 nbcb_std_callback (w, nbcb_find, cbs);
202 VISIBLELINE_LOOP (PCB->Data);
204 if (TEST_FLAG (FOUNDFLAG, line) && !TEST_FLAG (LOCKFLAG, line))
205 RemoveObject (LINE_TYPE, layer, line, line);
207 ENDALL_LOOP;
209 VISIBLEARC_LOOP (PCB->Data);
211 if (TEST_FLAG (FOUNDFLAG, arc) && !TEST_FLAG (LOCKFLAG, arc))
212 RemoveObject (ARC_TYPE, layer, arc, arc);
214 ENDALL_LOOP;
216 if (PCB->ViaOn)
217 VIA_LOOP (PCB->Data);
219 if (TEST_FLAG (FOUNDFLAG, via) && !TEST_FLAG (LOCKFLAG, via))
220 RemoveObject (VIA_TYPE, via, via, via);
222 END_LOOP;
225 static void
226 netnode_browse (Widget w, XtPointer v, XmListCallbackStruct * cbs)
228 LibraryMenuType *menu = PCB->NetlistLib.Menu + last_pick;
229 char *name = menu->Entry[cbs->item_position - 1].ListEntry;
230 char *ename, *pname;
232 ename = strdup (name);
233 pname = strchr (ename, '-');
234 if (! pname)
236 free (ename);
237 return;
239 *pname++ = 0;
241 ELEMENT_LOOP (PCB->Data);
243 if (strcmp (element->Name[NAMEONPCB_INDEX].TextString, ename) == 0)
245 PIN_LOOP (element);
247 if (strcmp (pin->Number, pname) == 0)
249 MoveCrosshairAbsolute (pin->X, pin->Y);
250 free (ename);
251 return;
254 END_LOOP;
255 PAD_LOOP (element);
257 if (strcmp (pad->Number, pname) == 0)
259 int x = (pad->Point1.X + pad->Point2.X) / 2;
260 int y = (pad->Point1.Y + pad->Point2.Y) / 2;
261 gui->set_crosshair (x, y, HID_SC_PAN_VIEWPORT);
262 free (ename);
263 return;
266 END_LOOP;
269 END_LOOP;
270 free (ename);
273 #define NLB_FORM ((Widget)(~0))
274 static Widget
275 netlist_button (Widget parent, char *name, char *string,
276 Widget top, Widget bottom, Widget left, Widget right,
277 XtCallbackProc callback, void *user_data)
279 Widget rv;
280 XmString str;
282 #define NLB_W(w) if (w == NLB_FORM) { stdarg(XmN ## w ## Attachment, XmATTACH_FORM); } \
283 else if (w) { stdarg(XmN ## w ## Attachment, XmATTACH_WIDGET); \
284 stdarg (XmN ## w ## Widget, w); }
286 NLB_W (top);
287 NLB_W (bottom);
288 NLB_W (left);
289 NLB_W (right);
290 str = XmStringCreateLocalized (string);
291 stdarg(XmNlabelString, str);
292 rv = XmCreatePushButton (parent, name, args, n);
293 XtManageChild (rv);
294 if (callback)
295 XtAddCallback (rv, XmNactivateCallback, callback, (XtPointer)user_data);
296 XmStringFree(str);
297 return rv;
300 static int
301 build_netlist_dialog ()
303 Widget b_sel, b_unsel, b_find, b_ripup, b_rat_on, b_rat_off, l_ops;
304 XmString ops_str;
306 if (!mainwind)
307 return 1;
308 if (netlist_dialog)
309 return 0;
311 n = 0;
312 stdarg (XmNresizePolicy, XmRESIZE_GROW);
313 stdarg (XmNtitle, "Netlists");
314 stdarg (XmNautoUnmanage, False);
315 netlist_dialog = XmCreateFormDialog (mainwind, "netlist", args, n);
317 n = 0;
318 b_rat_on = netlist_button (netlist_dialog, "rat_on", "Enable for rats",
319 0, NLB_FORM, NLB_FORM, 0,
320 (XtCallbackProc)nbcb_std_callback, nbcb_rat_on);
322 n = 0;
323 b_rat_off = netlist_button (netlist_dialog, "rat_off", "Disable for rats",
324 0, NLB_FORM, b_rat_on, 0,
325 (XtCallbackProc)nbcb_std_callback, nbcb_rat_off);
327 n = 0;
328 b_sel = netlist_button (netlist_dialog, "select", "Select",
329 0, b_rat_on, NLB_FORM, 0,
330 (XtCallbackProc)nbcb_std_callback, nbcb_select);
332 n = 0;
333 b_unsel = netlist_button (netlist_dialog, "deselect", "Deselect",
334 0, b_rat_on, b_sel, 0,
335 (XtCallbackProc)nbcb_std_callback, nbcb_deselect);
337 n = 0;
338 b_find = netlist_button (netlist_dialog, "find", "Find",
339 0, b_rat_on, b_unsel, 0,
340 (XtCallbackProc)nbcb_std_callback, nbcb_find);
343 n = 0;
344 b_ripup = netlist_button (netlist_dialog, "ripup", "Rip Up",
345 0, b_rat_on, b_find, 0,
346 (XtCallbackProc)nbcb_ripup, 0);
348 n = 0;
349 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
350 stdarg (XmNbottomWidget, b_sel);
351 stdarg (XmNleftAttachment, XmATTACH_FORM);
352 ops_str = XmStringCreateLocalized ("Operations on selected net names:");
353 stdarg (XmNlabelString, ops_str);
354 l_ops = XmCreateLabel (netlist_dialog, "ops", args, n);
355 XtManageChild (l_ops);
357 n = 0;
358 stdarg (XmNtopAttachment, XmATTACH_FORM);
359 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
360 stdarg (XmNbottomWidget, l_ops);
361 stdarg (XmNleftAttachment, XmATTACH_FORM);
362 stdarg (XmNrightAttachment, XmATTACH_POSITION);
363 stdarg (XmNrightPosition, 50);
364 stdarg (XmNvisibleItemCount, 10);
365 stdarg (XmNselectionPolicy, XmEXTENDED_SELECT);
366 netlist_list = XmCreateScrolledList (netlist_dialog, "nets", args, n);
367 XtManageChild (netlist_list);
368 XtAddCallback (netlist_list, XmNdefaultActionCallback, (XtCallbackProc)netlist_select, 0);
369 XtAddCallback (netlist_list, XmNextendedSelectionCallback, (XtCallbackProc)netlist_extend, 0);
371 n = 0;
372 stdarg (XmNtopAttachment, XmATTACH_FORM);
373 stdarg (XmNbottomAttachment, XmATTACH_WIDGET);
374 stdarg (XmNbottomWidget, l_ops);
375 stdarg (XmNrightAttachment, XmATTACH_FORM);
376 stdarg (XmNleftAttachment, XmATTACH_POSITION);
377 stdarg (XmNleftPosition, 50);
378 netnode_list = XmCreateScrolledList (netlist_dialog, "nodes", args, n);
379 XtManageChild (netnode_list);
380 XtAddCallback (netnode_list, XmNbrowseSelectionCallback, (XtCallbackProc)netnode_browse, 0);
382 return 0;
385 static int
386 NetlistChanged (int argc, char **argv, int x, int y)
388 int i;
389 if (!PCB->NetlistLib.MenuN)
390 return 0;
391 if (build_netlist_dialog ())
392 return 0;
393 last_pick = -1;
394 if (netlist_strings)
395 free (netlist_strings);
396 netlist_strings =
397 (XmString *) malloc (PCB->NetlistLib.MenuN * sizeof (XmString));
398 for (i = 0; i < PCB->NetlistLib.MenuN; i++)
399 netlist_strings[i] =
400 XmStringCreateLocalized (PCB->NetlistLib.Menu[i].Name);
401 n = 0;
402 stdarg (XmNitems, netlist_strings);
403 stdarg (XmNitemCount, PCB->NetlistLib.MenuN);
404 XtSetValues (netlist_list, args, n);
405 pick_net (0);
406 return 0;
409 static const char netlistshow_syntax[] =
410 "NetlistShow()";
412 static const char netlistshow_help[] =
413 "Displays the netlist window.";
415 /* %start-doc actions NetlistShow
417 %end-doc */
419 static int
420 NetlistShow (int argc, char **argv, int x, int y)
422 if (build_netlist_dialog ())
423 return 0;
424 return 0;
427 void
428 lesstif_show_netlist ()
430 build_netlist_dialog ();
431 XtManageChild (netlist_dialog);
434 HID_Action lesstif_netlist_action_list[] = {
435 {"NetlistChanged", 0, NetlistChanged,
436 netlistchanged_help, netlistchanged_syntax},
437 {"NetlistShow", 0, NetlistShow,
438 netlistshow_help, netlistshow_syntax}
441 REGISTER_ACTIONS (lesstif_netlist_action_list)