1 /* utils.c - Personal utilities for Gtk+ development
2 *
3 * Copyright (C) 2000 - 2010 Patrice St-Gelais
4 * patrstg@users.sourceforge.net
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 #include "utils.h"
22 #include "x_alloc.h"
23 #include <string.h>
24 #include <ctype.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <sys/stat.h>
31 #include "../icons/attention.xpm"
32 #include "../icons/bombe.xpm"
33 #include "../icons/fleur.xpm"
34 #include "../icons/peur.xpm"
35 #include "../icons/info.xpm"
36 #include "../icons/downarrow.xpm"
37 #include "../icons/uparrow.xpm"
38
39
swap_buffers(gpointer * a,gpointer * b)40 void swap_buffers (gpointer *a, gpointer *b) {
41 gpointer c;
42 c = *a;
43 *a = *b;
44 *b = c;
45 }
order_int(gint * i1,gint * i2)46 void order_int (gint *i1, gint *i2) {
47 // Order 2 integers so that i2 > i1
48 gint i;
49 if ((*i2)>=(*i1))
50 return;
51 i = *i2;
52 *i2 = *i1;
53 *i1 = i;
54 return;
55 }
56
gint_adj_callb(GtkWidget * wdg,gpointer data)57 gint gint_adj_callb (GtkWidget *wdg, gpointer data) {
58 *((gint *) data) = (gint) GTK_ADJUSTMENT(wdg)->value;
59 return FALSE;
60 }
61
gdouble_adj_callb(GtkWidget * wdg,gpointer data)62 gint gdouble_adj_callb (GtkWidget *wdg, gpointer data) {
63 *((gdouble *) data) = (gdouble) GTK_ADJUSTMENT(wdg)->value;
64 return FALSE;
65 }
66
gfloat_adj_callb(GtkWidget * wdg,gpointer data)67 gint gfloat_adj_callb (GtkWidget *wdg, gpointer data) {
68 *((gfloat *) data) = (gfloat) GTK_ADJUSTMENT(wdg)->value;
69 return FALSE;
70 }
71
gboolean_set_true(GtkWidget * wdg,gpointer data)72 gint gboolean_set_true (GtkWidget *wdg, gpointer data) {
73 *((gboolean *) data) = TRUE;
74 return FALSE;
75 }
76
gboolean_set_false(GtkWidget * wdg,gpointer data)77 gint gboolean_set_false (GtkWidget *wdg, gpointer data) {
78 *((gboolean *) data) = FALSE;
79 return FALSE;
80 }
81
gboolean_set_false_event(GtkWidget * wdg,GdkEventButton * event,gpointer data)82 gint gboolean_set_false_event (GtkWidget *wdg, GdkEventButton *event, gpointer data) {
83 *((gboolean *) data) = FALSE;
84 return FALSE;
85 }
86
gboolean_set_true_event(GtkWidget * wdg,GdkEventButton * event,gpointer data)87 gint gboolean_set_true_event (GtkWidget *wdg, GdkEventButton *event, gpointer data) {
88 *((gboolean *) data) = TRUE;
89 return FALSE;
90 }
91
92
zero_callb(GtkWidget * wdg,gpointer adj)93 void zero_callb (GtkWidget *wdg, gpointer adj) {
94 // Resets any scale adjustment to 0
95 if (!GTK_IS_ADJUSTMENT(adj))
96 return;
97 gtk_adjustment_set_value(GTK_ADJUSTMENT(adj), 0.0);
98 }
99
toggle_check_button_callb(GtkWidget * checkbutton,gpointer data)100 gint toggle_check_button_callb (GtkWidget *checkbutton, gpointer data) {
101 // printf("DATA in toggle_check_button_callb: %p\n",data);
102 if (GTK_TOGGLE_BUTTON(checkbutton)->active) {
103 *((gboolean *) data) = TRUE;
104 }
105 else
106 *((gboolean *) data) = FALSE;
107 return FALSE;
108 }
109
hide_callb(GtkWidget * wdg,gpointer data)110 void hide_callb(GtkWidget *wdg, gpointer data) {
111 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
112 return;
113 gtk_widget_hide(GTK_WIDGET(data));
114 }
show_callb(GtkWidget * wdg,gpointer data)115 void show_callb(GtkWidget *wdg, gpointer data) {
116 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
117 return;
118 gtk_widget_show(GTK_WIDGET(data));
119 }
set_flag_hide(GtkWidget * wdg,gpointer show_flag)120 void set_flag_hide(GtkWidget *wdg, gpointer show_flag) {
121 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
122 return;
123 *((gboolean *) show_flag) = FALSE;
124 }
set_flag_show(GtkWidget * wdg,gpointer show_flag)125 void set_flag_show(GtkWidget *wdg, gpointer show_flag) {
126 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg)))
127 return;
128 *((gboolean *) show_flag) = TRUE;
129 }
130
hideshow_dialog_new(GtkWidget * window,GtkOrientation orient,GtkWidget * wdg,gboolean * flag)131 GtkWidget *hideshow_dialog_new(GtkWidget *window,
132 GtkOrientation orient,
133 GtkWidget *wdg,
134 gboolean *flag) {
135 // Generates a toolbar allowing to hide / show a widget
136 // "wdg" is the widget to show/hide
137 GtkWidget *toolbar, *button1, *button2;
138 toolbar = gtk_toolbar_new();
139 gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar),orient);
140 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),GTK_TOOLBAR_ICONS);
141 gtk_widget_show(GTK_WIDGET(toolbar));
142
143 button1 = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
144 GTK_TOOLBAR_CHILD_RADIOBUTTON,NULL,_("Show"),
145 _("Show the dialog"), NULL,
146 create_widget_from_xpm(window,downarrow_xpm),
147 GTK_SIGNAL_FUNC(show_callb),wdg);
148
149 button2 = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar),
150 GTK_TOOLBAR_CHILD_RADIOBUTTON,button1,_("Hide"),
151 _("Hide the dialog"), NULL,
152 create_widget_from_xpm(window,uparrow_xpm),
153 GTK_SIGNAL_FUNC(hide_callb),wdg);
154 if (flag) {
155 gtk_signal_connect ( GTK_OBJECT (button1),
156 "toggled",
157 GTK_SIGNAL_FUNC(set_flag_show),
158 (gpointer) flag);
159 gtk_signal_connect ( GTK_OBJECT (button2),
160 "toggled",
161 GTK_SIGNAL_FUNC(set_flag_hide),
162 (gpointer) flag);
163 if (*flag) {
164 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button1),TRUE);
165 show_callb(button1, (gpointer) wdg);
166 }
167 else {
168 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button2),TRUE);
169 hide_callb(button2, (gpointer) wdg);
170 }
171 }
172 return toolbar;
173 }
174
print_list(GList * list)175 void print_list (GList *list) {
176 GList *node;
177 gint i = 0;
178 for (node = g_list_first(list); node; node = node->next)
179 printf("(%d) prev: %p; CURRENT: %p; next: %p\n",
180 ++i, (node->prev)?node->prev->data:NULL,
181 node->data, (node->next)?node->next->data:NULL);
182 }
183
emit_expose_event(GtkWidget * window)184 void emit_expose_event (GtkWidget *window) {
185 // Emit an expose event on a widget (typically a window)
186 // Kind of dummy event, allowing testing of document updates
187 static GdkEventExpose event;
188 static gint w, h;
189 if ( ! window)
190 return;
191 if ( ! GDK_IS_WINDOW(window->window) )
192 return;
193 gdk_window_get_geometry (window->window, NULL, NULL, &w, &h, NULL);
194 event.type = GDK_EXPOSE;
195 event.window = window->window;
196 event.send_event = FALSE;
197 event.area.x = 0;
198 event.area.y = 0;
199 event.area.width = w;
200 event.area.height = h;
201 event.count = 0;
202 // Change for GTK2
203 // gtk_widget_event(window, (GdkEvent *) &event);
204 gdk_window_invalidate_rect (event.window, &event.area , TRUE);
205 }
206
directory_exists(char * directory_name)207 int directory_exists (char *directory_name) {
208
209 // Check if directory_name exists using the stat command
210
211 struct stat *statres;
212 statres = (struct stat *) x_calloc(sizeof(struct stat),1, "struct stat (statres in directory_exists in utils.c)");
213 stat(directory_name, statres);
214 if (statres && S_ISDIR(statres->st_mode)) {
215 x_free(statres);
216 return TRUE;
217 }
218 else {
219 x_free(statres);
220 return FALSE;
221 }
222 }
223
filexists(char * file_name)224 int filexists(char *file_name) {
225 FILE *test;
226 if (!file_name) return FALSE;
227 test = fopen(file_name,"r");
228 if (test) {
229 fclose(test);
230 return TRUE;
231 }
232 else
233 return FALSE;
234 }
235
add_filesep(gchar * dname)236 gchar *add_filesep (gchar *dname) {
237 // Add a separator at the end of a dir name, if it's absent
238 // Returns a new pointer if a separator is added, otherwise returns the same pointer
239 // The calling function must free the old pointer, if required
240
241 gint i;
242 gchar *buf;
243 i = strlen(dname)-1;
244 while ((dname[i]==' ') && (i>0)) i--; // Remove spaces
245 if (!dname)
246 return dname;
247 if (dname[i] == FILESEP)
248 return dname;
249 buf = (gchar *) x_malloc(strlen(dname)+2, "gchar (buf in add_filesep in utils.c)");
250 strcpy(buf,dname);
251 buf[i+1]= FILESEP ;
252 buf[i+2]='\0';
253 return buf;
254 }
255
concat_dname_fname(gchar * dname,gchar * fname)256 gchar *concat_dname_fname (gchar *dname, gchar *fname) {
257 // Written for catenating a dir name and a file name, but can be used in other contexts
258 // Add a separator at the end of dname if it doesn't exist
259 gchar *buf;
260 gint sep=0,i;
261 i = strlen(dname)-1;
262 while ((dname[i]==' ') && (i>0)) i--; // Remove spaces
263 if (dname) {
264 if (dname[i]!= FILESEP) sep=1;
265 buf = (gchar *) x_malloc(strlen(dname)+strlen(fname)+1+sep, "gchar (buf in concat_dname_fname)");
266 strcpy(buf,dname);
267 if (sep) {
268 buf[i+1]= FILESEP ;
269 buf[i+2]='\0';
270 }
271 strcat(buf, fname);
272 }
273 else {
274 buf = (gchar *) x_malloc(strlen(fname)+1, "gchar (buf in concat_dname_fname)");
275 strcpy(buf, fname);
276 }
277 return buf;
278 }
279
split_dir_file(gchar * path_n_file,gchar ** dname,gchar ** fname,gchar sep)280 void split_dir_file (gchar *path_n_file, gchar **dname, gchar **fname, gchar sep) {
281 // Splits a path into a file name and a directory name, given the separator
282 // Creates new strings if a path is found,
283 // otherwise returns the original string in the file address
284 gchar *separator;
285 separator = (gchar *) strrchr(path_n_file, sep);
286 if (separator) {
287 (*fname) = (gchar *) x_malloc(strlen(separator)+1, "gchar (fname in split_dir_file)");
288 strcpy((*fname), separator+1);
289 (*dname) = (gchar *) x_malloc(separator+2-path_n_file, "gchar (dname in split_dir_file)");
290 strncpy((*dname), path_n_file, separator+1-path_n_file);
291 (*dname)[separator+1-path_n_file] = '\0';
292 }
293 else {
294 (*fname) = path_n_file;
295 (*dname) = NULL;
296 }
297 }
298
get_dir_name(gchar * path_n_file,gchar sep)299 gchar *get_dir_name(gchar *path_n_file, gchar sep) {
300 // Copy the dir name from path_n_file
301 // If no separator found, returns NULL
302 gchar *separator, *dname;
303 separator = (gchar *) strrchr(path_n_file, sep);
304 if (separator) {
305 dname = (gchar *) x_malloc(separator+2-path_n_file, "gchar (dname in get_dir_name)");
306 strncpy(dname, path_n_file, separator+1-path_n_file);
307 dname[separator+1-path_n_file] = '\0';
308 }
309 else
310 dname = NULL;
311 return dname;
312 }
313
get_file_name(gchar * path_n_file,gchar sep)314 gchar *get_file_name(gchar *path_n_file, gchar sep) {
315 // Copy the file name from path_n_file
316 // If no separator found, returns a new string with the path_n_file content
317 gchar *separator, *fname;
318 gint i;
319 separator = (gchar *) strrchr(path_n_file, sep);
320 if (separator) {
321 fname = (gchar *) x_malloc(strlen(separator)+1, "gchar (fname in get_file_name)");
322 strcpy(fname, separator+1);
323 }
324 else
325 {
326 fname = (gchar *) x_malloc(strlen(path_n_file)+1,"gchar (fname in get_file_name)" );
327 memcpy(fname, path_n_file, strlen(path_n_file)+1);
328 }
329 // Remove spaces at the end
330 i = strlen(fname)-1;
331 while ((fname[i]==' ') && (i>0)) i--;
332 fname[i+1]='\0';
333 fname = (gchar *) x_realloc(fname,1+strlen(fname), "gchar (fname - realloc in get_file_name)");
334 return fname;
335 }
336
init_default_dir()337 char* init_default_dir() {
338 // Default dir is $HOME or "" otherwise
339 // This function can be used to initialize the global variable
340 // "default_dir" declared in utils.h, or to initialize a local variable
341 // with the returned string
342 char *buf;
343 if (default_dir)
344 return default_dir;
345 buf = getenv("HOME");
346 if (!buf) {
347 default_dir = (char *) x_malloc(1, "gchar (default_dir in init_default_dir)");
348 strcpy(default_dir,"");
349 }
350 else {
351 default_dir = (char *) x_malloc(strlen(buf)+2, "gchar (default_dir in init_default_dir)");
352 strcpy(default_dir,buf);
353 strcat(default_dir,"/");
354 }
355 return default_dir;
356 }
357
create_widget_from_xpm(GtkWidget * reference_window,gchar ** data)358 GtkWidget *create_widget_from_xpm (GtkWidget *reference_window, gchar **data) {
359 // Less or more from Harlow's example
360 GdkBitmap *mask;
361 GdkPixmap *pm_data;
362 GtkWidget *pm_widget;
363 if (!data)
364 return (NULL);
365 if (GTK_IS_WIDGET(reference_window))
366 pm_data = gdk_pixmap_create_from_xpm_d (reference_window->window, &mask, NULL, (gchar **) data);
367 else
368 pm_data = gdk_pixmap_create_from_xpm_d (NULL, &mask, NULL, (gchar **) data);
369 pm_widget = gtk_pixmap_new(pm_data, mask);
370 gtk_widget_show(pm_widget);
371 return(pm_widget);
372 }
373
msg_callb1(GtkWidget * widget,int flag_exit)374 void msg_callb1(GtkWidget *widget,int flag_exit) {
375 if (flag_exit == ABORT) {
376 exit(0);
377 }
378 }
379
380
my_msg_subcall(gchar * message,int flag_exit,GtkWidget * dialog,GtkWidget * label1,GtkWidget * pixmap_widget,int if_vertical)381 void my_msg_subcall(gchar * message, int flag_exit, GtkWidget *dialog, GtkWidget *label1, GtkWidget *pixmap_widget, int if_vertical) {
382
383 GtkWidget *label2, *ok, *hbox, *vbox;
384 GMainLoop *loop;
385 loop = g_main_new(FALSE);
386 // To be sure the user sees the dialog, we display it in the center...
387 gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_CENTER);
388 // The message should be translated before calling my_msg
389 // Here we don't use gettext
390 // It could be a composed message created with sprintf, in that
391 // case it won't translate correctly here
392 label2 = gtk_label_new(message);
393 gtk_misc_set_padding(GTK_MISC(label1), 10, 10);
394 gtk_misc_set_padding(GTK_MISC(label2), 10, 10);
395 vbox = gtk_vbox_new(FALSE,10);
396 hbox = gtk_hbox_new(FALSE,10);
397 gtk_box_pack_start(GTK_BOX(vbox),label1, FALSE, FALSE, 0);
398 if (if_vertical)
399 gtk_box_pack_start(GTK_BOX(vbox), pixmap_widget, FALSE, FALSE, 0);
400 else
401 gtk_box_pack_start(GTK_BOX(hbox), pixmap_widget, FALSE, FALSE, 0);
402 gtk_box_pack_start(GTK_BOX(vbox),label2, FALSE, FALSE, 0);
403 gtk_box_pack_start(GTK_BOX(hbox),vbox, FALSE, FALSE, 0);
404 ok = gtk_button_new_with_label(_("OK"));
405 gtk_signal_connect_object(GTK_OBJECT(ok), "clicked",
406 GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
407 gtk_signal_connect_object(GTK_OBJECT(ok), "clicked",
408 GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
409 gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
410 GTK_SIGNAL_FUNC(msg_callb1), (void *)flag_exit);
411 gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
412 GTK_SIGNAL_FUNC(g_main_loop_quit), (void *) loop);
413 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),ok);
414 gtk_button_box_set_layout (GTK_BUTTON_BOX(GTK_DIALOG(dialog)->action_area), GTK_BUTTONBOX_SPREAD);
415 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
416 gtk_widget_show_all(dialog);
417 gtk_grab_add(dialog);
418 g_main_run (loop);
419 g_main_destroy(loop);
420 }
421
my_msg(gchar * message,gint flag_exit)422 void my_msg(gchar * message, gint flag_exit) {
423 GtkWidget *pixmap_widget, *label, *dialog;
424 dialog = gtk_dialog_new();
425 gtk_widget_realize(GTK_WIDGET(dialog));
426 switch (flag_exit) {
427 case WARNING:
428 label = gtk_label_new(_("WARNING!"));
429 pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),attention_xpm);
430 break;
431 case FAIL:
432 label = gtk_label_new(_("ERROR!"));
433 pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),peur_xpm);
434 break;
435 case ABORT:
436 label = gtk_label_new(_("FATAL ERROR! The program will abort"));
437 pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),bombe_xpm);
438 break;
439 case SORRY:
440 label = gtk_label_new(_("SORRY!"));
441 pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),fleur_xpm);
442 break;
443 case INFO:
444 label = gtk_label_new(_("INFORMATION"));
445 pixmap_widget = create_widget_from_xpm(GTK_WIDGET(dialog),info_xpm);
446 }
447 my_msg_subcall (message, flag_exit, dialog, label, pixmap_widget, FALSE);
448 }
449
my_msg_with_image(gchar * title,gchar * message,GtkWidget * pixmap_widget)450 void my_msg_with_image(gchar *title, gchar * message, GtkWidget *pixmap_widget) {
451
452 GtkWidget *label, *dialog;
453 dialog = gtk_dialog_new();
454 gtk_widget_realize(GTK_WIDGET(dialog));
455 label = gtk_label_new(_(title));
456 my_msg_subcall (message, INFO, dialog, label, pixmap_widget, TRUE);
457 }
458
modal_delete_callb(GtkWidget * dummy,GdkEvent * dummy_event,gpointer * args)459 gint modal_delete_callb (GtkWidget *dummy, GdkEvent *dummy_event, gpointer *args) {
460 // Kind of "wrapper" for callback OK/CANCEL after a delete window event
461 cb_args_struct *cb_args;
462 cb_args = (cb_args_struct *) args;
463 if (cb_args->callb_fn) {
464 (*cb_args->callb_fn) (dummy, cb_args->callb_data);
465 }
466 return TRUE;
467 }
468
469
modal_dialog_with_titles_window_provided(GtkWidget * window,GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gchar * ok_title,gint (* cancel_callb)(GtkWidget *,gpointer),gchar * cancel_title,gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)470 void modal_dialog_with_titles_window_provided (GtkWidget *window,
471 GtkWidget *wdg, gchar *title,
472 gint (*ok_callb) (GtkWidget*, gpointer),
473 gchar *ok_title,
474 gint (*cancel_callb) (GtkWidget *, gpointer),
475 gchar *cancel_title,
476 gpointer callb_data,
477 GtkWindowPosition pos,
478 gboolean if_ok_default) {
479
480 // See modal_dialog_with_titles for explanation
481 // Providing the window allows to connect to it events from the outer context.
482 // For instance, a click in a widget contained in "wdg" could destroy the window
483 GtkWidget *button, *okbox, *vbox;
484 GMainLoop *loop;
485 cb_args_struct *args;
486 args = (cb_args_struct *) x_malloc(sizeof(cb_args_struct), "cbs_args_struct (args in modal_dialog_with_titles_windows_provided)");
487 loop = g_main_new(FALSE);
488 // "title" is not translated here, see the explanations in "my_msg"
489 gtk_window_set_title (GTK_WINDOW (window), title);
490 if (pos)
491 gtk_window_set_position(GTK_WINDOW(window), pos);
492 gtk_widget_realize(GTK_WIDGET(window));
493
494 // Defines a vbox for containing from top to bottom: 1. "wdg"; 2. OK - Cancel
495 vbox = gtk_vbox_new(FALSE,0);
496 gtk_widget_show(GTK_WIDGET(vbox));
497
498 // OK / cancel buttons appear in a hbox at the bottom
499 okbox = gtk_hbox_new(FALSE,0);
500 gtk_widget_show(GTK_WIDGET(okbox));
501 button = gtk_button_new_with_label(_(ok_title));
502 gtk_widget_show(GTK_WIDGET(button));
503 gtk_container_set_border_width(GTK_CONTAINER(button),DEF_PAD);
504 if (ok_callb)
505 gtk_signal_connect(GTK_OBJECT(button), "clicked",
506 GTK_SIGNAL_FUNC(ok_callb), (gpointer) callb_data);
507
508 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
509 GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) window);
510
511 gtk_box_pack_start(GTK_BOX(okbox), button, FALSE, FALSE, DEF_PAD);
512
513 if (cancel_callb) {
514 button = gtk_button_new_with_label(_(cancel_title));
515
516 gtk_widget_show(GTK_WIDGET(button));
517
518 gtk_container_set_border_width(GTK_CONTAINER(button),DEF_PAD);
519
520 gtk_signal_connect(GTK_OBJECT(button), "clicked",
521 GTK_SIGNAL_FUNC(cancel_callb), (gpointer) callb_data);
522
523 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
524 GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) window);
525
526 gtk_box_pack_start(GTK_BOX(okbox), button, FALSE, FALSE, DEF_PAD);
527 }
528
529 if (if_ok_default)
530 // Closing the window means "OK";
531 args->callb_fn = ok_callb;
532 else
533 // Closing the window means "Cancel";
534 args->callb_fn = cancel_callb;
535
536 args->callb_data = callb_data;
537
538 gtk_signal_connect(GTK_OBJECT(window), "delete_event",
539 GTK_SIGNAL_FUNC(modal_delete_callb), (gpointer) args);
540
541 gtk_signal_connect_object(GTK_OBJECT(window), "destroy",
542 GTK_SIGNAL_FUNC(gtk_grab_remove), (gpointer) window);
543
544 gtk_signal_connect_object(GTK_OBJECT(window), "destroy",
545 GTK_SIGNAL_FUNC(g_main_loop_quit), (gpointer) loop);
546
547 gtk_box_pack_start(GTK_BOX(vbox), wdg, FALSE, FALSE, 0);
548 gtk_box_pack_start(GTK_BOX(vbox), align_widget(okbox,0.5,0.5), FALSE, FALSE, 0);
549 gtk_container_add(GTK_CONTAINER(window), vbox);
550
551 gtk_widget_show(GTK_WIDGET(window));
552 gtk_grab_add(window);
553
554 g_main_run (loop);
555
556 g_main_destroy(loop);
557 }
558
modal_dialog_with_titles(GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gchar * ok_title,gint (* cancel_callb)(GtkWidget *,gpointer),gchar * cancel_title,gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)559 void modal_dialog_with_titles (GtkWidget *wdg, gchar *title,
560 gint (*ok_callb) (GtkWidget*, gpointer),
561 gchar *ok_title,
562 gint (*cancel_callb) (GtkWidget *, gpointer),
563 gchar *cancel_title,
564 gpointer callb_data,
565 GtkWindowPosition pos,
566 gboolean if_ok_default) {
567
568 // Packs "wdg" in a modal window, with an OK and an optional cancel button
569 // Returns TRUE if OK, FALSE if CANCEL
570 // If cancel_callb is NULL, omit the cancel button
571 // If ok_callb is NULL, display an OK button with basic exit behavior
572 // "wdg" is usually a container packing peculiar controls / widgets
573 // "wdg" is destroyed with the window, so maybe the calling app should nullify it
574 // Note: closing the window means "OK" (calls the ok callback)
575 // All terminating events stop the main loop
576 GtkWidget *window;
577 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
578 modal_dialog_with_titles_window_provided (window, wdg, title, ok_callb,
579 ok_title, cancel_callb, cancel_title, callb_data, pos, if_ok_default);
580 }
581
modal_dialog(GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gint (* cancel_callb)(GtkWidget *,gpointer),gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)582 void modal_dialog(GtkWidget *wdg, gchar *title,
583 gint (*ok_callb) (GtkWidget*, gpointer),
584 gint (*cancel_callb) (GtkWidget *, gpointer),
585 gpointer callb_data,
586 GtkWindowPosition pos,
587 gboolean if_ok_default) {
588 modal_dialog_with_titles (wdg, title, ok_callb, "OK", cancel_callb, "Cancel", callb_data, pos, if_ok_default);
589 }
590
modal_delete_showhide(GtkWidget * window,GdkEvent * dummy_event,gpointer args)591 gint modal_delete_showhide (GtkWidget *window, GdkEvent *dummy_event, gpointer args) {
592 // Kind of "wrapper" for callback OK/CANCEL after a delete window event
593 cb_args_struct *cb_args;
594 cb_args = (cb_args_struct *) args;
595 if (cb_args->callb_fn) {
596 // printf("Executing grabbed window callback function\n");
597 if ((*cb_args->callb_fn) (window, cb_args->callb_data))
598 return TRUE;
599 }
600 gtk_grab_remove(window);
601 gtk_widget_hide(window);
602 // printf("Delete event on %d\n", window);
603 return TRUE;
604 }
605
606
modal_dialog_showhide_with_titles(GtkWidget * window,GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gchar * ok_title,gint (* cancel_callb)(GtkWidget *,gpointer),gchar * cancel_title,gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)607 void modal_dialog_showhide_with_titles (GtkWidget *window,
608 GtkWidget *wdg, gchar *title,
609 gint (*ok_callb) (GtkWidget*, gpointer),
610 gchar *ok_title,
611 gint (*cancel_callb) (GtkWidget *, gpointer),
612 gchar *cancel_title,
613 gpointer callb_data,
614 GtkWindowPosition pos,
615 gboolean if_ok_default) {
616
617 // Same as modal_dialog, without a new loop
618 // The dialog is intended to be permanent
619 // Unrealized parent window must be given by the caller
620 // "delete_event" hides the window and grab_removes it
621 // The parent app can reactivate the dialog this way:
622 // gtk_widget_show(GTK_WIDGET(given_window));
623 // gtk_grab_add(GTK_WIDGET(given_window));
624
625 GtkWidget *button, *okbox, *vbox;
626 cb_args_struct *args;
627 args = (cb_args_struct *) x_malloc(sizeof(cb_args_struct), "cbs_args_struct (args in modal_dialog_showhide_with_titles_windows)");
628 // "title" is not translated here, see the explanations in "my_msg"
629 gtk_window_set_title (GTK_WINDOW (window), title);
630 if (pos)
631 gtk_window_set_position(GTK_WINDOW(window), pos);
632 gtk_widget_realize(GTK_WIDGET(window));
633
634 // Defines a vbox for containing from top to bottom: 1. "wdg"; 2. OK - Cancel
635 vbox = gtk_vbox_new(FALSE,0);
636 gtk_widget_show(GTK_WIDGET(vbox));
637
638 // OK / cancel buttons appear in a hbox at the bottom
639 okbox = gtk_hbox_new(TRUE,0);
640 gtk_widget_show(GTK_WIDGET(okbox));
641 button = gtk_button_new_with_label(ok_title);
642 gtk_widget_show(GTK_WIDGET(button));
643 gtk_container_set_border_width(GTK_CONTAINER(button),DEF_PAD);
644 if (ok_callb)
645 gtk_signal_connect(GTK_OBJECT(button), "clicked",
646 GTK_SIGNAL_FUNC(ok_callb), (gpointer) callb_data);
647
648 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
649 GTK_SIGNAL_FUNC(gtk_grab_remove), (gpointer) window);
650 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
651 GTK_SIGNAL_FUNC(gtk_widget_hide), (gpointer) window);
652
653 gtk_box_pack_start(GTK_BOX(okbox), button, FALSE, FALSE, DEF_PAD);
654
655 if (cancel_callb) {
656 button = gtk_button_new_with_label(cancel_title);
657 gtk_widget_show(GTK_WIDGET(button));
658 gtk_container_set_border_width(GTK_CONTAINER(button),DEF_PAD);
659 gtk_signal_connect(GTK_OBJECT(button), "clicked",
660 GTK_SIGNAL_FUNC(cancel_callb), (gpointer) callb_data);
661 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
662 GTK_SIGNAL_FUNC(gtk_grab_remove), (gpointer) window);
663 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
664 GTK_SIGNAL_FUNC(gtk_widget_hide), (gpointer) window);
665 gtk_box_pack_start(GTK_BOX(okbox), button, FALSE, FALSE, DEF_PAD);
666 }
667
668 if (if_ok_default)
669 // Closing the window means "OK";
670 args->callb_fn = ok_callb;
671 else
672 // Closing the window means "Cancel";
673 args->callb_fn = cancel_callb;
674
675 args->callb_data = callb_data;
676
677 gtk_signal_connect(GTK_OBJECT(window), "delete_event",
678 GTK_SIGNAL_FUNC(modal_delete_showhide), (gpointer) args);
679
680 gtk_box_pack_start(GTK_BOX(vbox), wdg, TRUE, TRUE, 0);
681 gtk_box_pack_start(GTK_BOX(vbox), align_widget(okbox,0.5,0.5), FALSE, FALSE, 0);
682 gtk_container_add(GTK_CONTAINER(window), vbox);
683
684 gtk_widget_show(window);
685 gtk_grab_add(window);
686 }
687
688
689
modal_dialog_showhide(GtkWidget * window,GtkWidget * wdg,gchar * title,gint (* ok_callb)(GtkWidget *,gpointer),gint (* cancel_callb)(GtkWidget *,gpointer),gpointer callb_data,GtkWindowPosition pos,gboolean if_ok_default)690 void modal_dialog_showhide(GtkWidget *window, GtkWidget *wdg, gchar *title,
691 gint (*ok_callb) (GtkWidget*, gpointer),
692 gint (*cancel_callb) (GtkWidget *, gpointer),
693 gpointer callb_data,
694 GtkWindowPosition pos,
695 gboolean if_ok_default) {
696 modal_dialog_showhide_with_titles (window, wdg, title, ok_callb, _("OK"), cancel_callb, _("Cancel"), callb_data, pos, if_ok_default);
697 }
698
process_yes(GtkWidget * widget,int * yes_no)699 void process_yes (GtkWidget *widget, int *yes_no) {
700 *yes_no = TRUE;
701 }
process_no(GtkWidget * widget,int * yes_no)702 void process_no (GtkWidget *widget, int *yes_no) {
703 *yes_no = FALSE;
704 }
process_cancel(GtkWidget * widget,int * yes_no)705 void process_cancel (GtkWidget *widget, int *yes_no) {
706 *yes_no = CANCEL_YESNO;
707 }
708
delete_yesno(GtkWidget * widget,GdkEvent * event,gpointer data)709 gboolean delete_yesno (GtkWidget *widget, GdkEvent *event, gpointer data) {
710 // Do nothing when the users tries to close the window
711 return TRUE;
712 }
713
yes_no(gchar * message,int default_choice)714 int yes_no(gchar * message, int default_choice) {
715
716 GtkWidget *dialog, *label, *yes, *no;
717 int yes_no;
718 GMainLoop *loop;
719 loop = g_main_new(FALSE);
720 dialog = gtk_dialog_new();
721 gtk_widget_realize(GTK_WIDGET(dialog));
722 // We want to be sure the user sees the dialog...
723 gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_CENTER);
724 // "message" is not translated here, see the explanations in "my_msg"
725 label = gtk_label_new(message);
726 gtk_misc_set_padding(GTK_MISC(label), 10, 10);
727 yes = gtk_button_new_with_label(_("Yes"));
728 no = gtk_button_new_with_label(_("No"));
729 gtk_signal_connect(GTK_OBJECT(yes), "clicked",
730 GTK_SIGNAL_FUNC(process_yes),&yes_no);
731 gtk_signal_connect(GTK_OBJECT(no), "clicked",
732 GTK_SIGNAL_FUNC(process_no), &yes_no);
733 gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", GTK_SIGNAL_FUNC(delete_yesno), NULL);
734 gtk_signal_connect_object(GTK_OBJECT(yes), "clicked",
735 GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
736 gtk_signal_connect_object(GTK_OBJECT(no), "clicked",
737 GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
738 gtk_signal_connect_object(GTK_OBJECT(yes), "clicked",
739 GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
740 gtk_signal_connect_object(GTK_OBJECT(no), "clicked",
741 GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
742 gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
743 GTK_SIGNAL_FUNC(g_main_loop_quit), (void *) loop);
744 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), yes, TRUE, TRUE, 0);
745 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), no, TRUE, TRUE, 0);
746 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
747 GTK_WIDGET_SET_FLAGS(yes, GTK_CAN_DEFAULT);
748 GTK_WIDGET_SET_FLAGS(no, GTK_CAN_DEFAULT);
749 if (default_choice)
750 gtk_widget_grab_default(yes);
751 else
752 gtk_widget_grab_default(no);
753 gtk_widget_show_all(dialog);
754 gtk_grab_add(dialog);
755 g_main_run (loop);
756 g_main_destroy(loop);
757 return yes_no;
758 }
759
yes_no_cancel(gchar * message,int default_choice)760 int yes_no_cancel(gchar * message, int default_choice) {
761
762 GtkWidget *dialog, *label, *yes, *no, *cancel;
763 int yes_no;
764 GMainLoop *loop;
765 loop = g_main_new(FALSE);
766 dialog = gtk_dialog_new();
767 gtk_widget_realize(GTK_WIDGET(dialog));
768 // We want to be sure the user sees the dialog...
769 gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_CENTER);
770 // The message should be already translated, see the explanations in my_msg
771 label = gtk_label_new(message);
772 gtk_misc_set_padding(GTK_MISC(label), 10, 10);
773 yes = gtk_button_new_with_label(_("Yes"));
774 no = gtk_button_new_with_label(_("No"));
775 cancel = gtk_button_new_with_label(_("Cancel"));
776 gtk_signal_connect(GTK_OBJECT(yes), "clicked",
777 GTK_SIGNAL_FUNC(process_yes),&yes_no);
778 gtk_signal_connect(GTK_OBJECT(no), "clicked",
779 GTK_SIGNAL_FUNC(process_no), &yes_no);
780 gtk_signal_connect(GTK_OBJECT(cancel), "clicked",
781 GTK_SIGNAL_FUNC(process_cancel), &yes_no);
782 gtk_signal_connect(GTK_OBJECT(dialog), "delete_event", GTK_SIGNAL_FUNC(delete_yesno), NULL);
783 gtk_signal_connect_object(GTK_OBJECT(yes), "clicked",
784 GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
785 gtk_signal_connect_object(GTK_OBJECT(no), "clicked",
786 GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
787 gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked",
788 GTK_SIGNAL_FUNC(gtk_grab_remove), GTK_OBJECT(dialog));
789 gtk_signal_connect_object(GTK_OBJECT(yes), "clicked",
790 GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
791 gtk_signal_connect_object(GTK_OBJECT(no), "clicked",
792 GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
793 gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked",
794 GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
795 gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
796 GTK_SIGNAL_FUNC(g_main_loop_quit), (void *) loop);
797 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), yes, TRUE, TRUE, 0);
798 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), no, TRUE, TRUE, 0);
799 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), cancel, TRUE, TRUE, 0);
800 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
801 GTK_WIDGET_SET_FLAGS(yes, GTK_CAN_DEFAULT);
802 GTK_WIDGET_SET_FLAGS(no, GTK_CAN_DEFAULT);
803 GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
804 switch (default_choice) {
805 case TRUE:
806 gtk_widget_grab_default(yes);
807 break;
808 case FALSE:
809 gtk_widget_grab_default(no);
810 break;
811 case CANCEL_YESNO:
812 gtk_widget_grab_default(cancel);
813 }
814 gtk_widget_show_all(dialog);
815 gtk_grab_add(dialog);
816 g_main_run (loop);
817 g_main_destroy(loop);
818 return yes_no;
819 }
820
findnextrec(FILE * file,char * rec)821 int findnextrec (FILE *file,char *rec)
822 {
823 /* Find next record, skipping comments */
824 int i;
825 while (1) {
826 if (!fgets(rec,250,file))
827 return FALSE;
828 /* Find next char which is not blank */
829 for (i=0;i<strlen(rec);i++)
830 if (rec[i]!=' ') break;
831 if (rec[i]!='#')
832 break;
833 }
834 return TRUE;
835 }
836
remove_spaces_both_ends(char * str)837 char *remove_spaces_both_ends (char *str) {
838 // Remove spaces at both ends of a string
839 // Allocates a new pointer
840 int max_length, i, j;
841 char *s;
842 max_length = strlen(str);
843 if (!max_length)
844 return str;
845 i = max_length-1;
846 // Removing spaces at the end
847 while ( (i>=0) && (str[i]==' ') ) {
848 i--;
849 }
850
851 i++;
852 // printf("STR[%d]: %d\n",i,str[i]);
853
854 s = (char *) x_malloc(i+1, "char (s in remove_spaces_both_ends)");
855 if (i)
856 strncpy(s,str,i);
857 s[i]='\0';
858 if (!i) // empty string
859 return s;
860
861 max_length = i;
862 // Removing spaces at the beginning
863 i = 0;
864 while ( (i<=max_length) && (s[i]==' ') )
865 i++;
866
867 if (i) { // There is something to remove
868 for (j=0; (j+i)<=(max_length+1) ; j++)
869 s[j] = s[i+j];
870 return (char *) x_realloc(s, j+1, "char (s - realloc in remove_spaces_both_ends)");
871 }
872 else
873 return s;
874 }
875
876
strupp(char * my_string)877 char *strupp(char *my_string) {
878 // Converts my_string to uppercase
879 int i;
880 char *buf;
881 buf = (char *) x_malloc(strlen(my_string)+1, "char (buf in strupp)");
882 for (i=0; i<strlen(my_string); i++)
883 buf[i]=(char) toupper((int) my_string[i]);
884 buf[i]='\0';
885 return buf;
886 }
887
strlow(char * my_string)888 char *strlow(char *my_string) {
889 // Converts my_string to lowercase
890 int i;
891 char *buf;
892 buf = (char *) x_malloc(strlen(my_string)+1, "char (buf in strlow)");
893 for (i=0; i<strlen(my_string); i++)
894 buf[i]=(char) tolower((int) my_string[i]);
895 buf[i]='\0';
896 return buf;
897 }
898
is_integer(gchar * buf)899 gboolean is_integer(gchar *buf) {
900 // Check if buf is a valid integer
901 gint i;
902 if (!strlen(buf))
903 return FALSE;
904 for (i = 0; i<strlen(buf); i++) {
905 if ( (!i) && ((*(buf+i))=='-')) // Negative sign
906 continue;
907 if (!isdigit(*(buf+i)))
908 return FALSE;
909 }
910 return TRUE;
911 }
912
is_float(gchar * buf)913 gboolean is_float(gchar *buf) {
914 // Check if buf is a valid float in the 9999,9... format
915 // Rough test - to be improved
916 // Doesn't check the 999 E+99 format
917 // We don't consider the locale, but assume
918 // that , or . are valid decimal separators
919 // No comma allowed for thousands separators!!
920 gint i;
921 gboolean beginning_spaces=TRUE, if_comma=FALSE;
922 // printf("BUF: %s\n",buf);
923 if (!strlen(buf))
924 return FALSE;
925 for (i = 0; i<strlen(buf); i++) {
926 // printf("%d = %c\n", i, (char) *(buf+i));
927 if (beginning_spaces) {
928 if ((*(buf+i))==' ')
929 continue;
930 }
931 if ( beginning_spaces && ((*(buf+i))=='-')) { // Negative sign
932 beginning_spaces = FALSE;
933 continue;
934 }
935 beginning_spaces = FALSE;
936 if (!isdigit(*(buf+i))) {
937 if (if_comma) // 2nd comma...
938 return FALSE;
939 if ( ((*(buf+i))!=',') && ( (*(buf+i))!='.') )
940 return FALSE;
941 else
942 if_comma=TRUE;
943 }
944 }
945 return TRUE;
946 }
947
string_to_double(gchar * buf)948 gdouble string_to_double (gchar *buf) {
949 // As the title says...
950 // Added 2005-04-26, for processing the geomorphrc file without
951 // considering the locale
952 // We assume that , or . could be decimal separators
953 // Doesn't work with the 999 E+99 format
954 gdouble result=0.0;
955 gint i, digits;
956 gboolean beginning_spaces=TRUE, if_comma=FALSE, negative = FALSE;
957 gchar *new_buf;
958 // printf("BUF: %s\n",buf);
959 if (!strlen(buf))
960 return result;
961
962 new_buf = (gchar *) x_malloc(1+(sizeof(gchar)*strlen(buf)), "gchar (new_buf in string_to_double)");
963
964 digits = 0;
965 for (i = 0; i<strlen(buf); i++) {
966 // printf("%d = %c\n", i, (char) *(buf+i));
967 if (beginning_spaces) {
968 if ((*(buf+i))==' ')
969 continue;
970 }
971 if ( beginning_spaces && ((*(buf+i))=='-')) { // Negative sign
972 beginning_spaces = FALSE;
973 negative = TRUE;
974 continue;
975 }
976 beginning_spaces = FALSE;
977 if (!isdigit(*(buf+i))) {
978 if (if_comma) { // 2nd comma, not supposed to, stop there
979 x_free(new_buf);
980 if (negative)
981 result *= -1;
982 return result;
983 }
984 if ( ((*(buf+i))!=',') && ( (*(buf+i))!='.') ) {
985 x_free(new_buf);
986 if (negative)
987 result *= -1;
988 return result;
989 }
990 else {
991 if_comma=TRUE;
992 *(new_buf+digits) = '\0';
993 result = atof(new_buf);
994 digits = 0;
995 }
996 }
997 else {
998 *(new_buf+digits) = *(buf+i);
999 digits++;
1000 }
1001 }
1002 *(new_buf+digits) = '\0';
1003 result += atof(new_buf) / pow(10.0,(gdouble)digits);
1004 x_free(new_buf);
1005 if (negative)
1006 result *= -1;
1007 return result;
1008 }
1009
define_button_in_table(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint pad)1010 GtkWidget * define_button_in_table (char *txt, GtkWidget *table, gint colfrom,
1011 gint colto, gint linefrom, gint lineto, gint pad)
1012 {
1013 GtkWidget *button;
1014 button = gtk_button_new_with_label (_(txt));
1015 gtk_table_attach (GTK_TABLE (table), button, colfrom, colto, linefrom, lineto, 0, 0, pad, pad);
1016 gtk_widget_show(button);
1017 return button;
1018 }
1019
define_check_button_in_table(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint pad)1020 GtkWidget * define_check_button_in_table (char *txt, GtkWidget *table, gint colfrom,
1021 gint colto, gint linefrom, gint lineto, gint pad)
1022 {
1023 GtkWidget *button;
1024 button = gtk_check_button_new_with_label (_(txt));
1025 gtk_table_attach (GTK_TABLE (table), button, colfrom, colto, linefrom, lineto, 0, 0, pad, pad);
1026 gtk_widget_show(button);
1027 return button;
1028 }
define_check_button_in_box(char * txt,GtkWidget * box,gint expand,gint fill,gint pad)1029 GtkWidget * define_check_button_in_box (char *txt, GtkWidget *box, gint expand, gint fill, gint pad)
1030 {
1031 GtkWidget *button;
1032 button = gtk_check_button_new_with_label (_(txt));
1033 gtk_box_pack_start(GTK_BOX(box), button, expand, fill, pad);
1034 gtk_widget_show(button);
1035 return button;
1036 }
define_label_in_box(char * txt,GtkWidget * box,gint expand,gint fill,gint pad)1037 GtkWidget *define_label_in_box(char *txt, GtkWidget *box, gint expand, gint fill, gint pad)
1038 {
1039 GtkWidget *label;
1040 label = gtk_label_new(_(txt));
1041 gtk_misc_set_alignment(GTK_MISC(label),0,0.5);
1042 gtk_widget_show (label);
1043 gtk_box_pack_start(GTK_BOX(box), label, expand, fill, pad);
1044 return label;
1045 }
1046
define_scale_in_table(GtkObject * adj,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint digits,gint pad)1047 GtkWidget * define_scale_in_table(GtkObject *adj, GtkWidget *table, gint colfrom, gint colto,
1048 gint linefrom, gint lineto, gint digits, gint pad)
1049 {
1050 GtkWidget *scale;
1051 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1052 gtk_scale_set_digits (GTK_SCALE (scale), digits);
1053 gtk_widget_set_usize(scale,80,0);
1054 // gtk_table_attach (GTK_TABLE (table), scale, colfrom, colto, linefrom, lineto,
1055 // GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, pad, pad);
1056 gtk_table_attach_defaults (GTK_TABLE (table), scale, colfrom, colto, linefrom, lineto);
1057 gtk_widget_show (scale);
1058 return(scale);
1059 }
1060
define_scale_in_box(GtkObject * adj,GtkWidget * box,gint digits,gint pad)1061 GtkWidget * define_scale_in_box(GtkObject *adj, GtkWidget *box, gint digits, gint pad)
1062 {
1063 GtkWidget *scale;
1064 if (GTK_IS_HBOX(GTK_OBJECT(box))) {
1065 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1066 gtk_widget_set_usize(scale,75,0);
1067 }
1068 else {
1069 scale = gtk_vscale_new (GTK_ADJUSTMENT (adj));
1070 gtk_widget_set_usize(scale,0,75);
1071 }
1072 gtk_scale_set_digits (GTK_SCALE (scale), digits);
1073 gtk_box_pack_start (GTK_BOX (box), scale, TRUE, TRUE, pad);
1074 gtk_widget_show (scale);
1075 return(scale);
1076 }
1077
define_label_in_table_align(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint pad,gfloat horiz,gfloat vertic)1078 GtkWidget *define_label_in_table_align (char *txt,GtkWidget *table, gint colfrom, gint colto,
1079 gint linefrom, gint lineto, gint pad, gfloat horiz, gfloat vertic)
1080 {
1081 GtkWidget *label,*lbl;
1082 label = gtk_label_new(_(txt));
1083 gtk_widget_show (label);
1084 gtk_misc_set_alignment(GTK_MISC(label),0,0.5);
1085 if ((horiz==ALIGN_CENTER) && (vertic==ALIGN_CENTER))
1086 lbl = label;
1087 else
1088 lbl = align_widget(label,horiz,vertic);
1089 gtk_table_attach (GTK_TABLE (table), lbl, colfrom, colto, linefrom, lineto,
1090 GTK_FILL, GTK_FILL, pad, pad);
1091 return label;
1092 }
1093
define_label_in_table(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,gint pad)1094 GtkWidget *define_label_in_table(char *txt,GtkWidget *table, gint colfrom, gint colto,
1095 gint linefrom, gint lineto, gint pad)
1096 {
1097 return define_label_in_table_align(txt, table, colfrom, colto,
1098 linefrom, lineto, pad, ALIGN_CENTER, ALIGN_CENTER);
1099 }
1100
define_entry_in_table_align(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,int length,int widget_len,gint pad,gfloat horiz,gfloat vertic)1101 GtkWidget * define_entry_in_table_align(char *txt,GtkWidget *table, gint colfrom, gint colto,
1102 gint linefrom, gint lineto, int length, int widget_len, gint pad, gfloat horiz, gfloat vertic)
1103 {
1104 // "length" is in characters
1105 // "widget_len" is in pixels (seems to be)
1106 GtkWidget *entry, *entr;
1107 entry = gtk_entry_new_with_max_length(length);
1108 gtk_widget_show(entry);
1109 gtk_widget_set_usize(GTK_WIDGET(entry),widget_len,0);
1110 gtk_entry_set_text(GTK_ENTRY(entry),txt);
1111 if ((horiz==ALIGN_CENTER) && (vertic==ALIGN_CENTER))
1112 entr = entry;
1113 else
1114 entr = align_widget(entry,horiz,vertic);
1115 gtk_table_attach (GTK_TABLE (table), entr,
1116 colfrom, colto, linefrom, lineto,
1117 GTK_FILL, GTK_FILL, pad, pad);
1118 return(entry);
1119 }
1120
define_entry_in_table(char * txt,GtkWidget * table,gint colfrom,gint colto,gint linefrom,gint lineto,int length,int widget_len,gint pad)1121 GtkWidget * define_entry_in_table(char *txt,GtkWidget *table, gint colfrom, gint colto,
1122 gint linefrom, gint lineto, int length, int widget_len, gint pad)
1123 {
1124 return define_entry_in_table_align(txt,table,colfrom,colto, linefrom,
1125 lineto, length,widget_len,pad, ALIGN_CENTER, ALIGN_CENTER);
1126 }
1127
define_entry_in_box(char * txt,GtkWidget * box,gint expand,gint fill,gint pad,int length,int widget_len)1128 GtkWidget * define_entry_in_box(char *txt, GtkWidget *box, gint expand,
1129 gint fill, gint pad, int length, int widget_len)
1130 {
1131 GtkWidget *entry;
1132 entry = gtk_entry_new_with_max_length(length);
1133 gtk_widget_set_usize(GTK_WIDGET(entry),widget_len,0);
1134 gtk_entry_set_text(GTK_ENTRY(entry),txt);
1135 gtk_box_pack_start(GTK_BOX(box), entry, expand, fill, pad);
1136 gtk_widget_show(entry);
1137 return(entry);
1138 }
1139
define_radio_button_in_box(GtkWidget * box,GSList ** group,char * txt,void (* callback_fn)(GtkWidget *,gpointer),int if_default)1140 GtkWidget * define_radio_button_in_box (GtkWidget *box, GSList **group, char *txt,
1141 void (*callback_fn) (GtkWidget *, gpointer ),
1142 int if_default ) {
1143
1144 // This form uses the label text as the callback data
1145 // Data is flowed from the widget to the application through a global variable
1146 // which is initialized in the callback function, from the label
1147 GtkWidget *button;
1148 button = gtk_radio_button_new_with_label (*group, _(txt));
1149 gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
1150 *group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
1151 if (if_default)
1152 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1153 gtk_widget_show(button);
1154 if (callback_fn)
1155 gtk_signal_connect ( GTK_OBJECT (button),
1156 "toggled",
1157 GTK_SIGNAL_FUNC(callback_fn),
1158 (gpointer) txt);
1159 return button;
1160 }
1161
define_radio_button_in_box_with_data(GtkWidget * box,GSList ** group,char * txt,void (* callback_fn)(GtkWidget *,gpointer),gpointer callb_data,int if_default)1162 GtkWidget * define_radio_button_in_box_with_data (GtkWidget *box, GSList **group, char *txt,
1163 void (*callback_fn) (GtkWidget *, gpointer ),
1164 gpointer callb_data,
1165 int if_default ) {
1166
1167 // This forms implies that the callback data is the structure modified with the
1168 // information drawed from the radio button label
1169 // The callback function must tests the radio button label like this:
1170 // gchar *txt;
1171 // gtk_label_get(GTK_LABEL(GTK_BIN(radio_button)->child), &txt);
1172
1173 GtkWidget *button;
1174 button = gtk_radio_button_new_with_label (*group, _(txt));
1175 gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
1176 *group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
1177 gtk_widget_show(button);
1178 if (callback_fn)
1179 gtk_signal_connect ( GTK_OBJECT (button),
1180 "toggled",
1181 GTK_SIGNAL_FUNC(callback_fn),
1182 callb_data);
1183 if (if_default) {
1184 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1185 // printf("Activating %s\n",txt);
1186 }
1187 return button;
1188 }
1189
define_radio_button_in_table_with_data(GtkWidget * table,GSList ** group,char * txt,void (* callback_fn)(GtkWidget *,gpointer),gpointer callb_data,gint if_default,gint colfrom,gint colto,gint linefrom,gint lineto)1190 GtkWidget * define_radio_button_in_table_with_data (GtkWidget *table, GSList **group, char *txt,
1191 void (*callback_fn) (GtkWidget *, gpointer ),
1192 gpointer callb_data, gint if_default, gint colfrom, gint colto, gint linefrom, gint lineto ) {
1193
1194 // This forms implies that the callback data is the structure modified with the
1195 // information drawed from the radio button label
1196 // The callback function must tests the radio button label like this:
1197 // gchar *txt;
1198 // gtk_label_get(GTK_LABEL(GTK_BIN(radio_button)->child), &txt);
1199
1200 GtkWidget *button;
1201 button = gtk_radio_button_new_with_label (*group, _(txt));
1202
1203 gtk_table_attach (GTK_TABLE (table), button, colfrom, colto, linefrom, lineto, 0, 0, 0, 0);
1204
1205 *group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
1206 if (if_default)
1207 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1208 gtk_widget_show(button);
1209 if (callback_fn)
1210 gtk_signal_connect ( GTK_OBJECT (button),
1211 "toggled",
1212 GTK_SIGNAL_FUNC(callback_fn),
1213 callb_data);
1214 return button;
1215 }
1216
find_omenu_option(omenu_struct_type * omenu,char * label)1217 int find_omenu_option (omenu_struct_type *omenu, char *label) {
1218 // Finds the option menu index from label
1219 int i;
1220 char *buf1, *buf2;
1221 buf1 = strupp(label);
1222 for (i=0; i<omenu->max_index; i++) {
1223 buf2 = strupp(omenu->list[i].lbl);
1224 if (!strcmp(buf1,buf2)) {
1225 x_free(buf2);
1226 break;
1227 }
1228 x_free(buf2);
1229 }
1230 x_free(buf1);
1231 if (i == omenu->max_index)
1232 return 0;
1233 else
1234 return i;
1235 }
1236
find_omenu_option_num(omenu_struct_type * omenu,int value)1237 int find_omenu_option_num(omenu_struct_type *omenu, int value) {
1238 // Finds the option menu index from the numeric value
1239 int i;
1240 for (i=0; i<omenu->max_index; i++)
1241 if (value == omenu->list[i].num)
1242 break;
1243 if (i == omenu->max_index)
1244 return 0;
1245 else
1246 return i;
1247 }
1248
find_omenu_num(omenu_list_type * list,int value,int max)1249 int find_omenu_num (omenu_list_type *list, int value, int max) {
1250 // Finds the option menu index from the numeric value
1251 // Same as preceding, but the omenu_struct_type is not known
1252 int i;
1253 for (i=0; i<max; i++) {
1254 if (value == list[i].num)
1255 break;
1256 }
1257 if (i == max)
1258 return 0;
1259 else {
1260 // printf("FIND_OMENU_NUM - valeur cherch�e: %d; i: %d; v. cour: %d\n",value,i, list[i].num);
1261 return i;
1262 }
1263 }
1264
menu_choice(omenu_list_type * item_list)1265 void menu_choice (omenu_list_type *item_list)
1266 {
1267 /* Initialise current label and index */
1268 ((omenu_struct_type *) item_list->parent_omenu)->current_lbl = _(item_list->lbl);
1269 ((omenu_struct_type *) item_list->parent_omenu)->current_index =
1270 find_omenu_option(
1271 (omenu_struct_type *) item_list->parent_omenu,
1272 item_list->lbl );
1273 // printf("ITEM_LIST->lbl: %s\n",item_list->lbl);
1274 // /* Is there a function pointer to execute ? */
1275 // Done in define_menu_item 2001.12.16
1276 // if (item_list->callback_fn)
1277 // (*item_list->callback_fn)((gpointer *) item_list->lbl);
1278 }
1279
define_menu_item(omenu_struct_type * omenu,omenu_list_type * omenu_list,GSList ** group,GtkWidget * menu)1280 GtkWidget * define_menu_item (omenu_struct_type *omenu, omenu_list_type *omenu_list,
1281 GSList **group, GtkWidget *menu)
1282 {
1283 GtkWidget *menuitem;
1284 menuitem = gtk_radio_menu_item_new_with_label
1285 (*group,_(omenu_list->lbl));
1286 *group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM(menuitem));
1287 gtk_menu_append(GTK_MENU(menu),menuitem);
1288 gtk_widget_show(menuitem);
1289 gtk_signal_connect_object(GTK_OBJECT(menuitem), "activate",
1290 GTK_SIGNAL_FUNC(menu_choice), (gpointer) omenu_list);
1291 if (omenu_list->callback_fn) {
1292 // Is there a function pointer to execute ?
1293 if (!omenu->data)
1294 // Old version: the data was the label
1295 gtk_signal_connect_object(GTK_OBJECT(menuitem), "activate",
1296 GTK_SIGNAL_FUNC(omenu_list->callback_fn),
1297 (gpointer) omenu_list->lbl);
1298 else
1299 gtk_signal_connect_object(GTK_OBJECT(menuitem), "activate",
1300 GTK_SIGNAL_FUNC(omenu_list->callback_fn),
1301 (gpointer) omenu);
1302 }
1303 return menuitem;
1304 }
1305
define_omenu(omenu_struct_type * omenu_str,int max,int def)1306 GtkWidget * define_omenu (omenu_struct_type *omenu_str, int max, int def)
1307 {
1308 /* Defines an option menu and sets the default value */
1309 int i,j=0;
1310 GSList *group=NULL;
1311 GtkWidget *omenu, *menu;
1312 omenu = gtk_option_menu_new();
1313 menu = gtk_menu_new();
1314
1315 for(i=0;i<max;i++) {
1316 if (i==def)
1317 j=i;
1318 omenu_str->list[i].menuitem =
1319 define_menu_item (omenu_str,&omenu_str->list[i], &group, menu);
1320 }
1321 gtk_option_menu_set_menu (GTK_OPTION_MENU(omenu),menu);
1322 gtk_widget_show(omenu);
1323 /* Toggle, show, initialise default value */
1324 gtk_option_menu_set_history(GTK_OPTION_MENU(omenu),j);
1325 gtk_menu_item_activate(GTK_MENU_ITEM(omenu_str->list[j].menuitem));
1326 omenu_str->current_lbl = _(omenu_str->list[j].lbl);
1327 return omenu;
1328 }
1329
create_omenu(omenu_struct_type ** new_omenu,omenu_list_type * list,int max_index,int def_index)1330 int create_omenu (omenu_struct_type **new_omenu,
1331 omenu_list_type *list,
1332 int max_index,
1333 int def_index)
1334 {
1335
1336 // Creates an Option Menu Structure from an undefined
1337 // omenu_struct_type pointer, a defined list of options
1338 // and a few indexes - maximum + default
1339
1340 int i;
1341 if (NULL == ((*new_omenu) =
1342 (omenu_struct_type *) x_malloc(sizeof(omenu_struct_type), "omenu_struct_type (new_omenu in create_omenu)")))
1343 return FALSE;
1344
1345 (*new_omenu)->list = list;
1346
1347 (*new_omenu)->max_index = max_index;
1348
1349 (*new_omenu)->def_index = def_index;
1350
1351 (*new_omenu)->data = NULL;
1352
1353 // We need to know the parent pointer in the child structure
1354 for (i=0; i<max_index; i++)
1355 (*new_omenu)->list[i].parent_omenu = *new_omenu;
1356
1357 (*new_omenu)->omenu_ptr = define_omenu(*new_omenu, max_index, def_index);
1358
1359 return TRUE;
1360 }
1361
1362
create_omenu_with_callb_data(omenu_struct_type ** new_omenu,omenu_list_type * list,int max_index,int def_index,gpointer data)1363 int create_omenu_with_callb_data (omenu_struct_type **new_omenu,
1364 omenu_list_type *list,
1365 int max_index,
1366 int def_index,
1367 gpointer data)
1368 {
1369
1370 // Creates an Option Menu Structure from an undefined
1371 // omenu_struct_type pointer, a defined list of options
1372 // and a few indexes - maximum + default
1373
1374 int i;
1375 if (NULL == ((*new_omenu) =
1376 (omenu_struct_type *) x_malloc(sizeof(omenu_struct_type),"omenu_struct_type (new_omenu in create_omenu_with_callb_data)" )))
1377 return FALSE;
1378
1379 (*new_omenu)->list = list;
1380
1381 (*new_omenu)->max_index = max_index;
1382
1383 (*new_omenu)->def_index = def_index;
1384
1385 (*new_omenu)->data = data;
1386
1387 // We need to know the parent pointer in the child structure
1388 for (i=0; i<max_index; i++)
1389 (*new_omenu)->list[i].parent_omenu = *new_omenu;
1390
1391 (*new_omenu)->omenu_ptr = define_omenu(*new_omenu, max_index, def_index);
1392
1393 return TRUE;
1394 }
1395
set_option_menu_from_label(GtkWidget * omenu,gchar * label)1396 void set_option_menu_from_label (GtkWidget *omenu, gchar *label) {
1397 // Written 2002.09
1398 // A lot simpler than the preceding functions
1399 // (no need of a complex option menu struct, all data can be found
1400 // in the option menu... when one finally understands the widget :-( )
1401 // 2005-02: seems to work with GTK2 (at least when the menu item is a label!)
1402 GtkWidget *menu;
1403 GList *node;
1404 gchar *txt,*lbl;
1405 lbl = remove_spaces_both_ends(label);
1406 if (GTK_IS_LABEL(GTK_BIN(omenu)->child)) {
1407 gtk_label_get(GTK_LABEL(GTK_BIN(omenu)->child), &txt);
1408 if (!strcmp(txt,lbl)) // Nothing to do, the label is already set
1409 return;
1410 }
1411 menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(omenu));
1412 node = GTK_MENU_SHELL(menu)->children;
1413 while (node) {
1414 if (GTK_IS_LABEL(GTK_BIN(node->data)->child)) {
1415 gtk_label_get(GTK_LABEL(GTK_BIN(node->data)->child), &txt);
1416 if (!strcmp(txt,lbl)) {
1417 break;
1418 }
1419 } // If the child is not a label (typically it would be NULL),
1420 // we skip it because the menu item is the current one
1421 node = node->next;
1422 }
1423 if (node) { // Label found
1424 gtk_menu_item_activate(GTK_MENU_ITEM(node->data));
1425 gtk_option_menu_set_history(GTK_OPTION_MENU(omenu),
1426 g_list_index(GTK_MENU_SHELL(menu)->children, node->data));
1427 }
1428 else { // Label not found, revert to default
1429 gtk_menu_item_activate(GTK_MENU_ITEM(GTK_MENU_SHELL(menu)->children->data));
1430 gtk_option_menu_set_history(GTK_OPTION_MENU(omenu),0);
1431 }
1432 free(lbl);
1433 }
1434
my_exec(char * com,char ** argum,int (* exec_to_use)(const char *,char * arg[]))1435 int my_exec(char *com, char **argum, int (*exec_to_use) (const char *, char *arg[])) {
1436
1437 /* "Wrapper" for execution of a command with execvp or execv
1438 Control returned to parent process (uses fork)
1439 argum must end with a NULL!!
1440 ... and preferably begin with the command to execute
1441 (we tested it!)
1442 */
1443
1444 int i=0;
1445 pid_t pid;
1446 char **buf=NULL, *bufmsg=NULL;
1447
1448 // printf("*Argum: %s == %s : %d\n" ,*argum,com, strcmp(*argum,com));
1449
1450 // Arguments must begin with the command to execute
1451 if (strcmp(*argum,com)) { // No
1452 while (*(argum+i)!=NULL) i++;
1453 buf = (char **) x_calloc((i+2),sizeof(*argum), "*argum (buf in my_exec)");
1454 // printf("Allocation: %d:%d\n",i+2,(i+2)*sizeof(*argum));
1455 *buf = com;
1456 while (i+1) {
1457 *(buf+i+1) = *(argum+i);
1458 // printf("I: %d; BUF: %s; ARGUM: %s\n", i, *(buf+i+1), *(argum+i));
1459 i--;
1460 }
1461 }
1462 else {
1463 buf = argum;
1464 }
1465
1466 // printf("com: %s; Buf 0: %s, Buf 1: %s, Buf 2: %s, Buf 3: %s, Buf 4: %s; Buf 5: %s\n", com, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
1467
1468 pid = fork ();
1469
1470 // printf("PID: %d\n",pid);
1471
1472 if (pid == 0) {
1473 // Child process OK, execute the command
1474 if ((*exec_to_use) (com, buf)<0) { // Command not OK
1475 bufmsg = (char *) x_malloc(5+strlen(strerror(errno))+
1476 strlen(com), "char (bufmsg in my_exec)");
1477 sprintf(bufmsg,"%s: %s",com,strerror(errno));
1478
1479 my_msg(bufmsg,FAIL);
1480
1481 x_free(bufmsg);
1482 printf("%s: %s\n", com, strerror(errno));
1483 _exit(-1);
1484 }
1485 }
1486 else
1487 if (pid < 0) {
1488 /* Error, no child process, Parent process OK */
1489 my_msg(strerror(errno),FAIL);
1490 }
1491 else { // pid > 0, Parent process OK, child OK
1492 // Remove zombie process, if any
1493 // printf("PID: %d\n",pid);
1494 waitpid(pid, NULL, WNOHANG);
1495 }
1496
1497 if (buf && (buf != argum)) x_free(buf);
1498
1499 return pid;
1500 }
1501
execution(char * file,char ** argum)1502 int execution(char *file, char **argum) {
1503 return my_exec(file, argum, (gpointer) execvp);
1504 }
1505
1506 // int execution(char *path, char **argum) {
1507 // return my_exec(path, argum, (gpointer) execv);
1508 //}
1509
log2i(gint x)1510 int log2i(gint x) {
1511 gint i;
1512 i = 0;
1513 while (x) {
1514 i++;
1515 x = x>>1;
1516 }
1517 return(i-1);
1518 }
1519
set_sensitive_callb(GtkWidget * wdg,gpointer widget)1520 void set_sensitive_callb (GtkWidget *wdg, gpointer widget) {
1521 // Enable "widget" when an event reaches "wdg"
1522 gtk_widget_set_sensitive(GTK_WIDGET(widget),TRUE);
1523 }
1524
unset_sensitive_callb(GtkWidget * wdg,gpointer widget)1525 void unset_sensitive_callb (GtkWidget *wdg, gpointer widget) {
1526 // Disable "widget" when an event reaches "wdg"
1527 gtk_widget_set_sensitive(GTK_WIDGET(widget),FALSE);
1528 }
1529
show_if_true(GtkWidget * check_button,gpointer widget)1530 void show_if_true(GtkWidget *check_button, gpointer widget) {
1531 // Show widget if button is true, hide if false
1532 if (GTK_TOGGLE_BUTTON(check_button)->active)
1533 gtk_widget_show(GTK_WIDGET(widget));
1534 else
1535 gtk_widget_hide(GTK_WIDGET(widget));
1536 }
hide_if_true(GtkWidget * check_button,gpointer widget)1537 void hide_if_true(GtkWidget *check_button, gpointer widget) {
1538 // Hide widget if button is true, show if false
1539 if (GTK_TOGGLE_BUTTON(check_button)->active)
1540 gtk_widget_hide(GTK_WIDGET(widget));
1541 else
1542 gtk_widget_show(GTK_WIDGET(widget));
1543 }
1544
sensitive_if_true(GtkWidget * check_button,gpointer widget)1545 void sensitive_if_true(GtkWidget *check_button, gpointer widget) {
1546 // Make widget sensitive if button is true, make unsensitive if false
1547 gtk_widget_set_sensitive(GTK_WIDGET(widget), GTK_TOGGLE_BUTTON(check_button)->active);
1548 }
unsensitive_if_true(GtkWidget * check_button,gpointer widget)1549 void unsensitive_if_true(GtkWidget *check_button, gpointer widget) {
1550 // Make widget sensitive if button is false, make sensitive if true
1551 gtk_widget_set_sensitive(GTK_WIDGET(widget), !GTK_TOGGLE_BUTTON(check_button)->active);
1552 }
1553
align_widget(GtkWidget * wdg,gfloat horizontal,gfloat vertical)1554 GtkWidget *align_widget(GtkWidget *wdg, gfloat horizontal, gfloat vertical) {
1555 // Aligns a widget, returns the GTK_ALIGNMENT created for this purpose
1556 // No expansion control ("scale")
1557 GtkWidget *align_wdg;
1558 align_wdg = gtk_alignment_new(horizontal,vertical,0.0,0.0);
1559 gtk_container_add(GTK_CONTAINER(align_wdg), wdg);
1560 gtk_widget_show(GTK_WIDGET(align_wdg));
1561 return align_wdg;
1562 }
1563
frame_new(gchar * label,gint pad)1564 GtkWidget *frame_new(gchar *label, gint pad) {
1565 // Standard boring frame creation
1566 GtkWidget *frame;
1567 frame = gtk_frame_new(_(label));
1568 gtk_widget_show(GTK_WIDGET(frame));
1569 gtk_frame_set_label_align(GTK_FRAME(frame),0,0);
1570 gtk_container_set_border_width(GTK_CONTAINER(frame), pad);
1571 return frame;
1572 }
1573
adjust_adj_callb(GtkAdjustment * adj_trigger,gpointer adj_toadjust)1574 gint adjust_adj_callb (GtkAdjustment *adj_trigger, gpointer adj_toadjust) {
1575 GtkAdjustment *adj;
1576 adj = (GtkAdjustment *) adj_toadjust;
1577 gtk_adjustment_set_value (adj, gtk_adjustment_get_value (GTK_ADJUSTMENT(adj_trigger)));
1578 return TRUE; // Don't trigger other adj. changes
1579 }
1580
synchro_scr_win(GtkWidget * scr_win1,GtkWidget * scr_win2)1581 void synchro_scr_win (GtkWidget *scr_win1, GtkWidget *scr_win2) {
1582 // Synchronizes scrolled windows
1583 // Windows should be of the same size
1584 GtkAdjustment *vadj1, *vadj2, *hadj1, *hadj2;
1585 vadj1 = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW(scr_win1));
1586 hadj1 = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW(scr_win1));
1587 vadj2 = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW(scr_win2));
1588 hadj2 = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW(scr_win2));
1589 gtk_signal_connect (GTK_OBJECT (vadj1), "value_changed",
1590 (GtkSignalFunc) adjust_adj_callb, (gpointer) vadj2);
1591 gtk_signal_connect (GTK_OBJECT (vadj2), "value_changed",
1592 (GtkSignalFunc) adjust_adj_callb, (gpointer) vadj1);
1593 gtk_signal_connect (GTK_OBJECT (hadj1), "value_changed",
1594 (GtkSignalFunc) adjust_adj_callb, (gpointer) hadj2);
1595 gtk_signal_connect (GTK_OBJECT (hadj2), "value_changed",
1596 (GtkSignalFunc) adjust_adj_callb, (gpointer) hadj1);
1597 }
1598
1599 /* Create a new hbox with an image and a label packed into it
1600 * and return the box. */
1601 // Adapted from the GTK+ 2.x tutorial
1602
xpm_label_box(GtkWidget * window,gchar ** xpm,gchar * label_text)1603 GtkWidget *xpm_label_box (GtkWidget *window, gchar **xpm, gchar *label_text )
1604 {
1605 GtkWidget *box;
1606 GtkWidget *label;
1607 GtkWidget *image;
1608
1609 /* Create box for image and label */
1610 box = gtk_hbox_new (FALSE, 0);
1611 gtk_container_set_border_width (GTK_CONTAINER (box), 2);
1612
1613 /* Now on to the image stuff */
1614 image = create_widget_from_xpm (window,xpm) ;
1615
1616 /* Create a label for the button */
1617 label = gtk_label_new (label_text);
1618
1619 /* Pack the image and label into the box */
1620 gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 3);
1621 gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 3);
1622
1623 gtk_widget_show (image);
1624 gtk_widget_show (label);
1625
1626 return box;
1627 }
1628
1629