gattrib
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * gattrib -- gEDA component and net attribute manipulation using spreadsheet. 00003 * Copyright (C) 2003-2010 Stuart D. Brorson. 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 00020 /*------------------------------------------------------------------*/ 00029 #ifdef HAVE_CONFIG_H 00030 #include "config.h" 00031 #endif 00032 00033 /*------------------------------------------------------------------ 00034 * Includes required to run graphical widgets. 00035 *------------------------------------------------------------------*/ 00036 #include <stdio.h> 00037 #include <stdlib.h> 00038 #include <gtk/gtk.h> 00039 #include <gdk/gdk.h> 00040 #include <gdk/gdkkeysyms.h> 00041 00042 #include <glib.h> 00043 #include <glib-object.h> 00044 00045 #ifdef HAVE_STRING_H 00046 #include <string.h> 00047 #endif 00048 00049 00050 /*------------------------------------------------------------------ 00051 * Gattrib specific includes 00052 *------------------------------------------------------------------*/ 00053 #include <libgeda/libgeda.h> /* geda library fcns */ 00054 #include "../include/struct.h" /* typdef and struct declarations */ 00055 #include "../include/prototype.h" /* function prototypes */ 00056 #include "../include/globals.h" 00057 00058 00059 #ifdef HAVE_LIBDMALLOC 00060 #include <dmalloc.h> 00061 #endif 00062 00063 static void show_entry(GtkWidget *widget, gpointer data); 00064 00070 void 00071 x_gtksheet_init() 00072 { 00073 gint i; 00074 gchar *folder[]= {"Components", 00075 "Nets", 00076 "Pins"}; 00077 00078 00079 /* --- Create three new sheets. were malloc'ed in x_window_init --- */ 00080 00081 /* ----- Components ----- */ 00082 if ((sheet_head->comp_count > 0) && (sheet_head->comp_attrib_count >0)) { 00083 sheets[0] = (GtkSheet *) gtk_sheet_new((guint) sheet_head->comp_count, (guint) sheet_head->comp_attrib_count, "Components"); 00084 } else { 00085 x_dialog_fatal_error("No components found in design. Please check your schematic and try again!\n", 1); 00086 } 00087 00088 00089 #ifdef UNIMPLEMENTED_FEATURES 00090 /* ----- Nets ----- */ 00091 if ((sheet_head->net_count > 0) && (sheet_head->net_attrib_count >0)) { 00092 sheets[1] = (GtkSheet *) gtk_sheet_new(sheet_head->net_count, sheet_head->net_attrib_count, "Nets"); 00093 gtk_sheet_set_locked(GTK_SHEET(sheets[1]), TRUE); /* disallow editing of attribs for now */ 00094 } else { 00095 sheets[1] = (GtkSheet *) gtk_sheet_new(1, 1, "Nets"); 00096 gtk_sheet_row_button_add_label(sheets[1], 0, "TBD"); 00097 gtk_sheet_row_button_justify(sheets[1], 0, GTK_JUSTIFY_LEFT); 00098 gtk_sheet_column_button_add_label(sheets[1], 0, "TBD"); 00099 gtk_sheet_column_button_justify(sheets[1], 0, GTK_JUSTIFY_LEFT); 00100 gtk_sheet_set_locked(GTK_SHEET(sheets[1]), TRUE); /* disallow editing of attribs for now */ 00101 } 00102 #endif 00103 00104 00105 #ifdef UNIMPLEMENTED_FEATURES 00106 /* ----- Pins ----- */ 00107 if ((sheet_head->pin_count > 0) && (sheet_head->pin_attrib_count >0)) { 00108 sheets[2] = (GtkSheet *) gtk_sheet_new(sheet_head->pin_count, sheet_head->pin_attrib_count, "Pins"); 00109 gtk_sheet_set_locked(GTK_SHEET(sheets[2]), TRUE); /* disallow editing of attribs for now */ 00110 } else { 00111 sheets[2] = (GtkSheet *) gtk_sheet_new(1, 1, "Pins"); 00112 gtk_sheet_set_locked(GTK_SHEET(sheets[2]), TRUE); /* disallow editing of attribs for now */ 00113 } 00114 #endif 00115 00116 00117 00118 /* --- Finally stick labels on the notebooks holding the two sheets. --- */ 00119 for(i=0; i<NUM_SHEETS; i++){ 00120 if (sheets[i] != NULL) { /* is this check needed? 00121 * Yes, it prevents us from segfaulting on empty nets sheet. */ 00122 00123 00124 scrolled_windows=(GtkWidget **)realloc(scrolled_windows, (i+1)*sizeof(GtkWidget *)); 00125 scrolled_windows[i]=gtk_scrolled_window_new(NULL, NULL); 00126 00127 gtk_container_add( GTK_CONTAINER(scrolled_windows[i]), GTK_WIDGET(sheets[i]) ); 00128 00129 /* First remove old notebook page. I should probably do some checking here. */ 00130 if (notebook != NULL) 00131 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), i); 00132 00133 00134 /* Then add new, updated notebook page */ 00135 label= gtk_label_new(folder[i]); 00136 00137 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(scrolled_windows[i]), 00138 GTK_WIDGET(label) ); 00139 00140 gtk_widget_show( GTK_WIDGET(sheets[i]) ); 00141 gtk_widget_show( GTK_WIDGET(scrolled_windows[i]) ); 00142 gtk_widget_show( GTK_WIDGET(notebook) ); /* show updated notebook */ 00143 00144 00145 /* "changed" signal raised when user changes anything in entry cell */ 00146 /* Note that the entry cell is the text entry field at the top of the 00147 * sheet's working area (like in MS E*cel). I have removed this from 00148 * gattrib, but leave the code in just in case I want to put it back. */ 00149 gtk_signal_connect(GTK_OBJECT(gtk_sheet_get_entry(GTK_SHEET(sheets[i]))), 00150 "changed", (GtkSignalFunc) show_entry, NULL); 00151 } 00152 } 00153 } 00154 00155 00156 00157 /*------------------------------------------------------------------*/ 00165 void 00166 x_gtksheet_add_row_labels(GtkSheet *sheet, int count, STRING_LIST *list_head) 00167 { 00168 STRING_LIST *string_list_item; 00169 gchar *text; 00170 int j; 00171 int width = 0; 00172 int new_width = 0; 00173 int char_width; 00174 00175 /* Leave if no items to add are available */ 00176 if ((count == 0) || (list_head == NULL)) return; 00177 00178 /* Get character width based upon "X", which is a large char. 00179 * font_combo is a global. Where is it set? */ 00180 if ( GTK_WIDGET(sheet)->style->private_font ) 00181 char_width = gdk_char_width (GTK_WIDGET(sheet)->style->private_font, (gchar)'X'); 00182 else 00183 char_width = 12; 00184 00185 string_list_item = list_head; 00186 for (j = 0; j < count; j++) { 00187 text = (gchar *) g_strdup(string_list_item->data); 00188 new_width = char_width * strlen(text); 00189 if (new_width > width) 00190 width = new_width; 00191 00192 gtk_sheet_row_button_add_label(sheet, j, text); 00193 gtk_sheet_row_button_justify(sheet, j, GTK_JUSTIFY_LEFT); 00194 g_free(text); 00195 string_list_item = string_list_item->next; 00196 } 00197 00198 00199 gtk_sheet_set_row_titles_width(sheet, width+8); 00200 } 00201 00202 00203 /*------------------------------------------------------------------*/ 00211 void 00212 x_gtksheet_add_col_labels(GtkSheet *sheet, int count, STRING_LIST *list_head) 00213 { 00214 STRING_LIST *string_list_item; 00215 gchar *text; 00216 int j; 00217 00218 /* Leave if no items to add are available */ 00219 if ((count == 0) || (list_head == NULL)) return; 00220 00221 string_list_item = list_head; 00222 for (j = 0; j < count; j++) { 00223 text = (gchar *) g_strdup(string_list_item->data); 00224 gtk_sheet_column_button_add_label(sheet, j, text); 00225 gtk_sheet_column_button_justify(sheet, j, GTK_JUSTIFY_LEFT); 00226 /* need to resize the column width here . . . */ 00227 g_free(text); 00228 string_list_item = string_list_item->next; 00229 } 00230 } 00231 00232 00233 /*------------------------------------------------------------------*/ 00244 void 00245 x_gtksheet_add_cell_item(GtkSheet *sheet,gint i, gint j, 00246 gchar *text, 00247 gint visibility, 00248 gint show_name_value) 00249 { 00250 00251 /* Should I do some sanity checking here? */ 00252 00253 gtk_sheet_set_cell(sheet, i, j, GTK_JUSTIFY_LEFT, text); 00254 if (visibility == INVISIBLE) { 00255 x_gtksheet_set_cell_text_color(sheet, i, j, GREY); 00256 } else { 00257 switch(show_name_value) { 00258 00259 case(SHOW_NAME_VALUE): 00260 x_gtksheet_set_cell_text_color(sheet, i, j, BLUE); 00261 break; 00262 00263 case(SHOW_NAME): 00264 x_gtksheet_set_cell_text_color(sheet, i, j, RED); 00265 break; 00266 00267 case(SHOW_VALUE): 00268 x_gtksheet_set_cell_text_color(sheet, i, j, BLACK); 00269 break; 00270 } 00271 } /* if (visibility == INVISIBLE) */ 00272 00273 00274 00275 /* Need to find a way to ensure that the text in a cell is clipped. 00276 * Otherwise, long attribs overwrite adjacent cells. */ 00277 } 00278 00279 00289 int x_gtksheet_get_min_col(GtkSheet *sheet) { 00290 if (sheet->state == GTK_SHEET_COLUMN_SELECTED) { 00291 return sheet->range.col0; 00292 } else { 00293 return -1; 00294 } 00295 } 00296 00297 00305 int x_gtksheet_get_max_col(GtkSheet *sheet) { 00306 if (sheet->state == GTK_SHEET_COLUMN_SELECTED) { 00307 return sheet->range.coli; 00308 } else { 00309 return -1; 00310 } 00311 } 00312 00313 00322 void x_gtksheet_set_cell_text_color(GtkSheet *sheet, gint row, gint col, 00323 gint color_name) 00324 { 00325 GtkSheetRange *range; 00326 GdkColormap *cmap; 00327 GdkColor *color; 00328 00329 /* First get the system color map and allocate the color */ 00330 cmap = gdk_colormap_get_system (); 00331 color = g_malloc(sizeof(GdkColor)); 00332 switch(color_name) { 00333 case RED: 00334 color->red = 0xffff; 00335 color->green = 0x0; 00336 color->blue = 0x0; 00337 break; 00338 00339 case BLUE: 00340 color->red = 0x0; 00341 color->green = 0x0; 00342 color->blue = 0xffff; 00343 break; 00344 00345 case BLACK: 00346 color->red = 0x0; 00347 color->green = 0x0; 00348 color->blue = 0x0; 00349 break; 00350 00351 case GREY: 00352 color->red = 0x9999; 00353 color->green = 0x9999; 00354 color->blue = 0x9999; 00355 break; 00356 } 00357 00358 if (!gdk_colormap_alloc_color (cmap, color, FALSE, FALSE)) { 00359 g_error ("couldn't allocate color"); 00360 return; 00361 } 00362 /* g_free(cmap); */ 00363 00364 /* XXXXX Attempt to set cell color */ 00365 range = g_malloc(sizeof(GtkSheetRange)); 00366 range->row0 = row; 00367 range->rowi = row; 00368 range->col0 = col; 00369 range->coli = col; 00370 00371 /* Now set color */ 00372 gtk_sheet_range_set_foreground(sheet, range, color); 00373 g_free(color); 00374 g_free(range); 00375 } 00376 00377 00386 static void 00387 show_entry(GtkWidget *widget, gpointer data) 00388 { 00389 gchar *text; 00390 GtkSheet *sheet; 00391 GtkWidget *sheet_entry = NULL; 00392 gint cur_page; 00393 00394 if(!GTK_WIDGET_HAS_FOCUS(widget)) { 00395 return; 00396 } 00397 00398 cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); 00399 00400 sheet = GTK_SHEET(sheets[cur_page]); 00401 if (sheet != NULL) { 00402 sheet_entry = gtk_sheet_get_entry( GTK_SHEET(sheet) ); 00403 } 00404 00405 /* Here's another place where we mix entry and sheet_entry */ 00406 if (entry != NULL) { 00407 text = (gchar *) gtk_entry_get_text (GTK_ENTRY(sheet_entry)); 00408 if( text != NULL ) { 00409 gtk_entry_set_text(GTK_ENTRY(entry), text); 00410 } 00411 else { 00412 gtk_entry_set_text(GTK_ENTRY(entry), (const gchar *) ""); 00413 /* gtk_entry_set_text(GTK_ENTRY(entry), NULL); */ 00414 } 00415 } 00416 } 00417