Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gattrib / src / x_window.c
blob521a96acc1bc372315d2825f8f93b7d0ef57207b
1 /* gEDA - GPL Electronic Design Automation
2 * gattrib -- gEDA component and net attribute manipulation using spreadsheet.
3 * Copyright (C) 2003-2010 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 /*------------------------------------------------------------------
46 * Gattrib specific includes
47 *------------------------------------------------------------------*/
48 #include <libgeda/libgeda.h> /* geda library fcns */
49 #include "../include/struct.h" /* typdef and struct declarations */
50 #include "../include/prototype.h" /* function prototypes */
51 #include "../include/globals.h"
53 #ifdef HAVE_LIBDMALLOC
54 #include <dmalloc.h>
55 #endif
57 /*------------------------------------------------------------------
58 * Gattrib specific defines
59 *------------------------------------------------------------------*/
60 #define GATTRIB_THEME_ICON_NAME "geda-gattrib"
62 static void
63 x_window_create_menu(GtkWindow *window, GtkWidget **menubar);
65 static void
66 x_window_set_default_icon( void );
68 /*! \brief Initialises the toplevel gtksheet
70 * This function initializes the toplevel gtksheet stuff.
72 * It basically just initializes the following widgets:
73 * GTK_WINDOW *window
74 * GTK_CONTAINER *main_vbox
75 * GTK_MENU
77 * Note that it doesn't display the spreadsheet itself. This is done
78 * in x_sheet_build_sheet. I suppose I could postpone all initialization
79 * until x_sheet_build_sheet, but I figured that I could at least do
80 * some initialization here. In particular, the stuff to put up the
81 * menus is long & it is worthwhile to separate it from other code.
82 * Maybe I'll refactor this later.
84 void
85 x_window_init()
87 GtkWidget *menu_bar;
88 GtkWidget *main_vbox;
90 /* Set default icon */
91 x_window_set_default_icon();
93 /* window is a global declared in globals.h. */
94 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
96 gtk_window_set_title( GTK_WINDOW(window), "gattrib -- gEDA attribute editor");
97 gtk_window_set_default_size(GTK_WINDOW(window), 750, 600);
99 gtk_signal_connect (GTK_OBJECT (window), "delete_event",
100 GTK_SIGNAL_FUNC (gattrib_really_quit), 0);
102 /* ----- Now create main_vbox. This is a container which organizes child ----- */
103 /* ----- widgets into a vertical column. ----- */
104 main_vbox = gtk_vbox_new(FALSE,1);
105 gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 1);
106 gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(main_vbox) );
108 /* ----- Now create menu bar ----- */
109 x_window_create_menu(GTK_WINDOW(window), &menu_bar);
110 gtk_box_pack_start(GTK_BOX (main_vbox), menu_bar, FALSE, TRUE, 0);
112 /* ----- Now init notebook widget ----- */
113 notebook = gtk_notebook_new();
114 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM);
115 gtk_box_pack_start(GTK_BOX(main_vbox), notebook, TRUE, TRUE, 0);
117 /* ----- Now malloc -- but don't fill out -- space for sheets ----- */
118 /* This basically sets up the overhead for the sheets, as I understand
119 * it. The memory for the actual sheet cells is allocated later,
120 * when gtk_sheet_new is invoked, I think. */
121 sheets = g_malloc0(NUM_SHEETS * sizeof(GtkWidget *));
125 /*------------------------------------------------------------------
126 * \brief File Open menu
128 * File open menu. Currently unimplemented.
129 * \todo this should really be done in two stages:
130 * -# close the current project and reinitialize structures
131 * -# load the new project
133 #ifdef UNIMPLEMENTED_FEATURES
134 static void
135 menu_file_open()
137 x_dialog_unimplemented_feature();
138 #if 0
139 GSList *file_list;
141 file_list = x_fileselect_open();
143 /* Load the files, don't check if it went OK */
144 x_fileselect_load_files(file_list);
146 g_slist_foreach(file_list, (GFunc)g_free, NULL);
147 g_slist_free(file_list);
148 #endif
150 #endif
153 * \brief File->Save menu item
155 * Implement the File->Save menu
157 static void
158 menu_file_save()
160 s_toplevel_gtksheet_to_toplevel(); /* Dumps sheet data into TOPLEVEL */
161 s_page_save_all(pr_current); /* saves all pages in design */
163 sheet_head->CHANGED = FALSE;
167 * \brief File->Export CSV menu item
169 * Implement the File->Export CSV menu item
171 static void
172 menu_file_export_csv()
174 gint cur_page;
176 /* first verify that we are on the correct page (components) */
177 cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
179 /* Check that we are on components page. */
180 if (cur_page == 0) {
181 x_dialog_export_file();
182 } else {
183 x_dialog_unimplemented_feature(); /* We only support export
184 of components now */
189 * \brief Edit->New attrib menu item
191 * Implement the New attrib menu item
193 static void
194 menu_edit_newattrib()
196 gint cur_page;
198 /* first verify that we are on the correct page (components) */
199 cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
201 /* Check that we are on components page. */
202 if (cur_page == 0) {
203 x_dialog_newattrib(); /* This creates dialog box */
208 * \brief Edit->Delete Attribute menu item
210 * Implements the Delete Attribute menu item
212 static void
213 menu_edit_delattrib()
215 x_dialog_delattrib();
219 * The Gtk action table
221 static const GtkActionEntry actions[] = {
222 /* name, stock-id, label, accelerator, tooltip, callback function */
223 /* File menu */
224 { "file", NULL, "_File"},
225 /* { "file-open", GTK_STOCK_OPEN, "Open", "<Control>O", "", menu_file_open}, */
226 { "file-save", GTK_STOCK_SAVE, "Save", "<Control>S", "", menu_file_save},
227 { "file-export-csv", NULL, "Export CSV", "", "", menu_file_export_csv},
228 /* { "file-print", GTK_STOCK_PRINT, "Print", "<Control>P", "", x_dialog_unimplemented_feature}, */
229 { "file-quit", GTK_STOCK_QUIT, "Quit", "<Control>Q", "", G_CALLBACK(gattrib_really_quit)},
231 /* Edit menu */
232 { "edit", NULL, "_Edit"},
233 { "edit-add-attrib", NULL, "Add new attrib column", "", "", menu_edit_newattrib},
234 { "edit-delete-attrib", NULL, "Delete attrib column", "", "", menu_edit_delattrib},
235 /* { "edit-find-attrib", GTK_STOCK_FIND, "Find attrib value", "<Control>F", "", x_dialog_unimplemented_feature}, */
236 /* { "edit-search-replace-attrib-value", NULL, "Search and replace attrib value", "", "", x_dialog_unimplemented_feature}, */
237 /* { "edit-search-for-refdes", NULL, "Search for refdes", "", "", x_dialog_unimplemented_feature}, */
239 /* Visibility menu */
240 { "visibility", NULL, "_Visibility"},
241 { "visibility-invisible", NULL, "Set selected invisible", "", "", s_visibility_set_invisible},
242 { "visibility-name-only", NULL, "Set selected name visible only", "", "", s_visibility_set_name_only},
243 { "visibility-value-only", NULL, "Set selected value visible only", "", "", s_visibility_set_value_only},
244 { "visibility-name-value", NULL, "Set selected name and value visible", "", "", s_visibility_set_name_and_value},
246 /* Help menu */
247 { "help", NULL, "_Help"},
248 { "help-about", GTK_STOCK_ABOUT, "About", "", "", x_dialog_about_dialog},
252 /*! \brief Create and attach the menu bar
254 * Create the menu bar and attach it to the main window.
256 * First, the GtkActionGroup object is created and filled with
257 * entries of type GtkActionEntry (each entry specifies a single
258 * action, such as opening a file). Then the GtkUIManager object
259 * is created and used to load menus.xml file with the menu
260 * description. Finally, the GtkAccelGroup is added to the
261 * main window to enable keyboard accelerators and a pointer
262 * to the menu bar is retrieved from the GtkUIManager object.
263 * \param window Window to add the menubar to
264 * \param [out] menubar Created menubar
266 static void
267 x_window_create_menu(GtkWindow *window, GtkWidget **menubar)
269 gchar *menu_file;
270 GtkUIManager *ui;
271 GtkActionGroup *action_group;
272 GError *error = NULL;
274 /* Create and fill the action group object */
275 action_group = gtk_action_group_new("");
276 gtk_action_group_add_actions(action_group, actions, G_N_ELEMENTS(actions), NULL);
278 /* Create the UI manager object */
279 ui = gtk_ui_manager_new();
281 gtk_ui_manager_insert_action_group(ui, action_group, 0);
283 menu_file = g_build_filename(s_path_sys_data (), "gattrib-menus.xml", NULL);
285 gtk_ui_manager_add_ui_from_file(ui, menu_file, &error);
286 if(error != NULL) {
287 /* An error occured, terminate */
288 fprintf(stderr, "Error loading %s:\n%s\n", menu_file, error->message);
289 exit(1);
292 g_free(menu_file);
294 gtk_window_add_accel_group (window, gtk_ui_manager_get_accel_group(ui));
296 *menubar = gtk_ui_manager_get_widget(ui, "/ui/menubar/");
300 /*! \brief Add all items to the top level window
302 * This function updates the top level window
303 * after a new page is read in.
305 * It does the following:
307 * -# Create a new gtksheet having the current dimensions.
308 * -# Call x_gktsheet_add_row_labels(comp_count, master_*_list_head)
309 * -# Call x_gktsheet_add_col_labels(comp_attrib_count, master_*_attrib_list_head)
310 * -# Call x_gktsheet_add_row_labels(net_count, master_*_list_head)
311 * -# Call x_gktsheet_add_col_labels(net_attrib_count, master_*_attrib_list_head)
312 * -# loop on i, j -- call x_gtksheet_add_entry(i, j, attrib_value)
313 * -# Call gtk_widget_show(window) to show new window.
315 void
316 x_window_add_items()
318 gint i, j;
319 gint num_rows, num_cols;
320 gchar *text, *error_string;
321 gint visibility, show_name_value;
323 /* Do these sanity check to prevent later segfaults */
324 if (sheet_head->comp_count == 0) {
325 error_string = "No components found in entire design!\n"
326 "Do you have refdeses on your components?";
327 x_dialog_fatal_error(error_string, 1);
330 if (sheet_head->comp_attrib_count == 0) {
331 error_string = "No configurable component attributes found in entire design!\n"
332 "Please attach at least some attributes before running gattrib.";
333 x_dialog_fatal_error(error_string, 2);
336 if (sheet_head->pin_count == 0) {
337 error_string = "No pins found on any components!\n"
338 "Please check your design.";
339 x_dialog_fatal_error(error_string, 3);
343 /* initialize the gtksheet. */
344 x_gtksheet_init(); /* this creates a new gtksheet having dimensions specified
345 * in sheet_head->comp_count, etc. . . */
347 if (sheet_head->comp_count > 0 ) {
348 x_gtksheet_add_row_labels(GTK_SHEET(sheets[0]),
349 sheet_head->comp_count, sheet_head->master_comp_list_head);
350 x_gtksheet_add_col_labels(GTK_SHEET(sheets[0]),
351 sheet_head->comp_attrib_count, sheet_head->master_comp_attrib_list_head);
354 #ifdef UNIMPLEMENTED_FEATURES
355 /* This is not ready. I need to implement net attributes */
356 if (sheet_head->net_count > 0 ) {
357 x_gtksheet_add_row_labels(GTK_SHEET(sheets[1]),
358 sheet_head->net_count, sheet_head->master_net_list_head);
359 x_gtksheet_add_col_labels(GTK_SHEET(sheets[1]),
360 sheet_head->net_attrib_count, sheet_head->master_net_attrib_list_head);
361 } else {
362 x_gtksheet_add_row_labels(GTK_SHEET(sheets[1]), 1, NULL);
363 x_gtksheet_add_col_labels(GTK_SHEET(sheets[1]), 1, NULL);
365 #endif
367 #ifdef UNIMPLEMENTED_FEATURES
368 if (sheet_head->pin_count > 0 ) {
369 x_gtksheet_add_row_labels(GTK_SHEET(sheets[2]),
370 sheet_head->pin_count, sheet_head->master_pin_list_head);
371 x_gtksheet_add_col_labels(GTK_SHEET(sheets[2]),
372 sheet_head->pin_attrib_count, sheet_head->master_pin_attrib_list_head);
374 #endif
376 /* ------ Comp sheet: put values in the individual cells ------- */
377 num_rows = sheet_head->comp_count;
378 num_cols = sheet_head->comp_attrib_count;
379 for (i = 0; i < num_rows; i++) {
380 for (j = 0; j < num_cols; j++) {
381 if ( (sheet_head->component_table)[i][j].attrib_value ) { /* NULL = no entry */
382 text = (gchar *) g_strdup( (sheet_head->component_table)[i][j].attrib_value );
383 visibility = (sheet_head->component_table)[i][j].visibility;
384 show_name_value = (sheet_head->component_table)[i][j].show_name_value;
385 x_gtksheet_add_cell_item( GTK_SHEET(sheets[0]), i, j, (gchar *) text,
386 visibility, show_name_value );
387 g_free(text);
392 #ifdef UNIMPLEMENTED_FEATURES
393 /* ------ Net sheet: put values in the individual cells ------- */
394 num_rows = sheet_head->net_count;
395 num_cols = sheet_head->net_attrib_count;
396 for (i = 0; i < num_rows; i++) {
397 for (j = 0; j < num_cols; j++) {
398 if ( (sheet_head->net_table)[i][j].attrib_value ) { /* NULL = no entry */
399 text = (gchar *) g_strdup( (sheet_head->net_table)[i][j].attrib_value );
400 visibility = (sheet_head->net_table)[i][j].visibility;
401 show_name_value = (sheet_head->component_table)[i][j].show_name_value;
402 x_gtksheet_add_cell_item( GTK_SHEET(sheets[1]), i, j, (gchar *) text,
403 visibility, show_name_value );
404 g_free(text);
408 #endif
410 #ifdef UNIMPLEMENTED_FEATURES
411 /* ------ Pin sheet: put pin attribs in the individual cells ------- */
412 num_rows = sheet_head->pin_count;
413 num_cols = sheet_head->pin_attrib_count;
414 for (i = 0; i < num_rows; i++) {
415 for (j = 0; j < num_cols; j++) {
416 if ( (sheet_head->pin_table)[i][j].attrib_value ) { /* NULL = no entry */
417 text = (gchar *) g_strdup( (sheet_head->pin_table)[i][j].attrib_value );
418 /* pins have no visibility attributes, must therefore provide default. */
419 x_gtksheet_add_cell_item( GTK_SHEET(sheets[2]), i, j, (gchar *) text,
420 VISIBLE, SHOW_VALUE );
421 g_free(text);
425 #endif
427 gtk_widget_show_all( GTK_WIDGET(window) );
431 /*! \brief Set application icon
433 * Setup default icon for GTK windows
435 * Sets the default window icon by name, to be found in the current icon
436 * theme. The name used is #defined above as GATTRIB_THEME_ICON_NAME.
438 static void
439 x_window_set_default_icon( void )
441 gtk_window_set_default_icon_name( GATTRIB_THEME_ICON_NAME );