1 /* gEDA - GPL Electronic Design Automation
2 * gattrib -- gEDA component and net attribute manipulation using spreadsheet.
3 * Copyright (C) 2003-2007 Stuart D. Brorson.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 /*------------------------------------------------------------------
21 * This file holds fcns used to handle the toplevel window and
22 * various widgets held by that window. Widges used to handle
23 * (GtkSheet *sheet) itself are held in a different file.
24 *------------------------------------------------------------------*/
31 /*------------------------------------------------------------------
32 * Includes required to run graphical widgets.
33 *------------------------------------------------------------------*/
38 #include <gdk/gdkkeysyms.h>
41 #include <glib-object.h>
48 #include "gtksheet_2_2.h"
49 #include "gtkitementry_2_2.h"
51 /*------------------------------------------------------------------
52 * Gattrib specific includes
53 *------------------------------------------------------------------*/
54 #include <libgeda/libgeda.h> /* geda library fcns */
55 #include "../include/struct.h" /* typdef and struct declarations */
56 #include "../include/prototype.h" /* function prototypes */
57 #include "../include/globals.h"
58 #include "../include/x_menu.h"
60 #ifdef HAVE_LIBDMALLOC
65 /* ====================== Public functions ======================== */
67 /*------------------------------------------------------------------
68 * x_window_init -- this fcn initialies the toplevel gtksheet stuff. It
69 * basically just initializes the following widgets:
71 * GTK_CONTAINER *main_vbox
73 * Note that it doesn't display the spreadsheet itself. This is done
74 * in x_sheet_build_sheet.
75 * I suppose I ctould postpone all initialization until x_sheet_build_sheet, but I
76 * figured that I could at least do some initialization here.
77 * In particular, the stuff to put up the menus is long & it is worthwhile
78 * to separate it from other code. Maybe I'll refactor this later.
79 *------------------------------------------------------------------*/
83 /* note that the graphical widgets themselves (window, main_vbox, menu_bar)
84 * are globals defined in ../include/globals.h On pr_current I
85 * attach pointers to some of them here for future reference. */
88 /* ----- First initialize stuff in the top-level window ----- */
91 printf("In x_window_init, about to call gtk_window_new.\n");
93 /* window is a global declared in globals.h. */
94 window
= (GtkWidget
*) gtk_window_new(GTK_WINDOW_TOPLEVEL
);
96 /* I attach a pointer to window to the TOPLEVEL structure */
97 pr_current
->main_window
= window
;
100 printf("In x_window_init, about to call gtk_window_set_title.\n");
102 gtk_window_set_title( GTK_WINDOW(window
), "gattrib -- gEDA attribute editor");
103 /* gtk_widget_set_usize(GTK_WIDGET(window), 900, 600); */
104 gtk_window_set_default_size(GTK_WINDOW(window
), 750, 600);
108 printf("In x_window_init, about to connect delete and destroy signals to window.\n");
110 gtk_signal_connect (GTK_OBJECT (window
), "delete_event",
111 GTK_SIGNAL_FUNC (gattrib_really_quit
), 0);
112 gtk_signal_connect (GTK_OBJECT (window
), "destroy",
113 GTK_SIGNAL_FUNC (gattrib_really_quit
), 0);
116 /* ----- Now create main_vbox. This is a container which organizes child ----- */
117 /* ----- widgets into a vertical column. ----- */
118 /* main_vbox is a global defined in globals.h */
120 printf("In x_window_init, about to set up vobx.\n");
122 main_vbox
= gtk_vbox_new(FALSE
,1);
123 gtk_container_set_border_width(GTK_CONTAINER(main_vbox
), 1);
124 gtk_container_add(GTK_CONTAINER(window
), GTK_WIDGET(main_vbox
) );
125 gtk_widget_show(GTK_WIDGET(main_vbox
) );
128 /* ----- Now create menu bar ----- */
129 /* menu_bar is a global defined in globals.h */
131 printf("In x_window_init, about to create menu bar.\n");
133 x_window_create_menu(&menu_bar
);
134 pr_current
->menubar
= menu_bar
; /* attach pointer to menu_bar to (TOPLEVEL pr_current) */
135 gtk_box_pack_start (GTK_BOX (main_vbox
), menu_bar
, FALSE
, TRUE
, 0);
136 gtk_widget_show( GTK_WIDGET(menu_bar
) );
138 /* ----- Now init notebook widget ----- */
140 printf("In x_window_init, about to create notbook.\n");
142 notebook
=gtk_notebook_new();
143 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook
), GTK_POS_BOTTOM
);
144 gtk_box_pack_start(GTK_BOX(main_vbox
), notebook
, TRUE
, TRUE
, 0);
145 gtk_widget_show( notebook
);
148 /* ----- Now malloc -- but don't fill out -- space for sheets ----- */
149 /* This basically sets up the overhead for the sheets, as I understand
150 * it. The memory for the actual sheet cells is allocated later,
151 * when gtk_sheet_new is invoked, I think. */
153 printf("In x_window_init, about to malloc space for sheets.\n");
155 for(i
=0; i
<NUM_SHEETS
; i
++){
156 sheets
=(GtkSheet
**) g_realloc(sheets
, (i
+1)*sizeof(GtkWidget
*));
159 /* ----- Finally show top level window to make everything appear ----- */
161 /* printf("In x_window_init, about to show window widget.\n"); */
165 * gtk_widget_show( GTK_WIDGET(window) );
171 /*------------------------------------------------------------------
172 * x_window_create_menu: This creates the menu widget. This fcn
173 * cloned from GTK+ tutorial.
174 *------------------------------------------------------------------*/
176 x_window_create_menu(GtkWidget
**menubar
)
178 GtkItemFactory
*item_factory
;
179 GtkAccelGroup
*accel_group
;
180 gint nmenu_items
= sizeof (menu_items
) / sizeof (menu_items
[0]);
182 accel_group
= gtk_accel_group_new ();
184 /* This function initializes the item factory.
185 Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU,
186 or GTK_TYPE_OPTION_MENU.
187 Param 2: The path of the menu.
188 Param 3: A pointer to a gtk_accel_group. The item factory sets up
189 the accelerator table while generating menus.
193 printf("In x_window_create_menu, about to create new item factory\n");
195 item_factory
= gtk_item_factory_new (GTK_TYPE_MENU_BAR
, "<main>",
198 /* This function generates the menu items. Pass the item factory,
199 the number of items in the array, the array itself, and any
200 callback data for the the menu items. */
201 /* SDB notes: callback data is pr_current, which should hopefully have pointers
202 * to any data required in the callback. */
203 gtk_item_factory_create_items (item_factory
, nmenu_items
, menu_items
, pr_current
);
206 /* Attach the new accelerator group to the window. */
207 /* SDB says: Here's where it comes in handy to have attached a pointer to
208 * the main window to the TOPLEVEL structure. */
209 gtk_window_add_accel_group (GTK_WINDOW(pr_current
->main_window
), accel_group
);
212 /* Finally, return the actual menu bar created by the item factory. */
213 *menubar
= gtk_item_factory_get_widget (item_factory
, "<main>");
219 /*------------------------------------------------------------------
220 * x_window_add_items -- this fcn updates the top level window
221 * after a new page is read in. It does the following:
223 * 2. Create a new gtksheet having the current dimensions.
224 * 3. Call x_gktsheet_add_row_labels(comp_count, master_*_list_head)
225 * 4. Call x_gktsheet_add_col_labels(comp_attrib_count, master_*_attrib_list_head)
226 * 5. Call x_gktsheet_add_row_labels(net_count, master_*_list_head)
227 * 6. Call x_gktsheet_add_col_labels(net_attrib_count, master_*_attrib_list_head)
228 * 7. loop on i, j -- call x_gtksheet_add_entry(i, j, attrib_value)
229 * 8. Call gtk_widget_show(window) to show new window.
230 *------------------------------------------------------------------*/
235 gint num_rows
, num_cols
;
236 gchar
*text
, *error_string
;
237 gint visibility
, show_name_value
;
242 printf("Entered x_window_add_items . . . . . ..\n");
245 /* Do these sanity check to prevent later segfaults */
246 if (sheet_head
->comp_count
== 0) {
247 error_string
= g_strdup("\n\nNo components found in entire design! ");
248 error_string
= g_strconcat(error_string
,
249 "Do you have refdeses on your components? \n", NULL
);
250 error_string
= g_strconcat(error_string
,
251 "Exiting. . . .\n", NULL
);
252 fprintf(stderr
, "%s", error_string
);
253 x_dialog_exit_announcement(error_string
, -1);
254 g_free(error_string
);
258 if (sheet_head
->comp_attrib_count
== 0) {
259 error_string
= g_strdup("\n\nNo configurable component attributes found in entire design! ");
260 error_string
= g_strconcat(error_string
,
261 "Please attach at least some attributes before running gattrib.\n", NULL
);
262 error_string
= g_strconcat(error_string
, "Exiting. . . .\n", NULL
);
263 fprintf(stderr
, "%s", error_string
);
264 x_dialog_exit_announcement(error_string
, -2);
265 g_free(error_string
);
270 if (sheet_head
->pin_count
== 0) {
271 error_string
= g_strdup("\n\nNo pins found on any components! ");
272 error_string
= g_strconcat(error_string
, "Please check your design.\n", NULL
);
273 error_string
= g_strconcat(error_string
, "Exiting. . . .\n", NULL
);
274 fprintf(stderr
, "%s", error_string
);
275 x_dialog_exit_announcement(error_string
, -3);
276 g_free(error_string
);
281 /* initialize the gtksheet. */
283 printf("In x_window_add_items, about to call x_gtksheet_init.\n");
285 x_gtksheet_init(); /* this creates a new gtksheet having dimensions specified
286 * in sheet_head->comp_count, etc. . . */
290 printf("In x_window_add_items, now load up the row and column labels.\n");
292 if (sheet_head
->comp_count
> 0 ) {
293 x_gtksheet_add_row_labels(GTK_SHEET(sheets
[0]),
294 sheet_head
->comp_count
, sheet_head
->master_comp_list_head
);
295 x_gtksheet_add_col_labels(GTK_SHEET(sheets
[0]),
296 sheet_head
->comp_attrib_count
, sheet_head
->master_comp_attrib_list_head
);
300 /* This is not ready. I need to implement net attributes */
301 if (sheet_head
->net_count
> 0 ) {
302 x_gtksheet_add_row_labels(GTK_SHEET(sheets
[1]),
303 sheet_head
->net_count
, sheet_head
->master_net_list_head
);
304 x_gtksheet_add_col_labels(GTK_SHEET(sheets
[1]),
305 sheet_head
->net_attrib_count
, sheet_head
->master_net_attrib_list_head
);
307 x_gtksheet_add_row_labels(GTK_SHEET(sheets
[1]), 1, NULL
);
308 x_gtksheet_add_col_labels(GTK_SHEET(sheets
[1]), 1, NULL
);
312 if (sheet_head
->pin_count
> 0 ) {
313 x_gtksheet_add_row_labels(GTK_SHEET(sheets
[2]),
314 sheet_head
->pin_count
, sheet_head
->master_pin_list_head
);
315 x_gtksheet_add_col_labels(GTK_SHEET(sheets
[2]),
316 sheet_head
->pin_attrib_count
, sheet_head
->master_pin_attrib_list_head
);
321 printf("In x_window_add_items, now put comp attrib values in the comp sheet.\n");
323 /* ------ Comp sheet: put values in the individual cells ------- */
324 num_rows
= sheet_head
->comp_count
;
325 num_cols
= sheet_head
->comp_attrib_count
;
326 for (i
= 0; i
< num_rows
; i
++) {
327 for (j
= 0; j
< num_cols
; j
++) {
328 if ( (sheet_head
->component_table
)[i
][j
].attrib_value
) { /* NULL = no entry */
329 text
= (gchar
*) g_strdup( (sheet_head
->component_table
)[i
][j
].attrib_value
);
330 visibility
= (sheet_head
->component_table
)[i
][j
].visibility
;
331 show_name_value
= (sheet_head
->component_table
)[i
][j
].show_name_value
;
332 x_gtksheet_add_cell_item( GTK_SHEET(sheets
[0]), i
, j
, (gchar
*) text
,
333 visibility
, show_name_value
);
338 /* Do I really need these shows here? */
339 gtk_widget_show( GTK_WIDGET(sheets
[0]) );
340 gtk_widget_show( GTK_WIDGET(scrolled_windows
[0]) );
344 printf("In x_window_add_items, now put net attrib values in the net sheet.\n");
346 /* ------ Net sheet: put values in the individual cells ------- */
347 num_rows
= sheet_head
->net_count
;
348 num_cols
= sheet_head
->net_attrib_count
;
349 for (i
= 0; i
< num_rows
; i
++) {
350 for (j
= 0; j
< num_cols
; j
++) {
351 if ( (sheet_head
->net_table
)[i
][j
].attrib_value
) { /* NULL = no entry */
352 text
= (gchar
*) g_strdup( (sheet_head
->net_table
)[i
][j
].attrib_value
);
353 visibility
= (sheet_head
->net_table
)[i
][j
].visibility
;
354 show_name_value
= (sheet_head
->component_table
)[i
][j
].show_name_value
;
355 x_gtksheet_add_cell_item( GTK_SHEET(sheets
[1]), i
, j
, (gchar
*) text
,
356 visibility
, show_name_value
);
361 /* Do I really need these shows here? */
362 if (sheet_head
->net_count
> 0) {
363 gtk_widget_show( GTK_WIDGET(sheets
[1]) );
364 gtk_widget_show( GTK_WIDGET(scrolled_windows
[1]) );
369 printf("In x_window_add_items, now put pin attrib values in the pin sheet.\n");
371 /* ------ Pin sheet: put pin attribs in the individual cells ------- */
372 num_rows
= sheet_head
->pin_count
;
373 num_cols
= sheet_head
->pin_attrib_count
;
374 for (i
= 0; i
< num_rows
; i
++) {
375 for (j
= 0; j
< num_cols
; j
++) {
376 if ( (sheet_head
->pin_table
)[i
][j
].attrib_value
) { /* NULL = no entry */
377 text
= (gchar
*) g_strdup( (sheet_head
->pin_table
)[i
][j
].attrib_value
);
378 /* pins have no visibility attributes, must therefore provide default. */
379 x_gtksheet_add_cell_item( GTK_SHEET(sheets
[2]), i
, j
, (gchar
*) text
,
380 VISIBLE
, SHOW_VALUE
);
385 /* Do I really need these shows here? */
386 if (sheet_head
->pin_count
> 0) {
387 gtk_widget_show( GTK_WIDGET(sheets
[2]) );
388 gtk_widget_show( GTK_WIDGET(scrolled_windows
[2]) );
391 gtk_widget_show( GTK_WIDGET(notebook
) );
392 /* gtk_widget_show( GTK_WIDGET(main_vbox) ); */
393 gtk_widget_show( GTK_WIDGET(window
) );
398 /* ====================== Private functions ======================== */