This source file includes following definitions.
- history_dlg_reposition
- history_dlg_callback
- history_create_item
- history_release_item
- history_descriptor_init
- history_show
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <config.h>
36
37 #include <stdlib.h>
38 #include <sys/types.h>
39
40 #include "lib/global.h"
41
42 #include "lib/tty/tty.h"
43 #include "lib/strutil.h"
44 #include "lib/widget.h"
45 #include "lib/keybind.h"
46
47
48
49
50
51 #define B_VIEW (B_USER + 1)
52 #define B_EDIT (B_USER + 2)
53
54
55
56 typedef struct
57 {
58 int y;
59 int x;
60 size_t count;
61 size_t max_width;
62 } history_dlg_data;
63
64
65
66
67
68 static cb_ret_t
69 history_dlg_reposition (WDialog * dlg_head)
70 {
71 history_dlg_data *data;
72 int x = 0, y, he, wi;
73 WRect r;
74
75
76 if ((dlg_head == NULL) || (dlg_head->data == NULL))
77 return MSG_NOT_HANDLED;
78
79 data = (history_dlg_data *) dlg_head->data;
80
81 y = data->y;
82 he = data->count + 2;
83
84 if (he <= y || y > (LINES - 6))
85 {
86 he = MIN (he, y - 1);
87 y -= he;
88 }
89 else
90 {
91 y++;
92 he = MIN (he, LINES - y);
93 }
94
95 if (data->x > 2)
96 x = data->x - 2;
97
98 wi = data->max_width + 4;
99
100 if ((wi + x) > COLS)
101 {
102 wi = MIN (wi, COLS);
103 x = COLS - wi;
104 }
105
106 rect_init (&r, y, x, he, wi);
107
108 return dlg_default_callback (WIDGET (dlg_head), NULL, MSG_RESIZE, 0, &r);
109 }
110
111
112
113 static cb_ret_t
114 history_dlg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
115 {
116 switch (msg)
117 {
118 case MSG_RESIZE:
119 return history_dlg_reposition (DIALOG (w));
120
121 case MSG_NOTIFY:
122 {
123
124 WDialog *d = DIALOG (w);
125
126 switch (parm)
127 {
128 case CK_View:
129 d->ret_value = B_VIEW;
130 break;
131 case CK_Edit:
132 d->ret_value = B_EDIT;
133 break;
134 case CK_Enter:
135 d->ret_value = B_ENTER;
136 break;
137 default:
138 return MSG_NOT_HANDLED;
139 }
140
141 dlg_stop (d);
142 return MSG_HANDLED;
143 }
144
145 default:
146 return dlg_default_callback (w, sender, msg, parm, data);
147 }
148 }
149
150
151
152 static void
153 history_create_item (history_descriptor_t * hd, void *data)
154 {
155 char *text = (char *) data;
156 size_t width;
157
158 width = str_term_width1 (text);
159 hd->max_width = MAX (width, hd->max_width);
160
161 listbox_add_item (hd->listbox, LISTBOX_APPEND_AT_END, 0, text, NULL, TRUE);
162 }
163
164
165
166 static void *
167 history_release_item (history_descriptor_t * hd, WLEntry * le)
168 {
169 void *text;
170
171 (void) hd;
172
173 text = le->text;
174 le->text = NULL;
175
176 return text;
177 }
178
179
180
181
182
183 void
184 history_descriptor_init (history_descriptor_t * hd, int y, int x, GList * history, int current)
185 {
186 hd->list = history;
187 hd->y = y;
188 hd->x = x;
189 hd->current = current;
190 hd->action = CK_IgnoreKey;
191 hd->text = NULL;
192 hd->max_width = 0;
193 hd->listbox = listbox_new (1, 1, 2, 2, TRUE, NULL);
194
195 hd->create = history_create_item;
196 hd->release = history_release_item;
197 hd->free = g_free;
198 }
199
200
201
202 void
203 history_show (history_descriptor_t * hd)
204 {
205 GList *z, *hi;
206 size_t count;
207 WDialog *query_dlg;
208 history_dlg_data hist_data;
209 int dlg_ret;
210
211 if (hd == NULL || hd->list == NULL)
212 return;
213
214 hd->max_width = str_term_width1 (_("History")) + 2;
215
216 for (z = hd->list; z != NULL; z = g_list_previous (z))
217 hd->create (hd, z->data);
218
219
220 count = listbox_get_length (hd->listbox);
221
222 hist_data.y = hd->y;
223 hist_data.x = hd->x;
224 hist_data.count = count;
225 hist_data.max_width = hd->max_width;
226
227 query_dlg =
228 dlg_create (TRUE, 0, 0, 4, 4, WPOS_KEEP_DEFAULT, TRUE, dialog_colors, history_dlg_callback,
229 NULL, "[History-query]", _("History"));
230 query_dlg->data = &hist_data;
231
232
233
234 group_add_widget_autopos (GROUP (query_dlg), hd->listbox, WPOS_KEEP_ALL, NULL);
235
236
237
238
239
240
241 send_message (query_dlg, NULL, MSG_RESIZE, 0, NULL);
242
243 if (WIDGET (query_dlg)->rect.y < hd->y)
244 {
245
246
247 g_queue_reverse (hd->listbox->list);
248 if (hd->current < 0 || (size_t) hd->current >= count)
249 listbox_select_last (hd->listbox);
250 else
251 listbox_select_entry (hd->listbox, count - 1 - (size_t) hd->current);
252 }
253 else
254 {
255
256 if (hd->current > 0)
257 listbox_select_entry (hd->listbox, hd->current);
258 }
259
260 dlg_ret = dlg_run (query_dlg);
261 if (dlg_ret != B_CANCEL)
262 {
263 char *q;
264
265 switch (dlg_ret)
266 {
267 case B_EDIT:
268 hd->action = CK_Edit;
269 break;
270 case B_VIEW:
271 hd->action = CK_View;
272 break;
273 default:
274 hd->action = CK_Enter;
275 }
276
277 listbox_get_current (hd->listbox, &q, NULL);
278 hd->text = g_strdup (q);
279 }
280
281
282 z = NULL;
283 for (hi = listbox_get_first_link (hd->listbox); hi != NULL; hi = g_list_next (hi))
284
285 z = g_list_prepend (z, hd->release (hd, LENTRY (hi->data)));
286
287
288 if (WIDGET (query_dlg)->rect.y < hd->y)
289 z = g_list_reverse (z);
290
291 widget_destroy (WIDGET (query_dlg));
292
293 hd->list = g_list_first (hd->list);
294 g_list_free_full (hd->list, hd->free);
295 hd->list = g_list_last (z);
296 }
297
298