Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gschem / src / x_attribedit.c
blobdd98c0677154b04f07951edf9ad5c320b8a48589
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 /*! \todo STILL NEED to clean up line lengths in aa and tr
22 #include <config.h>
24 #include <stdio.h>
25 #ifdef HAVE_STDLIB_H
26 #include <stdlib.h>
27 #endif
28 #ifdef HAVE_STRING_H
29 #include <string.h>
30 #endif
32 #include "gschem.h"
34 #ifdef HAVE_LIBDMALLOC
35 #include <dmalloc.h>
36 #endif
38 /***************** Start of Attrib Edit dialog box ********************/
39 /*! \section attrib-edit-dialog-box Atrib Edit Dialog Box */
41 /*! \todo Finish function documentation!!!
42 * \brief
43 * \par Function Documentation
46 gint option_menu_get_history (GtkOptionMenu *option_menu)
48 GtkWidget *active_widget;
50 g_return_val_if_fail (GTK_IS_OPTION_MENU (option_menu), -1);
52 active_widget = gtk_menu_get_active (GTK_MENU (option_menu->menu));
54 if (active_widget)
55 return g_list_index (GTK_MENU_SHELL (option_menu->menu)->children,
56 active_widget);
57 else
58 return -1;
61 /*! \todo Finish function documentation!!!
62 * \brief
63 * \par Function Documentation
66 void attrib_edit_dialog_ok(GtkWidget * w, GSCHEM_TOPLEVEL *w_current)
68 TOPLEVEL *toplevel = w_current->toplevel;
69 const char *value, *label;
70 char *newtext;
71 GtkEntry *value_entry, *name_entry;
72 GtkWidget *visbutton, *show_options;
73 GtkWidget *addtocompsbutton, *addtonetsbutton, *addtoallbutton;
74 GtkWidget *overwritebutton;
75 OBJECT *attribptr;
76 OBJECT *object;
77 GList *s_current = NULL;
78 OBJECT *a_current;
79 GList *a_iter;
80 int vis, show;
81 int invocation_flag;
82 int nsel=0, addto=0, replace=0, addmask=0;
83 int option_index;
84 gint wx, wy;
86 i_set_state(w_current, SELECT);
88 value_entry =
89 gtk_object_get_data(GTK_OBJECT(w_current->aewindow), "value_entry");
90 name_entry =
91 gtk_object_get_data(GTK_OBJECT(w_current->aewindow), "attrib_combo_entry");
92 visbutton =
93 gtk_object_get_data(GTK_OBJECT(w_current->aewindow), "visbutton");
94 show_options =
95 gtk_object_get_data(GTK_OBJECT(w_current->aewindow), "show_options");
97 value = gtk_entry_get_text(value_entry);
98 label = gtk_entry_get_text(name_entry);
99 newtext = g_strconcat (label, "=", value, NULL);
101 if (!x_dialog_validate_attribute(GTK_WINDOW(w_current->aewindow), newtext))
103 g_free(newtext);
104 return;
107 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(visbutton)))
108 vis = VISIBLE;
109 else
110 vis = INVISIBLE;
112 option_index = option_menu_get_history(GTK_OPTION_MENU (show_options));
113 switch(option_index) {
114 case(0):
115 show = SHOW_VALUE;
116 break;
118 case(1):
119 show = SHOW_NAME;
120 break;
122 case(2):
123 show = SHOW_NAME_VALUE;
124 break;
126 default:
127 fprintf(stderr, _("Got invalid show option; defaulting to show both\n"));
128 show = SHOW_NAME_VALUE;
129 break;
132 attribptr =
133 gtk_object_get_data(GTK_OBJECT(w_current->aewindow), "attrib");
134 if (!attribptr) {
135 OBJECT *new = NULL;
137 s_current = geda_list_get_glist( toplevel->page_current->selection_list );
138 while (s_current != NULL) {
139 object = (OBJECT *)s_current->data;
140 if (object == NULL) {
141 fprintf(stderr, _("ERROR: NULL object!\n"));
142 exit(-1);
144 if (!object->attached_to) {
145 nsel++;
147 s_current = g_list_next(s_current);
149 s_current = geda_list_get_glist( toplevel->page_current->selection_list );
150 if (nsel > 1) {
152 addtoallbutton =
153 gtk_object_get_data(GTK_OBJECT(w_current->aewindow),
154 "addtoallbutton");
156 addtocompsbutton =
157 gtk_object_get_data(GTK_OBJECT(w_current->aewindow),
158 "addtocompsbutton");
160 addtonetsbutton =
161 gtk_object_get_data(GTK_OBJECT(w_current->aewindow),
162 "addtonetsbutton");
164 overwritebutton =
165 gtk_object_get_data(GTK_OBJECT(w_current->aewindow),
166 "overwritebutton");
168 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(overwritebutton))) {
169 replace = 1;
170 } else {
171 replace = 0;
174 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(addtoallbutton))) {
175 addto = 7;
177 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(addtocompsbutton))) {
178 addto = 2;
180 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(addtonetsbutton))) {
181 addto = 1;
184 while (s_current != NULL) {
185 gboolean replaced;
187 object = (OBJECT *) s_current->data;
188 if (object && !object->attached_to && object->type != OBJ_TEXT ) {
189 addmask = 4;
190 if (object->type == OBJ_COMPLEX || object->type == OBJ_PLACEHOLDER) {
191 addmask = 2;
193 if (object->type == OBJ_NET) {
194 addmask = 1;
196 replaced = FALSE;
197 if (addmask & addto) {
198 a_iter = object->attribs;
199 if (replace) {
200 while (a_iter != NULL) {
201 a_current = a_iter->data;
202 const gchar *str = o_text_get_string (toplevel, a_current);
203 if (str) {
204 if (!strncmp (str, newtext, strchr (newtext, '=') - newtext)) {
205 o_text_change(w_current, a_current, newtext, vis, show);
206 replaced = TRUE;
207 toplevel->page_current->CHANGED = 1;
210 a_iter = g_list_next (a_iter);
213 if (!replaced) {
214 new = o_attrib_add_attrib(w_current, newtext, vis, show, object);
218 s_current = g_list_next (s_current);
220 o_undo_savestate(w_current, UNDO_ALL);
221 } else {
222 object = o_select_return_first_object(w_current);
223 new = o_attrib_add_attrib(w_current, newtext, vis, show, object);
225 invocation_flag =
226 GPOINTER_TO_INT( gtk_object_get_data(GTK_OBJECT(w_current->aewindow),
227 "invocation_flag") );
228 wx = GPOINTER_TO_INT( gtk_object_get_data(GTK_OBJECT(w_current->aewindow),
229 "position_wx"));
230 wy = GPOINTER_TO_INT( gtk_object_get_data(GTK_OBJECT(w_current->aewindow),
231 "position_wy"));
233 #if DEBUG
234 printf("invocation flag: %d\n", invocation_flag);
235 #endif
236 if (invocation_flag == FROM_HOTKEY
237 && wx != -1 && wy != -1) {
238 o_invalidate (w_current, new);
239 new->text->x = wx;
240 new->text->y = wy;
241 o_text_recreate(toplevel, new);
242 o_invalidate (w_current, new);
243 toplevel->page_current->CHANGED = 1;
244 o_undo_savestate(w_current, UNDO_ALL);
247 } else {
248 o_text_change(w_current, attribptr, newtext, vis, show);
249 toplevel->page_current->CHANGED = 1;
250 o_undo_savestate(w_current, UNDO_ALL);
252 gtk_grab_remove(w_current->aewindow);
253 gtk_widget_destroy(w_current->aewindow);
254 w_current->aewindow = NULL;
255 g_free(newtext);
258 /*! \brief Response function for the attribute add/edit dialog
259 * \par Function Description
260 * This function catches the user response for the add and edit
261 * attribute dialog.
263 void attribute_edit_dialog_response(GtkWidget *w, gint response,
264 GSCHEM_TOPLEVEL *w_current)
266 switch(response) {
267 case GTK_RESPONSE_APPLY:
268 attrib_edit_dialog_ok(NULL, w_current);
269 break;
270 case GTK_RESPONSE_REJECT:
271 case GTK_RESPONSE_DELETE_EVENT:
272 i_set_state(w_current, SELECT);
273 gtk_grab_remove(w_current->aewindow);
274 gtk_widget_destroy(w_current->aewindow);
275 w_current->aewindow = NULL;
276 break;
277 default:
278 printf("attrib_edit_dialog_response(): strange signal %d\n", response);
280 /* clean up */
285 /*! \brief Create the attribute add/edit dialog
286 * \par Function Description
287 * This function creates the single attribute edit dialog.
289 void attrib_edit_dialog (GSCHEM_TOPLEVEL *w_current, OBJECT *attr_obj, int flag)
291 TOPLEVEL *toplevel = w_current->toplevel;
292 GtkWidget *aewindow;
293 GtkWidget *vbox, *label, *table, *alignment;
294 GtkWidget *show_options;
295 GtkWidget *show_options_menu;
296 GtkWidget *glade_menuitem;
297 GtkWidget *attrib_combo_box_entry;
298 GtkWidget *attrib_combo_entry;
299 GtkWidget *value_entry;
300 GtkWidget *visbutton;
301 GSList *hbox2_group = NULL;
302 GtkWidget *addtoallbutton;
303 GtkWidget *addtocompsbutton;
304 GtkWidget *addtonetsbutton;
305 GtkWidget *overwritebutton;
306 GtkEntryCompletion *attrib_combo_entry_completion;
308 /* gschem specific */
309 GList *s_current = NULL;
310 char* string = NULL;
311 int nsel=0, i, len;
312 char *name = NULL;
313 char *val = NULL;
314 OBJECT *attrib = NULL;
315 gint wx, wy;
317 /* gschem specific */
318 if (w_current->aewindow)
319 return;
321 /* gschem specific: What do we count here? (Werner) */
322 for (s_current = geda_list_get_glist( toplevel->page_current->selection_list );
323 s_current != NULL;
324 s_current = g_list_next(s_current)) {
325 if (!((OBJECT *) s_current->data)->attached_to) {
326 nsel++;
330 aewindow = gschem_dialog_new_with_buttons(_("Single Attribute Editor"),
331 GTK_WINDOW(w_current->main_window),
332 GTK_DIALOG_MODAL,
333 "singleattrib", w_current,
334 GTK_STOCK_CANCEL,
335 GTK_RESPONSE_REJECT,
336 GTK_STOCK_OK,
337 GTK_RESPONSE_APPLY,
338 NULL);
339 /* Set the alternative button order (ok, cancel, help) for other systems */
340 gtk_dialog_set_alternative_button_order(GTK_DIALOG(aewindow),
341 GTK_RESPONSE_APPLY,
342 GTK_RESPONSE_REJECT,
343 -1);
345 gtk_signal_connect(GTK_OBJECT(aewindow), "response",
346 GTK_SIGNAL_FUNC(attribute_edit_dialog_response), w_current);
348 gtk_window_set_position (GTK_WINDOW (aewindow), GTK_WIN_POS_MOUSE);
350 gtk_dialog_set_default_response(GTK_DIALOG(aewindow),
351 GTK_RESPONSE_APPLY);
353 vbox = GTK_DIALOG(aewindow)->vbox;
354 gtk_container_set_border_width(GTK_CONTAINER(aewindow),
355 DIALOG_BORDER_SPACING);
356 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING);
358 if (attr_obj)
359 label = gtk_label_new(_("<b>Edit Attribute</b>"));
360 else
361 label = gtk_label_new(_("<b>Add Attribute</b>"));
362 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
363 gtk_misc_set_alignment(GTK_MISC(label),0,0);
364 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
366 alignment = gtk_alignment_new(0,0,1,1);
367 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0,
368 DIALOG_INDENTATION, 0);
369 gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0);
371 table = gtk_table_new (3, 2, FALSE);
372 gtk_table_set_row_spacings(GTK_TABLE(table), DIALOG_V_SPACING);
373 gtk_table_set_col_spacings(GTK_TABLE(table), DIALOG_H_SPACING);
374 gtk_container_add (GTK_CONTAINER (alignment), table);
376 /* Name selection */
377 label = gtk_label_new (_("Name:"));
378 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
379 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
380 (GtkAttachOptions) (GTK_FILL),
381 (GtkAttachOptions) (GTK_FILL), 0, 0);
383 attrib_combo_box_entry = gtk_combo_box_entry_new_text ();
384 attrib_combo_entry = gtk_bin_get_child(GTK_BIN(attrib_combo_box_entry));
385 gtk_table_attach (GTK_TABLE (table), attrib_combo_box_entry, 1, 2, 0, 1,
386 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
387 (GtkAttachOptions) (0), 0, 0);
388 g_object_ref (attrib_combo_entry);
389 g_object_set_data_full (G_OBJECT (aewindow),
390 "attrib_combo_entry", attrib_combo_entry,
391 (GtkDestroyNotify) gtk_widget_unref);
393 /* Value entry */
394 label = gtk_label_new (_("Value:"));
395 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
396 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
397 (GtkAttachOptions) (GTK_FILL),
398 (GtkAttachOptions) (0), 0, 0);
400 value_entry = gtk_entry_new ();
401 gtk_widget_ref (value_entry);
402 gtk_object_set_data_full (GTK_OBJECT (aewindow), "value_entry", value_entry,
403 (GtkDestroyNotify) gtk_widget_unref);
404 gtk_table_attach (GTK_TABLE (table), value_entry, 1, 2, 1, 2,
405 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
406 (GtkAttachOptions) (0), 0, 0);
407 gtk_entry_set_activates_default(GTK_ENTRY(value_entry), TRUE);
409 /* Visibility */
410 visbutton = gtk_check_button_new_with_label (_("Visible"));
411 gtk_widget_ref (visbutton);
412 gtk_object_set_data_full (GTK_OBJECT (aewindow), "visbutton", visbutton,
413 (GtkDestroyNotify) gtk_widget_unref);
415 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (visbutton), TRUE);
416 gtk_table_attach (GTK_TABLE (table), visbutton, 0, 1, 2, 3,
417 (GtkAttachOptions) (GTK_FILL),
418 (GtkAttachOptions) (0), 0, 0);
420 show_options = gtk_option_menu_new ();
421 gtk_widget_ref (show_options);
422 gtk_object_set_data_full (GTK_OBJECT (aewindow), "show_options",
423 show_options,
424 (GtkDestroyNotify) gtk_widget_unref);
425 gtk_widget_show (show_options);
426 gtk_table_attach (GTK_TABLE (table), show_options, 1, 2, 2, 3,
427 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
428 (GtkAttachOptions) (0), 0, 0);
429 show_options_menu = gtk_menu_new ();
430 glade_menuitem = gtk_menu_item_new_with_label (_("Show Value Only"));
431 gtk_menu_append (GTK_MENU (show_options_menu), glade_menuitem);
432 glade_menuitem = gtk_menu_item_new_with_label (_("Show Name Only"));
433 gtk_menu_append (GTK_MENU (show_options_menu), glade_menuitem);
434 glade_menuitem = gtk_menu_item_new_with_label (_("Show Name & Value"));
435 gtk_menu_append (GTK_MENU (show_options_menu), glade_menuitem);
436 gtk_option_menu_set_menu (GTK_OPTION_MENU (show_options), show_options_menu);
437 gtk_option_menu_set_history (GTK_OPTION_MENU (show_options), 0);
439 if (nsel > 1) { /* gschem specific */
441 label = gtk_label_new(_("<b>Attach Options</b>"));
442 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
443 gtk_misc_set_alignment(GTK_MISC(label),0,0);
444 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
446 alignment = gtk_alignment_new(0,0,1,1);
447 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0,
448 DIALOG_INDENTATION, 0);
449 gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0);
451 table = gtk_table_new (2, 3, FALSE);
452 gtk_table_set_row_spacings(GTK_TABLE(table), DIALOG_V_SPACING);
453 gtk_table_set_col_spacings(GTK_TABLE(table), DIALOG_H_SPACING);
454 gtk_container_add (GTK_CONTAINER (alignment), table);
456 addtoallbutton = gtk_radio_button_new_with_label (hbox2_group, _("All"));
457 hbox2_group = gtk_radio_button_group (GTK_RADIO_BUTTON (addtoallbutton));
458 gtk_widget_ref (addtoallbutton);
459 gtk_object_set_data_full (GTK_OBJECT (aewindow), "addtoallbutton", addtoallbutton,
460 (GtkDestroyNotify) gtk_widget_unref);
461 gtk_table_attach(GTK_TABLE(table), addtoallbutton, 0, 1, 0, 1,
462 (GtkAttachOptions) (GTK_FILL), 0, 0, 0);
464 addtocompsbutton = gtk_radio_button_new_with_label (hbox2_group, _("Components"));
465 hbox2_group = gtk_radio_button_group (GTK_RADIO_BUTTON (addtocompsbutton));
466 gtk_widget_ref (addtocompsbutton);
467 gtk_object_set_data_full (GTK_OBJECT (aewindow), "addtocompsbutton", addtocompsbutton,
468 (GtkDestroyNotify) gtk_widget_unref);
469 gtk_table_attach(GTK_TABLE(table), addtocompsbutton, 1, 2, 0, 1,
470 (GtkAttachOptions) (GTK_FILL), 0, 0, 0);
472 addtonetsbutton = gtk_radio_button_new_with_label (hbox2_group, _("Nets"));
473 hbox2_group = gtk_radio_button_group (GTK_RADIO_BUTTON (addtonetsbutton));
474 gtk_widget_ref (addtonetsbutton);
475 gtk_object_set_data_full (GTK_OBJECT (aewindow), "addtonetsbutton", addtonetsbutton,
476 (GtkDestroyNotify) gtk_widget_unref);
477 gtk_table_attach(GTK_TABLE(table), addtonetsbutton, 2, 3, 0, 1,
478 (GtkAttachOptions) (GTK_FILL), 0, 0, 0);
480 overwritebutton = gtk_check_button_new_with_label (_("Replace existing attributes"));
481 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(overwritebutton), TRUE);
482 gtk_widget_ref (overwritebutton);
483 gtk_object_set_data_full (GTK_OBJECT (aewindow), "overwritebutton", overwritebutton,
484 (GtkDestroyNotify) gtk_widget_unref);
485 gtk_table_attach(GTK_TABLE(table), overwritebutton, 0, 3, 1, 2,
486 (GtkAttachOptions) (GTK_FILL), 0, 0, 0);
489 /* gschem specific */
490 if (attr_obj) {
491 o_attrib_get_name_value (attr_obj, &name, &val);
492 attrib = attr_obj;
493 if (attrib->visibility == VISIBLE) {
494 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(visbutton), TRUE);
495 } else {
496 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(visbutton), FALSE);
499 if (attrib->show_name_value == SHOW_VALUE) {
500 gtk_option_menu_set_history (GTK_OPTION_MENU (show_options), 0);
501 } else if (attrib->show_name_value == SHOW_NAME) {
502 gtk_option_menu_set_history (GTK_OPTION_MENU (show_options), 1);
503 } else {
504 gtk_option_menu_set_history (GTK_OPTION_MENU (show_options), 2);
506 } else {
507 OBJECT *object;
509 attrib = NULL;
511 if ((object = o_select_return_first_object(w_current))) {
512 if (object->type == OBJ_NET)
513 name = g_strdup("netname");
516 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(visbutton), TRUE);
517 /* show value only */
518 gtk_option_menu_set_history (GTK_OPTION_MENU (show_options), 0);
520 gtk_object_set_data(GTK_OBJECT(aewindow), "attrib", attrib);
521 if (name) {
522 gtk_entry_set_text(GTK_ENTRY(attrib_combo_entry), name);
524 if (val) {
525 gtk_entry_set_text(GTK_ENTRY(value_entry), val);
526 len = strlen(val);
527 gtk_entry_select_region(GTK_ENTRY(value_entry), 0, len);
529 gtk_object_set_data(GTK_OBJECT(aewindow), "invocation_flag",
530 GINT_TO_POINTER(flag));
532 if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy)) {
533 wx = wy = -1;
535 gtk_object_set_data(GTK_OBJECT(aewindow), "position_wx",
536 GINT_TO_POINTER(wx));
537 gtk_object_set_data(GTK_OBJECT(aewindow), "position_wy",
538 GINT_TO_POINTER(wy));
540 /* gschem specific */
541 i = 0;
542 string = (char *) s_attrib_get(i);
543 while (string != NULL) {
544 gtk_combo_box_append_text(GTK_COMBO_BOX(attrib_combo_box_entry), string);
545 i++;
546 string = (char *) s_attrib_get(i);
549 /* Add completion to attribute combo box entry */
550 attrib_combo_entry_completion = gtk_entry_completion_new();
551 gtk_entry_completion_set_model(attrib_combo_entry_completion,
552 gtk_combo_box_get_model(GTK_COMBO_BOX(attrib_combo_box_entry)));
553 gtk_entry_completion_set_text_column(attrib_combo_entry_completion, 0);
554 gtk_entry_completion_set_inline_completion(attrib_combo_entry_completion, TRUE);
555 gtk_entry_completion_set_popup_single_match(attrib_combo_entry_completion, FALSE);
556 gtk_entry_set_completion(GTK_ENTRY(attrib_combo_entry), attrib_combo_entry_completion);
558 /* gschem specific */
559 gtk_widget_show_all(aewindow);
560 w_current->aewindow = aewindow;
562 gtk_grab_add(w_current->aewindow);
564 if (attrib || (name && strcmp(name, "netname") == 0)) {
565 gtk_widget_grab_focus(value_entry);
566 } else {
567 gtk_widget_grab_focus(attrib_combo_entry);
570 g_free(name);
571 g_free(val);
574 /***************** End of Attrib Edit dialog box **********************/