gattrib

x_gtksheet.c

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines