Changed tarball name to be all lower case to make package maintainers happier
[geda-gaf/cesar.git] / gattrib / src / x_window.c
blob5e4cc4ff984bbbcaab7efb3c30b3bc9fdd35b81a
1 /* gEDA - GPL Electronic Design Automation
2 * gattrib -- gEDA component and net attribute manipulation using spreadsheet.
3 * Copyright (C) 2003-2008 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 /*! \file
22 * \brief Functions for the toplevel window
24 * This file holds functions used to handle the toplevel window and
25 * various widgets held by that window. Widges used to handle
26 * (GtkSheet *sheet) itself are held in a different file.
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
34 /*------------------------------------------------------------------
35 * Includes required to run graphical widgets.
36 *------------------------------------------------------------------*/
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <gtk/gtk.h>
41 #ifdef HAVE_STRING_H
42 #include <string.h>
43 #endif
45 #include "gtksheet_2_2.h"
46 #include "gtkitementry_2_2.h"
48 /*------------------------------------------------------------------
49 * Gattrib specific includes
50 *------------------------------------------------------------------*/
51 #include <libgeda/libgeda.h> /* geda library fcns */
52 #include "../include/struct.h" /* typdef and struct declarations */
53 #include "../include/prototype.h" /* function prototypes */
54 #include "../include/globals.h"
56 #ifdef HAVE_LIBDMALLOC
57 #include <dmalloc.h>
58 #endif
60 /*------------------------------------------------------------------
61 * Gattrib specific defines
62 *------------------------------------------------------------------*/
63 #define GATTRIB_THEME_ICON_NAME "geda-gattrib"
65 static void
66 x_window_create_menu(GtkWindow *window, GtkWidget **menubar);
68 static void
69 x_window_set_default_icon( void );
71 /*! \brief Initialises the toplevel gtksheet
73 * This function initializes the toplevel gtksheet stuff.
75 * It basically just initializes the following widgets:
76 * GTK_WINDOW *window
77 * GTK_CONTAINER *main_vbox
78 * GTK_MENU
80 * Note that it doesn't display the spreadsheet itself. This is done
81 * in x_sheet_build_sheet. I suppose I could postpone all initialization
82 * until x_sheet_build_sheet, but I figured that I could at least do
83 * some initialization here. In particular, the stuff to put up the
84 * menus is long & it is worthwhile to separate it from other code.
85 * Maybe I'll refactor this later.
87 void
88 x_window_init()
90 GtkWidget *menu_bar;
91 GtkWidget *main_vbox;
93 /* Set default icon */
94 x_window_set_default_icon();
96 /* window is a global declared in globals.h. */
97 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
99 gtk_window_set_title( GTK_WINDOW(window), "gattrib -- gEDA attribute editor");
100 gtk_window_set_default_size(GTK_WINDOW(window), 750, 600);
102 gtk_signal_connect (GTK_OBJECT (window), "delete_event",
103 GTK_SIGNAL_FUNC (gattrib_really_quit), 0);
105 /* ----- Now create main_vbox. This is a container which organizes child ----- */
106 /* ----- widgets into a vertical column. ----- */
107 main_vbox = gtk_vbox_new(FALSE,1);
108 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 1);
109 gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(main_vbox) );
111 /* ----- Now create menu bar ----- */
112 x_window_create_menu(GTK_WINDOW(window), &menu_bar);
113 gtk_box_pack_start(GTK_BOX (main_vbox), menu_bar, FALSE, TRUE, 0);
115 /* ----- Now init notebook widget ----- */
116 notebook = gtk_notebook_new();
117 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM);
118 gtk_box_pack_start(GTK_BOX(main_vbox), notebook, TRUE, TRUE, 0);
120 /* ----- Now malloc -- but don't fill out -- space for sheets ----- */
121 /* This basically sets up the overhead for the sheets, as I understand
122 * it. The memory for the actual sheet cells is allocated later,
123 * when gtk_sheet_new is invoked, I think. */
124 sheets = g_malloc0(NUM_SHEETS * sizeof(GtkWidget *));
128 /*------------------------------------------------------------------
129 * \brief File Open menu
131 * File open menu. Currently unimplemented.
132 * \todo this should really be done in two stages:
133 * -# close the current project and reinitialize structures
134 * -# load the new project
136 #ifdef UNIMPLEMENTED_FEATURES
137 static void
138 menu_file_open()
140 x_dialog_unimplemented_feature();
141 #if 0
142 GSList *file_list;
144 file_list = x_fileselect_open();
146 /* Load the files, don't check if it went OK */
147 x_fileselect_load_files(file_list);
149 g_slist_foreach(file_list, (GFunc)g_free, NULL);
150 g_slist_free(file_list);
151 #endif
153 #endif
156 * \brief File->Save menu item
158 * Implement the File->Save menu
160 static void
161 menu_file_save()
163 s_toplevel_gtksheet_to_toplevel(); /* Dumps sheet data into TOPLEVEL */
164 s_page_save_all(pr_current); /* saves all pages in design */
166 sheet_head->CHANGED = FALSE;
170 * \brief File->Export CSV menu item
172 * Implement the File->Export CSV menu item
174 static void
175 menu_file_export_csv()
177 gint cur_page;
179 /* first verify that we are on the correct page (components) */
180 cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
182 /* Check that we are on components page. */
183 if (cur_page == 0) {
184 x_dialog_export_file();
185 } else {
186 x_dialog_unimplemented_feature(); /* We only support export
187 of components now */
192 * \brief Edit->New attrib menu item
194 * Implement the New attrib menu item
196 static void
197 menu_edit_newattrib()
199 gint cur_page;
201 /* first verify that we are on the correct page (components) */
202 cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
204 /* Check that we are on components page. */
205 if (cur_page == 0) {
206 x_dialog_newattrib(); /* This creates dialog box */
211 * \brief Edit->Delete Attribute menu item
213 * Implements the Delete Attribute menu item
215 static void
216 menu_edit_delattrib()
218 x_dialog_delattrib();
222 * The Gtk action table
224 static const GtkActionEntry actions[] = {
225 /* name, stock-id, label, accelerator, tooltip, callback function */
226 /* File menu */
227 { "file", NULL, "_File"},
228 /* { "file-open", GTK_STOCK_OPEN, "Open", "<Control>O", "", menu_file_open}, */
229 { "file-save", GTK_STOCK_SAVE, "Save", "<Control>S", "", menu_file_save},
230 { "file-export-csv", NULL, "Export CSV", "", "", menu_file_export_csv},
231 /* { "file-print", GTK_STOCK_PRINT, "Print", "<Control>P", "", x_dialog_unimplemented_feature}, */
232 { "file-quit", GTK_STOCK_QUIT, "Quit", "<Control>Q", "", G_CALLBACK(gattrib_really_quit)},
234 /* Edit menu */
235 { "edit", NULL, "_Edit"},
236 { "edit-add-attrib", NULL, "Add new attrib column", "", "", menu_edit_newattrib},
237 { "edit-delete-attrib", NULL, "Delete attrib column", "", "", menu_edit_delattrib},
238 /* { "edit-find-attrib", GTK_STOCK_FIND, "Find attrib value", "<Control>F", "", x_dialog_unimplemented_feature}, */
239 /* { "edit-search-replace-attrib-value", NULL, "Search and replace attrib value", "", "", x_dialog_unimplemented_feature}, */
240 /* { "edit-search-for-refdes", NULL, "Search for refdes", "", "", x_dialog_unimplemented_feature}, */
242 /* Visibility menu */
243 { "visibility", NULL, "_Visibility"},
244 { "visibility-invisible", NULL, "Set selected invisible", "", "", s_visibility_set_invisible},
245 { "visibility-name-only", NULL, "Set selected name visible only", "", "", s_visibility_set_name_only},
246 { "visibility-value-only", NULL, "Set selected value visible only", "", "", s_visibility_set_value_only},
247 { "visibility-name-value", NULL, "Set selected name and value visible", "", "", s_visibility_set_name_and_value},
249 /* Help menu */
250 { "help", NULL, "_Help"},
251 { "help-about", GTK_STOCK_ABOUT, "About", "", "", x_dialog_about_dialog},
255 /*! \brief Create and attach the menu bar
257 * Create the menu bar and attach it to the main window.
259 * First, the GtkActionGroup object is created and filled with
260 * entries of type GtkActionEntry (each entry specifies a single
261 * action, such as opening a file). Then the GtkUIManager object
262 * is created and used to load menus.xml file with the menu
263 * description. Finally, the GtkAccelGroup is added to the
264 * main window to enable keyboard accelerators and a pointer
265 * to the menu bar is retrieved from the GtkUIManager object.
266 * \param window Window to add the menubar to
267 * \param [out] menubar Created menubar
269 static void
270 x_window_create_menu(GtkWindow *window, GtkWidget **menubar)
272 gchar *menu_file;
273 GtkUIManager *ui;
274 GtkActionGroup *action_group;
275 GError *error = NULL;
277 /* Create and fill the action group object */
278 action_group = gtk_action_group_new("");
279 gtk_action_group_add_actions(action_group, actions, G_N_ELEMENTS(actions), NULL);
281 /* Create the UI manager object */
282 ui = gtk_ui_manager_new();
284 gtk_ui_manager_insert_action_group(ui, action_group, 0);
286 menu_file = g_build_filename(s_path_sys_data (), "gattrib-menus.xml", NULL);
288 gtk_ui_manager_add_ui_from_file(ui, menu_file, &error);
289 if(error != NULL) {
290 /* An error occured, terminate */
291 fprintf(stderr, "Error loading %s:\n%s\n", menu_file, error->message);
292 exit(1);
295 g_free(menu_file);
297 gtk_window_add_accel_group (window, gtk_ui_manager_get_accel_group(ui));
299 *menubar = gtk_ui_manager_get_widget(ui, "/ui/menubar/");
303 /*! \brief Add all items to the top level window
305 * This function updates the top level window
306 * after a new page is read in.
308 * It does the following:
310 * -# Create a new gtksheet having the current dimensions.
311 * -# Call x_gktsheet_add_row_labels(comp_count, master_*_list_head)
312 * -# Call x_gktsheet_add_col_labels(comp_attrib_count, master_*_attrib_list_head)
313 * -# Call x_gktsheet_add_row_labels(net_count, master_*_list_head)
314 * -# Call x_gktsheet_add_col_labels(net_attrib_count, master_*_attrib_list_head)
315 * -# loop on i, j -- call x_gtksheet_add_entry(i, j, attrib_value)
316 * -# Call gtk_widget_show(window) to show new window.
318 void
319 x_window_add_items()
321 gint i, j;
322 gint num_rows, num_cols;
323 gchar *text, *error_string;
324 gint visibility, show_name_value;
326 /* Do these sanity check to prevent later segfaults */
327 if (sheet_head->comp_count == 0) {
328 error_string = "No components found in entire design!\n"
329 "Do you have refdeses on your components?";
330 x_dialog_fatal_error(error_string, 1);
333 if (sheet_head->comp_attrib_count == 0) {
334 error_string = "No configurable component attributes found in entire design!\n"
335 "Please attach at least some attributes before running gattrib.";
336 x_dialog_fatal_error(error_string, 2);
339 if (sheet_head->pin_count == 0) {
340 error_string = "No pins found on any components!\n"
341 "Please check your design.";
342 x_dialog_fatal_error(error_string, 3);
346 /* initialize the gtksheet. */
347 x_gtksheet_init(); /* this creates a new gtksheet having dimensions specified
348 * in sheet_head->comp_count, etc. . . */
350 if (sheet_head->comp_count > 0 ) {
351 x_gtksheet_add_row_labels(GTK_SHEET(sheets[0]),
352 sheet_head->comp_count, sheet_head->master_comp_list_head);
353 x_gtksheet_add_col_labels(GTK_SHEET(sheets[0]),
354 sheet_head->comp_attrib_count, sheet_head->master_comp_attrib_list_head);
357 #ifdef UNIMPLEMENTED_FEATURES
358 /* This is not ready. I need to implement net attributes */
359 if (sheet_head->net_count > 0 ) {
360 x_gtksheet_add_row_labels(GTK_SHEET(sheets[1]),
361 sheet_head->net_count, sheet_head->master_net_list_head);
362 x_gtksheet_add_col_labels(GTK_SHEET(sheets[1]),
363 sheet_head->net_attrib_count, sheet_head->master_net_attrib_list_head);
364 } else {
365 x_gtksheet_add_row_labels(GTK_SHEET(sheets[1]), 1, NULL);
366 x_gtksheet_add_col_labels(GTK_SHEET(sheets[1]), 1, NULL);
368 #endif
370 #ifdef UNIMPLEMENTED_FEATURES
371 if (sheet_head->pin_count > 0 ) {
372 x_gtksheet_add_row_labels(GTK_SHEET(sheets[2]),
373 sheet_head->pin_count, sheet_head->master_pin_list_head);
374 x_gtksheet_add_col_labels(GTK_SHEET(sheets[2]),
375 sheet_head->pin_attrib_count, sheet_head->master_pin_attrib_list_head);
377 #endif
379 /* ------ Comp sheet: put values in the individual cells ------- */
380 num_rows = sheet_head->comp_count;
381 num_cols = sheet_head->comp_attrib_count;
382 for (i = 0; i < num_rows; i++) {
383 for (j = 0; j < num_cols; j++) {
384 if ( (sheet_head->component_table)[i][j].attrib_value ) { /* NULL = no entry */
385 text = (gchar *) g_strdup( (sheet_head->component_table)[i][j].attrib_value );
386 visibility = (sheet_head->component_table)[i][j].visibility;
387 show_name_value = (sheet_head->component_table)[i][j].show_name_value;
388 x_gtksheet_add_cell_item( GTK_SHEET(sheets[0]), i, j, (gchar *) text,
389 visibility, show_name_value );
390 g_free(text);
395 #ifdef UNIMPLEMENTED_FEATURES
396 /* ------ Net sheet: put values in the individual cells ------- */
397 num_rows = sheet_head->net_count;
398 num_cols = sheet_head->net_attrib_count;
399 for (i = 0; i < num_rows; i++) {
400 for (j = 0; j < num_cols; j++) {
401 if ( (sheet_head->net_table)[i][j].attrib_value ) { /* NULL = no entry */
402 text = (gchar *) g_strdup( (sheet_head->net_table)[i][j].attrib_value );
403 visibility = (sheet_head->net_table)[i][j].visibility;
404 show_name_value = (sheet_head->component_table)[i][j].show_name_value;
405 x_gtksheet_add_cell_item( GTK_SHEET(sheets[1]), i, j, (gchar *) text,
406 visibility, show_name_value );
407 g_free(text);
411 #endif
413 #ifdef UNIMPLEMENTED_FEATURES
414 /* ------ Pin sheet: put pin attribs in the individual cells ------- */
415 num_rows = sheet_head->pin_count;
416 num_cols = sheet_head->pin_attrib_count;
417 for (i = 0; i < num_rows; i++) {
418 for (j = 0; j < num_cols; j++) {
419 if ( (sheet_head->pin_table)[i][j].attrib_value ) { /* NULL = no entry */
420 text = (gchar *) g_strdup( (sheet_head->pin_table)[i][j].attrib_value );
421 /* pins have no visibility attributes, must therefore provide default. */
422 x_gtksheet_add_cell_item( GTK_SHEET(sheets[2]), i, j, (gchar *) text,
423 VISIBLE, SHOW_VALUE );
424 g_free(text);
428 #endif
430 gtk_widget_show_all( GTK_WIDGET(window) );
434 /*! \brief Set application icon
436 * Setup default icon for GTK windows
438 * Sets the default window icon by name, to be found in the current icon
439 * theme. The name used is #defined above as GATTRIB_THEME_ICON_NAME.
441 static void
442 x_window_set_default_icon( void )
444 gtk_window_set_default_icon_name( GATTRIB_THEME_ICON_NAME );