1 /*
2  * Sweep, a sound wave editor.
3  *
4  * Copyright (C) 2000 Conrad Parker
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include <math.h>
28 
29 #include <sweep/sweep_i18n.h>
30 #include <sweep/sweep_types.h>
31 #include "sweep_app.h"
32 #include "interface.h"
33 
34 #include "../pixmaps/ladlogo.xpm"
35 
36 extern GtkStyle * style_bw;
37 
38 static gint
param_cmp(sw_param_type type,sw_param p1,sw_param p2)39 param_cmp (sw_param_type type, sw_param p1, sw_param p2)
40 {
41   switch (type) {
42   case SWEEP_TYPE_BOOL:
43     if (p1.b == p2.b) return 0;
44     if (p2.b) return -1;
45     if (p1.b) return 1;
46     break;
47   case SWEEP_TYPE_INT:
48     if (p1.i == p2.i) return 0;
49     if (p1.i < p2.i) return -1;
50     if (p1.i > p2.i) return 1;
51     break;
52   case SWEEP_TYPE_FLOAT:
53     if (p1.f == p2.f) return 0;
54     if (p1.f < p2.f) return -1;
55     if (p1.f > p2.f) return 1;
56     break;
57   case SWEEP_TYPE_STRING:
58     return strcmp (p1.s, p2.s);
59     break;
60   default:
61     return -1;
62     break;
63   }
64 
65   return -1;
66 }
67 
68 /*
69  * param_copy (p1, p2)
70  *
71  * src: p1
72  * dest: p2
73  */
74 static void
param_copy(sw_param * p1,sw_param * p2)75 param_copy (sw_param * p1, sw_param * p2)
76 {
77   if (p1 == p2) return;
78   memcpy (p2, p1, sizeof (sw_param));
79 }
80 
81 sw_param *
sw_param_set_new(sw_procedure * proc)82 sw_param_set_new (sw_procedure * proc)
83 {
84   sw_param * p;
85 
86   p = g_malloc0 (sizeof(sw_param) * proc->nr_params);
87 
88   return p;
89 }
90 
91 static void
print_type(sw_param_type type)92 print_type (sw_param_type type)
93 {
94   switch (type) {
95   case SWEEP_TYPE_BOOL:
96     printf ("SWEEP_TYPE_BOOL");
97     break;
98   case SWEEP_TYPE_INT:
99     printf ("SWEEP_TYPE_INT");
100     break;
101   case SWEEP_TYPE_FLOAT:
102     printf ("SWEEP_TYPE_FLOAT");
103     break;
104   case SWEEP_TYPE_STRING:
105     printf ("SWEEP_TYPE_STRING");
106     break;
107   default:
108     break;
109   }
110 }
111 
112 static void
snprint_param(gchar * s,gint n,sw_param_type type,sw_param p)113 snprint_param (gchar * s, gint n, sw_param_type type, sw_param p)
114 {
115   switch (type) {
116   case SWEEP_TYPE_BOOL:
117     if (p.b) snprintf (s, n, _("TRUE"));
118     else snprintf (s, n, _("FALSE"));
119     break;
120   case SWEEP_TYPE_INT:
121     snprintf (s, n, "%d", p.i);
122     break;
123   case SWEEP_TYPE_FLOAT:
124     snprintf (s, n, "%f", p.f);
125     break;
126   case SWEEP_TYPE_STRING:
127     snprintf (s, n, "%s", _(p.s));
128     break;
129   default:
130     break;
131   }
132 }
133 
134 static void
print_param(sw_param_type type,sw_param p)135 print_param (sw_param_type type, sw_param p)
136 {
137 #define BUF_LEN 64
138   gchar buf[BUF_LEN];
139 
140   snprint_param (buf, BUF_LEN, type, p);
141   printf ("%s", buf);
142 #undef BUF_LEN
143 }
144 
145 void
print_param_set(sw_procedure * proc,sw_param_set pset)146 print_param_set (sw_procedure * proc, sw_param_set pset)
147 {
148   int i, j;
149   sw_param_spec * ps;
150   int valid_mask;
151 
152   printf ("\"%s\" has %d params.\n\n", proc->name, proc->nr_params);
153 
154   for (i=0; i < proc->nr_params; i++) {
155     ps = &proc->param_specs[i];
156     printf ("%d\t\"%s\" (\"%s\")\n", i, ps->name, ps->desc);
157     printf ("\tType: ");
158     print_type (ps->type);
159     printf ("\n");
160     if (ps->constraint_type == SW_PARAM_CONSTRAINED_NOT) {
161       printf ("\tUnconstrained.\n");
162     } else if (ps->constraint_type == SW_PARAM_CONSTRAINED_LIST) {
163       printf ("\tConstrained to ");
164       print_param (SWEEP_TYPE_INT, ps->constraint.list[0]);
165       printf (" list values.");
166       for (j=1; j <= ps->constraint.list[0].i; j++) {
167 	printf ("\n\t");
168 	print_param (ps->type, ps->constraint.list[j]);
169       }
170       printf ("\n");
171     } else if (ps->constraint_type == SW_PARAM_CONSTRAINED_RANGE) {
172       valid_mask = ps->constraint.range->valid_mask;
173 
174       if (valid_mask & SW_RANGE_LOWER_BOUND_VALID) {
175 	printf ("\tBounded below by ");
176 	print_param (ps->type, ps->constraint.range->lower);
177 	printf ("\n");
178       }
179       if (valid_mask & SW_RANGE_UPPER_BOUND_VALID) {
180 	printf ("\tBounded above by ");
181 	print_param (ps->type, ps->constraint.range->upper);
182 	printf ("\n");
183       }
184       if (valid_mask & SW_RANGE_STEP_VALID) {
185 	printf ("\tValues quantised by ");
186 	print_param (ps->type, ps->constraint.range->step);
187 	printf ("\n");
188       }
189     }
190     printf ("\tCURRENT VALUE ");
191     print_param (ps->type, pset[i]);
192     printf ("\n");
193   }
194 }
195 
196 typedef enum {
197   SW_PS_TOGGLE_BUTTON,
198   SW_PS_KNOWN_PARAM,
199   SW_PS_ADJUSTMENT
200 } sw_ps_widget_t;
201 
202 typedef struct _sw_ps_widget sw_ps_widget;
203 typedef struct _sw_ps_adjuster sw_ps_adjuster;
204 
205 struct _sw_ps_widget {
206   sw_ps_widget_t type;
207   union {
208     GtkWidget * toggle_button;
209     sw_param * known_param;
210     GtkObject * adjustment;
211   } w;
212 };
213 
214 struct _sw_ps_adjuster {
215   sw_procedure * proc;
216   sw_view * view;
217   sw_param_set pset;
218   GtkWidget * window;
219   GtkWidget * scrolled;
220   GtkWidget * table;
221   sw_ps_widget * widgets;
222   GList * plsk_list;
223 };
224 
225 static sw_ps_adjuster *
ps_adjuster_new(sw_procedure * proc,sw_view * view,sw_param_set pset,GtkWidget * window)226 ps_adjuster_new (sw_procedure * proc, sw_view * view, sw_param_set pset,
227 		 GtkWidget * window)
228 {
229   sw_ps_adjuster * ps;
230 
231   ps = g_malloc (sizeof (*ps));
232 
233   ps->proc = proc;
234   ps->view = view;
235   ps->pset = pset;
236   ps->window = window;
237 
238   ps->scrolled = NULL;
239   ps->table = NULL;
240 
241   ps->widgets = g_malloc (sizeof (sw_ps_widget) * proc->nr_params);
242   ps->plsk_list = NULL;
243 
244   return ps;
245 }
246 
247 static void
ps_adjuster_destroy(sw_ps_adjuster * ps)248 ps_adjuster_destroy (sw_ps_adjuster * ps)
249 {
250 #if 0 /* XXX */
251   GList * gl;
252 
253   g_free (ps->pset);
254 
255   for (gl = ps->plsk_list; gl; gl = gl->next) {
256     g_free (gl->data);
257   }
258 #endif
259 }
260 
261 static void
get_param_values(sw_procedure * proc,sw_param_set pset,sw_ps_widget * widgets)262 get_param_values (sw_procedure * proc, sw_param_set pset, sw_ps_widget * widgets)
263 {
264   gint i;
265   sw_param_spec * pspec;
266   gfloat value;
267 
268   for (i=0; i < proc->nr_params; i++) {
269     pspec = &proc->param_specs[i];
270 
271     switch (widgets[i].type) {
272     case SW_PS_TOGGLE_BUTTON:
273       /* Assume boolean */
274       pset[i].b = gtk_toggle_button_get_active
275 	(GTK_TOGGLE_BUTTON(widgets[i].w.toggle_button));
276       break;
277     case SW_PS_KNOWN_PARAM:
278       param_copy (widgets[i].w.known_param, &pset[i]);
279       break;
280     case SW_PS_ADJUSTMENT:
281       value = GTK_ADJUSTMENT(widgets[i].w.adjustment)->value;
282       switch (pspec->type) {
283       case SWEEP_TYPE_BOOL:
284 	pset[i].b = (value == 0.0);
285 	break;
286       case SWEEP_TYPE_INT:
287 	pset[i].i = (sw_int)(value);
288 	break;
289       case SWEEP_TYPE_FLOAT:
290 	pset[i].f = (sw_float)(value);
291 	break;
292       default:
293 
294 	g_assert_not_reached ();
295 
296 	/* pset[i].i = 0; */
297 	break;
298       }
299       break;
300     default:
301       break;
302     }
303   }
304 }
305 
306 /*
307  * Callback for OK button of param_set_adjuster
308  */
309 static void
param_set_apply_cb(GtkWidget * widget,gpointer data)310 param_set_apply_cb (GtkWidget * widget, gpointer data)
311 {
312   sw_ps_adjuster * ps = (sw_ps_adjuster *)data;
313 
314   get_param_values (ps->proc, ps->pset, ps->widgets);
315 
316 #ifdef DEBUG
317   print_param_set (ps->proc, ps->pset);
318 #endif
319 
320   if (ps->proc->apply) {
321     ps->proc->apply (ps->view->sample,
322 		     ps->pset, ps->proc->custom_data);
323   }
324 
325   gtk_widget_destroy (ps->window);
326 
327   ps_adjuster_destroy (ps);
328 }
329 
330 /*
331  * Callback for Cancel button of param_set_adjuster
332  */
333 static void
param_set_cancel_cb(GtkWidget * widget,gpointer data)334 param_set_cancel_cb (GtkWidget * widget, gpointer data)
335 {
336   sw_ps_adjuster * ps = (sw_ps_adjuster *)data;
337 
338   gtk_widget_destroy (ps->window);
339 
340   ps_adjuster_destroy (ps);
341 }
342 
343 typedef struct _sw_pl_set_known sw_pl_set_known;
344 
345 struct _sw_pl_set_known {
346   sw_param ** p1;
347   sw_param * p2;
348 };
349 
350 /*
351  * Callback for setting known parameters from lists
352  */
353 static void
param_list_set_known_cb(GtkWidget * widget,gpointer data)354 param_list_set_known_cb (GtkWidget * widget, gpointer data)
355 {
356   sw_pl_set_known * plsk = (sw_pl_set_known *)data;
357 
358   *(plsk->p1) = plsk->p2;
359 }
360 
361 static GtkWidget *
create_param_set_table(sw_ps_adjuster * ps)362 create_param_set_table (sw_ps_adjuster * ps)
363 {
364   gint i, j;
365 
366   sw_procedure * proc = ps->proc;
367   sw_param_set pset = ps->pset;
368 
369   sw_param_spec * pspec;
370   sw_pl_set_known * plsk;
371   gint nr_options;
372   int valid=0;
373 
374 #define BUF_LEN 64
375   gchar buf[BUF_LEN];
376 
377   GtkWidget * table;
378   GtkWidget * hbox;
379   GtkWidget * label;
380   GtkWidget * optionmenu;
381   GtkWidget * menu;
382   GtkWidget * menuitem;
383   GtkWidget * checkbutton;
384   GtkWidget * num_widget; /* numeric input widget: hscale or spinbutton */
385 
386   GtkObject * adj;
387   gfloat value, lower, upper, step_inc, page_inc, page_size;
388   gint digits = 1; /* nr. of decimal places to show on hscale */
389 
390   table = gtk_table_new (proc->nr_params, 2, FALSE);
391 
392   for (i=0; i < proc->nr_params; i++) {
393     pspec = &proc->param_specs[i];
394 
395     if (pspec->type == SWEEP_TYPE_BOOL) {
396 
397       checkbutton = gtk_check_button_new_with_label (_(pspec->name));
398       gtk_table_attach (GTK_TABLE (table), checkbutton, 0, 2, i, i+1,
399 			GTK_FILL, GTK_FILL, 0, 0);
400 
401       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton),
402 				    pset[i].b);
403 
404       gtk_widget_show (checkbutton);
405 
406       ps->widgets[i].type = SW_PS_TOGGLE_BUTTON;
407       ps->widgets[i].w.toggle_button = checkbutton;
408 
409       /* YYY: yes, the naming seems inconsistent. GtkToggleButton is
410        * the parent class of GtkCheckButton
411        */
412 
413     } else {
414 
415       hbox = gtk_hbox_new (FALSE, 0);
416       gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, i, i+1,
417 			GTK_FILL|GTK_SHRINK, GTK_SHRINK, 4, 4);
418       gtk_widget_show (hbox);
419 
420       label = gtk_label_new (_(pspec->name));
421       gtk_box_pack_end (GTK_BOX(hbox), label, FALSE, FALSE, 4);
422       gtk_widget_show (label);
423 
424       if (pspec->constraint_type == SW_PARAM_CONSTRAINED_LIST) {
425 
426 	optionmenu = gtk_option_menu_new ();
427 	gtk_table_attach (GTK_TABLE (table), optionmenu, 1, 2, i, i+1,
428 			  GTK_FILL|GTK_EXPAND, GTK_SHRINK, 0, 0);
429 	gtk_widget_show (optionmenu);
430 
431 	menu = gtk_menu_new ();
432 
433 	ps->widgets[i].w.known_param = &pset[i];
434 
435 	nr_options = pspec->constraint.list[0].i;
436 	plsk = g_malloc (sizeof (sw_pl_set_known) * nr_options);
437 
438 	ps->plsk_list = g_list_append (ps->plsk_list, plsk);
439 
440 	for (j=0; j < nr_options; j++) {
441 	  plsk[j].p1 = &ps->widgets[i].w.known_param;
442 	  plsk[j].p2 = &pspec->constraint.list[j+1];
443 
444 	  snprint_param (buf, BUF_LEN, pspec->type,
445 			 pspec->constraint.list[j+1]);
446 
447 	  menuitem = gtk_menu_item_new_with_label (buf);
448 	  gtk_menu_append (GTK_MENU(menu), menuitem);
449 	  gtk_widget_show (menuitem);
450 
451           g_signal_connect (G_OBJECT(menuitem), "activate",
452             G_CALLBACK(param_list_set_known_cb), &plsk[j]);
453 
454 	  if (!param_cmp (pspec->type, pspec->constraint.list[j+1], pset[i])) {
455 	    gtk_option_menu_set_history (GTK_OPTION_MENU(optionmenu), j);
456 	    ps->widgets[i].w.known_param = &pspec->constraint.list[j+1];
457 	  }
458 	}
459 
460 	gtk_option_menu_set_menu (GTK_OPTION_MENU(optionmenu), menu);
461 
462 	ps->widgets[i].type = SW_PS_KNOWN_PARAM;
463 
464 
465 #define ADJUSTER_NUMERIC(T, DIGITS) \
466                                                                            \
467 	value = (gfloat) pset[i].T;                                        \
468                                                                            \
469         if (pspec->constraint_type == SW_PARAM_CONSTRAINED_NOT) {          \
470           valid = 0;                                                       \
471         } else if (pspec->constraint_type == SW_PARAM_CONSTRAINED_RANGE) { \
472           valid = pspec->constraint.range->valid_mask;                     \
473         }                                                                  \
474 	                                                                   \
475 	if (valid & SW_RANGE_LOWER_BOUND_VALID) {                          \
476 	  lower = (gfloat) pspec->constraint.range->lower.T;               \
477 	} else {                                                           \
478 	  lower = G_MINFLOAT;                                              \
479 	}                                                                  \
480 	                                                                   \
481 	if (valid & SW_RANGE_UPPER_BOUND_VALID) {                          \
482 	  upper = (gfloat) pspec->constraint.range->upper.T;               \
483 	} else {                                                           \
484 	  upper = G_MAXFLOAT;                                              \
485 	}                                                                  \
486 	                                                                   \
487 	if (valid & SW_RANGE_STEP_VALID) {                                 \
488 	  step_inc = (gfloat) pspec->constraint.range->step.T;             \
489 	} else if (lower != G_MINFLOAT && upper != G_MAXFLOAT) {           \
490           step_inc = (upper - lower) / 100.0;                              \
491         } else {                                                           \
492 	  step_inc = (gfloat) 0.01;                                        \
493 	}                                                                  \
494 	page_inc = step_inc;                                               \
495 	page_size = step_inc;                                              \
496         if (step_inc < 1.0)                                                \
497           digits = - (gint)ceil(log10((double)step_inc));                  \
498         else                                                               \
499           digits = 1;                                                      \
500                                                                            \
501 	adj = gtk_adjustment_new (value, lower, upper, step_inc,           \
502 				  page_inc, page_size);                    \
503                                                                            \
504 	if ( (valid & SW_RANGE_LOWER_BOUND_VALID) &&                       \
505 	     (valid & SW_RANGE_UPPER_BOUND_VALID)) {                       \
506           GTK_ADJUSTMENT(adj)->upper += step_inc;                          \
507 	  num_widget = gtk_hscale_new (GTK_ADJUSTMENT(adj));               \
508           gtk_scale_set_digits (GTK_SCALE(num_widget), digits);            \
509           gtk_widget_set_size_request (num_widget, 75, -1);                       \
510 	  gtk_table_attach (GTK_TABLE (table), num_widget, 1, 2, i, i+1,   \
511 			    GTK_FILL|GTK_EXPAND, GTK_SHRINK, 0, 0);        \
512 	} else {                                                           \
513 	  num_widget = gtk_spin_button_new (GTK_ADJUSTMENT(adj),           \
514 					    10.0, /* climb_rate */         \
515 					    (DIGITS)/* digits */           \
516 					    );                             \
517           gtk_spin_button_set_numeric (GTK_SPIN_BUTTON(num_widget), TRUE); \
518           gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON(num_widget),  \
519                                          TRUE);                            \
520           gtk_widget_set_size_request (num_widget, 75, -1);                       \
521 	  gtk_table_attach (GTK_TABLE (table), num_widget, 1, 2, i, i+1,   \
522 			    GTK_FILL|GTK_EXPAND, GTK_SHRINK, 0, 0);        \
523 	}                                                                  \
524                                                                            \
525 	gtk_widget_show (num_widget);                                      \
526         ps->widgets[i].type = SW_PS_ADJUSTMENT;                            \
527         ps->widgets[i].w.adjustment = adj;
528 
529       } else if (pspec->type == SWEEP_TYPE_INT) {
530 	ADJUSTER_NUMERIC(i, 0);
531       } else if (pspec->type == SWEEP_TYPE_FLOAT) {
532 	ADJUSTER_NUMERIC(f, 3);
533       }
534     }
535   }
536 
537   return table;
538 
539 #undef BUF_LEN
540 }
541 
542 /*
543  * Callback for Suggest button of param_set_adjuster
544  */
545 static void
param_set_suggest_cb(GtkWidget * widget,gpointer data)546 param_set_suggest_cb (GtkWidget * widget, gpointer data)
547 {
548   sw_ps_adjuster * ps = (sw_ps_adjuster *)data;
549 
550   GtkWidget * table;
551 
552   if (ps->proc->suggest) {
553     ps->proc->suggest (ps->view->sample,
554 		       ps->pset, ps->proc->custom_data);
555   }
556 
557   gtk_widget_destroy (ps->table);
558 
559   table = create_param_set_table (ps);
560   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (ps->scrolled),
561 					 table);
562   gtk_widget_show (table);
563 
564   ps->table = table;
565 }
566 
567 gint
create_param_set_adjuster(sw_procedure * proc,sw_view * view,sw_param_set pset)568 create_param_set_adjuster (sw_procedure * proc, sw_view * view,
569 			   sw_param_set pset)
570 {
571   sw_ps_adjuster * ps;
572   GtkWidget * window;
573   GtkWidget * main_vbox;
574   GtkWidget * pixmap;
575   GtkWidget * label;
576   GtkWidget * scrolled;
577   GtkWidget * ebox;
578   GtkWidget * hbox;
579   GtkWidget * vbox;
580   GtkWidget * table;
581   GtkWidget * frame;
582   GtkWidget * button, * ok_button;
583 
584   /* Place the meta info about the plugin in a text widget (white background)
585    *  aligned to the left of the parameter settings by defining _USE_TEXT
586    */
587 /*#define _USE_TEXT*/
588 
589 #ifdef _USE_TEXT
590   GtkWidget * text;
591 
592 #define BUF_LEN 1024
593   gchar buf[BUF_LEN];
594   gint n;
595 
596 #endif /* _USE_TEXT */
597 
598   window = gtk_dialog_new ();
599   gtk_window_set_title (GTK_WINDOW(window), _(proc->name));
600   /*  gtk_container_border_width (GTK_CONTAINER (window), 8);*/
601 
602   ps = ps_adjuster_new (proc, view, pset, window);
603 
604   g_signal_connect (G_OBJECT(window), "destroy",
605 		      G_CALLBACK(param_set_cancel_cb), ps);
606 
607 #ifdef _USE_TEXT
608   hbox = gtk_hbox_new (FALSE, 0);
609   gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->vbox), hbox, TRUE, TRUE, 0);
610   gtk_widget_show (hbox);
611 
612   text = gtk_text_new (NULL, NULL);
613   gtk_text_set_editable (GTK_TEXT (text), FALSE);
614   gtk_text_set_word_wrap (GTK_TEXT (text), FALSE);
615   gtk_widget_set_size_request (text, 320, -1);
616   gtk_box_pack_start (GTK_BOX (hbox), text, FALSE, FALSE, 0);
617   gtk_widget_show (text);
618 
619   main_vbox = gtk_vbox_new (FALSE, 0);
620   gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0);
621   gtk_widget_show (main_vbox);
622 
623   vbox = main_vbox;
624 
625   gtk_text_freeze (GTK_TEXT (text));
626 
627 #else
628 
629   main_vbox = GTK_DIALOG(window)->vbox;
630 
631   ebox = gtk_event_box_new ();
632   gtk_box_pack_start (GTK_BOX(main_vbox), ebox, FALSE, FALSE, 0);
633   gtk_widget_set_style (ebox, style_bw);
634   gtk_widget_show (ebox);
635 
636   hbox = gtk_hbox_new (FALSE, 0);
637   gtk_container_add (GTK_CONTAINER(ebox), hbox);
638   gtk_container_set_border_width (GTK_CONTAINER(hbox), 4);
639   gtk_widget_show (hbox);
640 
641   pixmap = create_widget_from_xpm (window, ladlogo_xpm);
642   gtk_box_pack_start (GTK_BOX(hbox), pixmap, FALSE, FALSE, 0);
643   gtk_widget_show (pixmap);
644 
645   vbox = gtk_vbox_new (FALSE, 0);
646   gtk_box_pack_start (GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
647   gtk_widget_show (vbox);
648 
649 
650 #endif
651 
652   if (proc->name != NULL) {
653 
654 #ifdef _USE_TEXT
655 /*
656  * font =
657  * gdk_font_load("-Adobe-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*");
658  *
659  * n = snprintf (buf, BUF_LEN, "%s\n\n", _(proc->name));
660  * gtk_text_insert (GTK_TEXT (text), font, NULL, NULL, buf, n);
661  */
662 #else
663 
664 /* pangoise?
665  *
666  * style = gtk_style_new ();
667  * gdk_font_unref (style->font);
668  * style->font =
669  * gdk_font_load("-adobe-helvetica-medium-r-normal-*-*-180-*-*-*-*-*-*");
670  * gtk_widget_push_style (style);
671  */
672     label = gtk_label_new (_(proc->name));
673     gtk_misc_set_padding (GTK_MISC (label), 10, 10);
674     gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
675     gtk_widget_show (label);
676 
677 /*  gtk_widget_pop_style ();*/
678 
679 #endif
680   }
681 
682 #ifdef _USE_TEXT
683   n = 0;
684 
685   if (proc->description != NULL) {
686     n = snprintf (buf, BUF_LEN, "%s\n\n", _(proc->description));
687   }
688 
689   if (proc->author != NULL) {
690     n += snprintf (buf+n, BUF_LEN, "by %s", proc->author);
691   }
692 
693   if (proc->copyright != NULL) {
694     n += snprintf (buf+n, BUF_LEN, ", %s.\n", proc->copyright);
695   }
696 
697   if (proc->url != NULL) {
698     n += snprintf (buf+n, BUF_LEN, "\nFor more information see\n%s\n",
699 		   proc->url);
700   }
701 
702   if (n > 0) {
703     gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, buf, n);
704   }
705 
706   gtk_text_thaw (GTK_TEXT (text));
707 
708 #else
709   if (proc->description != NULL) {
710     label = gtk_label_new (_(proc->description));
711     gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
712     gtk_widget_show (label);
713   }
714 
715   if (proc->author != NULL) {
716     label = gtk_label_new (proc->author);
717     gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
718     gtk_widget_show (label);
719   }
720 
721   if (proc->copyright != NULL) {
722     label = gtk_label_new (proc->copyright);
723     gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
724     gtk_widget_show (label);
725   }
726 
727   if (proc->url != NULL) {
728     label = gtk_label_new (proc->url);
729     gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
730     gtk_widget_show (label);
731   }
732 #endif
733 
734   hbox = gtk_hbox_new (FALSE, 0);
735   gtk_box_pack_start (GTK_BOX(main_vbox), hbox, TRUE, TRUE, 8);
736   gtk_widget_show (hbox);
737 
738   frame = gtk_frame_new (_("Parameters"));
739   gtk_box_pack_start (GTK_BOX(hbox), frame, TRUE, TRUE, 8);
740   gtk_widget_show (frame);
741 
742   vbox = gtk_vbox_new (FALSE, 4);
743   gtk_container_add (GTK_CONTAINER (frame), vbox);
744   gtk_container_set_border_width (GTK_CONTAINER(vbox), 8);
745   gtk_widget_show (vbox);
746 
747   button = gtk_button_new_with_label (_("Defaults"));
748   gtk_box_pack_start (GTK_BOX(vbox), button, FALSE, FALSE, 8);
749   gtk_widget_show (button);
750   g_signal_connect (G_OBJECT(button), "clicked",
751 		      G_CALLBACK (param_set_suggest_cb), ps);
752 
753   scrolled = gtk_scrolled_window_new (NULL, NULL);
754   gtk_widget_set_size_request (scrolled, -1, 240);
755   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
756 				  GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
757   gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 8);
758   gtk_widget_show (scrolled);
759 
760   table = create_param_set_table (ps);
761   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled),
762 					 table);
763   gtk_widget_show (table);
764 
765   ps->scrolled = scrolled;
766   ps->table = table;
767 
768 #if 0
769   frame = gtk_frame_new (_("Preview"));
770   gtk_box_pack_start (GTK_BOX(hbox), frame, TRUE, TRUE, 8);
771   gtk_widget_show (frame);
772 
773   vbox = gtk_vbox_new (FALSE, 4);
774   gtk_container_add (GTK_CONTAINER (frame), vbox);
775   gtk_container_set_border_width (GTK_CONTAINER(vbox), 8);
776   gtk_widget_show (vbox);
777 #endif
778 
779   ok_button = gtk_button_new_with_label (_("OK"));
780   GTK_WIDGET_SET_FLAGS (GTK_WIDGET (ok_button), GTK_CAN_DEFAULT);
781   gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->action_area), ok_button,
782 		      TRUE, TRUE, 0);
783   gtk_widget_show (ok_button);
784   g_signal_connect (G_OBJECT(ok_button), "clicked",
785 		      G_CALLBACK (param_set_apply_cb), ps);
786 
787 
788   button = gtk_button_new_with_label (_("Cancel"));
789   GTK_WIDGET_SET_FLAGS (GTK_WIDGET (button), GTK_CAN_DEFAULT);
790   gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->action_area), button,
791 		      TRUE, TRUE, 0);
792   gtk_widget_show (button);
793   g_signal_connect (G_OBJECT(button), "clicked",
794 		      G_CALLBACK (param_set_cancel_cb), ps);
795 
796   gtk_widget_grab_default (ok_button);
797 
798   gtk_widget_show (window);
799 
800   return 1;
801 }
802