ru.po: Corrections from Evgeny Bulgakov <bgav@netvision.net.il>
[midnight-commander.git] / gnome / gwidget.c
blob14a3798c85423b3f0dac8346c577432cdb6bbd6d
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 = GTK_WIDGET (p->widget->wdata);
24 if (GNOME_IS_ENTRY (w))
25 return (gnome_entry_gtk_entry ((GnomeEntry *)(w)));
26 else
27 return (GTK_WIDGET (p->widget->wdata));
30 void
31 x_dialog_stop (Dlg_head *h)
33 if (h->grided & DLG_GNOME_APP)
34 return;
35 gtk_main_quit ();
38 void
39 x_focus_widget (Widget_Item *p)
41 GtkWidget *w = get_gtk_widget (p);
43 gtk_widget_grab_focus (w);
46 void
47 x_unfocus_widget (Widget_Item *p)
49 GtkWidget *w = get_gtk_widget (p);
50 GtkWidget *toplevel = gtk_widget_get_toplevel (w);
52 /* Only happens if the widget is not yet added to its container */
53 /* I am not yet sure why this happens */
54 if (GTK_IS_WINDOW (toplevel))
55 gtk_window_set_focus (GTK_WINDOW (gtk_widget_get_toplevel (w)), NULL);
58 void
59 x_destroy_cmd (void *w)
61 Widget *widget = (Widget *) w;
63 if (!widget->wdata)
64 return;
65 gtk_widget_destroy (GTK_WIDGET(widget->wdata));
68 /* Buttons */
69 static void
70 gbutton_callback (GtkWidget *w, void *data)
72 WButton *b = data;
73 Dlg_head *h = (Dlg_head *) b->widget.parent;
74 int stop = 0;
76 if (b->callback)
77 stop = (*b->callback)(b->action, b->callback_data);
79 if (!b->callback || stop){
80 h->ret_value = b->action;
81 dlg_stop (h);
85 char *
86 stock_from_text (char *text)
88 char *stock;
90 if ( g_strcasecmp (text, _("ok")) == 0)
91 stock = GNOME_STOCK_BUTTON_OK;
92 else if ( g_strcasecmp (text, _("cancel")) == 0)
93 stock = GNOME_STOCK_BUTTON_CANCEL;
94 else if ( g_strcasecmp (text, _("help")) == 0)
95 stock = GNOME_STOCK_BUTTON_HELP;
96 else if ( g_strcasecmp (text, _("yes")) == 0)
97 stock = GNOME_STOCK_BUTTON_YES;
98 else if ( g_strcasecmp (text, _("no")) == 0)
99 stock = GNOME_STOCK_BUTTON_NO;
100 else if ( g_strcasecmp (text, _("exit")) == 0)
101 stock = GNOME_STOCK_BUTTON_CLOSE;
102 else if ( g_strcasecmp (text, _("abort")) == 0)
103 stock = GNOME_STOCK_BUTTON_CANCEL;
104 else
105 stock = 0;
107 return stock;
111 x_create_button (Dlg_head *h, widget_data parent, WButton *b)
113 GtkWidget *button;
114 char *stock;
115 int tag;
117 stock = stock_from_text (b->text);
119 if (stock){
120 button = gnome_stock_button (stock);
121 } else
122 button = gtk_button_new_with_label (b->text);
124 if (b->flags == DEFPUSH_BUTTON){
125 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
126 gtk_widget_grab_default (button);
128 gtk_widget_show (button);
129 tag = gtk_signal_connect (GTK_OBJECT(button), "clicked", (GtkSignalFunc) gbutton_callback, b);
130 gtk_object_set_data (GTK_OBJECT (button), "click-signal-tag", (void *) tag);
131 b->widget.wdata = (widget_data) button;
133 return 1;
136 static void
137 x_set_text (GtkWidget *w, gpointer data)
139 if (!GTK_IS_LABEL (w))
140 return;
141 gtk_label_set (GTK_LABEL(w), data);
144 void
145 x_button_set (WButton *b, char *text)
147 GtkWidget *button = GTK_WIDGET (b->widget.wdata);
149 gtk_container_foreach (GTK_CONTAINER (button), x_set_text, text);
152 /* Radio buttons */
154 void
155 x_radio_focus_item (WRadio *radio)
157 GList *children = GTK_BOX (radio->widget.wdata)->children;
158 int i;
160 for (i = 0; i < radio->count; i++){
161 if (i == radio->pos){
162 GtkBoxChild *bc = (GtkBoxChild *) children->data;
164 gtk_widget_grab_focus (GTK_WIDGET (bc->widget));
165 break;
167 children = children->next;
171 void
172 x_radio_toggle (WRadio *radio)
174 GList *children = GTK_BOX (radio->widget.wdata)->children;
175 int i;
177 for (i = 0; i < radio->count; i++){
178 GtkBoxChild *bc = (GtkBoxChild *) children->data;
180 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bc->widget), (i == radio->sel) ? 1 : 0);
181 children = children->next;
185 static void
186 radio_toggle (GtkObject *object, WRadio *r)
188 int idx = (int) gtk_object_get_data (object, "index");
190 if (!GTK_TOGGLE_BUTTON (object)->active)
191 return;
193 g_return_if_fail (idx != 0);
194 idx--;
195 r->sel = idx;
198 static char *
199 remove_hotkey (char *text)
201 char *t = g_strdup (text);
202 char *p = strchr (t,'&');
204 if (p)
205 strcpy (p, p+1);
207 return t;
211 x_create_radio (Dlg_head *h, widget_data parent, WRadio *r)
213 GtkWidget *w, *vbox;
214 int i;
216 vbox = gtk_vbox_new (0, 0);
217 for (i = 0; i < r->count; i++){
218 char *text = remove_hotkey (_(r->texts [i]));
220 if (i == 0){
221 w = gtk_radio_button_new_with_label (NULL, text);
222 r->first_gtk_radio = w;
223 } else
224 w = gtk_radio_button_new_with_label_from_widget (r->first_gtk_radio, text);
226 g_free (text);
227 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), (i == r->sel));
228 gtk_signal_connect (GTK_OBJECT (w), "toggled", GTK_SIGNAL_FUNC (radio_toggle), r);
229 gtk_object_set_data (GTK_OBJECT (w), "index", (void *) (i+1));
230 gtk_box_pack_start_defaults (GTK_BOX (vbox), w);
232 gtk_widget_show_all (vbox);
234 r->widget.wdata = (widget_data) vbox;
236 return 1;
239 static void
240 x_check_changed (GtkToggleButton *t, WCheck *c)
242 c->state ^= C_BOOL;
243 c->state ^= C_CHANGE;
246 /* Check buttons */
248 x_create_check (Dlg_head *h, widget_data parent, WCheck *c)
250 GtkWidget *w;
252 w = gtk_check_button_new_with_label (c->text);
253 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), (c->state & C_BOOL));
254 gtk_signal_connect (GTK_OBJECT (w), "toggled", GTK_SIGNAL_FUNC (x_check_changed), c);
255 gtk_widget_show (w);
256 c->widget.wdata = (widget_data) w;
257 return 1;
260 /* Input lines */
261 static void
262 entry_click (GtkWidget *widget, GdkEvent *event, WInput *in)
264 dlg_select_widget (in->widget.parent, in);
265 in->first = 0;
268 static void
269 entry_release (GtkEditable *entry, GdkEvent *event, WInput *in)
271 in->point = entry->current_pos;
272 in->mark = (entry->current_pos == entry->selection_start_pos) ?
273 entry->selection_end_pos : entry->selection_start_pos;
274 if (in->point != in->mark)
275 in->first = 1;
278 static void
279 wentry_changed (GtkEditable *editable, WInput *in)
281 char *text = gtk_entry_get_text (GTK_ENTRY (editable));
283 assign_text (in, text);
284 input_set_point (in, editable->current_pos);
288 x_create_input (Dlg_head *h, widget_data parent, WInput *in)
290 GtkWidget *gnome_entry;
291 GtkEntry *entry;
293 /* The widget might have been initialized manually.
294 * Look in gscreen.c for an example
296 if (in->widget.wdata)
297 return 1;
299 #ifdef USE_GNOME_ENTRY
300 gnome_entry = gnome_entry_new (in->widget.tkname);
301 #else
302 entry = GTK_ENTRY (gnome_entry = gtk_entry_new ());
303 gtk_entry_set_visibility (entry, !in->is_password);
304 #endif
305 gtk_widget_show (gnome_entry);
306 in->widget.wdata = (widget_data) gnome_entry;
308 #ifdef USE_GNOME_ENTRY
309 entry = GTK_ENTRY (gnome_entry_gtk_entry (GNOME_ENTRY (gnome_entry)));
310 #endif
311 gtk_entry_set_text (entry, in->buffer);
312 gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
313 gtk_entry_set_position (entry, in->point);
315 gtk_signal_connect (GTK_OBJECT (entry), "button_press_event",
316 GTK_SIGNAL_FUNC (entry_click), in);
318 gtk_signal_connect (GTK_OBJECT (entry), "button_release_event",
319 GTK_SIGNAL_FUNC (entry_release), in);
321 gtk_signal_connect (GTK_OBJECT (entry), "changed",
322 GTK_SIGNAL_FUNC (wentry_changed), in);
323 return 1;
326 void
327 x_update_input (WInput *in)
329 #ifdef USE_GNOME_ENTRY
330 GnomeEntry *gnome_entry;
331 #endif
332 GtkEntry *entry;
333 char *text;
334 int draw = 0;
336 /* If the widget has not been initialized yet (done by WIDGET_INIT) */
337 if (!in->widget.wdata)
338 return;
340 #ifdef USE_GNOME_ENTRY
341 gnome_entry = GNOME_ENTRY (in->widget.wdata);
342 entry = GTK_ENTRY (gnome_entry_gtk_entry (gnome_entry));
343 #else
344 entry = GTK_ENTRY (in->widget.wdata);
345 #endif
347 /* Block the signal handler */
348 gtk_signal_handler_block_by_func (
349 GTK_OBJECT (entry),
350 GTK_SIGNAL_FUNC(wentry_changed), in);
352 /* Do the actual work */
353 if (in->first == -1){
354 gtk_editable_select_region (GTK_EDITABLE (entry), 0, 0);
355 in->first = 0;
358 text = gtk_entry_get_text (GTK_ENTRY (entry));
360 if (text && strcmp (text, in->buffer)){
361 gtk_entry_set_text (entry, in->buffer);
362 draw = 1;
365 if (GTK_EDITABLE (entry)->current_pos != in->point){
366 gtk_entry_set_position (entry, in->point);
367 draw = 1;
370 if (draw){
371 #ifdef USE_GNOME_ENTRY
372 gtk_widget_draw (GTK_WIDGET (gnome_entry), NULL);
373 #else
374 gtk_widget_draw (GTK_WIDGET (entry), NULL);
375 #endif
376 gtk_editable_changed (GTK_EDITABLE (entry));
377 gtk_widget_queue_draw (GTK_WIDGET (entry));
380 /* Unblock the signal handler */
381 gtk_signal_handler_unblock_by_func (
382 GTK_OBJECT (entry),
383 GTK_SIGNAL_FUNC(wentry_changed), in);
386 /* Listboxes */
387 static GtkWidget *
388 listbox_pull (widget_data data)
390 return GTK_BIN (data)->child;
393 void
394 x_listbox_select_nth (WListbox *l, int nth)
396 static int inside;
397 GtkCList *clist;
399 if (inside)
400 return;
402 if (!l->widget.wdata)
403 return;
405 inside = 1;
406 clist = GTK_CLIST (listbox_pull (l->widget.wdata));
408 gtk_clist_select_row (clist, nth, 0);
409 if (gtk_clist_row_is_visible (clist, nth) != GTK_VISIBILITY_FULL)
410 gtk_clist_moveto (clist, nth, 0, 0.5, 0.0);
412 inside = 0;
415 void
416 x_listbox_delete_nth (WListbox *l, int nth)
418 gtk_clist_remove (GTK_CLIST (listbox_pull (l->widget.wdata)), nth);
421 static void
422 listbox_select (GtkWidget *widget, int row, int column, GdkEvent *event, WListbox *l)
424 Dlg_head *h = l->widget.parent;
425 static int inside;
427 if (inside)
428 return;
429 inside = 1;
431 listbox_select_by_number (l, row);
433 if (!event){
434 inside = 0;
435 return;
439 if (event->type == GDK_2BUTTON_PRESS){
440 switch (l->action){
441 case listbox_nothing:
442 break;
444 case listbox_finish:
445 h->running = 0;
446 h->ret_value = B_ENTER;
447 gtk_main_quit ();
448 return;
450 case listbox_cback:
451 if ((*l->cback)(l) == listbox_finish){
452 gtk_main_quit ();
453 return;
458 /* Send an artificial DLG_POST_KEY */
459 if (event->type == GDK_BUTTON_PRESS)
460 (*l->widget.parent->callback)(l->widget.parent, 0, DLG_POST_KEY);
462 inside = 0;
466 x_create_listbox (Dlg_head *h, widget_data parent, WListbox *l)
468 GtkWidget *listbox, *sw;
469 GtkRequisition req;
470 WLEntry *p;
471 int i;
473 listbox = gtk_clist_new (1);
474 sw = gtk_scrolled_window_new (NULL, NULL);
475 gtk_container_add (GTK_CONTAINER (sw), listbox);
477 gtk_clist_set_selection_mode (GTK_CLIST (listbox), GTK_SELECTION_BROWSE);
478 gtk_widget_size_request (listbox, &req);
479 gtk_widget_set_usize (listbox, req.width, req.height + 20*8);
480 gtk_signal_connect (GTK_OBJECT (listbox), "select_row",
481 GTK_SIGNAL_FUNC (listbox_select), l);
482 l->widget.wdata = (widget_data) sw;
483 gtk_widget_show (listbox);
485 g_warning ("FIXME: actually compute the real size of the listbox");
486 l->height = 8;
488 for (p = l->list, i = 0; i < l->count; i++, p = p->next){
489 char *text [1];
491 text [0] = p->text;
492 gtk_clist_append (GTK_CLIST (listbox), text);
494 x_listbox_select_nth (l, l->pos);
495 return 1;
498 void
499 x_list_insert (WListbox *l, WLEntry *p, WLEntry *e)
501 int pos = 0, i;
502 char *text [1];
504 if (!l->widget.wdata)
505 return;
507 for (i = 0; i < l->count; i++){
508 if (p == e)
509 break;
510 p = p->next;
511 pos++;
514 if (p != e){
515 printf ("x_list_insert: should not happen!\n");
516 return;
518 text [0] = e->text;
519 gtk_clist_append (GTK_CLIST (listbox_pull (l->widget.wdata)), text);
522 /* Labels */
524 x_create_label (Dlg_head *g, widget_data parent, WLabel *l)
526 GtkWidget *label;
528 /* Tempo-hack */
529 if (*l->text == 0){
530 if (0)
531 label = gtk_label_new (l->widget.tkname);
532 else
533 label = gtk_label_new ("");
534 } else
535 label = gtk_label_new (l->text);
536 gtk_widget_show (label);
537 l->widget.wdata = (widget_data) label;
539 return 1;
542 void
543 x_label_set_text (WLabel *label, char *text)
545 if (label->widget.wdata)
546 gtk_label_set (GTK_LABEL (label->widget.wdata), text);
549 #if 0
550 /* Buttonbar */
551 static void
552 buttonbar_clicked (GtkWidget *widget, WButtonBar *bb)
554 GtkBox *box = GTK_BOX (widget->parent);
555 GList *children = box->children;
556 int i;
558 /* Find out which button we are (number) */
559 for (i = 0; children; children = children->next, i++){
560 if (((GtkBoxChild *)children->data)->widget == widget){
561 if (bb->labels [i].function)
562 (*bb->labels [i].function)(bb->labels [i].data);
563 return;
566 printf ("Mhm, should not happen or The Cow is out\n");
568 #endif
571 x_create_buttonbar (Dlg_head *h, widget_data parent, WButtonBar *bb)
573 GtkWidget *hbox;
574 #if 0
575 int i;
576 #endif
578 hbox = gtk_hbox_new (0, 0);
579 #if 0
580 for (i = 0; i < 10; i++){
581 char buffer [40];
582 GtkButton *b;
584 g_snprintf (buffer, sizeof (buffer), "F%d %s", i+1, bb->labels [i].text ? bb->labels [i].text : " ");
585 b = (GtkButton *) gtk_button_new_with_label (buffer);
586 gtk_signal_connect (GTK_OBJECT (b), "clicked",
587 GTK_SIGNAL_FUNC (buttonbar_clicked), bb);
588 gtk_widget_show (GTK_WIDGET (b));
589 gtk_box_pack_start_defaults (GTK_BOX (hbox), (GtkWidget *)b);
591 gtk_widget_show (hbox);
592 #endif
593 bb->widget.wdata = (widget_data) hbox;
594 return 1;
597 void
598 x_redefine_label (WButtonBar *bb, int idx)
600 #if 0
601 GtkBox *box = GTK_BOX (bb->widget.wdata);
602 GtkBoxChild *bc = (GtkBoxChild *)g_list_nth (box->children, idx)->data;
603 GtkButton *button = GTK_BUTTON (bc->widget);
604 GtkWidget *label = gtk_label_new (bb->labels [idx].text);
606 gtk_widget_show (label);
607 gtk_container_remove (GTK_CONTAINER (button), button->child);
608 gtk_container_add (GTK_CONTAINER (button), label);
609 #endif
612 /* Gauges */
614 x_create_gauge (Dlg_head *h, widget_data parent, WGauge *g)
616 GtkWidget *pbar;
618 pbar = gtk_progress_bar_new ();
619 gtk_widget_show (pbar);
620 g->widget.wdata = (widget_data) pbar;
622 return 1;
625 void
626 x_gauge_show (WGauge *g)
628 gtk_widget_show (GTK_WIDGET (g->widget.wdata));
631 void
632 x_gauge_set_value (WGauge *g, int max, int current)
634 gtk_progress_bar_update (GTK_PROGRESS_BAR (g->widget.wdata), ((gfloat) current / (gfloat) max));