1 /* Widgets for the Midnight Commander
3 Copyright (C) 1994, 1995, 1996 the Free Software Foundation
5 Authors: 1994, 1995 Radek Doulik
6 1994, 1995 Miguel de Icaza
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
43 #include "key.h" /* XCTRL and ALT macros */
45 #include "profile.h" /* for history loading and saving */
48 # define x_create_button(a,b,c) 1
49 # define x_create_radio(a,b,c) 1
50 # define x_create_check(a,b,c) 1
51 # define x_create_label(a,b,c) 1
52 # define x_create_input(a,b,c) 1
53 # define x_create_listbox(a,b,c) 1
54 # define x_create_buttonbar(a,b,c) 1
55 # define x_create_gauge(a,b,c) 1
56 # define x_listbox_select_nth(a,b)
57 # define x_list_insert(a,b,c)
58 # define x_redefine_label(a,b)
61 #ifndef PORT_HAS_DESTROY_CMD
62 # define x_destroy_cmd(w)
65 #ifndef PORT_HAS_RADIO_FOCUS_ITEM
66 # define x_radio_focus_item(r)
69 #ifndef PORT_HAS_RADIO_TOGGLE
70 # define x_radio_toggle
73 static int button_event (Gpm_Event
*event
, WButton
*b
);
78 button_callback (Dlg_head
*h
, WButton
*b
, int Msg
, int Par
)
86 return x_create_button (h
, h
->wdata
, b
);
89 if (b
->hotkey
== Par
|| toupper(b
->hotkey
) == Par
){
90 button_callback (h
, b
, WIDGET_KEY
, ' '); /* to make action */
96 if (Par
!= ' ' && Par
!= '\n')
100 stop
= (*b
->callback
)(b
->action
, b
->callback_data
);
101 if (!b
->callback
|| stop
){
102 h
->ret_value
= b
->action
;
111 char *s
= b
->action
== B_ENTER
? ".button" : "";
113 tk_evalf ("focus %s%s", (char *)(b
->widget
.wdata
)+1, s
);
114 /* Do not call default_proc: we did the tk focus command */
135 widget_move (&b
->widget
, 0, b
->hotpos
+ off
);
141 if (Msg
==WIDGET_UNFOCUS
)
143 else if (Msg
==WIDGET_FOCUS
)
148 sprintf (buf
, "[< %s >]", b
->text
);
152 sprintf (buf
, "[ %s ]", b
->text
);
156 sprintf (buf
, "[%s]", b
->text
);
167 attrset ((b
->selected
) ? FOCUSC
: NORMALC
);
168 widget_move (&b
->widget
, 0, 0);
173 attrset ((b
->selected
) ? HOT_FOCUSC
: HOT_NORMALC
);
174 widget_move (&b
->widget
, 0, b
->hotpos
+off
);
175 addch ((unsigned char)b
->text
[b
->hotpos
]);
177 if (Msg
== WIDGET_FOCUS
)
183 #endif /* !HAVE_XVIEW */
185 return default_proc (h
, Msg
, Par
);
189 button_event (Gpm_Event
*event
, WButton
*b
)
192 if (event
->type
& (GPM_DOWN
|GPM_UP
)){
193 Dlg_head
*h
=b
->widget
.parent
;
194 dlg_select_widget (h
, b
);
195 if (event
->type
& GPM_UP
){
196 button_callback (h
, b
, WIDGET_KEY
, ' ');
197 (*h
->callback
) (h
, ' ', DLG_POST_KEY
);
206 button_destroy (WButton
*b
)
213 button_len (const char *text
, unsigned int flags
)
216 int ret
= strlen (text
);
233 return strlen (text
);
238 * Assuming that button text is malloc'ed, we may safely change it
239 * (as opposed to statically allocated); from other hand, excluding &
240 * and shifting data past it to the left results to one unused byte.
241 * This does not harm though :)
244 button_scan_hotkey(WButton
* b
)
246 char* cp
= strchr (b
->text
, '&');
248 if (cp
!= NULL
&& cp
[1] != '\0'){
250 b
->hotkey
= tolower (*cp
);
251 b
->hotpos
= cp
- b
->text
;
256 button_new (int y
, int x
, int action
, int flags
, char *text
,
257 int (*callback
)(int, void *), void *callback_data
, char *tkname
)
259 WButton
*b
= xmalloc (sizeof (WButton
), "new_button");
261 init_widget (&b
->widget
, y
, x
, 1, button_len (text
, flags
),
262 (callback_fn
) button_callback
,
263 (destroy_fn
) button_destroy
, (mouse_h
)button_event
, tkname
);
268 b
->text
= strdup (text
);
269 b
->callback
= callback
;
270 b
->callback_data
= callback_data
;
271 widget_want_hotkey (b
->widget
, 1);
275 button_scan_hotkey(b
);
280 button_set_text (WButton
*b
, char *text
)
283 b
->text
= strdup (text
);
284 b
->widget
.cols
= button_len (text
, b
->flags
);
285 button_scan_hotkey(b
);
287 x_button_set (b
, b
->text
);
289 dlg_redraw (b
->widget
.parent
);
294 /* Radio button widget */
295 static int radio_event (Gpm_Event
*event
, WRadio
*r
);
298 radio_callback (Dlg_head
*h
, WRadio
*r
, int Msg
, int Par
)
304 return x_create_radio (h
, h
->wdata
, r
);
309 int i
, lp
= tolower(Par
);
312 for (i
= 0; i
< r
->count
; i
++){
313 cp
= strchr (r
->texts
[i
], '&');
314 if (cp
!= NULL
&& cp
[1] != '\0'){
315 int c
= tolower (cp
[1]);
320 radio_callback (h
, r
, WIDGET_KEY
, ' '); /* Take action */
331 (*h
->callback
) (h
, h
->current
->dlg_id
, DLG_ACTION
);
332 radio_callback (h
, r
, WIDGET_FOCUS
, ' ');
340 x_radio_focus_item (r
);
347 if (r
->count
- 1 > r
->pos
) {
349 x_radio_focus_item (r
);
358 x_radio_focus_item (r
);
365 (*h
->callback
) (h
, h
->current
->dlg_id
, DLG_ACTION
);
366 radio_callback (h
, r
, WIDGET_FOCUS
, ' ');
367 widget_move (&r
->widget
, r
->pos
, 1);
373 for (i
= 0; i
< r
->count
; i
++){
375 attrset ((i
==r
->pos
&& Msg
==WIDGET_FOCUS
) ? FOCUSC
:NORMALC
);
376 widget_move (&r
->widget
, i
, 0);
378 printw("(%c) ", (r
->sel
== i
) ? '*' : ' ');
379 for (cp
= r
->texts
[i
]; *cp
; cp
++)
383 attrset ((i
==r
->pos
&& Msg
==WIDGET_FOCUS
)
384 ? HOT_FOCUSC
: HOT_NORMALC
);
386 attrset ((i
==r
->pos
&& Msg
==WIDGET_FOCUS
) ? FOCUSC
: NORMALC
);
396 return default_proc (h
, Msg
, Par
);
400 static void Radio_destroy (WRadio
*r
)
404 # define radio_destroy (destroy_fn) Radio_destroy
406 # define radio_destroy 0
410 radio_event (Gpm_Event
*event
, WRadio
*r
)
413 if (event
->type
& (GPM_DOWN
|GPM_UP
)){
414 Dlg_head
*h
= r
->widget
.parent
;
416 r
->pos
= event
->y
- 1;
417 dlg_select_widget (h
, r
);
418 if (event
->type
& GPM_UP
){
419 radio_callback (h
, r
, WIDGET_KEY
, ' ');
420 radio_callback (h
, r
, WIDGET_FOCUS
, 0);
421 (*h
->callback
) (h
, ' ', DLG_POST_KEY
);
430 radio_new (int y
, int x
, int count
, char **texts
, int use_hotkey
, char *tkname
)
432 WRadio
*r
= xmalloc (sizeof (WRadio
), "radio_new");
435 /* Compute the longest string */
437 for (i
= 0; i
< count
; i
++){
438 m
= strlen (texts
[i
]);
443 init_widget (&r
->widget
, y
, x
, count
, max
, (callback_fn
) radio_callback
,
444 radio_destroy
, (mouse_h
) radio_event
, tkname
);
450 r
->upper_letter_is_hotkey
= use_hotkey
;
451 widget_want_hotkey (r
->widget
, 1);
457 /* Checkbutton widget */
459 static int check_event (Gpm_Event
*event
, WCheck
*b
);
462 check_callback (Dlg_head
*h
, WCheck
*c
, int Msg
, int Par
)
466 return x_create_check (h
, h
->wdata
, c
);
470 if (c
->hotkey
==Par
||
471 (c
->hotkey
>='a' && c
->hotkey
<='z' && c
->hotkey
-32==Par
)){
472 check_callback (h
, c
, WIDGET_KEY
, ' '); /* make action */
481 c
->state
^= C_CHANGE
;
482 (*h
->callback
) (h
, h
->current
->dlg_id
, DLG_ACTION
);
483 check_callback (h
, c
, WIDGET_FOCUS
, ' ');
488 widget_move (&c
->widget
, 0, 1);
494 attrset ((Msg
== WIDGET_FOCUS
) ? FOCUSC
: NORMALC
);
495 widget_move (&c
->widget
, 0, 0);
496 printw ("[%c] %s", (c
->state
& C_BOOL
) ? 'x' : ' ', c
->text
);
499 attrset ((Msg
== WIDGET_FOCUS
) ? HOT_FOCUSC
: HOT_NORMALC
);
500 widget_move (&c
->widget
, 0, + c
->hotpos
+4);
501 addch ((unsigned char)c
->text
[c
->hotpos
]);
505 #endif /* !HAVE_XVIEW */
507 return default_proc (h
, Msg
, Par
);
511 check_event (Gpm_Event
*event
, WCheck
*c
)
514 if (event
->type
& (GPM_DOWN
|GPM_UP
)){
515 Dlg_head
*h
= c
->widget
.parent
;
517 dlg_select_widget (h
, c
);
518 if (event
->type
& GPM_UP
){
519 check_callback (h
, c
, WIDGET_KEY
, ' ');
520 check_callback (h
, c
, WIDGET_FOCUS
, 0);
521 (*h
->callback
) (h
, ' ', DLG_POST_KEY
);
530 check_destroy (WCheck
*c
)
537 check_new (int y
, int x
, int state
, char *text
, char *tkname
)
539 WCheck
*c
= xmalloc (sizeof (WCheck
), "check_new");
542 init_widget (&c
->widget
, y
, x
, 1, strlen (text
),
543 (callback_fn
)check_callback
,
544 (destroy_fn
)check_destroy
, (mouse_h
) check_event
, tkname
);
545 c
->state
= state
? C_BOOL
: 0;
546 c
->text
= strdup (text
);
549 widget_want_hotkey (c
->widget
, 1);
551 /* Scan for the hotkey */
552 for (s
= text
, t
= c
->text
; *s
; s
++, t
++){
559 c
->hotkey
= tolower (*s
);
560 c
->hotpos
= t
- c
->text
;
572 label_callback (Dlg_head
*h
, WLabel
*l
, int Msg
, int Par
)
574 if (Msg
== WIDGET_INIT
)
575 return x_create_label (h
, h
->wdata
, l
);
577 /* We don't want to get the focus */
578 if (Msg
== WIDGET_FOCUS
)
581 if (Msg
== WIDGET_DRAW
&& l
->text
){
582 char *p
= l
->text
, *q
, c
= 0;
585 attrset (DEFAULT_COLOR
);
591 q
= strchr (p
, '\n');
596 widget_move (&l
->widget
, y
, 0);
598 xlen
= l
->widget
.cols
- strlen (p
);
600 printw ("%*s", xlen
, " ");
610 return default_proc (h
, Msg
, Par
);
614 label_set_text (WLabel
*label
, char *text
)
616 int newcols
= label
->widget
.cols
;
618 if (label
->text
&& text
&& !strcmp (label
->text
, text
))
619 return; /* Flickering is not nice */
625 label
->text
= strdup (text
);
626 if (label
->auto_adjust_cols
) {
627 newcols
= strlen (text
);
628 if (newcols
> label
->widget
.cols
)
629 label
->widget
.cols
= newcols
;
634 if (label
->widget
.parent
)
636 x_label_set_text (label
, text
);
638 label_callback (label
->widget
.parent
, label
, WIDGET_DRAW
, 0);
640 if (newcols
< label
->widget
.cols
)
641 label
->widget
.cols
= newcols
;
645 label_destroy (WLabel
*l
)
653 label_new (int y
, int x
, char *text
, char *tkname
)
655 WLabel
*l
= xmalloc (sizeof (WLabel
), "label_new");
657 init_widget (&l
->widget
, y
, x
, 1, 1,
658 (callback_fn
) label_callback
,
659 (destroy_fn
) label_destroy
, NULL
, tkname
);
660 l
->text
= text
? strdup (text
) : 0;
661 l
->auto_adjust_cols
= 1;
663 widget_want_cursor (l
->widget
, 0);
668 /* Gauge widget (progress indicator) */
669 /* Currently width is hardcoded here for text mode */
673 gauge_callback (Dlg_head
*h
, WGauge
*g
, int Msg
, int Par
)
676 if (Msg
== WIDGET_INIT
)
677 return x_create_gauge (h
, h
->wdata
, g
);
679 /* We don't want to get the focus */
680 if (Msg
== WIDGET_FOCUS
)
684 if (Msg
== WIDGET_DRAW
){
685 widget_move (&g
->widget
, 0, 0);
688 printw ("%*s", gauge_len
, "");
690 long percentage
, columns
;
691 long total
= g
->max
, done
= g
->current
;
693 if (total
<= 0 || done
< 0) {
699 while (total
> 65535) {
703 percentage
= (200 * done
/ total
+ 1) / 2;
704 columns
= (2 * (gauge_len
- 7) * done
/ total
+ 1) / 2;
706 attrset (GAUGE_COLOR
);
707 printw ("%*s", columns
, "");
709 printw ("%*s] %3d%%", gauge_len
- 7 - columns
, "", percentage
);
714 return default_proc (h
, Msg
, Par
);
718 gauge_set_value (WGauge
*g
, int max
, int current
)
720 if (g
->current
== current
&& g
->max
== max
)
721 return; /* Do not flicker */
723 max
= 1; /* I do not like division by zero :) */
725 /* NOTE: x_gauge_set_value has to be called before we change actual
726 * max and current values in g, since it assumes g->max and
727 * g->current as the previous values and max and current
728 * as the new ones :) */
729 x_gauge_set_value (g
, max
, current
);
731 g
->current
= current
;
734 gauge_callback (g
->widget
.parent
, g
, WIDGET_DRAW
, 0);
739 gauge_show (WGauge
*g
, int shown
)
741 if (g
->shown
== shown
)
747 gauge_callback (g
->widget
.parent
, g
, WIDGET_DRAW
, 0);
752 gauge_destroy (WGauge
*g
)
758 gauge_new (int y
, int x
, int shown
, int max
, int current
, char *tkname
)
760 WGauge
*g
= xmalloc (sizeof (WGauge
), "gauge_new");
762 init_widget (&g
->widget
, y
, x
, 1, gauge_len
,
763 (callback_fn
) gauge_callback
,
764 (destroy_fn
) gauge_destroy
, NULL
, tkname
);
767 max
= 1; /* I do not like division by zero :) */
769 g
->current
= current
;
771 widget_want_cursor (g
->widget
, 0);
778 /* {{{ history button */
780 #define LARGE_HISTORY_BUTTON 1
782 #ifdef LARGE_HISTORY_BUTTON
783 # define HISTORY_BUTTON_WIDTH 3
785 # define HISTORY_BUTTON_WIDTH 1
788 #define should_show_history_button(in) \
789 (in->history && in->field_len > HISTORY_BUTTON_WIDTH * 2 + 1 && in->widget.parent)
791 static void draw_history_button (WInput
* in
)
794 c
= in
->history
->next
? (in
->history
->prev
? '|' : 'v') : '^';
795 widget_move (&in
->widget
, 0, in
->field_len
- HISTORY_BUTTON_WIDTH
);
796 #ifdef LARGE_HISTORY_BUTTON
799 h
= in
->widget
.parent
;
801 attrset (NORMALC
); /* button has the same colour as other buttons */
803 attrset (HOT_NORMALC
);
805 attrset (NORMAL_COLOR
);
807 /* Too distracting: attrset (MARKED_COLOR); */
809 widget_move (&in
->widget
, 0, in
->field_len
- HISTORY_BUTTON_WIDTH
+ 1);
813 attrset (MARKED_COLOR
);
818 /* }}} history button */
821 /* Input widgets now have a global kill ring */
822 /* Pointer to killed data */
823 static char *kill_buffer
= 0;
826 update_input (WInput
*in
, int clear_first
)
832 int buf_len
= strlen (in
->buffer
);
834 if (should_show_history_button (in
))
835 has_history
= HISTORY_BUTTON_WIDTH
;
837 if (in
->disable_update
)
840 /* Make the point visible */
841 if ((in
->point
< in
->first_shown
) ||
842 (in
->point
>= in
->first_shown
+in
->field_len
- has_history
)){
843 in
->first_shown
= in
->point
- (in
->field_len
/ 3);
844 if (in
->first_shown
< 0)
848 /* Adjust the mark */
849 if (in
->mark
> buf_len
)
853 if (clear_first
&& in
->first
)
859 draw_history_button (in
);
863 widget_move (&in
->widget
, 0, 0);
864 for (i
= 0; i
< in
->field_len
- has_history
; i
++)
866 widget_move (&in
->widget
, 0, 0);
868 for (i
= 0, j
= in
->first_shown
; i
< in
->field_len
- has_history
&& in
->buffer
[j
]; i
++){
869 c
= in
->buffer
[j
++];
870 c
= is_printable (c
) ? c
: '.';
875 widget_move (&in
->widget
, 0, in
->point
- in
->first_shown
);
885 winput_set_origin (WInput
*in
, int x
, int field_len
)
888 in
->field_len
= in
->widget
.cols
= field_len
;
889 update_input (in
, 0);
892 /* {{{ history saving and loading */
895 This loads and saves the history of an input line to and from the
896 widget. It is called with the widgets tk name on creation of the
897 widget, and returns the Hist list. It stores histories in the file
898 ~/.mc/history in using the profile code.
900 If def_text is passed as INPUT_LAST_TEXT (to the input_new()
901 function) then input_new assigns the default text to be the last text
902 entered, or "" if not found.
905 int num_history_items_recorded
= 60;
907 Hist
*history_get (char *input_name
)
910 Hist
*old
= 0, *new = 0;
913 if (!num_history_items_recorded
) /* this is how to disable */
919 profile
= concat_dir_and_file (home_dir
, HISTORY_FILE_NAME
);
922 char this_entry
[1024];
923 sprintf (key_name
, "%d", i
);
924 GetPrivateProfileString (input_name
, key_name
, "", this_entry
, sizeof (this_entry
), profile
);
927 new = xmalloc (sizeof (Hist
), "history_get");
928 memset (new, 0, sizeof (Hist
));
929 new->text
= strdup (this_entry
);
930 new->prev
= old
; /* set up list pointers */
936 return new; /* return pointer to last entry in list */
939 #ifdef PORT_WIDGET_WANTS_HISTORY
940 void history_put (char *input_name
, Hist
*h
)
954 if (!num_history_items_recorded
) /* this is how to disable */
957 profile
= concat_dir_and_file (home_dir
, HISTORY_FILE_NAME
);
958 while (h
->next
) /* go to end of list */
961 /* go back 60 places */
962 for (i
= 0; i
< num_history_items_recorded
- 1 && h
->prev
; i
++)
967 profile_clean_section (input_name
, profile
);
969 /* dump histories into profile */
973 /* probably aren't any null entries, but lets be sure */
976 sprintf (key_name
, "%d", i
++);
977 WritePrivateProfileString (input_name
, key_name
, h
->text
, profile
);
985 void history_put (char *input_name
, Hist
*h
)
990 /* }}} history saving and loading */
993 /* {{{ history display */
995 static const char history_title
[] = " History ";
997 int history_callback (Dlg_head
* h
, int Par
, int Msg
)
1002 attrset (COLOR_NORMAL
);
1004 draw_box (h
, 0, 0, h
->lines
, h
->cols
);
1005 attrset (COLOR_HOT_NORMAL
);
1006 dlg_move (h
, 0, (h
->cols
- strlen (history_title
)) / 2);
1007 printw ((char *) history_title
);
1014 static inline int listbox_fwd (WListbox
*l
);
1016 char *show_hist (Hist
*history
, int widget_x
, int widget_y
)
1019 int maxlen
= strlen(history_title
), i
, count
= 0;
1022 Dlg_head
*query_dlg
;
1023 WListbox
*query_list
;
1029 while (z
->prev
) /* goto first */
1033 if ((i
= strlen (hi
->text
)) > maxlen
)
1041 if (h
<= y
|| y
> LINES
- 6)
1049 h
= min(h
, LINES
- y
);
1053 if ((w
= maxlen
+ 4) + x
> COLS
)
1059 query_dlg
= create_dlg (y
, x
, h
, w
, dialog_colors
, history_callback
,
1060 "[History-query]", "history", DLG_NONE
);
1061 query_list
= listbox_new (1, 1, w
- 2, h
- 2, listbox_finish
, 0, NULL
);
1062 add_widget (query_dlg
, query_list
);
1065 while (hi
) { /* traverse */
1066 listbox_add_item (query_list
, 0, 0, hi
->text
, NULL
);
1069 while (listbox_fwd (query_list
));
1073 while (hi
) { /* traverse backwards */
1074 listbox_add_item (query_list
, 0, 0, hi
->text
, NULL
);
1078 run_dlg (query_dlg
);
1080 if (query_dlg
->ret_value
!= B_CANCEL
) {
1081 listbox_get_current (query_list
, &q
, NULL
);
1085 destroy_dlg (query_dlg
);
1089 static void do_show_hist (WInput
* in
)
1092 r
= show_hist (in
->history
, in
->widget
.x
, in
->widget
.y
);
1094 assign_text (in
, r
);
1099 /* }}} history display */
1102 input_destroy (WInput
*in
)
1105 fprintf (stderr
, "Internal error: null Input *\n");
1111 Hist
*current
, *old
;
1113 if (!in
->is_password
&& PORT_WIDGET_WANTS_HISTORY
) /* don't save passwords ;-) */
1114 history_put (in
->history_name
, in
->history
);
1116 current
= in
->history
;
1117 while (current
->next
)
1118 current
= current
->next
;
1121 current
= current
->prev
;
1128 free_completions (in
);
1129 if (in
->history_name
)
1130 free (in
->history_name
);
1133 static char disable_update
= 0;
1136 input_disable_update (WInput
*in
)
1138 in
->disable_update
++;
1142 input_enable_update (WInput
*in
)
1144 in
->disable_update
--;
1145 update_input (in
, 0);
1149 push_history (WInput
*in
, char *text
)
1154 for (p
= text
; *p
== ' ' || *p
== '\t'; p
++);
1158 while (in
->history
->next
)
1159 in
->history
= in
->history
->next
;
1160 if (!strcmp (in
->history
->text
, text
))
1162 new = xmalloc (sizeof (Hist
), "push_history");
1163 in
->history
->next
= new;
1165 new = xmalloc (sizeof (Hist
), "push_history");
1168 new->prev
= in
->history
;
1169 new->text
= strdup (text
);
1174 /* Cleans the input line and adds the current text to the history */
1176 new_input (WInput
*in
)
1179 push_history (in
, in
->buffer
);
1184 free_completions (in
);
1185 update_input (in
, 0);
1189 insert_char (WInput
*in
, int c_code
)
1197 if (strlen (in
->buffer
)+1 == in
->current_max_len
){
1198 /* Expand the buffer */
1199 char *narea
= xmalloc(in
->current_max_len
+ in
->field_len
, "string expansion");
1201 char *p
= in
->buffer
;
1203 strcpy (narea
, in
->buffer
);
1205 in
->current_max_len
+= in
->field_len
;
1209 if (strlen (in
->buffer
)+1 < in
->current_max_len
){
1210 int l
= strlen (&in
->buffer
[in
->point
]);
1211 for (i
= l
+1; i
> 0; i
--)
1212 in
->buffer
[in
->point
+i
] = in
->buffer
[in
->point
+i
-1];
1213 in
->buffer
[in
->point
] = c_code
;
1220 beginning_of_line (WInput
*in
)
1226 end_of_line (WInput
*in
)
1228 in
->point
= strlen (in
->buffer
);
1232 backward_char (WInput
*in
)
1239 forward_char (WInput
*in
)
1241 if (in
->buffer
[in
->point
])
1246 forward_word (WInput
*in
)
1248 char *p
= in
->buffer
+in
->point
;
1250 while ((*p
&& isspace (*p
)) || ispunct (*p
))
1252 while (*p
&& isalnum (*p
))
1254 in
->point
= p
- in
->buffer
;
1258 backward_word (WInput
*in
)
1260 char *p
= in
->buffer
+in
->point
;
1262 while (p
-1 > in
->buffer
-1 && (isspace (*(p
-1)) || ispunct (*(p
-1))))
1264 while (p
-1 > in
->buffer
-1 && isalnum (*(p
-1)))
1266 in
->point
= p
- in
->buffer
;
1271 key_left (WInput
*in
)
1273 if (ctrl_pressed ())
1280 key_right (WInput
*in
)
1282 if (ctrl_pressed ())
1288 #define key_left backward_char
1289 #define key_right forward_char
1293 backward_delete (WInput
*in
)
1299 for (i
= in
->point
; in
->buffer
[i
-1]; i
++)
1300 in
->buffer
[i
-1] = in
->buffer
[i
];
1306 delete_char (WInput
*in
)
1310 for (i
= in
->point
; in
->buffer
[i
]; i
++)
1311 in
->buffer
[i
] = in
->buffer
[i
+1];
1316 copy_region (WInput
*in
, int x_first
, int x_last
)
1318 int first
= min (x_first
, x_last
);
1319 int last
= max (x_first
, x_last
);
1327 kill_buffer
= xmalloc (last
-first
+ 1, "copy_region");
1328 strncpy (kill_buffer
, in
->buffer
+first
, last
-first
);
1329 kill_buffer
[last
-first
] = 0;
1333 delete_region (WInput
*in
, int x_first
, int x_last
)
1335 int first
= min (x_first
, x_last
);
1336 int last
= max (x_first
, x_last
);
1340 strcpy (&in
->buffer
[first
], &in
->buffer
[last
]);
1345 kill_word (WInput
*in
)
1347 int old_point
= in
->point
;
1351 new_point
= in
->point
;
1352 in
->point
= old_point
;
1354 copy_region (in
, old_point
, new_point
);
1355 delete_region (in
, old_point
, new_point
);
1360 back_kill_word (WInput
*in
)
1362 int old_point
= in
->point
;
1366 new_point
= in
->point
;
1367 in
->point
= old_point
;
1369 copy_region (in
, old_point
, new_point
);
1370 delete_region (in
, old_point
, new_point
);
1375 set_mark (WInput
*in
)
1377 in
->mark
= in
->point
;
1381 kill_save (WInput
*in
)
1383 copy_region (in
, in
->mark
, in
->point
);
1387 kill_region (WInput
*in
)
1390 delete_region (in
, in
->point
, in
->mark
);
1400 for (p
= kill_buffer
; *p
; p
++)
1401 insert_char (in
, *p
);
1405 kill_line (WInput
*in
)
1409 kill_buffer
= strdup (&in
->buffer
[in
->point
]);
1410 in
->buffer
[in
->point
] = 0;
1414 assign_text (WInput
*in
, char *text
)
1416 free_completions (in
);
1418 in
->buffer
= strdup (text
); /* was in->buffer->text */
1419 in
->current_max_len
= strlen (in
->buffer
) + 1;
1420 in
->point
= strlen (in
->buffer
);
1426 hist_prev (WInput
*in
)
1431 if (in
->need_push
) {
1432 switch (push_history (in
, in
->buffer
)) {
1433 case 2: in
->history
= in
->history
->prev
; break;
1434 case 1: if (in
->history
->prev
) in
->history
= in
->history
->prev
; break;
1437 } else if (in
->history
->prev
)
1438 in
->history
= in
->history
->prev
;
1441 assign_text (in
, in
->history
->text
);
1446 hist_next (WInput
*in
)
1448 if (in
->need_push
) {
1449 switch (push_history (in
, in
->buffer
)) {
1451 assign_text (in
, "");
1461 if (!in
->history
->next
) {
1462 assign_text (in
, "");
1466 in
->history
= in
->history
->next
;
1467 assign_text (in
, in
->history
->text
);
1473 void (*fn
)(WInput
*in
);
1476 { XCTRL('a'), beginning_of_line
},
1477 { KEY_HOME
, beginning_of_line
},
1478 { KEY_A1
, beginning_of_line
},
1479 { XCTRL('e'), end_of_line
},
1480 { KEY_END
, end_of_line
},
1481 { KEY_C1
, end_of_line
},
1482 { KEY_LEFT
, key_left
},
1483 { XCTRL('b'), backward_char
},
1484 { ALT('b'), backward_word
},
1485 { KEY_RIGHT
, key_right
},
1486 { XCTRL('f'), forward_char
},
1487 { ALT('f'), forward_word
},
1490 { 0177, backward_delete
},
1491 { KEY_BACKSPACE
, backward_delete
},
1492 { XCTRL('h'), backward_delete
},
1493 { KEY_DC
, delete_char
},
1494 { XCTRL('d'), delete_char
},
1495 { ALT('d'), kill_word
},
1496 { ALT(KEY_BACKSPACE
), back_kill_word
},
1497 { ALT(XCTRL('h')), back_kill_word
},
1498 { ALT(127), back_kill_word
},
1500 /* Region manipulation */
1502 { XCTRL('w'), kill_region
},
1503 { ALT('w'), kill_save
},
1504 { XCTRL('y'), yank
},
1505 { XCTRL('k'), kill_line
},
1508 { ALT('p'), hist_prev
},
1509 { ALT('n'), hist_next
},
1510 { ALT('h'), do_show_hist
},
1513 { ALT('\t'), complete
},
1518 /* This function is a test for a special input key used in complete.c */
1519 /* Returns 0 if it is not a special key, 1 if it is a non-complete key
1520 and 2 if it is a complete key */
1522 is_in_input_map (WInput
*in
, int c_code
)
1526 for (i
= 0; input_map
[i
].fn
; i
++)
1527 if (c_code
== input_map
[i
].key_code
)
1528 if (input_map
[i
].fn
== complete
)
1535 #ifdef PORT_WINPUT_DELETES_MARKED
1537 port_region_marked_for_delete (WInput
*in
)
1543 port_region_marked_for_delete (WInput
*in
)
1552 handle_char (WInput
*in
, int c_code
)
1560 in
->inserted_one
= 0;
1563 free_completions (in
);
1564 v
= insert_char (in
, c_code
);
1565 update_input (in
, 1);
1570 for (i
= 0; input_map
[i
].fn
; i
++){
1571 if (c_code
== input_map
[i
].key_code
){
1572 if (input_map
[i
].fn
!= complete
)
1573 free_completions (in
);
1574 (*input_map
[i
].fn
)(in
);
1579 if (!input_map
[i
].fn
){
1580 if (c_code
> 255 || !is_printable (c_code
))
1583 port_region_marked_for_delete (in
);
1585 free_completions (in
);
1586 v
= insert_char (in
, c_code
);
1587 in
->inserted_one
= c_code
;
1589 if (!disable_update
)
1590 update_input (in
, 1);
1594 /* Inserts text in input line */
1596 stuff (WInput
*in
, char *text
, int insert_extra_space
)
1598 input_disable_update (in
);
1600 handle_char (in
, *text
++);
1601 if (insert_extra_space
)
1602 handle_char (in
, ' ');
1603 input_enable_update (in
);
1604 update_input (in
, 1);
1608 input_set_point (WInput
*in
, int pos
)
1610 if (pos
> in
->current_max_len
)
1611 pos
= in
->current_max_len
;
1612 if (pos
!= in
->point
)
1613 free_completions (in
);
1615 update_input (in
, 1);
1618 int input_event (Gpm_Event
*event
, WInput
*b
);
1621 input_callback (Dlg_head
*h
, WInput
*in
, int Msg
, int Par
)
1625 return x_create_input (h
, h
->wdata
, in
);
1629 if (Par
== XCTRL('q')){
1633 v
= handle_char (in
, mi_getch ());
1637 if (Par
== KEY_UP
|| Par
== KEY_DOWN
||
1638 Par
== ESC_CHAR
|| Par
== KEY_F(10) ||
1640 return 0; /* We don't handle up/down */
1646 return handle_char (in
, Par
);
1649 case WIDGET_UNFOCUS
:
1651 update_input (in
, 0);
1653 #endif /* !HAVE_XVIEW */
1656 widget_move (&in
->widget
, 0, in
->point
- in
->first_shown
);
1661 return default_proc (h
, Msg
, Par
);
1664 /* Not declared static, since we check against this value in dlg.c */
1665 /* FIXME: Declare static again and provide an identification mechanism */
1667 input_event (Gpm_Event
*event
, WInput
*in
)
1670 if (event
->type
& (GPM_DOWN
|GPM_DRAG
)){
1671 dlg_select_widget (in
->widget
.parent
, in
);
1673 if (event
->x
>= in
->field_len
- HISTORY_BUTTON_WIDTH
+ 1 && should_show_history_button (in
)) {
1675 update_input (in
, 1);
1677 in
->point
= strlen (in
->buffer
);
1678 if (event
->x
- in
->first_shown
- 1 < in
->point
)
1679 in
->point
= event
->x
- in
->first_shown
- 1;
1683 update_input (in
, 1);
1691 input_new (int y
, int x
, int color
, int len
, char *def_text
, char *tkname
)
1693 WInput
*in
= xmalloc (sizeof (WInput
), "input_new");
1694 int initial_buffer_len
;
1696 init_widget (&in
->widget
, y
, x
, 1, len
,
1697 (callback_fn
) input_callback
,
1698 (destroy_fn
) input_destroy
, (mouse_h
) input_event
, tkname
);
1702 in
->history_name
= 0;
1703 if (tkname
&& PORT_WIDGET_WANTS_HISTORY
){
1705 in
->history_name
= strdup (tkname
);
1706 in
->history
= history_get (tkname
);
1709 if (def_text
== INPUT_LAST_TEXT
) {
1712 if (in
->history
->text
)
1713 def_text
= in
->history
->text
;
1715 initial_buffer_len
= 1 + max (len
, strlen (def_text
));
1716 in
->widget
.options
|= W_IS_INPUT
;
1717 in
->completions
= NULL
;
1718 in
->completion_flags
=
1719 INPUT_COMPLETE_FILENAMES
| INPUT_COMPLETE_HOSTNAMES
|
1720 INPUT_COMPLETE_VARIABLES
| INPUT_COMPLETE_USERNAMES
;
1721 in
->current_max_len
= initial_buffer_len
;
1722 in
->buffer
= xmalloc (initial_buffer_len
, "create_input: in->buffer");
1724 in
->field_len
= len
;
1726 in
->first_shown
= 0;
1727 in
->disable_update
= 0;
1730 in
->is_password
= 0;
1732 strcpy (in
->buffer
, def_text
);
1733 in
->point
= strlen (in
->buffer
);
1739 /* Listbox widget */
1741 /* Should draw the scrollbar, but currently draws only
1742 * indications that there is more information
1744 static int listbox_cdiff (WLEntry
*s
, WLEntry
*e
);
1747 listbox_drawscroll (WListbox
*l
)
1749 extern int slow_terminal
;
1752 int max_line
= l
->height
-1;
1754 /* Are we at the top? */
1755 widget_move (&l
->widget
, 0, l
->width
);
1756 if (l
->list
== l
->top
)
1761 /* Are we at the bottom? */
1762 widget_move (&l
->widget
, max_line
, l
->width
);
1763 top
= listbox_cdiff (l
->list
, l
->top
);
1764 if ((top
+ l
->height
== l
->count
) || l
->height
>= l
->count
)
1769 /* Now draw the nice relative pointer */
1771 line
= 1+ ((l
->pos
* (l
->height
-2)) / l
->count
);
1775 for (i
= 1; i
< max_line
; i
++){
1776 widget_move (&l
->widget
, i
, l
->width
);
1785 listbox_draw (WListbox
*l
, Dlg_head
*h
, int focused
)
1802 for (e
= l
->top
, i
= 0; (i
< l
->height
); i
++){
1804 /* Display the entry */
1805 if (e
== l
->current
&& sel_line
== -1){
1811 widget_move (&l
->widget
, i
, 0);
1813 if ((i
> 0 && e
== l
->list
) || !l
->list
)
1819 printw (" %-*s ", l
->width
-2, name_trunc (text
, l
->width
-2));
1821 l
->cursor_y
= sel_line
;
1825 listbox_drawscroll (l
);
1828 /* Returns the number of items between s and e,
1829 must be on the same linked list */
1831 listbox_cdiff (WLEntry
*s
, WLEntry
*e
)
1835 for (count
= 0; s
!= e
; count
++)
1841 listbox_check_hotkey (WListbox
*l
, int key
)
1853 /* If we didn't find anything, return */
1854 if (i
&& e
== l
->list
)
1857 if (e
->hotkey
== key
)
1865 /* Used only for display updating, for avoiding line at a time scroll */
1867 listbox_select_last (WListbox
*l
, int set_top
)
1870 l
->current
= l
->list
->prev
;
1871 l
->pos
= l
->count
- 1;
1873 l
->top
= l
->list
->prev
;
1874 x_listbox_select_nth (l
, l
->pos
);
1879 listbox_remove_list (WListbox
*l
)
1887 if (l
->widget
.wdata
!= (widget_data
) NULL
) {
1889 for (i
= 0; i
< l
->count
; i
++)
1890 x_listbox_delete_nth (l
, i
);
1895 while (l
->count
--) {
1901 l
->pos
= l
->count
= 0;
1902 l
->list
= l
->top
= l
->current
= 0;
1906 * bor 30.10.96: added force flag to remove *last* entry as well
1907 * bor 30.10.96: corrected selection bug if last entry was removed
1911 listbox_remove_current (WListbox
*l
, int force
)
1915 /* Ok, note: this won't allow for emtpy lists */
1916 if (!force
&& (!l
->count
|| l
->count
== 1))
1920 if (l
->widget
.wdata
!= (widget_data
) NULL
) {
1921 x_listbox_delete_nth (l
, l
->pos
);
1923 if (l
->current
->next
!= l
->list
)
1924 x_listbox_select_nth (l
, l
->pos
);
1925 else if (l
->current
!= l
->list
)
1926 x_listbox_select_nth (l
, l
->pos
- 1);
1928 x_listbox_select_nth (l
, 0);
1935 l
->current
->next
->prev
= l
->current
->prev
;
1936 l
->current
->prev
->next
= l
->current
->next
;
1937 if (p
->next
== l
->list
) {
1938 l
->current
= p
->prev
;
1942 l
->current
= p
->next
;
1945 l
->list
= l
->top
= p
->next
;
1948 l
->list
= l
->top
= l
->current
= 0;
1955 /* Makes *e the selected entry (sets current and pos) */
1957 listbox_select_entry (WListbox
*l
, WLEntry
*dest
)
1966 for (pos
= 0, e
= l
->list
; pos
< l
->count
; e
= e
->next
, pos
++){
1974 while (listbox_cdiff (l
->top
, l
->current
) >= l
->height
)
1975 l
->top
= l
->top
->next
;
1977 l
->top
= l
->current
;
1980 x_listbox_select_nth (l
, l
->pos
);
1984 /* If we are unable to find it, set decent values */
1985 l
->current
= l
->top
= l
->list
;
1987 x_listbox_select_nth (l
, l
->pos
);
1990 /* Selects from base the pos element */
1992 listbox_select_pos (WListbox
*l
, WLEntry
*base
, int pos
)
1994 WLEntry
*last
= l
->list
->prev
;
2007 listbox_back (WListbox
*l
)
2010 listbox_select_entry (l
, listbox_select_pos (l
, l
->list
, l
->pos
-1));
2017 listbox_fwd (WListbox
*l
)
2019 if (l
->current
!= l
->list
->prev
){
2020 listbox_select_entry (l
, listbox_select_pos (l
, l
->list
, l
->pos
+1));
2026 /* Returns 1 if we want a redraw */
2028 listbox_key (WListbox
*l
, int key
)
2039 l
->current
= l
->top
= l
->list
;
2045 l
->current
= l
->top
= l
->list
->prev
;
2046 for (i
= min (l
->height
- 1, l
->count
- 1); i
; i
--)
2047 l
->top
= l
->top
->prev
;
2048 l
->pos
= l
->count
- 1;
2063 for (i
= 0; i
< l
->height
-1; i
++)
2064 j
|= listbox_fwd (l
);
2069 for (i
= 0; i
< l
->height
-1; i
++)
2070 j
|= listbox_back (l
);
2076 static int listbox_event (Gpm_Event
*event
, WListbox
*l
);
2078 listbox_callback (Dlg_head
*h
, WListbox
*l
, int msg
, int par
)
2081 /* int selected_color; Never used */
2086 return x_create_listbox (h
, h
->wdata
, l
);
2090 if ((e
= listbox_check_hotkey (l
, par
)) != NULL
){
2091 listbox_select_entry (l
, e
);
2093 /* Take the appropriate action */
2094 if (l
->action
== listbox_finish
){
2095 l
->widget
.parent
->running
= 0;
2096 l
->widget
.parent
->ret_value
= B_ENTER
;
2097 } else if (l
->action
== listbox_cback
){
2098 if ((*l
->cback
)(l
) == listbox_finish
){
2099 l
->widget
.parent
->running
= 0;
2100 l
->widget
.parent
->ret_value
= B_ENTER
;
2108 if ((ret_code
= listbox_key (l
, par
)))
2109 listbox_draw (l
, h
, 1);
2114 widget_move (&l
->widget
, l
->cursor_y
, 0);
2118 case WIDGET_UNFOCUS
:
2120 listbox_draw (l
, h
, msg
!= WIDGET_UNFOCUS
);
2123 #endif /* !HAVE_XVIEW */
2125 return default_proc (h
, msg
, par
);
2129 listbox_event (Gpm_Event
*event
, WListbox
*l
)
2134 Dlg_head
*h
= l
->widget
.parent
;
2137 if (event
->type
& GPM_DOWN
)
2138 dlg_select_widget (l
->widget
.parent
, l
);
2141 if (event
->type
& (GPM_DOWN
|GPM_DRAG
)){
2142 if (event
->x
< 0 || event
->x
>= l
->width
)
2145 for (i
= -event
->y
; i
>= 0; i
--)
2147 else if (event
->y
> l
->height
)
2148 for (i
= event
->y
- l
->height
; i
> 0; i
--)
2151 listbox_select_entry (l
, listbox_select_pos (l
, l
->top
,
2154 /* We need to refresh ourselves since the dialog manager doesn't */
2155 /* know about this event */
2156 listbox_callback (h
, l
, WIDGET_DRAW
, 0);
2162 if ((event
->type
& (GPM_DOUBLE
|GPM_UP
)) == (GPM_UP
|GPM_DOUBLE
)){
2163 if (event
->x
< 0 || event
->x
>= l
->width
)
2165 if (event
->y
< 1 || event
->y
> l
->height
)
2168 dlg_select_widget (l
->widget
.parent
, l
);
2169 listbox_select_entry (l
, listbox_select_pos (l
, l
->top
, event
->y
- 1));
2172 case listbox_nothing
:
2175 case listbox_finish
:
2176 h
->ret_value
= B_ENTER
;
2181 if ((*l
->cback
)(l
) == listbox_finish
)
2190 listbox_destroy (WListbox
*l
)
2192 WLEntry
*n
, *p
= l
->list
;
2196 for (i
= 0; i
< l
->count
; i
++){
2205 listbox_new (int y
, int x
, int width
, int height
,
2206 int action
, lcback callback
, char *tkname
)
2208 WListbox
*l
= xmalloc (sizeof (WListbox
), "listbox_new");
2209 extern int slow_terminal
;
2211 init_widget (&l
->widget
, y
, x
, height
, width
,
2212 (callback_fn
)listbox_callback
,
2213 (destroy_fn
) listbox_destroy
, (mouse_h
)listbox_event
, tkname
);
2215 l
->list
= l
->top
= l
->current
= 0;
2222 l
->cback
= callback
;
2224 l
->allow_duplicates
= 1;
2225 l
->scrollbar
= slow_terminal
? 0 : 1;
2226 widget_want_hotkey (l
->widget
, 1);
2231 /* Listbox item adding function. They still lack a lot of functionality */
2233 /* 1.11.96 bor: added pos argument to control placement of new entry */
2235 listbox_append_item (WListbox
*l
, WLEntry
*e
, enum append_pos pos
)
2243 } else if (pos
== LISTBOX_APPEND_AT_END
) {
2245 e
->prev
= l
->list
->prev
;
2246 l
->list
->prev
->next
= e
;
2248 } else if (pos
== LISTBOX_APPEND_BEFORE
){
2249 e
->next
= l
->current
;
2250 e
->prev
= l
->current
->prev
;
2251 l
->current
->prev
->next
= e
;
2252 l
->current
->prev
= e
;
2253 if (l
->list
== l
->current
) { /* move list one position down */
2257 } else if (pos
== LISTBOX_APPEND_AFTER
) {
2258 e
->prev
= l
->current
;
2259 e
->next
= l
->current
->next
;
2260 l
->current
->next
->prev
= e
;
2261 l
->current
->next
= e
;
2263 x_list_insert (l
, l
->list
, e
);
2268 listbox_add_item (WListbox
*l
, enum append_pos pos
, int hotkey
, char *text
,
2276 if (!l
->allow_duplicates
)
2277 if (listbox_search_text (l
, text
))
2280 entry
= xmalloc (sizeof (WLEntry
), "listbox_add_item");
2281 entry
->text
= strdup (text
);
2283 entry
->hotkey
= hotkey
;
2285 listbox_append_item (l
, entry
, pos
);
2290 /* Selects the nth entry in the listbox */
2292 listbox_select_by_number (WListbox
*l
, int n
)
2294 listbox_select_entry (l
, listbox_select_pos (l
, l
->list
, n
));
2298 listbox_search_text (WListbox
*l
, char *text
)
2307 if(!strcmp (e
->text
, text
))
2310 } while (e
!=l
->list
);
2315 /* Returns the current string text as well as the associated extra data */
2317 listbox_get_current (WListbox
*l
, char **string
, char **extra
)
2323 if (string
&& l
->current
)
2324 *string
= l
->current
->text
;
2325 if (extra
&& l
->current
)
2326 *extra
= l
->current
->data
;
2330 buttonbar_callback (Dlg_head
*h
, WButtonBar
*bb
, int msg
, int par
)
2336 return x_create_buttonbar (h
, h
->wdata
, bb
);
2343 for (i
= 0; i
< 10; i
++){
2344 if (par
== KEY_F(i
+1) && bb
->labels
[i
].function
){
2345 (*bb
->labels
[i
].function
)(bb
->labels
[i
].data
);
2355 widget_move (&bb
->widget
, 0, 0);
2356 attrset (DEFAULT_COLOR
);
2357 printw ("%-*s", bb
->widget
.cols
- 1, "");
2358 for (i
= 0; i
< COLS
/8 && i
< 10; i
++){
2359 widget_move (&bb
->widget
, 0, i
*8);
2360 attrset (DEFAULT_COLOR
);
2362 attrset (SELECTED_COLOR
);
2363 printw ("%-*s", ((i
+1) * 8 == COLS
? 5 : 6),
2364 bb
->labels
[i
].text
? bb
->labels
[i
].text
: "");
2365 attrset (DEFAULT_COLOR
);
2367 attrset (SELECTED_COLOR
);
2370 #endif /* !HAVE_XVIEW */
2372 return default_proc (h
, msg
, par
);
2376 buttonbar_destroy (WButtonBar
*bb
)
2380 for (i
= 0; i
< 10; i
++){
2381 if (bb
->labels
[i
].text
)
2382 free (bb
->labels
[i
].text
);
2387 buttonbar_event (Gpm_Event
*event
, WButtonBar
*bb
)
2392 if (!(event
->type
& GPM_UP
))
2396 button
= event
->x
/ 8;
2397 if (button
< 10 && bb
->labels
[button
].function
)
2398 (*bb
->labels
[button
].function
)(bb
->labels
[button
].data
);
2404 buttonbar_new (int visible
)
2407 WButtonBar
*bb
= xmalloc (sizeof (WButtonBar
), "buttonbar_new");
2409 init_widget (&bb
->widget
, LINES
-1, 0, 1, COLS
,
2410 (callback_fn
) buttonbar_callback
,
2411 (destroy_fn
) buttonbar_destroy
, (mouse_h
) buttonbar_event
, NULL
);
2413 bb
->visible
= visible
;
2414 for (i
= 0; i
< 10; i
++){
2415 bb
->labels
[i
].text
= 0;
2416 bb
->labels
[i
].function
= 0;
2418 widget_want_hotkey (bb
->widget
, 1);
2419 widget_want_cursor (bb
->widget
, 0);
2425 set_label_text (WButtonBar
*bb
, int index
, char *text
)
2427 if (bb
->labels
[index
-1].text
)
2428 free (bb
->labels
[index
-1].text
);
2430 bb
->labels
[index
-1].text
= strdup (text
);
2433 /* paneletc is either the panel widget, or info or view or tree widget */
2435 find_buttonbar (Dlg_head
*h
, Widget
*paneletc
)
2442 for (i
= 0, item
= h
->current
; i
< h
->count
; i
++, item
= item
->next
){
2443 if (item
->widget
->callback
== (callback_fn
) buttonbar_callback
){
2444 bb
= (WButtonBar
*) item
->widget
;
2446 /* Jakub: do we really need this routine here?
2447 * Does XView hold more that a buttonbar per Dlg_head?
2449 if (x_find_buttonbar_check (bb
, paneletc
)) {
2461 define_label_data (Dlg_head
*h
, Widget
*paneletc
, int idx
, char *text
,
2462 buttonbarfn cback
, void *data
)
2464 WButtonBar
*bb
= find_buttonbar (h
, paneletc
);
2468 set_label_text (bb
, idx
, text
);
2469 bb
->labels
[idx
-1].function
= (void (*)(void *)) cback
;
2470 bb
->labels
[idx
-1].data
= data
;
2471 x_redefine_label (bb
, idx
);
2475 define_label (Dlg_head
*h
, Widget
*paneletc
, int idx
, char *text
, void (*cback
)(void))
2477 define_label_data (h
, paneletc
, idx
, text
, (void (*)(void *)) cback
, 0);
2481 void redraw_labels (Dlg_head
*h
, Widget
*paneletc
)
2487 redraw_labels (Dlg_head
*h
, Widget
*paneletc
)
2492 for (i
= 0, item
= h
->current
; i
< h
->count
; i
++, item
= item
->next
){
2493 if (item
->widget
->callback
== (callback_fn
) buttonbar_callback
){
2494 widget_redraw (h
, item
);