1 /* gEDA - GPL Electronic Design Automation
2  * gattrib -- gEDA component and net attribute manipulation using spreadsheet.
3  * Copyright (C) 2003-2010 Stuart D. Brorson.
4  *
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.
9  *
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.
14  *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 /*------------------------------------------------------------------*/
20 /*! \file
21  * \brief Functions to manipulate attribute visibility
22  *
23  * This file holds widgets and functions used in conjunction
24  * with setting attribute visibility.
25  * \todo There seems to be a lot of duplicated code in this file -
26  *       a good candidate for refactoring.
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 /*------------------------------------------------------------------
34  * Includes required to run graphical widgets.
35  *------------------------------------------------------------------*/
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <gtk/gtk.h>
39 #include <gdk/gdk.h>
40 #include <gdk/gdkkeysyms.h>
41 
42 #include <glib.h>
43 #include <glib-object.h>
44 
45 #include <sys/types.h>
46 
47 #ifdef HAVE_SYS_PARAM_H
48 #include <sys/param.h>
49 #endif
50 
51 #include <sys/stat.h>
52 
53 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56 
57 #ifdef HAVE_STRING_H
58 #include <string.h>
59 #endif
60 
61 
62 /*------------------------------------------------------------------
63  * Gattrib specific includes
64  *------------------------------------------------------------------*/
65 #include <libgeda/libgeda.h>       /* geda library fcns  */
66 #include "../include/struct.h"     /* typdef and struct declarations */
67 #include "../include/prototype.h"  /* function prototypes */
68 #include "../include/globals.h"
69 
70 #ifdef HAVE_LIBDMALLOC
71 #include <dmalloc.h>
72 #endif
73 
74 
75 /* ----- s_visibility stuff begins here ----- */
76 
77 
78 
79 /* ---------------------------------------------------------------------- */
80 /* \brief Set the selected cells to INVISIBLE
81  *
82  *
83  * This sets the selected cells to INVISIBLE.
84  * This function is called from the menu, it assumes you have
85  * selected a range of cells which are carried in the global
86  * variable "sheet".
87  */
s_visibility_set_invisible()88 void s_visibility_set_invisible() {
89   gint i, j;
90   gint row_start, row_end, col_start, col_end;
91   GtkSheet *sheet;
92   gint cur_page;
93 
94   cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
95   sheet = sheets[cur_page];
96 
97   g_return_if_fail (sheet != NULL);
98   g_return_if_fail (GTK_IS_SHEET (sheet));
99 
100   switch (sheet->state) {
101 
102   case GTK_SHEET_RANGE_SELECTED:
103   case GTK_SHEET_COLUMN_SELECTED:
104   case GTK_SHEET_ROW_SELECTED:
105 
106 #ifdef DEBUG
107     printf("In s_visibility_set_invisible, range/col/row selected.\n");
108 #endif
109 
110     row_start = sheet->range.row0;
111     row_end = sheet->range.rowi;
112     col_start = sheet->range.col0;
113     col_end = sheet->range.coli;
114     for (i=row_start; i<=row_end; i++) {
115       for (j=col_start; j<=col_end; j++) {
116 	/* first set cell in SHEET_DATA to invisible */
117 	s_visibility_set_cell(cur_page, i, j,
118 			      INVISIBLE,
119 			      LEAVE_NAME_VALUE_ALONE);
120 	/* Now set cell in gtksheet to desired color */
121 	/* Color names are defined
122 	 * in libgeda/include/colors.h */
123 	x_gtksheet_set_cell_text_color(sheet, i, j, GREY);
124 
125       }
126     }
127     /* Now return sheet to normal -- unselect range */
128     gtk_sheet_unselect_range (sheet);
129     break;
130 
131   case GTK_SHEET_NORMAL:
132 #ifdef DEBUG
133     printf("In s_visibility_set_invisible, normal selection.\n");
134 #endif
135     s_visibility_set_cell(cur_page,
136 			  sheet->active_cell.row,
137 			  sheet->active_cell.col,
138 			  INVISIBLE,
139 			  LEAVE_NAME_VALUE_ALONE);
140 
141     x_gtksheet_set_cell_text_color(sheet,
142 				   sheet->active_cell.row,
143 				   sheet->active_cell.col,
144 				   GREY);
145 
146     break;
147 
148   }
149 
150 
151 }
152 
153 /* ---------------------------------------------------------------------- */
154 /*! \brief Set the visibility of the selected cells to NAME_ONLY.
155  *
156  * This sets the selected cells to NAME_ONLY.
157  * This function is invoked from the menu, it assumes you have
158  * selected a range of cells which are carried in the global
159  * variable "sheet".
160  */
s_visibility_set_name_only()161 void s_visibility_set_name_only() {
162   gint i, j;
163   gint row_start, row_end, col_start, col_end;
164   GtkSheet *sheet;
165   gint cur_page;
166 
167   cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
168   sheet = sheets[cur_page];
169 
170   g_return_if_fail (sheet != NULL);
171   g_return_if_fail (GTK_IS_SHEET (sheet));
172 
173   switch (sheet->state) {
174 
175   case GTK_SHEET_RANGE_SELECTED:
176   case GTK_SHEET_COLUMN_SELECTED:
177   case GTK_SHEET_ROW_SELECTED:
178 #ifdef DEBUG
179     printf("In s_visibility_set_name_only, range/col/row selected.\n");
180 #endif
181     row_start = sheet->range.row0;
182     row_end = sheet->range.rowi;
183     col_start = sheet->range.col0;
184     col_end = sheet->range.coli;
185     for (i=row_start; i<=row_end; i++) {
186       for (j=col_start; j<=col_end; j++) {
187 	s_visibility_set_cell(cur_page, i, j, VISIBLE, SHOW_NAME);
188 	/* Color names are defined
189 	 * in libgeda/include/colors.h */
190 	x_gtksheet_set_cell_text_color(sheet, i, j, RED);
191 
192       }
193     }
194     /* Now return sheet to normal -- unselect range */
195     gtk_sheet_unselect_range (sheet);
196 
197     break;
198 
199   case GTK_SHEET_NORMAL:
200     s_visibility_set_cell(cur_page,
201 			  sheet->active_cell.row,
202 			  sheet->active_cell.col,
203 			  VISIBLE, SHOW_NAME);
204     x_gtksheet_set_cell_text_color(sheet,
205 				   sheet->active_cell.row,
206 				   sheet->active_cell.col,
207 				   RED);
208 
209     break;
210 
211   }
212 }
213 
214 /* ---------------------------------------------------------------------- */
215 /* \brief Set the selected cells' visibility to VALUE_ONLY
216  *
217  * s_visibility_set_value_only -- This sets the selected cells to VALUE_ONLY.
218  * This fcn is invoked from the menu, it assumes you have
219  * selected a range of cells which are carried in the global
220  * variable "sheet".
221  */
s_visibility_set_value_only()222 void s_visibility_set_value_only() {
223   gint i, j;
224   gint row_start, row_end, col_start, col_end;
225   GtkSheet *sheet;
226   gint cur_page;
227 
228   cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
229   sheet = sheets[cur_page];
230 
231   g_return_if_fail (sheet != NULL);
232   g_return_if_fail (GTK_IS_SHEET (sheet));
233 
234   switch (sheet->state) {
235 
236   case GTK_SHEET_RANGE_SELECTED:
237   case GTK_SHEET_COLUMN_SELECTED:
238   case GTK_SHEET_ROW_SELECTED:
239 #ifdef DEBUG
240     printf("In s_visibility_set_value_only, range/col/row selected.\n");
241 #endif
242     row_start = sheet->range.row0;
243     row_end = sheet->range.rowi;
244     col_start = sheet->range.col0;
245     col_end = sheet->range.coli;
246     for (i=row_start; i<=row_end; i++) {
247       for (j=col_start; j<=col_end; j++) {
248 	s_visibility_set_cell(cur_page, i, j, VISIBLE, SHOW_VALUE);
249 	/* Color names are defined
250 	 * in libgeda/include/colors.h */
251 	x_gtksheet_set_cell_text_color(sheet, i, j, BLACK);
252 
253       }
254     }
255     /* Now return sheet to normal -- unselect range */
256     gtk_sheet_unselect_range (sheet);
257 
258     break;
259 
260   case GTK_SHEET_NORMAL:
261 #ifdef DEBUG
262     printf("In s_visibility_set_value_only, sheet normal selected.\n");
263 #endif
264     s_visibility_set_cell(cur_page,
265 			  sheet->active_cell.row,
266 			  sheet->active_cell.col,
267 			  VISIBLE, SHOW_VALUE);
268     x_gtksheet_set_cell_text_color(sheet,
269 				   sheet->active_cell.row,
270 				   sheet->active_cell.col,
271 				   BLACK);
272     break;
273 
274   }
275 }
276 
277 /* ---------------------------------------------------------------------- */
278 /* \brief Set the visibility of the selected cells to NAME_AND_VALUE
279  *
280  * This sets the selected cells
281  * to NAME_AND_VALUE
282  * This fcn is invoked from the menu, it assumes you have
283  * selected a range of cells which are carried in the global
284  * variable "sheet".
285  *
286  */
s_visibility_set_name_and_value()287 void s_visibility_set_name_and_value() {
288   gint i, j;
289   gint row_start, row_end, col_start, col_end;
290   GtkSheet *sheet;
291   gint cur_page;
292 
293   cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
294   sheet = sheets[cur_page];
295 
296   g_return_if_fail (sheet != NULL);
297   g_return_if_fail (GTK_IS_SHEET (sheet));
298 
299   switch (sheet->state) {
300 
301   case GTK_SHEET_RANGE_SELECTED:
302   case GTK_SHEET_COLUMN_SELECTED:
303   case GTK_SHEET_ROW_SELECTED:
304     row_start = sheet->range.row0;
305     row_end = sheet->range.rowi;
306     col_start = sheet->range.col0;
307     col_end = sheet->range.coli;
308     for (i=row_start; i<=row_end; i++) {
309       for (j=col_start; j<=col_end; j++) {
310 	s_visibility_set_cell(cur_page, i, j, VISIBLE, SHOW_NAME_VALUE);
311 	/* Color names are defined
312 	 * in libgeda/include/colors.h */
313 	x_gtksheet_set_cell_text_color(sheet, i, j, BLUE);
314 
315       }
316     }
317     /* Now return sheet to normal -- unselect range */
318     gtk_sheet_unselect_range (sheet);
319 
320     break;
321 
322   case GTK_SHEET_NORMAL:
323     s_visibility_set_cell(cur_page,
324 			  sheet->active_cell.row,
325 			  sheet->active_cell.col,
326 			  VISIBLE,
327 			  SHOW_NAME_VALUE);
328     x_gtksheet_set_cell_text_color(sheet,
329 				   sheet->active_cell.row,
330 				   sheet->active_cell.col,
331 				   BLUE);
332 
333     break;
334 
335   }
336 }
337 
338 
339 /* ==================  Private functions  =================== */
340 
341 /* ---------------------------------------------------------------------- */
342 /* \brief set the visibility of an individual cell
343  *
344  * Set the visibility of an individual cell
345  * to "state".  The cell is identified by (row, col)
346  * \param cur_page index of spreadsheet tab
347  * \param row Row index of target cell
348  * \param col Column index of target cell
349  * \param visibility Visibility value to set cell to
350  * \param show_name_value Name, Value visibility flag
351  */
s_visibility_set_cell(gint cur_page,gint row,gint col,gint visibility,gint show_name_value)352 void s_visibility_set_cell(gint cur_page, gint row, gint col,
353 			   gint visibility,
354 			   gint show_name_value) {
355   TABLE **local_table = NULL;
356 
357 #ifdef DEBUG
358     printf("In s_visibility_set_cell, setting row = %d, col = %d.\n",
359 	   row, col);
360 #endif
361 
362   switch (cur_page) {
363 
364   case 0:
365     local_table = sheet_head->component_table;
366     break;
367 
368   case 1:
369     local_table = sheet_head->net_table;
370     break;
371 
372   case 2:
373     local_table = sheet_head->pin_table;
374     break;
375   }
376 
377   /* Question:  how to sanity check (row, col) selection? */
378   local_table[row][col].visibility = visibility;
379   sheet_head->CHANGED = 1;  /* cell has been updated.  */
380 
381   if (show_name_value != LEAVE_NAME_VALUE_ALONE) {
382     local_table[row][col].show_name_value = show_name_value;
383     sheet_head->CHANGED = 1;  /* cell has been updated.  */
384   }
385 }
386 
387