00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00031 #ifdef HAVE_CONFIG_H
00032 #include "config.h"
00033 #endif
00034
00035 #ifdef HAVE_STDLIB_H
00036 #include <stdlib.h>
00037 #endif
00038
00039 #ifdef HAVE_STRING_H
00040 #include <string.h>
00041 #endif
00042
00043 #ifdef HAVE_SYS_STAT_H
00044 #include <sys/stat.h>
00045 #endif
00046
00047 #include <gtk/gtk.h>
00048
00049 #include "gerbv.h"
00050 #include "attribute.h"
00051 #include "main.h"
00052
00053 #define dprintf if(DEBUG) printf
00054
00055 static int auto_uncheck_needed = 0;
00056 static GtkWidget * auto_uncheck_widget = NULL;
00057 static int * auto_uncheck_attr = NULL;
00058 static GtkWidget ** all_widgets = NULL;
00059 static int n_widgets;
00060
00061 static void clear_auto()
00062 {
00063 if( auto_uncheck_needed && auto_uncheck_widget != NULL && auto_uncheck_attr != NULL) {
00064
00065 auto_uncheck_needed = 0;
00066
00067
00068 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auto_uncheck_widget), 0);
00069
00070
00071 *auto_uncheck_attr = 0;
00072
00073
00074 auto_uncheck_needed = 1;
00075 }
00076 }
00077
00078
00079 static void
00080 set_flag_cb (GtkToggleButton * button, gboolean * flag)
00081 {
00082 int i, f;
00083
00084 *flag = gtk_toggle_button_get_active (button);
00085
00086
00087
00088
00089
00090 if (auto_uncheck_widget == GTK_WIDGET (button)) {
00091 f = *flag ? 0 : 1;
00092 printf ("flag = %d, f = %d\n", *flag, f);
00093 for (i = 1 ; i < n_widgets ; i++) {
00094 gtk_widget_set_sensitive (all_widgets[i], f);
00095 }
00096 } else {
00097 clear_auto ();
00098 }
00099 }
00100
00101
00102 static void
00103 intspinner_changed_cb (GtkWidget * spin_button, gpointer data)
00104 {
00105 int *ival = data;
00106
00107 *ival = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin_button));
00108 clear_auto ();
00109 }
00110
00111
00112 static void
00113 dblspinner_changed_cb (GtkWidget * spin_button, gpointer data)
00114 {
00115 double *dval = data;
00116
00117 *dval = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin_button));
00118 clear_auto ();
00119 }
00120
00121
00122 static void
00123 entry_changed_cb (GtkEntry * entry, char **str)
00124 {
00125 const gchar *s;
00126
00127 s = gtk_entry_get_text (entry);
00128
00129 if (*str)
00130 free (*str);
00131 *str = strdup (s);
00132
00133 clear_auto ();
00134 }
00135
00136
00137 static void
00138 enum_changed_cb (GtkWidget * combo_box, int *val)
00139 {
00140 gint active;
00141
00142 active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box));
00143 *val = active;
00144
00145 clear_auto ();
00146 }
00147
00148
00149
00150 static GtkWidget *
00151 ghid_category_vbox (GtkWidget * box, const gchar * category_header,
00152 gint header_pad,
00153 gint box_pad, gboolean pack_start, gboolean bottom_pad)
00154 {
00155 GtkWidget *vbox, *vbox1, *hbox, *label;
00156 gchar *s;
00157
00158 vbox = gtk_vbox_new (FALSE, 0);
00159 if (pack_start)
00160 gtk_box_pack_start (GTK_BOX (box), vbox, FALSE, FALSE, 0);
00161 else
00162 gtk_box_pack_end (GTK_BOX (box), vbox, FALSE, FALSE, 0);
00163
00164 if (category_header)
00165 {
00166 label = gtk_label_new (NULL);
00167 s = g_strconcat ("<span weight=\"bold\">", category_header,
00168 "</span>", NULL);
00169 gtk_label_set_markup (GTK_LABEL (label), s);
00170 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
00171 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, header_pad);
00172 g_free (s);
00173 }
00174
00175 hbox = gtk_hbox_new (FALSE, 0);
00176 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
00177 label = gtk_label_new (" ");
00178 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
00179 vbox1 = gtk_vbox_new (FALSE, box_pad);
00180 gtk_box_pack_start (GTK_BOX (hbox), vbox1, TRUE, TRUE, 0);
00181
00182 if (bottom_pad)
00183 {
00184 label = gtk_label_new ("");
00185 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
00186 }
00187 return vbox1;
00188 }
00189
00190
00191
00192 static void
00193 ghid_spin_button (GtkWidget * box, GtkWidget ** spin_button, gfloat value,
00194 gfloat low, gfloat high, gfloat step0, gfloat step1,
00195 gint digits, gint width,
00196 void (*cb_func) (), gpointer data, gboolean right_align,
00197 gchar * string)
00198 {
00199 GtkWidget *hbox = NULL, *label, *spin_but;
00200 GtkSpinButton *spin;
00201 GtkAdjustment *adj;
00202
00203 if (string && box)
00204 {
00205 hbox = gtk_hbox_new (FALSE, 0);
00206 gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 2);
00207 box = hbox;
00208 }
00209 adj = (GtkAdjustment *) gtk_adjustment_new (value,
00210 low, high, step0, step1, 0.0);
00211 spin_but = gtk_spin_button_new (adj, 0.5, digits);
00212 if (spin_button)
00213 *spin_button = spin_but;
00214 if (width > 0)
00215 gtk_widget_set_size_request (spin_but, width, -1);
00216 spin = GTK_SPIN_BUTTON (spin_but);
00217 gtk_spin_button_set_numeric (spin, TRUE);
00218 if (data == NULL)
00219 data = (gpointer) spin;
00220 if (cb_func)
00221 g_signal_connect (G_OBJECT (spin_but), "value_changed",
00222 G_CALLBACK (cb_func), data);
00223 if (box)
00224 {
00225 if (right_align && string)
00226 {
00227 label = gtk_label_new (string);
00228 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
00229 gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 2);
00230 }
00231 gtk_box_pack_start (GTK_BOX (box), spin_but, FALSE, FALSE, 2);
00232 if (!right_align && string)
00233 {
00234 label = gtk_label_new (string);
00235 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
00236 gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 2);
00237 }
00238 }
00239 }
00240
00241
00242
00243 static void
00244 ghid_check_button_connected (GtkWidget * box,
00245 GtkWidget ** button,
00246 gboolean active,
00247 gboolean pack_start,
00248 gboolean expand,
00249 gboolean fill,
00250 gint pad,
00251 void (*cb_func) (),
00252 gpointer data, gchar * string)
00253 {
00254 GtkWidget *b;
00255
00256 if (!string)
00257 return;
00258 b = gtk_check_button_new_with_label (string);
00259 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b), active);
00260 if (box && pack_start)
00261 gtk_box_pack_start (GTK_BOX (box), b, expand, fill, pad);
00262 else if (box && !pack_start)
00263 gtk_box_pack_end (GTK_BOX (box), b, expand, fill, pad);
00264
00265 if (cb_func)
00266 gtk_signal_connect (GTK_OBJECT (b), "clicked",
00267 GTK_SIGNAL_FUNC (cb_func), data);
00268 if (button)
00269 *button = b;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 int
00281 attribute_interface_dialog (gerbv_HID_Attribute * attrs,
00282 int n_attrs, gerbv_HID_Attr_Val * results,
00283 const char * title,
00284 const char * descr)
00285 {
00286 GtkWidget *dialog, *main_vbox, *vbox, *vbox1, *hbox, *entry;
00287 GtkWidget *combo;
00288 GtkWidget *widget;
00289 int i, j;
00290 GtkTooltips *tips;
00291 int rc = 0;
00292 int set_auto_uncheck = 0;
00293 int sen = TRUE;
00294
00295
00296
00297
00298
00299 n_widgets = n_attrs;
00300 if (all_widgets != NULL)
00301 free (all_widgets);
00302
00303 all_widgets = (GtkWidget **) malloc (n_widgets * sizeof(GtkWidget *));
00304 if (all_widgets == NULL) {
00305 fprintf (stderr, "%s(): malloc failed for an array of size %d\n", __FUNCTION__, n_widgets);
00306 exit (1);
00307 }
00308
00309 dprintf ("%s(%p, %d, %p, \"%s\", \"%s\")\n", __FUNCTION__, attrs, n_attrs, results, title, descr);
00310
00311 auto_uncheck_needed = 0;
00312 auto_uncheck_widget = NULL;
00313 auto_uncheck_attr = NULL;
00314
00315 tips = gtk_tooltips_new ();
00316
00317 dialog = gtk_dialog_new_with_buttons (title,
00318 GTK_WINDOW (screen.win.topLevelWindow),
00319 GTK_DIALOG_MODAL
00320 | GTK_DIALOG_DESTROY_WITH_PARENT,
00321 GTK_STOCK_CANCEL, GTK_RESPONSE_NONE,
00322 GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
00323 gtk_window_set_wmclass (GTK_WINDOW (dialog), "gerbv_attribute_editor", "gerbv");
00324
00325 main_vbox = gtk_vbox_new (FALSE, 6);
00326 gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
00327 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), main_vbox);
00328
00329 vbox = ghid_category_vbox (main_vbox, descr != NULL ? descr : "",
00330 4, 2, TRUE, TRUE);
00331
00332
00333
00334
00335
00336
00337
00338
00339 for (j = 0; j < n_attrs; j++)
00340 {
00341 dprintf ("%s(): Adding attribute #%d\n", __FUNCTION__, j);
00342 switch (attrs[j].type)
00343 {
00344 case HID_Label:
00345 widget = gtk_label_new (attrs[j].name);
00346 gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
00347 gtk_tooltips_set_tip (tips, widget, attrs[j].help_text, NULL);
00348 break;
00349
00350 case HID_Integer:
00351 hbox = gtk_hbox_new (FALSE, 4);
00352 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
00353
00354
00355
00356
00357
00358
00359 ghid_spin_button (hbox, &widget, attrs[j].default_val.int_value,
00360 attrs[j].min_val, attrs[j].max_val, 1.0, 1.0, 0, 0,
00361 intspinner_changed_cb,
00362 &(attrs[j].default_val.int_value), FALSE, NULL);
00363
00364 gtk_tooltips_set_tip (tips, widget, attrs[j].help_text, NULL);
00365 all_widgets[j] = widget;
00366
00367 widget = gtk_label_new (attrs[j].name);
00368 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
00369 break;
00370
00371 case HID_Real:
00372 hbox = gtk_hbox_new (FALSE, 4);
00373 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
00374
00375
00376
00377
00378
00379
00380 ghid_spin_button (hbox, &widget, attrs[j].default_val.real_value,
00381 attrs[j].min_val, attrs[j].max_val, 0.01, 0.01, 3,
00382 0,
00383 dblspinner_changed_cb,
00384 &(attrs[j].default_val.real_value), FALSE, NULL);
00385
00386 gtk_tooltips_set_tip (tips, widget, attrs[j].help_text, NULL);
00387 all_widgets[j] = widget;
00388
00389 widget = gtk_label_new (attrs[j].name);
00390 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
00391 break;
00392
00393 case HID_String:
00394 hbox = gtk_hbox_new (FALSE, 4);
00395 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
00396
00397 entry = gtk_entry_new ();
00398 gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
00399 gtk_entry_set_text (GTK_ENTRY (entry),
00400 attrs[j].default_val.str_value);
00401 gtk_tooltips_set_tip (tips, entry, attrs[j].help_text, NULL);
00402 g_signal_connect (G_OBJECT (entry), "changed",
00403 G_CALLBACK (entry_changed_cb),
00404 &(attrs[j].default_val.str_value));
00405 all_widgets[j] = entry;
00406
00407 widget = gtk_label_new (attrs[j].name);
00408 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
00409 break;
00410
00411 case HID_Boolean:
00412
00413 ghid_check_button_connected (vbox, &widget,
00414 attrs[j].default_val.int_value,
00415 TRUE, FALSE, FALSE, 0, set_flag_cb,
00416 &(attrs[j].default_val.int_value),
00417 attrs[j].name);
00418 gtk_tooltips_set_tip (tips, widget, attrs[j].help_text, NULL);
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 if (j == 0 && strcmp(attrs[j].name, "Autodetect file format") == 0) {
00435 set_auto_uncheck = 1;
00436 auto_uncheck_widget = widget;
00437 auto_uncheck_attr = &(attrs[j].default_val.int_value);
00438
00439
00440
00441
00442
00443 if (attrs[j].default_val.int_value)
00444 sen = FALSE;
00445 }
00446 all_widgets[j] = widget;
00447
00448 break;
00449
00450 case HID_Enum:
00451 hbox = gtk_hbox_new (FALSE, 4);
00452 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
00453
00454
00455
00456
00457
00458 widget = gtk_event_box_new ();
00459 gtk_tooltips_set_tip (tips, widget, attrs[j].help_text, NULL);
00460 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
00461
00462 combo = gtk_combo_box_new_text ();
00463 gtk_container_add (GTK_CONTAINER (widget), combo);
00464 g_signal_connect (G_OBJECT (combo), "changed",
00465 G_CALLBACK (enum_changed_cb),
00466 &(attrs[j].default_val.int_value));
00467
00468
00469
00470
00471
00472
00473 i = 0;
00474 while (attrs[j].enumerations[i])
00475 {
00476 gtk_combo_box_append_text (GTK_COMBO_BOX (combo),
00477 attrs[j].enumerations[i]);
00478 i++;
00479 }
00480 gtk_combo_box_set_active (GTK_COMBO_BOX (combo),
00481 attrs[j].default_val.int_value);
00482 all_widgets[j] = combo;
00483
00484 widget = gtk_label_new (attrs[j].name);
00485 gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
00486 break;
00487
00488 case HID_Mixed:
00489 dprintf ("HID_Mixed\n");
00490 break;
00491
00492 case HID_Path:
00493 vbox1 = ghid_category_vbox (vbox, attrs[j].name, 4, 2, TRUE, TRUE);
00494 entry = gtk_entry_new ();
00495 gtk_box_pack_start (GTK_BOX (vbox1), entry, FALSE, FALSE, 0);
00496 gtk_entry_set_text (GTK_ENTRY (entry),
00497 attrs[j].default_val.str_value);
00498 g_signal_connect (G_OBJECT (entry), "changed",
00499 G_CALLBACK (entry_changed_cb),
00500 &(attrs[j].default_val.str_value));
00501
00502 gtk_tooltips_set_tip (tips, entry, attrs[j].help_text, NULL);
00503 all_widgets[j] = entry;
00504 break;
00505
00506 default:
00507 fprintf (stderr, "%s: unknown type of HID attribute\n", __FUNCTION__);
00508 break;
00509 }
00510 }
00511
00512
00513 gtk_widget_show_all (dialog);
00514 auto_uncheck_needed = set_auto_uncheck;
00515
00516
00517
00518
00519
00520
00521 for (j = 1; j < n_widgets ; j++) {
00522 gtk_widget_set_sensitive (all_widgets[j], sen);
00523 }
00524 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
00525 {
00526
00527 for (i = 0; i < n_attrs; i++)
00528 {
00529 results[i] = attrs[i].default_val;
00530 if (results[i].str_value)
00531 results[i].str_value = strdup (results[i].str_value);
00532 }
00533 rc = 0;
00534 }
00535 else
00536 rc = 1;
00537
00538 gtk_widget_destroy (dialog);
00539
00540 return rc;
00541 }
00542