Codepage messages related translated & other stuff...
[midnight-commander.git] / gnome / gwidget.c
blob8b02d1b1721ce9b94e5f9c94dcb076b5a6a0d414
1 /*
2 * Widgets for the GNOME edition of the Midnight Commander
4 * Copyright (C) 1997 The Free Software Foundation
6 * Author: Miguel de Icaza (miguel@gnu.org)
8 */
10 #include <config.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <ctype.h>
15 #include "x.h"
16 #include "gwidget.h"
17 #include "dlg.h"
19 GtkWidget *
20 get_gtk_widget (Widget_Item *p)
22 GtkWidget *w;
24 g_return_val_if_fail(p, NULL);
25 g_return_val_if_fail(p->widget, NULL);
27 w = GTK_WIDGET (p->widget->wdata);
29 if (GNOME_IS_ENTRY (w))
30 return (gnome_entry_gtk_entry ((GnomeEntry *)(w)));
31 else
32 return (GTK_WIDGET (p->widget->wdata));
35 void
36 x_dialog_stop (Dlg_head *h)
38 if (h->grided & DLG_GNOME_APP)
39 return;
40 gtk_main_quit ();
43 void
44 x_focus_widget (Widget_Item *p)
46 GtkWidget *w = get_gtk_widget (p);
48 gtk_widget_grab_focus (w);
51 void
52 x_unfocus_widget (Widget_Item *p)
54 GtkWidget *w = get_gtk_widget (p);
55 GtkWidget *toplevel = gtk_widget_get_toplevel (w);
57 /* Only happens if the widget is not yet added to its container */
58 /* I am not yet sure why this happens */
59 if (GTK_IS_WINDOW (toplevel))
60 gtk_window_set_focus (GTK_WINDOW (gtk_widget_get_toplevel (w)), NULL);
63 void
64 x_destroy_cmd (void *w)
66 Widget *widget = (Widget *) w;
68 if (!widget->wdata)
69 return;
70 gtk_widget_destroy (GTK_WIDGET(widget->wdata));
73 /* Buttons */
74 static void
75 gbutton_callback (GtkWidget *w, void *data)
77 WButton *b = data;
78 Dlg_head *h = (Dlg_head *) b->widget.parent;
79 int stop = 0;
81 if (b->callback)
82 stop = (*b->callback)(b->action, b->callback_data);
84 if (!b->callback || stop){
85 h->ret_value = b->action;
86 dlg_stop (h);
90 char *
91 stock_from_text (char *text)
93 char *stock;
95 if ( g_strcasecmp (text, _("ok")) == 0)
96 stock = GNOME_STOCK_BUTTON_OK;
97 else if ( g_strcasecmp (text, _("cancel")) == 0)
98 stock = GNOME_STOCK_BUTTON_CANCEL;
99 else if ( g_strcasecmp (text, _("help")) == 0)
100 stock = GNOME_STOCK_BUTTON_HELP;
101 else if ( g_strcasecmp (text, _("yes")) == 0)
102 stock = GNOME_STOCK_BUTTON_YES;
103 else if ( g_strcasecmp (text, _("no")) == 0)
104 stock = GNOME_STOCK_BUTTON_NO;
105 else if ( g_strcasecmp (text, _("exit")) == 0)
106 stock = GNOME_STOCK_BUTTON_CLOSE;
107 else if ( g_strcasecmp (text, _("abort")) == 0)
108 stock = GNOME_STOCK_BUTTON_CANCEL;
109 else
110 stock = 0;
112 return stock;
116 x_create_button (Dlg_head *h, widget_data parent, WButton *b)
118 GtkWidget *button;
119 char *stock;
120 int tag;
122 stock = stock_from_text (b->text);
124 if (stock){
125 button = gnome_stock_button (stock);
126 } else
127 button = gtk_button_new_with_label (b->text);
129 if (b->flags == DEFPUSH_BUTTON){
130 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
131 gtk_widget_grab_default (button);
133 gtk_widget_show (button);
134 tag = gtk_signal_connect (GTK_OBJECT(button), "clicked", (GtkSignalFunc) gbutton_callback, b);
135 gtk_object_set_data (GTK_OBJECT (button), "click-signal-tag", (void *) tag);
136 b->widget.wdata = (widget_data) button;
138 return 1;
141 static void
142 x_set_text (GtkWidget *w, gpointer data)
144 if (!GTK_IS_LABEL (w))
145 return;
146 gtk_label_set (GTK_LABEL(w), data);
149 void
150 x_button_set (WButton *b, char *text)
152 GtkWidget *button = GTK_WIDGET (b->widget.wdata);
154 gtk_container_foreach (GTK_CONTAINER (button), x_set_text, text);
157 /* Radio buttons */
159 void
160 x_radio_focus_item (WRadio *radio)
162 GList *children = GTK_BOX (radio->widget.wdata)->children;
163 int i;
165 for (i = 0; i < radio->count; i++){
166 if (i == radio->pos){
167 GtkBoxChild *bc = (GtkBoxChild *) children->data;
169 gtk_widget_grab_focus (GTK_WIDGET (bc->widget));
170 break;
172 children = children->next;
176 void
177 x_radio_toggle (WRadio *radio)
179 GList *children = GTK_BOX (radio->widget.wdata)->children;
180 int i;
182 for (i = 0; i < radio->count; i++){
183 GtkBoxChild *bc = (GtkBoxChild *) children->data;
185 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bc->widget), (i == radio->sel) ? 1 : 0);
186 children = children->next;
190 static void
191 radio_toggle (GtkObject *object, WRadio *r)
193 int idx = (int) gtk_object_get_data (object, "index");
195 if (!GTK_TOGGLE_BUTTON (object)->active)
196 return;
198 g_return_if_fail (idx != 0);
199 idx--;
200 r->sel = idx;
203 static char *
204 remove_hotkey (char *text)
206 char *t = g_strdup (text);
207 char *p = strchr (t,'&');
209 if (p)
210 strcpy (p, p+1);
212 return t;
216 x_create_radio (Dlg_head *h, widget_data parent, WRadio *r)
218 GtkWidget *w, *vbox;
219 int i;
221 vbox = gtk_vbox_new (0, 0);
222 for (i = 0; i < r->count; i++){
223 char *text = remove_hotkey (_(r->texts [i]));
225 if (i == 0){
226 w = gtk_radio_button_new_with_label (NULL, text);
227 r->first_gtk_radio = w;
228 } else
229 w = gtk_radio_button_new_with_label_from_widget (r->first_gtk_radio, text);
231 g_free (text);
232 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), (i == r->sel));
233 gtk_signal_connect (GTK_OBJECT (w), "toggled", GTK_SIGNAL_FUNC (radio_toggle), r);
234 gtk_object_set_data (GTK_OBJECT (w), "index", (void *) (i+1));
235 gtk_box_pack_start_defaults (GTK_BOX (vbox), w);
237 gtk_widget_show_all (vbox);
239 r->widget.wdata = (widget_data) vbox;
241 return 1;
244 static void
245 x_check_changed (GtkToggleButton *t, WCheck *c)
247 c->state ^= C_BOOL;
248 c->state ^= C_CHANGE;
251 /* Check buttons */
253 x_create_check (Dlg_head *h, widget_data parent, WCheck *c)
255 GtkWidget *w;
257 w = gtk_check_button_new_with_label (c->text);
258 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), (c->state & C_BOOL));
259 gtk_signal_connect (GTK_OBJECT (w), "toggled", GTK_SIGNAL_FUNC (x_check_changed), c);
260 gtk_widget_show (w);
261 c->widget.wdata = (widget_data) w;
262 return 1;
265 /* Input lines */
266 static void
267 entry_click (GtkWidget *widget, GdkEvent *event, WInput *in)
269 dlg_select_widget (in->widget.parent, in);
270 in->first = 0;
273 static void
274 entry_release (GtkEditable *entry, GdkEvent *event, WInput *in)
276 in->point = entry->current_pos;
277 in->mark = (entry->current_pos == entry->selection_start_pos) ?
278 entry->selection_end_pos : entry->selection_start_pos;
279 if (in->point != in->mark)
280 in->first = 1;
283 static void
284 wentry_changed (GtkEditable *editable, WInput *in)
286 char *text = gtk_entry_get_text (GTK_ENTRY (editable));
288 assign_text (in, text);
289 input_set_point (in, editable->current_pos);
293 x_create_input (Dlg_head *h, widget_data parent, WInput *in)
295 GtkWidget *gnome_entry;
296 GtkEntry *entry;
298 /* The widget might have been initialized manually.
299 * Look in gscreen.c for an example
301 if (in->widget.wdata)
302 return 1;
304 #ifdef USE_GNOME_ENTRY
305 gnome_entry = gnome_entry_new (in->widget.tkname);
306 #else
307 entry = GTK_ENTRY (gnome_entry = gtk_entry_new ());
308 gtk_entry_set_visibility (entry, !in->is_password);
309 #endif
310 gtk_widget_show (gnome_entry);
311 in->widget.wdata = (widget_data) gnome_entry;
313 #ifdef USE_GNOME_ENTRY
314 entry = GTK_ENTRY (gnome_entry_gtk_entry (GNOME_ENTRY (gnome_entry)));
315 #endif
316 gtk_entry_set_text (entry, in->buffer);
317 gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
318 gtk_entry_set_position (entry, in->point);
320 gtk_signal_connect (GTK_OBJECT (entry), "button_press_event",
321 GTK_SIGNAL_FUNC (entry_click), in);
323 gtk_signal_connect (GTK_OBJECT (entry), "button_release_event",
324 GTK_SIGNAL_FUNC (entry_release), in);
326 gtk_signal_connect (GTK_OBJECT (entry), "changed",
327 GTK_SIGNAL_FUNC (wentry_changed), in);
328 return 1;
331 void
332 x_update_input (WInput *in)
334 #ifdef USE_GNOME_ENTRY
335 GnomeEntry *gnome_entry;
336 #endif
337 GtkEntry *entry;
338 char *text;
339 int draw = 0;
341 /* If the widget has not been initialized yet (done by WIDGET_INIT) */
342 if (!in->widget.wdata)
343 return;
345 #ifdef USE_GNOME_ENTRY
346 gnome_entry = GNOME_ENTRY (in->widget.wdata);
347 entry = GTK_ENTRY (gnome_entry_gtk_entry (gnome_entry));
348 #else
349 entry = GTK_ENTRY (in->widget.wdata);
350 #endif
352 /* Block the signal handler */
353 gtk_signal_handler_block_by_func (
354 GTK_OBJECT (entry),
355 GTK_SIGNAL_FUNC(wentry_changed), in);
357 /* Do the actual work */
358 if (in->first == -1){
359 gtk_editable_select_region (GTK_EDITABLE (entry), 0, 0);
360 in->first = 0;
363 text = gtk_entry_get_text (GTK_ENTRY (entry));
365 if (text && strcmp (text, in->buffer)){
366 gtk_entry_set_text (entry, in->buffer);
367 draw = 1;
370 if (GTK_EDITABLE (entry)->current_pos != in->point){
371 gtk_entry_set_position (entry, in->point);
372 draw = 1;
375 if (draw){
376 #ifdef USE_GNOME_ENTRY
377 gtk_widget_draw (GTK_WIDGET (gnome_entry), NULL);
378 #else
379 gtk_widget_draw (GTK_WIDGET (entry), NULL);
380 #endif
381 gtk_editable_changed (GTK_EDITABLE (entry));
382 gtk_widget_queue_draw (GTK_WIDGET (entry));
385 /* Unblock the signal handler */
386 gtk_signal_handler_unblock_by_func (
387 GTK_OBJECT (entry),
388 GTK_SIGNAL_FUNC(wentry_changed), in);
391 /* Listboxes */
392 static GtkWidget *
393 listbox_pull (widget_data data)
395 return GTK_BIN (data)->child;
398 void
399 x_listbox_select_nth (WListbox *l, int nth)
401 static int inside;
402 GtkCList *clist;
404 if (inside)
405 return;
407 if (!l->widget.wdata)
408 return;
410 inside = 1;
411 clist = GTK_CLIST (listbox_pull (l->widget.wdata));
413 gtk_clist_select_row (clist, nth, 0);
414 if (gtk_clist_row_is_visible (clist, nth) != GTK_VISIBILITY_FULL)
415 gtk_clist_moveto (clist, nth, 0, 0.5, 0.0);
417 inside = 0;
420 void
421 x_listbox_delete_nth (WListbox *l, int nth)
423 gtk_clist_remove (GTK_CLIST (listbox_pull (l->widget.wdata)), nth);
426 static void
427 listbox_select (GtkWidget *widget, int row, int column, GdkEvent *event, WListbox *l)
429 Dlg_head *h = l->widget.parent;
430 static int inside;
432 if (inside)
433 return;
434 inside = 1;
436 listbox_select_by_number (l, row);
438 if (!event){
439 inside = 0;
440 return;
444 if (event->type == GDK_2BUTTON_PRESS){
445 switch (l->action){
446 case listbox_nothing:
447 break;
449 case listbox_finish:
450 h->running = 0;
451 h->ret_value = B_ENTER;
452 gtk_main_quit ();
453 return;
455 case listbox_cback:
456 if ((*l->cback)(l) == listbox_finish){
457 gtk_main_quit ();
458 return;
463 /* Send an artificial DLG_POST_KEY */
464 if (event->type == GDK_BUTTON_PRESS)
465 (*l->widget.parent->callback)(l->widget.parent, 0, DLG_POST_KEY);
467 inside = 0;
471 x_create_listbox (Dlg_head *h, widget_data parent, WListbox *l)
473 GtkWidget *listbox, *sw;
474 GtkRequisition req;
475 WLEntry *p;
476 int i;
478 listbox = gtk_clist_new (1);
479 sw = gtk_scrolled_window_new (NULL, NULL);
480 gtk_container_add (GTK_CONTAINER (sw), listbox);
482 gtk_clist_set_selection_mode (GTK_CLIST (listbox), GTK_SELECTION_BROWSE);
483 gtk_widget_size_request (listbox, &req);
484 gtk_widget_set_usize (listbox, req.width, req.height + 20*8);
485 gtk_signal_connect (GTK_OBJECT (listbox), "select_row",
486 GTK_SIGNAL_FUNC (listbox_select), l);
487 l->widget.wdata = (widget_data) sw;
488 gtk_widget_show (listbox);
490 g_warning ("FIXME: actually compute the real size of the listbox");
491 l->height = 8;
493 for (p = l->list, i = 0; i < l->count; i++, p = p->next){
494 char *text [1];
496 text [0] = p->text;
497 gtk_clist_append (GTK_CLIST (listbox), text);
499 x_listbox_select_nth (l, l->pos);
500 return 1;
503 void
504 x_list_insert (WListbox *l, WLEntry *p, WLEntry *e)
506 int pos = 0, i;
507 char *text [1];
509 if (!l->widget.wdata)
510 return;
512 for (i = 0; i < l->count; i++){
513 if (p == e)
514 break;
515 p = p->next;
516 pos++;
519 if (p != e){
520 printf ("x_list_insert: should not happen!\n");
521 return;
523 text [0] = e->text;
524 gtk_clist_append (GTK_CLIST (listbox_pull (l->widget.wdata)), text);
527 /* Labels */
529 x_create_label (Dlg_head *g, widget_data parent, WLabel *l)
531 GtkWidget *label;
533 /* Tempo-hack */
534 if (*l->text == 0){
535 if (0)
536 label = gtk_label_new (l->widget.tkname);
537 else
538 label = gtk_label_new ("");
539 } else
540 label = gtk_label_new (l->text);
541 gtk_widget_show (label);
542 l->widget.wdata = (widget_data) label;
544 return 1;
547 void
548 x_label_set_text (WLabel *label, char *text)
550 if (label->widget.wdata)
551 gtk_label_set (GTK_LABEL (label->widget.wdata), text);
554 #if 0
555 /* Buttonbar */
556 static void
557 buttonbar_clicked (GtkWidget *widget, WButtonBar *bb)
559 GtkBox *box = GTK_BOX (widget->parent);
560 GList *children = box->children;
561 int i;
563 /* Find out which button we are (number) */
564 for (i = 0; children; children = children->next, i++){
565 if (((GtkBoxChild *)children->data)->widget == widget){
566 if (bb->labels [i].function)
567 (*bb->labels [i].function)(bb->labels [i].data);
568 return;
571 printf ("Mhm, should not happen or The Cow is out\n");
573 #endif
576 x_create_buttonbar (Dlg_head *h, widget_data parent, WButtonBar *bb)
578 GtkWidget *hbox;
579 #if 0
580 int i;
581 #endif
583 hbox = gtk_hbox_new (0, 0);
584 #if 0
585 for (i = 0; i < 10; i++){
586 char buffer [40];
587 GtkButton *b;
589 g_snprintf (buffer, sizeof (buffer), "F%d %s", i+1, bb->labels [i].text ? bb->labels [i].text : " ");
590 b = (GtkButton *) gtk_button_new_with_label (buffer);
591 gtk_signal_connect (GTK_OBJECT (b), "clicked",
592 GTK_SIGNAL_FUNC (buttonbar_clicked), bb);
593 gtk_widget_show (GTK_WIDGET (b));
594 gtk_box_pack_start_defaults (GTK_BOX (hbox), (GtkWidget *)b);
596 gtk_widget_show (hbox);
597 #endif
598 bb->widget.wdata = (widget_data) hbox;
599 return 1;
602 void
603 x_redefine_label (WButtonBar *bb, int idx)
605 #if 0
606 GtkBox *box = GTK_BOX (bb->widget.wdata);
607 GtkBoxChild *bc = (GtkBoxChild *)g_list_nth (box->children, idx)->data;
608 GtkButton *button = GTK_BUTTON (bc->widget);
609 GtkWidget *label = gtk_label_new (bb->labels [idx].text);
611 gtk_widget_show (label);
612 gtk_container_remove (GTK_CONTAINER (button), button->child);
613 gtk_container_add (GTK_CONTAINER (button), label);
614 #endif
617 /* Gauges */
619 x_create_gauge (Dlg_head *h, widget_data parent, WGauge *g)
621 GtkWidget *pbar;
623 pbar = gtk_progress_bar_new ();
624 gtk_widget_show (pbar);
625 g->widget.wdata = (widget_data) pbar;
627 return 1;
630 void
631 x_gauge_show (WGauge *g)
633 gtk_widget_show (GTK_WIDGET (g->widget.wdata));
636 void
637 x_gauge_set_value (WGauge *g, int max, int current)
639 gtk_progress_bar_update (GTK_PROGRESS_BAR (g->widget.wdata), ((gfloat) current / (gfloat) max));