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 /*------------------------------------------------------------------*/
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.
34 /*------------------------------------------------------------------
35 * Includes required to run graphical widgets.
36 *------------------------------------------------------------------*/
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
60 /*------------------------------------------------------------------
61 * Gattrib specific defines
62 *------------------------------------------------------------------*/
63 #define GATTRIB_THEME_ICON_NAME "geda-gattrib"
66 x_window_create_menu(GtkWindow
*window
, GtkWidget
**menubar
);
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:
77 * GTK_CONTAINER *main_vbox
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.
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
140 x_dialog_unimplemented_feature();
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
);
156 * \brief File->Save menu item
158 * Implement the File->Save menu
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
175 menu_file_export_csv()
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. */
184 x_dialog_export_file();
186 x_dialog_unimplemented_feature(); /* We only support export
192 * \brief Edit->New attrib menu item
194 * Implement the New attrib menu item
197 menu_edit_newattrib()
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. */
206 x_dialog_newattrib(); /* This creates dialog box */
211 * \brief Edit->Delete Attribute menu item
213 * Implements the Delete Attribute menu item
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 */
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
)},
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
},
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
270 x_window_create_menu(GtkWindow
*window
, GtkWidget
**menubar
)
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
);
290 /* An error occured, terminate */
291 fprintf(stderr
, "Error loading %s:\n%s\n", menu_file
, error
->message
);
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.
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
);
365 x_gtksheet_add_row_labels(GTK_SHEET(sheets
[1]), 1, NULL
);
366 x_gtksheet_add_col_labels(GTK_SHEET(sheets
[1]), 1, NULL
);
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
);
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
);
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
);
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
);
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.
442 x_window_set_default_icon( void )
444 gtk_window_set_default_icon_name( GATTRIB_THEME_ICON_NAME
);