[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-cvs: CVS update: Makefile.am
User: werner
Date: 06/12/12 13:11:40
Modified: . Makefile.am o_misc.c o_slot.c x_dialog.c
Added: . x_autonumber.c
Log:
merged the autonumber branch back to trunk
Revision Changes Path
1.47 +1 -1 eda/geda/gaf/gschem/src/Makefile.am
(In the diff below, changes in quantity of whitespace are not shown.)
Index: Makefile.am
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/gaf/gschem/src/Makefile.am,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -b -r1.46 -r1.47
--- Makefile.am 23 Sep 2006 08:33:02 -0000 1.46
+++ Makefile.am 12 Dec 2006 18:11:39 -0000 1.47
@@ -17,7 +17,7 @@
o_arc.c o_box.c o_circle.c o_complex.c o_select.c o_find.c \
o_line.c o_net.c o_text.c o_pin.c o_bus.c o_buffer.c o_undo.c \
o_picture.c \
- x_basic.c x_dialog.c \
+ x_autonumber.c x_basic.c x_dialog.c \
x_event.c x_grid.c x_log.c x_menus.c x_script.c \
x_pagesel.c x_print.c x_window.c x_stroke.c x_image.c x_color.c \
x_compselect.c x_fileselect.c x_preview.c x_attribedit.c \
1.36 +0 -374 eda/geda/gaf/gschem/src/o_misc.c
(In the diff below, changes in quantity of whitespace are not shown.)
Index: o_misc.c
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/gaf/gschem/src/o_misc.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- o_misc.c 25 Aug 2006 01:00:09 -0000 1.35
+++ o_misc.c 12 Dec 2006 18:11:39 -0000 1.36
@@ -38,21 +38,6 @@
#include <dmalloc.h>
#endif
-#define FOCUS_SELECTION 0
-#define FOCUS_SHEET 1
-#define FOCUS_ALL 2
-
-#define SELECTION_ALL 0
-#define SELECTION_UNNUMBERED 1
-
-#define AUTONUMBER_SKIP_NOT 0
-#define AUTONUMBER_SKIP_PAGE 1
-#define AUTONUMBER_SKIP_SELECTION 2
-
-#define AUTONUMBER_SORT_YX 1
-#define AUTONUMBER_SORT_XY 2
-#define AUTONUMBER_SORT_DIAGONAL 3
-
/* break with the tradition here and input a list */
/*! \todo probably should go back and do the same for o_copy o_move
* o_delete...
@@ -1146,365 +1131,6 @@
return (o_current == NULL);
}
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-int autonumber_sort_numbers(gconstpointer a, gconstpointer b) {
- if (GPOINTER_TO_INT(a) < GPOINTER_TO_INT(b))
- return -1;
- if (GPOINTER_TO_INT(a) > GPOINTER_TO_INT(b))
- return 1;
- return 0;
-}
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-int autonumber_sort_xy(gconstpointer a, gconstpointer b) {
- OBJECT *aa, *bb;
- aa=(OBJECT *) a; bb=(OBJECT *) b;
- if (aa->text->x < bb->text->x)
- return -1;
- if (aa->text->x > bb->text->x)
- return 1;
- /* x == x */
- if (aa->text->y > bb->text->y)
- return -1;
- if (aa->text->y < bb->text->y)
- return 1;
- return 0;
-}
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-int autonumber_sort_yx(gconstpointer a, gconstpointer b) {
- OBJECT *aa, *bb;
- aa=(OBJECT *) a; bb=(OBJECT *) b;
- if (aa->text->y > bb->text->y)
- return -1;
- if (aa->text->y < bb->text->y)
- return 1;
- /* x == x */
- if (aa->text->x < bb->text->x)
- return -1;
- if (aa->text->x > bb->text->x)
- return 1;
- return 0;
-}
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-int autonumber_sort_diagonal(gconstpointer a, gconstpointer b) {
- OBJECT *aa, *bb;
- aa=(OBJECT *) a; bb=(OBJECT *) b;
- if (aa->text->x - aa->text->y < bb->text->x - bb->text->y)
- return -1;
- if (aa->text->x - aa->text->y > bb->text->x - bb->text->y)
- return 1;
- return 0;
-}
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-void autonumber_find(TOPLEVEL * w_current, OBJECT * o_list, char *stext,
- GSList **used_numbers, int skip)
-{
- OBJECT *o_current = NULL;
- char *attrib = NULL;
- int count = 0;
- PAGE *parent = NULL;
- char *current_filename = NULL;
- int page_control = 0;
- int pcount = 0;
- int l, m;
-
- for (o_current = o_list; o_current != NULL; o_current=o_current->next) {
- if (o_current->type == OBJ_TEXT && skip != AUTONUMBER_SKIP_PAGE) {
- if (!(o_current->selected) || skip != AUTONUMBER_SKIP_SELECTION) {
- if ((l = strlen(o_current->text->string) - strlen(stext)) > 0) {
- if (!strncmp(stext, o_current->text->string, strlen(stext))) {
- if (isdigit((int) o_current->text->string[strlen(stext)])) {
- sscanf(o_current->text->string + strlen(stext), "%d", &m);
- *used_numbers = g_slist_append(*used_numbers,GINT_TO_POINTER(m));
- /* printf(" %d\n", m);*/
- }
- }
- }
- }
- }
- if (o_current->type == OBJ_COMPLEX) {
- parent = w_current->page_current;
- attrib = o_attrib_search_name_single_count(o_current,
- "source", count);
-
- /* if above is null, then look inside symbol */
- if (attrib == NULL) {
- attrib = o_attrib_search_name(o_current->
- complex->prim_objs, "source", count);
- /* looking_inside = TRUE; */
- }
-
- if (attrib) {
- pcount = 0;
- current_filename = u_basic_breakup_string(attrib, ',', pcount);
- if (current_filename != NULL) {
- /* printf("autonumber_find: recursion filename \"%s\"\n",
- current_filename); */
- page_control =
- s_hierarchy_down_schematic_single(w_current,
- current_filename,
- parent,
- page_control,
- HIERARCHY_NORMAL_LOAD);
- if (page_control != -1) {
- autonumber_find(w_current, w_current->page_current->object_head,
- stext, used_numbers, AUTONUMBER_SKIP_NOT);
- s_hierarchy_up(w_current, w_current->page_current->up);
- }
- else {
- s_log_message(_("Cannot find source [%s]\n"),
- current_filename);
- fprintf(stderr,
- _("Cannot find source [%s]\n"), current_filename);
- }
- }
- }
- }
- }
-}
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-void autonumber_text(TOPLEVEL * w_current, char *stext, GSList **used,
- int *currentnumber, int unnumbered, int searchfocus,
- int sortorder)
-{
- GSList *o_list = NULL;
- OBJECT *o_current = NULL;
- GSList *o_list_complex = NULL;
- OBJECT *o_complex_current = NULL;
- GSList *item;
-
- char *attrib = NULL;
- int count = 0;
- PAGE *parent = NULL;
- char *current_filename = NULL;
- int page_control = 0;
- int save_page_control = 0;
- int pcount = 0;
-
- char *ss;
- int l;
-
- o_current = w_current->page_current->object_head;
-
- for (o_current = w_current->page_current->object_head; o_current != NULL;
- o_current = o_current->next) {
- if (o_current->type == OBJ_COMPLEX) {
- o_list_complex = g_slist_append(o_list_complex, o_current);
- }
- if (o_current->type == OBJ_TEXT) {
- if (searchfocus != FOCUS_SELECTION || o_current->selected) {
- if ((l = strlen(o_current->text->string) - strlen(stext)) > 0) {
- if (!strncmp(stext, o_current->text->string, strlen(stext))) {
- if (o_current->text->string[strlen(stext)] == '?'
- || (isdigit((int) o_current->text->string[strlen(stext)])
- && unnumbered == SELECTION_ALL)){
- o_list=g_slist_append(o_list,o_current);
- /* printf("autonumber_text: text \"%s\" \n",
- o_current->text->string);*/
- }
- }
- }
- }
- }
- }
-
- /* sort o_list */
- switch (sortorder) {
- case AUTONUMBER_SORT_YX:
- o_list=g_slist_sort(o_list,autonumber_sort_yx);
- break;
- case AUTONUMBER_SORT_XY:
- o_list=g_slist_sort(o_list,autonumber_sort_xy);
- break;
- case AUTONUMBER_SORT_DIAGONAL:
- o_list=g_slist_sort(o_list,autonumber_sort_diagonal);
- break;
- default:
- ; /* unsorted file order */
- }
-
- for (item=o_list; item != NULL; item=g_slist_next(item)) {
- o_current= item->data;
- g_free(o_current->text->string);
-
- while (*used != NULL && *currentnumber > GPOINTER_TO_INT((*used)->data)) {
- *used=(*used)->next;
- }
-
- while (*used != NULL && *currentnumber == GPOINTER_TO_INT((*used)->data)) {
- *used=(*used)->next;
- (*currentnumber)++;
- while (*used != NULL && *currentnumber > GPOINTER_TO_INT((*used)->data))
- *used=(*used)->next;
- }
-
- /* printf("autonumber_text: currentnumber %d\n",*currentnumber);*/
-
- ss = g_strdup_printf("%s%d", stext, (*currentnumber)++);
- /* printf("%s\n", ss); */
- o_current->text->string =
- (char *) g_malloc(sizeof(char) * (strlen(ss) + 1));
- strcpy(o_current->text->string, ss);
- g_free(ss);
- o_text_erase(w_current, o_current);
- o_text_recreate(w_current, o_current);
- o_text_draw(w_current, o_current);
- w_current->page_current->CHANGED = 1;
- }
-
- /* only walk down the hierarchy if requested */
- if (searchfocus == FOCUS_ALL) {
- for (item=o_list_complex; item != NULL; item=g_slist_next(item)) {
- o_complex_current= item->data;
- parent = w_current->page_current;
- attrib = o_attrib_search_name_single_count(o_complex_current,
- "source", count);
-
- /* if above is null, then look inside symbol */
- if (attrib == NULL) {
- attrib = o_attrib_search_name(o_complex_current->
- complex->prim_objs, "source", count);
- /* looking_inside = TRUE; */
- }
-
- if (attrib) {
- pcount = 0;
- current_filename = u_basic_breakup_string(attrib, ',', pcount);
- if (current_filename != NULL) {
- save_page_control = page_control;
- page_control =
- s_hierarchy_down_schematic_single(w_current,
- current_filename,
- parent,
- page_control,
- HIERARCHY_NORMAL_LOAD);
- if (page_control != -1) {
- autonumber_text(w_current, stext, used, currentnumber,
- unnumbered, searchfocus, sortorder);
- s_hierarchy_up(w_current, w_current->page_current->up);
- }
- else {
- /* restore if we failed to load the page */
- page_control = save_page_control;
- }
- }
- }
- }
- }
- g_slist_free(o_list);
- g_slist_free(o_list_complex);
- o_undo_savestate(w_current, UNDO_ALL);
-}
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-void o_edit_autonumber_text(TOPLEVEL * w_current, char * searchtext,
- int startnumber,int searchfocus,
- int unnumbered, int sortorder)
-{
- GSList *used_numbers=NULL;
- GSList *searchtext_list=NULL;
- GSList *item;
- char* stext=NULL;
- int skip_numbering=AUTONUMBER_SKIP_NOT;
- GSList *used_iterator=NULL; /* used in recursive autonumber_text */
- int currentnumber; /* used in recursive autonumber_text */
-
- /* Step2: if searchtext has an asterisk at the end we have to find
- all matching searchtextes.
- The function can take care of the selection options.
- The search function should return all possibles searchtexts that have
- its own number space.
- This requires something like:
- grep searchtext | sort | uniq
- in the object list down the hierarchy.
-
- Example: "refdes=*" will match each text that starts with "refdes="
- and has a trailing "?" (and a trailing number if the "all"-option is set.
- The function should return a list of all possible prefixes:
- refdes=R, refdes=C in the same way the searchstring is entered.
-
- If there is only one search pattern, it becomes a single item
- in the searchtext list */
-
- if (searchtext[strlen(searchtext)-1] == '*') {
- fprintf(stderr,"o_edit_autonumber_text: multiple searchtext option\n"
- " not implemented yet\n");
- /* collect the possible searchtextes, not implemented yet */
- }
- else {
- /* single searchtext */
- searchtext_list=g_slist_append (searchtext_list, searchtext);
- }
-
- /* Step3: iterate over the search item in the list */
- for (item=searchtext_list; item !=NULL; item=g_slist_next(item)) {
- stext = item->data;
- /* printf("o_edit_autonumber_text: iterate text: \"%s\"\n",stext);*/
- /* Step3.1: get the used numbers, ignore numbers that will be overwritten*/
- if (unnumbered==SELECTION_ALL && searchfocus==FOCUS_ALL) {
- ; /* all numbers will be overwritten, don't search */
- }
- else {
- if (unnumbered == SELECTION_ALL && searchfocus == FOCUS_SHEET)
- skip_numbering = AUTONUMBER_SKIP_PAGE;
- if (unnumbered == SELECTION_ALL && searchfocus == FOCUS_SELECTION)
- skip_numbering = AUTONUMBER_SKIP_SELECTION;
-
- autonumber_find(w_current, w_current->page_current->object_head,
- stext, &used_numbers, skip_numbering);
- }
-
- /* printf("o_edit_autonumber_text: listlength: %d\n",
- g_slist_length(used_numbers)); */
- /* sort used numbers */
- used_numbers=g_slist_sort(used_numbers,autonumber_sort_numbers);
-
- /* Step3.2: get a list of all matching objects
- sort the list (sort option)
- renumber all objects (start number option)
- this whole step is done in the autonumber_text function */
- used_iterator=used_numbers;
- currentnumber=startnumber;
- autonumber_text(w_current, stext, &used_iterator, ¤tnumber,
- unnumbered, searchfocus, sortorder);
- g_slist_free(used_numbers);
- used_numbers=NULL;
- }
- g_slist_free(searchtext_list);
- o_redraw_all(w_current);
-}
/*! \todo Finish function documentation!!!
* \brief
1.21 +0 -1 eda/geda/gaf/gschem/src/o_slot.c
(In the diff below, changes in quantity of whitespace are not shown.)
Index: o_slot.c
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/gaf/gschem/src/o_slot.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- o_slot.c 7 Nov 2006 20:10:24 -0000 1.20
+++ o_slot.c 12 Dec 2006 18:11:39 -0000 1.21
@@ -239,7 +239,6 @@
o_redraw_single(w_current,object);
w_current->page_current->CHANGED = 1;
- o_undo_savestate(w_current, UNDO_ALL);
if (name) g_free(name);
if (value) g_free(value);
1.68 +0 -298 eda/geda/gaf/gschem/src/x_dialog.c
(In the diff below, changes in quantity of whitespace are not shown.)
Index: x_dialog.c
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/gaf/gschem/src/x_dialog.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -b -r1.67 -r1.68
--- x_dialog.c 10 Dec 2006 19:55:23 -0000 1.67
+++ x_dialog.c 12 Dec 2006 18:11:40 -0000 1.68
@@ -3577,304 +3577,6 @@
/*********** End of show text dialog box *******/
-/*********** Start of autonumber text dialog box *******/
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-int autonumber_text_keypress(GtkWidget * widget, GdkEventKey * event,
- TOPLEVEL * w_current)
-{
- if (strcmp(gdk_keyval_name(event->keyval), "Escape") == 0) {
- autonumber_text_done(NULL, w_current);
- return TRUE;
- }
- if (strcmp(gdk_keyval_name(event->keyval), "Return") == 0) {
- autonumber_text_ok(NULL, w_current);
- return TRUE;
- }
- return FALSE;
-}
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-void autonumber_text_ok(GtkWidget * w, TOPLEVEL * w_current)
-{
- char *searchtext = NULL;
- char *startnumber = NULL;
- int sortorder, searchfocus, unnumbered, startnumber_i=1;
- GtkWidget * widget;
-
- widget = g_object_get_data (G_OBJECT (w_current->tswindow), "searchtext");
- searchtext = (char *) gtk_entry_get_text(GTK_ENTRY(widget));
- strncpy(generic_textstring, searchtext, 256); /* ???????? */
-
- widget = g_object_get_data (G_OBJECT (w_current->tswindow), "startnumber");
- startnumber = (char *) gtk_entry_get_text(GTK_ENTRY(widget));
- sscanf(startnumber," %d",&startnumber_i);
-
- widget = g_object_get_data (G_OBJECT (w_current->tswindow), "searchfocus");
- searchfocus = (int) gtk_option_menu_get_history (GTK_OPTION_MENU(widget));
-
- widget = g_object_get_data (G_OBJECT (w_current->tswindow), "unnumbered");
- unnumbered = (int) gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
-
- widget = g_object_get_data (G_OBJECT (w_current->tswindow), "sortorder");
- sortorder = (int) gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
-
- if (startnumber_i < 0) { /* disallow negativ numbers */
- fprintf(stderr, _("Warning: negative numbers not allowed in the "
- "autonumber_text dialog\n"));
- return;
- }
-
- /* printf("autonumber_text_ok: searchtext: %s\n"
- " startnumber: %i\n searchfocus: %i\n"
- " unnumbered: %i\n sortorder: %i\n" ,searchtext,
- startnumber_i, searchfocus, unnumbered, sortorder); */
- o_edit_autonumber_text(w_current, searchtext, startnumber_i, searchfocus,
- unnumbered, sortorder);
-}
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-void autonumber_text_done(GtkWidget * w, TOPLEVEL * w_current)
-{
- gtk_grab_remove(w_current->tswindow);
- gtk_widget_destroy(w_current->tswindow);
- w_current->tswindow = NULL;
-}
-
-/*! \todo Finish function documentation!!!
- * \brief
- * \par Function Description
- *
- */
-void autonumber_text_dialog(TOPLEVEL * w_current)
-{
- GtkWidget *vbox, *action_area;
- GtkWidget *frame1; /* selection frame */
- GtkWidget *label1;
- GtkWidget *table1;
- GtkWidget *label1_1, *label1_2;
- GtkWidget *combo1;
- GList *combo1_items = NULL;
- GtkWidget *combo_entry1;
-
- GtkWidget *optionmenu1_2, *menu1_2;
- GtkWidget *option_selection1, *option_selection2, *option_selection3;
- GtkWidget *hbox1; /* contains radio buttons */
- GtkWidget *radiobutton1;
- GtkWidget *radiobutton2;
-
- GtkWidget *frame2; /* option frame */
- GtkWidget *label2;
- GtkWidget *table2;
- GtkWidget *label2_1, *label2_2;
- GtkWidget *entry2;
- GtkWidget *optionmenu2_1, *menu2_1;
- GtkWidget *option_order1, *option_order2, *option_order3, *option_order4;
-
- GtkWidget *buttonok = NULL;
- GtkWidget *buttoncancel = NULL;
-
- if (!w_current->tswindow) {
- w_current->tswindow = gtk_dialog_new();
- vbox=GTK_DIALOG(w_current->tswindow)->vbox;
- action_area=GTK_DIALOG(w_current->tswindow)->action_area;
-
- gtk_window_position(GTK_WINDOW(w_current->tswindow),
- GTK_WIN_POS_MOUSE);
-
- gtk_signal_connect(GTK_OBJECT(w_current->tswindow),
- "destroy",
- GTK_SIGNAL_FUNC(destroy_window),
- &w_current->tswindow);
-
- gtk_signal_connect(GTK_OBJECT(w_current->tswindow),
- "key_press_event",
- (GtkSignalFunc) autonumber_text_keypress,
- w_current);
-
-#if 0 /* removed because it was causing the dialog box to not close */
- gtk_signal_connect(GTK_OBJECT(w_current->tswindow),
- "delete_event",
- GTK_SIGNAL_FUNC(destroy_window),
- &w_current->tswindow);
-#endif
-
- gtk_window_set_title(GTK_WINDOW(w_current->tswindow),
- _("Autonumber text"));
-
- /* selection frame */
- frame1 = gtk_frame_new(NULL);
- gtk_widget_show (frame1);
- gtk_box_pack_start (GTK_BOX(vbox), frame1, TRUE, TRUE, 0);
- label1 = gtk_label_new (_("selection"));
- gtk_widget_show (label1);
- gtk_frame_set_label_widget (GTK_FRAME(frame1), label1);
-
- table1 = gtk_table_new(2,3,FALSE);
- gtk_widget_show (table1);
- gtk_container_add (GTK_CONTAINER(frame1), table1);
-
- /* search text section */
- label1_1 = gtk_label_new (_("search text"));
- gtk_widget_show (label1_1);
- gtk_table_attach (GTK_TABLE (table1), label1_1, 0, 1, 0, 1,
- (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
- (GtkAttachOptions) (0), 0, 0);
-
- combo1 = gtk_combo_new ();
- /* g_object_set_data (G_OBJECT (GTK_COMBO (combo1)->popwin),
- "GladeParentKey", combo1);*/
- gtk_widget_show (combo1);
- gtk_table_attach (GTK_TABLE (table1), combo1, 1, 2, 0, 1,
- (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
- (GtkAttachOptions) (0), 0, 0);
- /* gtk_combo_set_value_in_list (GTK_COMBO (combo1), TRUE, TRUE);*/
- combo1_items = g_list_append (combo1_items, (gpointer) "refdes=C");
- combo1_items = g_list_append (combo1_items, (gpointer) "refdes=Q");
- combo1_items = g_list_append (combo1_items, (gpointer) "refdes=R");
- combo1_items = g_list_append (combo1_items, (gpointer) "refdes=U");
- combo1_items = g_list_append (combo1_items, (gpointer) "refdes=X");
- gtk_combo_set_popdown_strings (GTK_COMBO (combo1), combo1_items);
- g_list_free (combo1_items);
-
- combo_entry1 = GTK_COMBO (combo1)->entry;
- gtk_widget_show (combo_entry1);
- gtk_entry_set_text (GTK_ENTRY (combo_entry1), "refdes=C");
- GLADE_HOOKUP_OBJECT(w_current->tswindow,combo_entry1,"searchtext");
-
- /* search focus section */
- label1_2 = gtk_label_new (_("search focus"));
- gtk_widget_show (label1_2);
- gtk_table_attach (GTK_TABLE (table1), label1_2, 0, 1, 1, 2,
- (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
- (GtkAttachOptions) (0), 0, 0);
-
- optionmenu1_2 = gtk_option_menu_new ();
- gtk_widget_show (optionmenu1_2);
- gtk_table_attach (GTK_TABLE (table1), optionmenu1_2, 1, 2, 1, 2,
- (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
- (GtkAttachOptions) (0), 0, 0);
-
- menu1_2 = gtk_menu_new();
- option_selection1 = gtk_menu_item_new_with_label (_("selected objects"));
- gtk_widget_show (option_selection1);
- gtk_container_add (GTK_CONTAINER (menu1_2), option_selection1);
- option_selection2 = gtk_menu_item_new_with_label (_("current sheet"));
- gtk_widget_show (option_selection2);
- gtk_container_add (GTK_CONTAINER (menu1_2), option_selection2);
- option_selection3 = gtk_menu_item_new_with_label (_("hierarchical sheets"));
- gtk_widget_show (option_selection3);
- gtk_container_add (GTK_CONTAINER (menu1_2), option_selection3);
- gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu1_2), menu1_2);
- GLADE_HOOKUP_OBJECT(w_current->tswindow,optionmenu1_2,"searchfocus");
-
- /* radio buttons */
- hbox1=gtk_hbox_new (FALSE,0);
- gtk_widget_show (hbox1);
- gtk_table_attach (GTK_TABLE (table1), hbox1, 0, 2, 2, 3,
- (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
- (GtkAttachOptions) (0), 0, 0);
- radiobutton1 = gtk_radio_button_new_with_label (NULL, _("unnumbered"));
- gtk_widget_show (radiobutton1);
- gtk_box_pack_start (GTK_BOX (hbox1), radiobutton1, TRUE, TRUE, 0);
- radiobutton2 = gtk_radio_button_new_with_label_from_widget(
- GTK_RADIO_BUTTON (radiobutton1), _("all"));
- gtk_widget_show (radiobutton2);
- gtk_box_pack_start (GTK_BOX (hbox1), radiobutton2, TRUE, TRUE, 0);
- GLADE_HOOKUP_OBJECT(w_current->tswindow,radiobutton1,"unnumbered");
-
- /* option frame */
- frame2=gtk_frame_new(NULL);
- gtk_widget_show(frame2);
- gtk_box_pack_start (GTK_BOX(vbox), frame2, TRUE, TRUE, 0);
- label2 = gtk_label_new (_("options"));
- gtk_widget_show (label2);
- gtk_frame_set_label_widget (GTK_FRAME(frame2), label2);
-
- table2 = gtk_table_new(2,2,FALSE);
- gtk_widget_show(table2);
- gtk_container_add (GTK_CONTAINER (frame2),table2);
- label2_1=gtk_label_new(_("start number"));
- gtk_widget_show(label2_1);
- gtk_table_attach (GTK_TABLE (table2), label2_1, 0, 1, 0, 1,
- (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
- (GtkAttachOptions) (0), 0, 0);
- entry2=gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(entry2), "1");
- gtk_widget_show(entry2);
- gtk_table_attach (GTK_TABLE (table2), entry2, 1, 2, 0, 1,
- (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
- (GtkAttachOptions) (0), 0, 0);
- GLADE_HOOKUP_OBJECT(w_current->tswindow,entry2,"startnumber");
-
- label2_2=gtk_label_new(_("sort order"));
- gtk_widget_show(label2_2);
- gtk_table_attach (GTK_TABLE (table2), label2_2, 0, 1, 1, 2,
- (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
- (GtkAttachOptions) (0), 0, 0);
-
- optionmenu2_1 = gtk_option_menu_new ();
- gtk_widget_show (optionmenu2_1);
- gtk_table_attach (GTK_TABLE (table2), optionmenu2_1, 1, 2, 1, 2,
- (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
- (GtkAttachOptions) (0), 0, 0);
- menu2_1 = gtk_menu_new();
- option_order1 = gtk_menu_item_new_with_label (_("file order"));
- gtk_widget_show (option_order1);
- gtk_container_add (GTK_CONTAINER (menu2_1), option_order1);
- option_order2 = gtk_menu_item_new_with_label (_("top down"));
- gtk_widget_show (option_order2);
- gtk_container_add (GTK_CONTAINER (menu2_1), option_order2);
- option_order3 = gtk_menu_item_new_with_label (_("left right"));
- gtk_widget_show (option_order3);
- gtk_container_add (GTK_CONTAINER (menu2_1), option_order3);
- option_order4 = gtk_menu_item_new_with_label (_("diagonal"));
- gtk_widget_show (option_order4);
- gtk_container_add (GTK_CONTAINER (menu2_1), option_order4);
- gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu2_1), menu2_1);
- GLADE_HOOKUP_OBJECT(w_current->tswindow,optionmenu2_1,"sortorder");
-
- /* Why is the entry attached to w_current ?? (Werner) */
- w_current->tsentry = combo_entry1;
-
- buttoncancel = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
- gtk_box_pack_start(GTK_BOX(action_area), buttoncancel, TRUE, TRUE, 0);
- gtk_signal_connect(GTK_OBJECT(buttoncancel), "clicked",
- GTK_SIGNAL_FUNC(autonumber_text_done), w_current);
- gtk_widget_show(buttoncancel);
-
- buttonok = gtk_button_new_from_stock (GTK_STOCK_APPLY);
- GTK_WIDGET_SET_FLAGS(buttonok, GTK_CAN_DEFAULT);
- gtk_box_pack_start(GTK_BOX(action_area), buttonok, TRUE, TRUE, 0);
- gtk_signal_connect(GTK_OBJECT(buttonok), "clicked",
- GTK_SIGNAL_FUNC(autonumber_text_ok), w_current);
- gtk_widget_show(buttonok);
- gtk_widget_grab_default(buttonok);
- }
-
- if (!GTK_WIDGET_VISIBLE(w_current->tswindow)) {
- gtk_entry_set_text(GTK_ENTRY(w_current->tsentry), generic_textstring);
- gtk_entry_select_region(GTK_ENTRY(w_current->tsentry),
- 0,strlen(generic_textstring));
- gtk_widget_show(w_current->tswindow);
- gtk_grab_add(w_current->tswindow);
- }
-}
-
-/*********** End of autonumber text dialog box *******/
-
/*********** Start of some Gtk utils *******/
/*! \todo Finish function documentation!!!
1.2 +1485 -0 eda/geda/gaf/gschem/src/x_autonumber.c
(In the diff below, changes in quantity of whitespace are not shown.)
Index: x_autonumber.c
===================================================================
RCS file: x_autonumber.c
diff -N x_autonumber.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ x_autonumber.c 12 Dec 2006 18:11:39 -0000 1.2
@@ -0,0 +1,1485 @@
+/* gEDA - GPL Electronic Design Automation
+ * gschem - gEDA Schematic Capture
+ * Copyright (C) 1998-2000 Ales V. Hvezda
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <libgeda/libgeda.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "../include/i_vars.h"
+#include "../include/globals.h"
+#include "../include/prototype.h"
+
+#ifdef HAVE_LIBDMALLOC
+#include <dmalloc.h>
+#endif
+
+#define GLADE_HOOKUP_OBJECT(component,widget,name) \
+ g_object_set_data_full (G_OBJECT (component), name, \
+ gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
+
+/** @brief How many entries to keep in the "Search text" combo box. */
+#define HISTORY_LENGTH 15
+
+/* autonumber text structs and enums */
+enum {
+ AUTONUMBER_SORT_DIAGONAL,
+ AUTONUMBER_SORT_YX,
+ AUTONUMBER_SORT_YX_REV,
+ AUTONUMBER_SORT_XY,
+ AUTONUMBER_SORT_XY_REV,
+ AUTONUMBER_SORT_FILE
+};
+
+enum {
+ AUTONUMBER_IGNORE,
+ AUTONUMBER_RENUMBER,
+ AUTONUMBER_RESPECT
+};
+
+enum {
+ SCOPE_SELECTED,
+ SCOPE_PAGE,
+ SCOPE_HIERARCHY
+};
+
+typedef struct autonumber_text_t AUTONUMBER_TEXT;
+
+/** @brief Stored state of the autonumber text dialog */
+struct autonumber_text_t {
+ /** @brief Search text history */
+ GList *scope_text;
+
+ /** @brief Scope for searching existing numbers */
+ gint scope_skip;
+
+ /** @brief Scope for autonumbering text */
+ gint scope_number;
+
+ /** @brief Overwrite existing numbers in scope */
+ gboolean scope_overwrite;
+
+ /** @brief Sort order */
+ gint order;
+
+ /** @brief Starting number for automatic numbering */
+ gint startnum;
+
+ /** @brief Remove numbers instead of automatic numbering */
+ gboolean removenum;
+
+ /** @brief Automatic assignments of slots */
+ gboolean slotting;
+
+ /** @brief Pointer to the dialog */
+ GtkWidget *dialog;
+
+ /** @brief Pointer to the toplevel struct */
+ TOPLEVEL *toplevel;
+
+ /* variables used while autonumbering */
+ gchar * current_searchtext;
+ gint root_page; /* flag whether its the root page or not */
+ GList *used_numbers; /* list of used numbers */
+ GList *free_slots; /* list of FREE_SLOT objects */
+ GList *used_slots; /* list of USED_SLOT objects */
+};
+
+typedef struct autonumber_slot_t AUTONUMBER_SLOT;
+
+struct autonumber_slot_t {
+ gchar *symbolname; /* or should I use the device name? (Werner) */
+ gint number; /* usually this is the refdes number */
+ gint slotnr; /* just the number of the free slot */
+};
+
+
+
+/* ***** BACK-END CODE ***************************************************** */
+
+/********** compare functions for g_list_sort, ... ***********************/
+/*! \brief GCompareFunc function to sort a list with g_list_sort().
+ * \par Function Description
+ * Compares the integer values of the gconstpointers a and b.
+ * \return -1 if a<b, 1 if a>b, 0 if a==b
+ */
+gint autonumber_sort_numbers(gconstpointer a, gconstpointer b) {
+ if (GPOINTER_TO_INT(a) < GPOINTER_TO_INT(b))
+ return -1;
+ if (GPOINTER_TO_INT(a) > GPOINTER_TO_INT(b))
+ return 1;
+ return 0;
+}
+
+/*! \brief GCompareFunc function to sort text objects by there location
+ * \par Function Description
+ * This Funcion takes two <B>OBJECT*</B> arguments and compares the
+ * location of the two text objects. The first sort criteria is the x location,
+ * the second sort criteria is the y location.
+ * The Function is used as GCompareFunc by g_list_sort().
+ */
+gint autonumber_sort_xy(gconstpointer a, gconstpointer b) {
+ OBJECT *aa, *bb;
+ aa=(OBJECT *) a; bb=(OBJECT *) b;
+ if (aa->text->x < bb->text->x)
+ return -1;
+ if (aa->text->x > bb->text->x)
+ return 1;
+ /* x == x */
+ if (aa->text->y > bb->text->y)
+ return -1;
+ if (aa->text->y < bb->text->y)
+ return 1;
+ return 0;
+}
+
+/*! \brief GCompareFunc function to sort text objects by there location
+ * \par Function Description
+ * This funcion takes two <B>OBJECT*</B> arguments and compares the
+ * location of the two text objects. The first sort criteria is the x location,
+ * the second sort criteria is the y location.
+ * This function sorts the objects in reverse order.
+ * The function is used as GCompareFunc by g_list_sort().
+ */
+gint autonumber_sort_xy_rev(gconstpointer a, gconstpointer b) {
+ OBJECT *aa, *bb;
+ aa=(OBJECT *) a; bb=(OBJECT *) b;
+ if (aa->text->x < bb->text->x)
+ return 1;
+ if (aa->text->x > bb->text->x)
+ return -1;
+ /* x == x */
+ if (aa->text->y < bb->text->y)
+ return 1;
+ if (aa->text->y > bb->text->y)
+ return -1;
+ return 0;
+}
+
+/*! \brief GCompareFunc function to sort text objects by there location
+ * \par Function Description
+ * This funcion takes two <B>OBJECT*</B> arguments and compares the
+ * location of the two text objects. The first sort criteria is the y location,
+ * the second sort criteria is the x location.
+ * The function is used as GCompareFunc by g_list_sort().
+ */
+int autonumber_sort_yx(gconstpointer a, gconstpointer b) {
+ OBJECT *aa, *bb;
+ aa=(OBJECT *) a; bb=(OBJECT *) b;
+ if (aa->text->y > bb->text->y)
+ return -1;
+ if (aa->text->y < bb->text->y)
+ return 1;
+ /* y == y */
+ if (aa->text->x < bb->text->x)
+ return -1;
+ if (aa->text->x > bb->text->x)
+ return 1;
+ return 0;
+}
+
+/*! \brief GCompareFunc function to sort text objects by there location
+ * \par Function Description
+ * This Funcion takes two <B>OBJECT*</B> arguments and compares the
+ * location of the two text objects. The first sort criteria is the y location,
+ * the second sort criteria is the x location.
+ * This function sorts the objects in reverse order.
+ * The function is used as GCompareFunc by g_list_sort().
+ */
+int autonumber_sort_yx_rev(gconstpointer a, gconstpointer b) {
+ OBJECT *aa, *bb;
+ aa=(OBJECT *) a; bb=(OBJECT *) b;
+ if (aa->text->y > bb->text->y)
+ return 1;
+ if (aa->text->y < bb->text->y)
+ return -1;
+ /* y == y */
+ if (aa->text->x > bb->text->x)
+ return 1;
+ if (aa->text->x < bb->text->x)
+ return -1;
+ return 0;
+}
+
+/*! \brief GCompareFunc function to sort text objects by there location
+ * \par Function Description
+ * This Funcion takes two <B>OBJECT*</B> arguments and compares the
+ * location of the two text objects. The sort criteria is the combined x- and the
+ * y-location. The function sorts from top left to bottom right.
+ * The function is used as GCompareFunc by g_list_sort().
+ */
+int autonumber_sort_diagonal(gconstpointer a, gconstpointer b) {
+ OBJECT *aa, *bb;
+ aa=(OBJECT *) a; bb=(OBJECT *) b;
+ if (aa->text->x - aa->text->y < bb->text->x - bb->text->y)
+ return -1;
+ if (aa->text->x - aa->text->y > bb->text->x - bb->text->y)
+ return 1;
+ return 0;
+}
+
+/*! \brief GCompareFunc function to acces <B>AUTONUMBER_SLOT</B> object in a GList
+ * \par Function Description
+ * This Funcion takes two <B>AUTONUMBER_SLOT*</B> arguments and compares them.
+ * Sorting criteria is are the AUTONUMBER_SLOT members: first the symbolname, than the
+ * number and last the slotnr.
+ * If the number or the slotnr is set to zero it acts as a wildcard.
+ * The function is used as GCompareFunc by GList functions.
+ */
+gint freeslot_compare(gconstpointer a, gconstpointer b)
+{
+ AUTONUMBER_SLOT *aa, *bb;
+ gint res;
+ aa = (AUTONUMBER_SLOT *) a; bb = (AUTONUMBER_SLOT *) b;
+
+ if ((res = strcmp(aa->symbolname, bb->symbolname)) != 0)
+ return res;
+
+ /* aa->symbolname == bb->symbolname */
+ if (aa->number == 0 || bb->number == 0)
+ return 0;
+ if (aa->number > bb->number)
+ return 1;
+ if (aa->number < bb->number)
+ return -1;
+
+ /* aa->number == bb->number */
+ if (aa->slotnr == 0 || bb->slotnr == 0)
+ return 0;
+ if (aa->slotnr > bb->slotnr)
+ return 1;
+ if (aa->slotnr < bb->slotnr)
+ return -1;
+
+ return 0;
+}
+
+/*! \brief Prints a <B>GList</B> of <B>AUTONUMBER_SLOT</B> elements
+ * \par Function Description
+ * This funcion prints the elements of a GList that contains <B>AUTONUMBER_SLOT</B> elements
+ * It is only used for debugging purposes.
+ */
+void freeslot_print(GList *list) {
+ GList *item;
+ AUTONUMBER_SLOT *fs;
+
+ printf("freeslot_print(): symname, number, slot\n");
+ for (item = list; item != NULL; item = g_list_next(item)) {
+ fs = item ->data;
+ printf(" %s, %d, %d\n",fs->symbolname, fs->number, fs->slotnr);
+ }
+}
+
+
+/*! \brief Function to clear the databases of used parts
+ * \par Function Descriptions
+ * Just remove the list of used numbers, used slots and free slots.
+ */
+void autonumber_clear_database (AUTONUMBER_TEXT *autotext)
+{
+ /* cleanup everything for the next searchtext */
+ if (autotext->used_numbers != NULL) {
+ g_list_free(autotext->used_numbers);
+ autotext->used_numbers = NULL;
+ }
+ if (autotext->free_slots != NULL) {
+ g_list_foreach(autotext->free_slots, (GFunc) g_free, NULL);
+ g_list_free(autotext->free_slots);
+ autotext->free_slots = NULL;
+ }
+ if (autotext->used_slots != NULL) {
+ g_list_foreach(autotext->used_slots, (GFunc) g_free, NULL);
+ g_list_free(autotext->used_slots);
+ autotext->used_slots = NULL;
+ }
+}
+
+/*! \brief Function to test, whether the OBJECT matches the autotext criterias
+ * \par Function Description
+ * The criterias are those of the autonumber text dialog. The function decides
+ * whether the <B>OBJECT</B> has to be renumberd, ignored or taken care of when
+ * renumbering all other objects.
+ * \return one of these integer values: <B>AUTONUMBER_IGNORE</B>,
+ * <B>AUTONUMBER_RESPECT</B> or <B>AUTONUMBER_RENUMBER</B> and the current number
+ * of the text object in <B>*number</B>.
+ */
+gint autonumber_match(AUTONUMBER_TEXT *autotext, OBJECT *o_current, gint *number)
+{
+ gint i, len, isnumbered=1;
+
+ len = strlen(autotext->current_searchtext);
+ /* first find out whether we can ignore that object */
+ if (o_current->type != OBJ_TEXT /* text object */
+ || !(strlen(o_current->text->string) - len > 0)
+ || !g_str_has_prefix(o_current->text->string, autotext->current_searchtext))
+ return AUTONUMBER_IGNORE;
+
+ /* the string object matches with its leading characters to the searchtext */
+ /* now look for the extension, either a number or the "?" */
+ if (g_str_has_suffix (o_current->text->string,"?")) {
+ isnumbered = 0;
+ }
+ else {
+ if (!isdigit(o_current->text->string[len])) /* has at least one digit */
+ return AUTONUMBER_IGNORE;
+
+ for (i=len+1; o_current->text->string[i]; i++) /* and only digits */
+ if (!isdigit(o_current->text->string[i]))
+ return AUTONUMBER_IGNORE;
+ }
+
+ /* we have six cases, 3 from focus multiplied by 2 selection cases */
+ if ((autotext->root_page || autotext->scope_number == SCOPE_HIERARCHY)
+ && (o_current->selected
+ || autotext->scope_number == SCOPE_HIERARCHY || autotext->scope_number == SCOPE_PAGE)
+ && (!isnumbered || (autotext->scope_overwrite)))
+ return AUTONUMBER_RENUMBER;
+
+ if (isnumbered
+ && !(autotext->scope_skip == SCOPE_SELECTED
+ && !(o_current->selected) && autotext->root_page)) {
+ sscanf(&(o_current->text->string[len])," %d", number);
+ return AUTONUMBER_RESPECT; /* numbered objects which we don't renumber */
+ }
+ else
+ return AUTONUMBER_IGNORE; /* unnumbered objects outside the focus */
+}
+
+
+/*! \brief Creates a list of already numbered objects and slots
+ * \par Function Description
+ * This function collects the used numbers of a single schematic page.
+ * The used element numbers are stored in a GList container
+ * inside the <B>AUTONUMBER_TEXT</B> struct.
+ * The slotting container is a little bit different. It stores free slots of
+ * multislotted symbols, that were used only partially.
+ * The criterias are derivated from the autonumber dialog entries.
+ */
+void autonumber_get_used(TOPLEVEL *w_current, AUTONUMBER_TEXT *autotext)
+{
+ gint number, numslots, slotnr, i;
+ OBJECT *o_current, *o_parent, *o_numslots;
+ ATTRIB *a_current;
+ AUTONUMBER_SLOT *slot;
+ GList *slot_item;
+ char *numslot_str, *slot_str;
+
+ for (o_current = w_current->page_current->object_head; o_current != NULL;
+ o_current = o_current->next) {
+ if (autonumber_match(autotext, o_current, &number) == AUTONUMBER_RESPECT) {
+ /* check slot and maybe add it to the lists */
+ if ((autotext->slotting)
+ && (a_current = o_current->attached_to) != NULL) {
+ o_parent = o_attrib_return_parent(a_current);
+ /* check for slotted symbol */
+ if ((numslot_str = o_attrib_search_numslots(o_parent, &o_numslots)) != NULL) {
+ sscanf(numslot_str," %d",&numslots);
+ free(numslot_str);
+
+ if (numslots > 0) {
+ slot_str=o_attrib_search_attrib_name(o_parent->attribs,"slot",0);
+ if (slot_str == NULL) {
+ s_log_message(_("slotted object without slot attribute may cause "
+ "problems when autonumbering slots\n"));
+ }
+ else {
+ sscanf(slot_str, " %d", &slotnr);
+ slot = g_new(AUTONUMBER_SLOT,1);
+ slot->number = number;
+ slot->slotnr = slotnr;
+ slot->symbolname = o_parent->complex_basename;
+
+
+ slot_item = g_list_find_custom(autotext->used_slots,
+ slot,
+ (GCompareFunc) freeslot_compare);
+ if (slot_item != NULL) { /* duplicate slot in used_slots */
+ s_log_message(_("duplicate slot may cause problems: "
+ "[symbolname=%s, number=%d, slot=%d]\n"),
+ slot->symbolname, slot->number, slot->slotnr);
+ g_free(slot);
+ }
+ else {
+ autotext->used_slots = g_list_insert_sorted(autotext->used_slots,
+ slot,
+ (GCompareFunc) freeslot_compare);
+
+ slot_item = g_list_find_custom(autotext->free_slots,
+ slot,
+ (GCompareFunc) freeslot_compare);
+ if (slot_item == NULL) {
+ /* insert all slots to the list, except of the current one */
+ for (i=1; i <= numslots; i++) {
+ if (i != slotnr) {
+ slot = g_memdup(slot, sizeof(AUTONUMBER_SLOT));
+ slot->slotnr = i;
+ autotext->free_slots = g_list_insert_sorted(autotext->free_slots,
+ slot,
+ (GCompareFunc) freeslot_compare);
+ }
+ }
+ }
+ else {
+ g_free(slot_item->data);
+ autotext->free_slots = g_list_delete_link(autotext->free_slots, slot_item);
+ }
+ }
+ }
+ }
+ }
+ }
+ /* put number into the used list */
+ autotext->used_numbers = g_list_insert_sorted(autotext->used_numbers,
+ GINT_TO_POINTER(number),
+ (GCompareFunc) autonumber_sort_numbers);
+ }
+ }
+}
+
+
+/*! \brief Gets or generates free numbers for the autonumbering process.
+ * \par Function Description
+ * This function gets or generates new numbers for the <B>OBJECT o_current</B>.
+ * It uses the element numbers <B>used_numbers</B> and the list of the free slots
+ * <B>free_slots</B> of the <B>AUTONUMBER_TEXT</B> struct.
+ * \return
+ * The new number is returned into the <B>number</B> parameter.
+ * <B>slot</B> is set if autoslotting is active, else it is set to zero.
+ */
+void autonumber_get_new_numbers(AUTONUMBER_TEXT *autotext, OBJECT *o_current,
+ gint *number, gint *slot)
+{
+ GList *item;
+ gint new_number, numslots, i;
+ AUTONUMBER_SLOT *freeslot;
+ OBJECT *o_parent = NULL, *o_numslots;
+ ATTRIB *a_current = NULL;
+ GList *freeslot_item;
+ gchar *numslot_str;
+
+ new_number = autotext->startnum;
+
+ /* Check for slots first */
+ /* 1. are there any unused slots in the database? */
+ if ((autotext->slotting) && (a_current = o_current->attached_to) != NULL) {
+ o_parent = o_attrib_return_parent(a_current);
+ freeslot = g_new(AUTONUMBER_SLOT,1);
+ freeslot->symbolname = o_parent->complex_basename;
+ freeslot->number = 0;
+ freeslot->slotnr = 0;
+ freeslot_item = g_list_find_custom(autotext->free_slots,
+ freeslot,
+ (GCompareFunc) freeslot_compare);
+ g_free(freeslot);
+ /* Yes! -> remove from database, apply it */
+ if (freeslot_item != NULL) {
+ freeslot = freeslot_item->data;
+ *number = freeslot->number;
+ *slot = freeslot->slotnr;
+ g_free(freeslot);
+ autotext->free_slots = g_list_delete_link(autotext->free_slots, freeslot_item);
+
+ return;
+ }
+ }
+
+ /* get a new number */
+ item = autotext->used_numbers;
+ while (1) {
+ while (item != NULL && GPOINTER_TO_INT(item->data) < new_number)
+ item = g_list_next(item);
+
+ if (item == NULL || GPOINTER_TO_INT(item->data) > new_number)
+ break;
+ else /* new_number == item->data */
+ new_number++;
+ }
+ *number = new_number;
+ *slot = 0;
+
+ /* insert the new number to the used list */
+ autotext->used_numbers = g_list_insert_sorted(autotext->used_numbers,
+ GINT_TO_POINTER(new_number),
+ (GCompareFunc) autonumber_sort_numbers);
+
+ /* 3. is o_current a slotted object ? */
+ if ((autotext->slotting) && o_parent != NULL) {
+ if ((numslot_str = o_attrib_search_numslots(o_parent, &o_numslots)) != NULL) {
+ sscanf(numslot_str," %d",&numslots);
+ free(numslot_str);
+ if (numslots > 0) {
+ /* Yes! -> new number and slot=1; add the other slots to the database */
+ *slot = 1;
+ for (i=2; i <=numslots; i++) {
+ freeslot = g_new(AUTONUMBER_SLOT,1);
+ freeslot->symbolname = o_parent->complex_basename;
+ freeslot->number = new_number;
+ freeslot->slotnr = i;
+ autotext->free_slots = g_list_insert_sorted(autotext->free_slots,
+ freeslot,
+ (GCompareFunc) freeslot_compare);
+ }
+ }
+ }
+ }
+}
+
+/** @brief Removes the number from the element.
+ *
+ * This function updates the text content of the \a o_current object.
+ *
+ * @param autotext Pointer to the state structure
+ * @param o_current Pointer to the object from which to remove the number
+ *
+ */
+void autonumber_remove_number(AUTONUMBER_TEXT * autotext, OBJECT *o_current)
+{
+ ATTRIB *a_current;
+ OBJECT *o_parent, *o_slot;
+ gchar *slot_str;
+
+ /* replace old text */
+ g_free(o_current->text->string);
+ o_current->text->string = g_strdup_printf("%s?",
+ autotext->current_searchtext);
+
+ /* redraw the text */
+ o_text_erase(autotext->toplevel, o_current);
+ o_text_recreate(autotext->toplevel, o_current);
+ o_text_draw(autotext->toplevel, o_current);
+
+ /* remove the slot attribute if slotting is active */
+ if (autotext->slotting) {
+ /* get the slot attribute */
+ if ((a_current = o_current->attached_to) != NULL) {
+ o_parent = o_attrib_return_parent(a_current);
+ slot_str = o_attrib_search_slot(o_parent, &o_slot);
+ if (slot_str != NULL && o_slot != NULL) {
+ g_free(slot_str);
+ /* delete the slot attribute */
+ o_selection_remove (autotext->toplevel->page_current->selection2_head, o_slot);
+ o_delete_text (autotext->toplevel, o_slot);
+ /* redraw the slotted object. So that the pinnumbers appear as with slot=1 */
+ /* --> No: should be done by o_delete_text as several dialog use it. */
+ }
+ }
+ }
+ autotext->toplevel->page_current->CHANGED = 1;
+}
+
+/*! \brief Changes the number <B>OBJECT</B> element. Changes the slot attribute.
+ * \par Function Description
+ * This function updates the text content of the <B>o_current</B> object.
+ * If the <B>slot</B> value is not zero. It updates the slot attribut of the
+ * complex element that is also the parent object of the o_current element.
+ */
+void autonumber_apply_new_text(AUTONUMBER_TEXT * autotext, OBJECT *o_current,
+ gint number, gint slot)
+{
+ ATTRIB *a_current;
+ OBJECT *o_parent, *o_slot;
+ gchar *slot_str;
+
+ /* add the slot as attribute to the object */
+ if (slot != 0
+ && (a_current = o_current->attached_to) != NULL) {
+ o_parent = o_attrib_return_parent(a_current);
+ slot_str = o_attrib_search_slot(o_parent, &o_slot);
+ if (slot_str != NULL) {
+ /* update the slot attribute */
+ g_free(slot_str);
+ g_free(o_slot->text->string);
+ o_slot->text->string = g_strdup_printf("slot=%d",slot);
+ o_text_erase(autotext->toplevel, o_slot);
+ o_text_recreate(autotext->toplevel, o_slot);
+ o_text_draw(autotext->toplevel, o_slot);
+ }
+ else {
+ /* create a new attribute and attach it */
+ o_attrib_add_attrib(autotext->toplevel,
+ g_strdup_printf("slot=%d",slot),
+ INVISIBLE, SHOW_NAME_VALUE,
+ o_parent);
+ }
+ o_attrib_slot_update(autotext->toplevel, o_parent);
+ }
+
+ /* replace old text */
+ g_free(o_current->text->string);
+ o_current->text->string = g_strdup_printf("%s%d", autotext->current_searchtext,
+ number);
+ /* redraw the text */
+ o_text_erase(autotext->toplevel, o_current);
+ o_text_recreate(autotext->toplevel, o_current);
+ o_text_draw(autotext->toplevel, o_current);
+ autotext->toplevel->page_current->CHANGED = 1;
+}
+
+
+/*! \brief Handles all the options of the autonumber text dialog
+ * \par Function Description
+ * This function is the master of all autonumber code. It receives the options of
+ * the the autonumber text dialog in an <B>AUTONUMBER_TEXT</B> structure.
+ * First it collects all pages of a hierarchical schematic.
+ * Second it gets all matching text elements for the searchtext.
+ * Then it renumbers all text elements of all schematic pages. The renumbering
+ * follows the rules of the parameters given in the autonumber text dialog.
+ */
+void autonumber_text_autonumber(AUTONUMBER_TEXT *autotext)
+{
+ GList *pages;
+ GList *searchtext_list=NULL;
+ GList *text_item, *obj_item, *page_item;
+ OBJECT *o_current;
+ TOPLEVEL *w_current;
+ gchar *searchtext;
+ gchar *scope_text;
+ gchar *new_searchtext;
+ gint i, number, slot;
+ GList *o_list = NULL;
+
+ w_current = autotext->toplevel;
+ autotext->current_searchtext = NULL;
+ autotext->root_page = 1;
+ autotext->used_numbers = NULL;
+ autotext->free_slots = NULL;
+ autotext->used_slots = NULL;
+
+ scope_text = g_list_first(autotext->scope_text)->data;
+
+ /* Step1: get all pages of the hierarchy */
+ pages = s_hierarchy_traversepages(w_current, HIERARCHY_NODUPS);
+
+ // g_list_foreach(pages, (GFunc) s_hierarchy_print_page, NULL);
+
+ /* Step2: if searchtext has an asterisk at the end we have to find
+ all matching searchtextes.
+
+ Example: "refdes=*" will match each text that starts with "refdes="
+ and has a trailing "?" or a trailing number if the "all"-option is set.
+ We get a list of possible prefixes: refdes=R, refdes=C.
+
+ If there is only one search pattern, it becomes a single item
+ in the searchtext list */
+
+ if (strlen(scope_text) == 0) {
+ s_log_message(_("No searchstring given in autonumber text."));
+ return; /* error */
+ }
+ else if (g_str_has_suffix(scope_text,"?") == TRUE) {
+ /* single searchtext, strip of the "?" */
+ searchtext = g_strndup(scope_text, strlen(scope_text)-1);
+ searchtext_list=g_list_append (searchtext_list, searchtext);
+ }
+ else if (g_str_has_suffix(scope_text,"*") == TRUE) {
+ /* strip of the "*" */
+ searchtext = g_strndup(scope_text, strlen(scope_text)-1);
+ /* collect all the possible searchtexts in all pages of the hierarchy */
+ for (page_item = pages; page_item != NULL; page_item = g_list_next(page_item)) {
+ s_page_goto(w_current, page_item->data);
+ /* iterate over all objects an look for matching searchtext's */
+ for (o_current = w_current->page_current->object_head; o_current != NULL;
+ o_current = o_current->next) {
+ if (o_current->type == OBJ_TEXT) {
+ if (autotext->scope_number == SCOPE_HIERARCHY
+ || autotext->scope_number == SCOPE_PAGE
+ || ((autotext->scope_number == SCOPE_SELECTED) && (o_current->selected))) {
+ if (g_str_has_prefix(o_current->text->string, searchtext) == TRUE) {
+ /* the beginnig of the current text matches with the searchtext now */
+ /* strip of the trailing [0-9?] chars and add it too the searchtext */
+ for (i = strlen(o_current->text->string)-1;
+ (i >= strlen(searchtext))
+ && (o_current->text->string[i] == '?'
+ || isdigit(o_current->text->string[i]));
+ i--)
+ ; /* void */
+
+ new_searchtext=g_strndup(o_current->text->string, i+1);
+ if (g_list_find_custom(searchtext_list, new_searchtext,
+ (GCompareFunc) strcmp) == NULL ) {
+ searchtext_list = g_list_append(searchtext_list, new_searchtext);
+ //printf("autonumber_text: text \"%s\", \"%s\"\n",
+ // o_current->text->string, new_searchtext);
+ }
+ else {
+ g_free(new_searchtext);
+ }
+ }
+ }
+ }
+ }
+ if (autotext->scope_number == SCOPE_SELECTED || autotext->scope_number == SCOPE_PAGE)
+ break; /* search only in the first page */
+ }
+ g_free(searchtext);
+ }
+ else {
+ s_log_message(_("No '*' or '?' given at the end of the autonumber text.\n"));
+ return;
+ }
+
+ /* Step3: iterate over the search items in the list */
+ for (text_item=searchtext_list; text_item !=NULL; text_item=g_list_next(text_item)) {
+ autotext->current_searchtext = text_item->data;
+ // printf("autonumber_text2: searchtext %s\n", autotext->current_searchtext);
+ /* decide whether to renumber page by page or get a global used-list */
+ if (autotext->scope_skip == SCOPE_HIERARCHY) { /* whole hierarchy database */
+ /* renumbering all means that no db is required */
+ if (!(autotext->scope_number == SCOPE_HIERARCHY
+ && autotext->scope_overwrite)) {
+ for (page_item = pages; page_item != NULL; page_item = g_list_next(page_item)) {
+ autotext->root_page = (pages->data == page_item->data);
+ s_page_goto(w_current, page_item->data);
+ autonumber_get_used(w_current, autotext);
+ }
+ }
+ }
+
+ /* renumber the elements */
+ for (page_item = pages; page_item != NULL; page_item = g_list_next(page_item)) {
+ s_page_goto(w_current, page_item->data);
+ autotext->root_page = (pages->data == page_item->data);
+ /* build a page database if we're numbering pagebypage or selection only*/
+ if (autotext->scope_skip == SCOPE_PAGE || autotext->scope_skip == SCOPE_SELECTED) {
+ autonumber_get_used(w_current, autotext);
+ }
+
+ /* RENUMBER CODE FOR ONE PAGE AND ONE SEARCHTEXT*/
+ /* 1. get objects to renumber */
+ for (o_current = w_current->page_current->object_head; o_current != NULL;
+ o_current = o_current->next) {
+ if (autonumber_match(autotext, o_current, &number) == AUTONUMBER_RENUMBER) {
+ /* put number into the used list */
+ o_list = g_list_append(o_list, o_current);
+ }
+ }
+
+ /* 2. sort object list */
+ switch (autotext->order) {
+ case AUTONUMBER_SORT_YX:
+ o_list=g_list_sort(o_list, autonumber_sort_yx);
+ break;
+ case AUTONUMBER_SORT_YX_REV:
+ o_list=g_list_sort(o_list, autonumber_sort_yx_rev);
+ break;
+ case AUTONUMBER_SORT_XY:
+ o_list=g_list_sort(o_list, autonumber_sort_xy);
+ break;
+ case AUTONUMBER_SORT_XY_REV:
+ o_list=g_list_sort(o_list, autonumber_sort_xy_rev);
+ break;
+ case AUTONUMBER_SORT_DIAGONAL:
+ o_list=g_list_sort(o_list, autonumber_sort_diagonal);
+ break;
+ default:
+ ; /* unsorted file order */
+ }
+
+ /* 3. renumber/reslot the objects */
+ for(obj_item=o_list; obj_item != NULL; obj_item=g_list_next(obj_item)) {
+ o_current= obj_item->data;
+ if(autotext->removenum) {
+ autonumber_remove_number(autotext, o_current);
+ } else {
+ /* get valid numbers from the database */
+ autonumber_get_new_numbers(autotext, o_current, &number, &slot);
+ /* and apply it. TODO: join these two functions */
+ autonumber_apply_new_text(autotext, o_current, number, slot);
+ }
+ }
+ g_list_free(o_list);
+ o_list = NULL;
+
+ /* destroy the page database */
+ if (autotext->scope_skip == SCOPE_PAGE
+ || autotext->scope_skip == SCOPE_SELECTED)
+ autonumber_clear_database(autotext);
+
+ if (autotext->scope_number == SCOPE_SELECTED
+ || autotext->scope_number == SCOPE_PAGE)
+ break; /* only renumber the parent page (the first page) */
+ }
+ autonumber_clear_database(autotext); /* cleanup */
+ }
+
+ /* cleanup and redraw all*/
+ g_list_foreach(searchtext_list, (GFunc) g_free, NULL);
+ g_list_free(searchtext_list);
+ s_page_goto(w_current, pages->data); /* go back to the root page */
+ o_redraw_all(w_current);
+ g_list_free(pages);
+ o_undo_savestate(w_current, UNDO_ALL);
+}
+
+/* ***** UTILITY GUI FUNCTIONS (move to a separate file in the future?) **** */
+
+/** @brief Finds a widget by its name given a pointer to its parent.
+ *
+ * @param widget Pointer to the parent widget.
+ * @param widget_name Name of the widget.
+ * @return Pointer to the widget or NULL if not found. */
+GtkWidget* lookup_widget(GtkWidget *widget, const gchar *widget_name)
+{
+ GtkWidget *found_widget;
+
+ found_widget = (GtkWidget*) g_object_get_data(G_OBJECT(widget),
+ widget_name);
+
+ return found_widget;
+}
+
+/*! \brief Put the icons and the text into the sortorder combobox
+ * \par Function Description
+ * Load all bitmaps for the combobox and store them together with the label
+ * in a GtkListStore.
+ */
+void autonumber_sortorder_create(TOPLEVEL *w_current, GtkWidget *sort_order)
+{
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkCellRenderer *renderer;
+ GdkPixbuf *pixbuf;
+ gchar *path;
+ GError *error=NULL;
+
+ gchar *filenames[] = {"gschem-diagonal.png",
+ "gschem-top2bottom.png", "gschem-bottom2top.png",
+ "gschem-left2right.png", "gschem-right2left.png",
+ "gschem-fileorder.png",
+ NULL};
+ gchar *names[] = {N_("Diagonal"),
+ N_("Top to bottom"), N_("Bottom to top"),
+ N_("Left to right"), N_("Right to left"),
+ N_("File order"),
+ NULL};
+ gint i;
+
+ store = gtk_list_store_new(2, G_TYPE_STRING, GDK_TYPE_PIXBUF);
+
+ for (i=0; filenames[i] != NULL; i++) {
+ path=g_strconcat(w_current->bitmap_directory,
+ G_DIR_SEPARATOR_S, filenames[i], NULL);
+ pixbuf = gdk_pixbuf_new_from_file(path, &error);
+ g_free(path);
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, names[i],
+ 1, pixbuf,
+ -1);
+ }
+
+ gtk_combo_box_set_model(GTK_COMBO_BOX(sort_order), GTK_TREE_MODEL(store));
+ renderer = gtk_cell_renderer_text_new ();
+
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (sort_order),
+ renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (sort_order),
+ renderer, "text", 0, NULL);
+ renderer = gtk_cell_renderer_pixbuf_new();
+ g_object_set(G_OBJECT(renderer), "xpad", 10, "ypad", 10, NULL);
+
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (sort_order),
+ renderer, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (sort_order),
+ renderer, "pixbuf", 1, NULL);
+}
+
+/* ***** STATE STRUCT HANDLING (interface between GUI and backend code) **** */
+
+/** @brief Adds a line to the search text history list
+ *
+ * Function makes sure that: 1) There are no duplicates in the list and 2) the
+ * last search text is always at the top of the list.
+ */
+GList *autonumber_history_add(GList *history, gchar *text)
+{
+ /* Search for this text in history and delete it (so we don't have
+ * duplicate entries) */
+
+ GList *cur;
+
+ cur=history;
+ while(cur!=NULL) {
+ if(!strcmp(text, cur->data)) {
+ history=g_list_remove_link(history, cur);
+
+ g_free(cur->data);
+ g_list_free(cur);
+ break;
+ }
+ cur=g_list_next(cur);
+ }
+
+ /* Add the new text at the beginning of the list */
+
+ history=g_list_prepend(history, text);
+
+ /* Truncate history */
+ while(g_list_length(history) > HISTORY_LENGTH) {
+ GList *last = g_list_last(history);
+
+ history = g_list_remove_link(history, last);
+
+ g_free(last->data);
+ g_list_free(last);
+ }
+
+ return history;
+}
+
+/** @brief Allocate and initialize the state structure
+ *
+ * @return Pointer to the allocated structure or NULL on error.
+ */
+AUTONUMBER_TEXT *autonumber_init_state()
+{
+ AUTONUMBER_TEXT *autotext;
+
+ /* Default contents of the combo box history */
+ gchar *default_text[] = {
+ "refdes=*",
+ "refdes=C?",
+ "refdes=D?",
+ "refdes=I?",
+ "refdes=L?",
+ "refdes=Q?",
+ "refdes=R?",
+ "refdes=T?",
+ "refdes=U?",
+ "refdes=X?",
+ "netname=*",
+ "netname=A?",
+ "netname=D?",
+ NULL
+ };
+ gchar **t;
+
+ autotext = g_new(AUTONUMBER_TEXT, 1);
+
+ if(autotext==NULL) return NULL;
+
+ autotext->scope_text = NULL;
+ t=default_text;
+ while(*t!=NULL) {
+ autotext->scope_text=g_list_append(autotext->scope_text,
+ g_strdup(*t));
+ t++;
+ }
+
+ autotext->scope_skip = SCOPE_SELECTED;
+ autotext->scope_number = SCOPE_SELECTED;
+
+ autotext->scope_overwrite = 0;
+ autotext->order = AUTONUMBER_SORT_DIAGONAL;
+
+ autotext->startnum=1;
+
+ autotext->removenum=0;
+ autotext->slotting=0;
+
+ autotext->dialog = NULL;
+
+ return autotext;
+}
+
+/** @brief Restore the settings for the autonumber text dialog
+ *
+ * @param autotext Pointer to the state struct.
+ */
+void autonumber_set_state(AUTONUMBER_TEXT *autotext)
+{
+ GtkWidget *widget;
+ GtkTreeModel *model;
+ GList *el;
+ /* Scope */
+
+ /* Search text history */
+ widget = lookup_widget(autotext->dialog, "scope_text");
+
+ /* Simple way to clear the ComboBox. Owen from #gtk+ says:
+ *
+ * Yeah, it's just slightly "shady" ... if you want to stick to fully
+ * advertised API, you need to remember how many rows you added and
+ * use gtk_combo_box_remove_text() */
+
+ model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
+ gtk_list_store_clear(GTK_LIST_STORE(model));
+
+ for (el= autotext->scope_text; el != NULL; el=g_list_next(el)) {
+ gtk_combo_box_append_text(GTK_COMBO_BOX(widget), el->data);
+ }
+
+ widget = lookup_widget(autotext->dialog, "scope_skip");
+ gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
+ autotext->scope_skip);
+
+ widget = lookup_widget(autotext->dialog, "scope_number");
+ gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
+ autotext->scope_number);
+
+ widget = lookup_widget(autotext->dialog, "scope_overwrite");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+ autotext->scope_overwrite);
+
+ /* Options */
+ widget = lookup_widget(autotext->dialog, "opt_startnum");
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),
+ autotext->startnum);
+
+ widget = lookup_widget(autotext->dialog, "sort_order");
+ gtk_combo_box_set_active(GTK_COMBO_BOX(widget), autotext->order);
+
+ widget = lookup_widget(autotext->dialog, "opt_removenum");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+ autotext->removenum);
+
+ widget = lookup_widget(autotext->dialog, "opt_slotting");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+ autotext->slotting);
+}
+
+/** @brief Get the settings from the autonumber text dialog
+ *
+ * Get the settings from the autonumber text dialog and store it in the
+ * <B>AUTONUMBER_TEXT</B> structure.
+ *
+ * @param autotext Pointer to the state struct.
+ */
+void autonumber_get_state(AUTONUMBER_TEXT *autotext)
+{
+ GtkWidget *widget;
+ gchar *text;
+
+ /* Scope */
+
+ /* Search text history */
+ widget = lookup_widget(autotext->dialog, "scope_text");
+ text=gtk_combo_box_get_active_text( GTK_COMBO_BOX(widget) );
+
+ autotext->scope_text=autonumber_history_add(autotext->scope_text, text);
+
+ widget = lookup_widget(autotext->dialog, "scope_skip");
+ autotext->scope_skip = gtk_combo_box_get_active( GTK_COMBO_BOX(widget) );
+
+ widget = lookup_widget(autotext->dialog, "scope_number");
+ autotext->scope_number = gtk_combo_box_get_active(GTK_COMBO_BOX(widget) );
+
+ widget = lookup_widget(autotext->dialog, "scope_overwrite");
+ autotext->scope_overwrite = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+
+ /* Sort order */
+ widget = lookup_widget(autotext->dialog, "sort_order");
+ autotext->order= gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+
+ /* Options */
+ widget = lookup_widget(autotext->dialog, "opt_startnum");
+ autotext->startnum=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+
+ widget = lookup_widget(autotext->dialog, "opt_removenum");
+ autotext->removenum = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+
+ widget = lookup_widget(autotext->dialog, "opt_slotting");
+ autotext->slotting = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+
+/* ***** CALLBACKS (functions that get called directly from the GTK) ******* */
+
+/*! \brief OK Button callback of the autonumber text dialog
+ * \par Function Description
+ * This function applies the dialog settings to the schematics.
+ */
+void autonumber_text_ok(GtkWidget * w, AUTONUMBER_TEXT *autotext)
+{
+ autonumber_get_state(autotext);
+
+ autonumber_text_autonumber(autotext);
+}
+
+/*! \brief Destroy callback function of the autonumber text dialog
+ */
+void autonumber_text_destroy(GtkWidget * w, AUTONUMBER_TEXT *autotext)
+{
+ /* The usual behaviour is that dialog contents are not stored if
+ * the user pressed "cancel" */
+
+ /* autonumber_text_getdata(autotext); */
+
+ autotext->dialog = NULL;
+}
+
+/** @brief Close button callback function of the autonumber text dialog
+ *
+ * Just destroys the dialog. The triggered destroy event will save the
+ * dialog contents.
+ */
+void autonumber_text_close(GtkWidget * w, AUTONUMBER_TEXT *autotext)
+{
+ gtk_widget_destroy(autotext->dialog);
+
+ /* the settings are stored by autonumber_text_destroy,
+ called by the destroy event */
+}
+
+/*! \brief Keypress callback for the autonumber text dialog
+ * \par Function Description
+ * The function just closes the dialog if one presses the Escape key.
+ * The Return key applies the dialogs ok button function.
+ */
+int autonumber_text_keypress(GtkWidget * widget, GdkEventKey * event,
+ AUTONUMBER_TEXT *autotext)
+{
+ if (strcmp(gdk_keyval_name(event->keyval), "Escape") == 0) {
+ autonumber_text_close(NULL, autotext);
+ autonumber_text_destroy(NULL, autotext);
+ return TRUE;
+ }
+ if (strcmp(gdk_keyval_name(event->keyval), "Return") == 0) {
+ autonumber_text_ok(NULL, autotext);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/** @brief Callback that activates or deactivates "overwrite existing numbers"
+ * check box.
+ *
+ * This gets called each time "remove numbers" check box gets clicked.
+ */
+void autonumber_removenum_toggled(GtkWidget * w, AUTONUMBER_TEXT *autotext)
+{
+ GtkWidget *scope_overwrite;
+ GtkWidget *opt_removenum;
+
+ scope_overwrite=lookup_widget(autotext->dialog, "scope_overwrite");
+ opt_removenum=w;
+
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(opt_removenum))) {
+ /* it does not make sense to have "remove numbers" enabled and
+ * "overwrite numbers" disabled */
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON(scope_overwrite),
+ 1);
+ gtk_widget_set_sensitive(scope_overwrite, 0);
+ } else {
+ gtk_widget_set_sensitive(scope_overwrite, 1);
+ }
+}
+
+
+/* ***** DIALOG SET-UP ***************************************************** */
+
+/** @brief Creates the autonumber text dialog.
+ *
+ * Dialog is not shown. No callbacks are registered. This is basically
+ * unmodified code returned by Glade.
+ *
+ * Only modification was the following substitution:
+ *
+ * %s/create_pixmap (autonumber_text, "\(.*\)")/autonumber_create_pixmap("gschem-\1", w_current)/
+ *
+ * and addition of the "w_current" parameter.
+ *
+ * @param w_current Pointer to the top level struct.
+ * @return Pointer to the dialog window.
+ */
+GtkWidget* autonumber_create_dialog(TOPLEVEL *w_current)
+{
+ GtkWidget *autonumber_text;
+ GtkWidget *vbox1;
+ GtkWidget *frame1;
+ GtkWidget *alignment1;
+ GtkWidget *vbox3;
+ GtkWidget *table1;
+ GtkWidget *label4;
+ GtkWidget *scope_text;
+ GtkWidget *label8;
+ GtkWidget *label6;
+ GtkWidget *scope_number;
+ GtkWidget *scope_skip;
+ GtkWidget *scope_overwrite;
+ GtkWidget *label1;
+ GtkWidget *frame3;
+ GtkWidget *alignment3;
+ GtkWidget *vbox4;
+ GtkWidget *table3;
+ GtkWidget *label12;
+ GtkWidget *label13;
+ GtkObject *opt_startnum_adj;
+ GtkWidget *opt_startnum;
+ GtkWidget *sort_order;
+ GtkWidget *opt_removenum;
+ GtkWidget *opt_slotting;
+ GtkWidget *label3;
+ GtkWidget *hbuttonbox1;
+ GtkWidget *button_close;
+ GtkWidget *button_ok;
+
+ autonumber_text = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (autonumber_text), _("Autonumber text"));
+ gtk_window_set_resizable (GTK_WINDOW (autonumber_text), FALSE);
+
+ vbox1 = gtk_vbox_new (FALSE, 24);
+ gtk_widget_show (vbox1);
+ gtk_container_add (GTK_CONTAINER (autonumber_text), vbox1);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox1), 12);
+
+ frame1 = gtk_frame_new (NULL);
+ gtk_widget_show (frame1);
+ gtk_box_pack_start (GTK_BOX (vbox1), frame1, TRUE, TRUE, 0);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_NONE);
+
+ alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment1);
+ gtk_container_add (GTK_CONTAINER (frame1), alignment1);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 0, 0, 24, 0);
+
+ vbox3 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox3);
+ gtk_container_add (GTK_CONTAINER (alignment1), vbox3);
+
+ table1 = gtk_table_new (3, 2, FALSE);
+ gtk_widget_show (table1);
+ gtk_box_pack_start (GTK_BOX (vbox3), table1, TRUE, TRUE, 0);
+ gtk_table_set_row_spacings (GTK_TABLE (table1), 3);
+ gtk_table_set_col_spacings (GTK_TABLE (table1), 12);
+
+ label4 = gtk_label_new (_("Search for:"));
+ gtk_widget_show (label4);
+ gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5);
+
+ scope_text = gtk_combo_box_entry_new_text ();
+ gtk_widget_show (scope_text);
+ gtk_table_attach (GTK_TABLE (table1), scope_text, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ label8 = gtk_label_new (_("Autonumber text in:"));
+ gtk_widget_show (label8);
+ gtk_table_attach (GTK_TABLE (table1), label8, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label8), 0, 0.5);
+
+ label6 = gtk_label_new (_("Skip numbers found in:"));
+ gtk_widget_show (label6);
+ gtk_table_attach (GTK_TABLE (table1), label6, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5);
+
+ scope_number = gtk_combo_box_new_text ();
+ gtk_widget_show (scope_number);
+ gtk_table_attach (GTK_TABLE (table1), scope_number, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (scope_number), _("Selected objects"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (scope_number), _("Current page"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (scope_number), _("Whole hierarchy"));
+
+ scope_skip = gtk_combo_box_new_text ();
+ gtk_widget_show (scope_skip);
+ gtk_table_attach (GTK_TABLE (table1), scope_skip, 1, 2, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (scope_skip), _("Selected objects"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (scope_skip), _("Current page"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (scope_skip), _("Whole hierarchy"));
+
+ scope_overwrite = gtk_check_button_new_with_mnemonic (_("Overwrite existing numbers"));
+ gtk_widget_show (scope_overwrite);
+ gtk_box_pack_start (GTK_BOX (vbox3), scope_overwrite, FALSE, FALSE, 6);
+
+ label1 = gtk_label_new (_("<b>Scope</b>"));
+ gtk_widget_show (label1);
+ gtk_frame_set_label_widget (GTK_FRAME (frame1), label1);
+ gtk_label_set_use_markup (GTK_LABEL (label1), TRUE);
+
+ frame3 = gtk_frame_new (NULL);
+ gtk_widget_show (frame3);
+ gtk_box_pack_start (GTK_BOX (vbox1), frame3, TRUE, TRUE, 0);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_NONE);
+
+ alignment3 = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment3);
+ gtk_container_add (GTK_CONTAINER (frame3), alignment3);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment3), 0, 0, 24, 0);
+
+ vbox4 = gtk_vbox_new (FALSE, 3);
+ gtk_widget_show (vbox4);
+ gtk_container_add (GTK_CONTAINER (alignment3), vbox4);
+
+ table3 = gtk_table_new (2, 2, FALSE);
+ gtk_widget_show (table3);
+ gtk_box_pack_start (GTK_BOX (vbox4), table3, TRUE, TRUE, 0);
+ gtk_table_set_row_spacings (GTK_TABLE (table3), 3);
+ gtk_table_set_col_spacings (GTK_TABLE (table3), 12);
+
+ label12 = gtk_label_new (_("Starting number:"));
+ gtk_widget_show (label12);
+ gtk_table_attach (GTK_TABLE (table3), label12, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label12), 0, 0.5);
+
+ label13 = gtk_label_new (_("Sort order:"));
+ gtk_widget_show (label13);
+ gtk_table_attach (GTK_TABLE (table3), label13, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label13), 0, 0.5);
+
+ opt_startnum_adj = gtk_adjustment_new (1, 0, 10000, 1, 10, 10);
+ opt_startnum = gtk_spin_button_new (GTK_ADJUSTMENT (opt_startnum_adj), 1, 0);
+ gtk_widget_show (opt_startnum);
+ gtk_table_attach (GTK_TABLE (table3), opt_startnum, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ sort_order = gtk_combo_box_new();
+ gtk_widget_show (sort_order);
+ gtk_table_attach (GTK_TABLE (table3), sort_order, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ opt_removenum = gtk_check_button_new_with_mnemonic (_("Remove numbers"));
+ gtk_widget_show (opt_removenum);
+ gtk_box_pack_start (GTK_BOX (vbox4), opt_removenum, FALSE, FALSE, 0);
+
+ opt_slotting = gtk_check_button_new_with_mnemonic (_("Automatic slotting"));
+ gtk_widget_show (opt_slotting);
+ gtk_box_pack_start (GTK_BOX (vbox4), opt_slotting, FALSE, FALSE, 0);
+
+ label3 = gtk_label_new (_("<b>Options</b>"));
+ gtk_widget_show (label3);
+ gtk_frame_set_label_widget (GTK_FRAME (frame3), label3);
+ gtk_label_set_use_markup (GTK_LABEL (label3), TRUE);
+
+ hbuttonbox1 = gtk_hbutton_box_new ();
+ gtk_widget_show (hbuttonbox1);
+ gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, TRUE, TRUE, 0);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 12);
+
+ button_close = gtk_button_new_from_stock ("gtk-close");
+ gtk_widget_show (button_close);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox1), button_close);
+ GTK_WIDGET_SET_FLAGS (button_close, GTK_CAN_DEFAULT);
+
+ button_ok = gtk_button_new_from_stock ("gtk-apply");
+ gtk_widget_show (button_ok);
+ gtk_container_add (GTK_CONTAINER (hbuttonbox1), button_ok);
+ GTK_WIDGET_SET_FLAGS (button_ok, GTK_CAN_DEFAULT);
+
+ /* Store pointers to all widgets, for use by lookup_widget(). */
+ GLADE_HOOKUP_OBJECT (autonumber_text, alignment1, "alignment1");
+ GLADE_HOOKUP_OBJECT (autonumber_text, scope_text, "scope_text");
+ GLADE_HOOKUP_OBJECT (autonumber_text, scope_number, "scope_number");
+ GLADE_HOOKUP_OBJECT (autonumber_text, scope_skip, "scope_skip");
+ GLADE_HOOKUP_OBJECT (autonumber_text, scope_overwrite, "scope_overwrite");
+ GLADE_HOOKUP_OBJECT (autonumber_text, opt_startnum, "opt_startnum");
+ GLADE_HOOKUP_OBJECT (autonumber_text, sort_order, "sort_order");
+ GLADE_HOOKUP_OBJECT (autonumber_text, opt_removenum, "opt_removenum");
+ GLADE_HOOKUP_OBJECT (autonumber_text, opt_slotting, "opt_slotting");
+ GLADE_HOOKUP_OBJECT (autonumber_text, button_close, "button_close");
+ GLADE_HOOKUP_OBJECT (autonumber_text, button_ok, "button_ok");
+
+ return autonumber_text;
+}
+
+/*! \brief Create or restore the autonumber text dialog
+ *
+ * If the function is called the first time the dialog is created.
+ * If the dialog is only in background it is moved to the foreground.
+ *
+ * @param w_current Pointer to the top level struct
+ */
+void autonumber_text_dialog(TOPLEVEL *w_current)
+{
+ static AUTONUMBER_TEXT *autotext = NULL;
+
+ GtkWidget *button_ok = NULL;
+ GtkWidget *button_close = NULL;
+ GtkWidget *opt_removenum = NULL;
+ GtkWidget *sort_order = NULL;
+
+ if(autotext == NULL) {
+ /* first call of this function, init dialog structure */
+ autotext=autonumber_init_state();
+ }
+
+ /* set the toplevel always. Can it be changed between the calls??? */
+ autotext->toplevel = w_current;
+
+ if(autotext->dialog == NULL) {
+ /* Dialog is not currently displayed - create it */
+
+ autotext->dialog = autonumber_create_dialog(w_current);
+
+ button_ok = lookup_widget(autotext->dialog, "button_ok");
+ button_close = lookup_widget(autotext->dialog, "button_close");
+ opt_removenum = lookup_widget(autotext->dialog, "opt_removenum");
+ sort_order = lookup_widget(autotext->dialog, "sort_order");
+
+ autonumber_sortorder_create(w_current, sort_order);
+
+ gtk_signal_connect(GTK_OBJECT(autotext->dialog),
+ "destroy",
+ GTK_SIGNAL_FUNC(autonumber_text_destroy),
+ autotext);
+
+ gtk_signal_connect(GTK_OBJECT(button_ok),
+ "clicked",
+ GTK_SIGNAL_FUNC(autonumber_text_ok),
+ autotext);
+
+ gtk_signal_connect(GTK_OBJECT(button_close),
+ "clicked",
+ GTK_SIGNAL_FUNC(autonumber_text_close),
+ autotext);
+
+ gtk_signal_connect(GTK_OBJECT(opt_removenum),
+ "clicked",
+ GTK_SIGNAL_FUNC(autonumber_removenum_toggled),
+ autotext);
+
+ gtk_signal_connect(GTK_OBJECT(autotext->dialog),
+ "key_press_event",
+ GTK_SIGNAL_FUNC(autonumber_text_keypress),
+ autotext);
+
+ autonumber_set_state(autotext);
+
+ gtk_widget_show_all(autotext->dialog);
+ }
+
+ /* if the dialog is in the background or minimized: show it */
+ gtk_window_present(GTK_WINDOW(autotext->dialog));
+}
_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs