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
69
70
71
72 static cb_ret_t
73 history_dlg_reposition (WDialog *dlg_head)
74 {
75 history_dlg_data *data;
76 int x = 0, y, he, wi;
77 WRect r;
78
79
80 if (dlg_head == NULL || dlg_head->data.p == NULL)
81 return MSG_NOT_HANDLED;
82
83 data = (history_dlg_data *) dlg_head->data.p;
84
85 y = data->y;
86 he = data->count + 2;
87
88 if (he <= y || y > (LINES - 6))
89 {
90 he = MIN (he, y - 1);
91 y -= he;
92 }
93 else
94 {
95 y++;
96 he = MIN (he, LINES - y);
97 }
98
99 if (data->x > 2)
100 x = data->x - 2;
101
102 wi = data->max_width + 4;
103
104 if ((wi + x) > COLS)
105 {
106 wi = MIN (wi, COLS);
107 x = COLS - wi;
108 }
109
110 rect_init (&r, y, x, he, wi);
111
112 return dlg_default_callback (WIDGET (dlg_head), NULL, MSG_RESIZE, 0, &r);
113 }
114
115
116
117 static cb_ret_t
118 history_dlg_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
119 {
120 switch (msg)
121 {
122 case MSG_RESIZE:
123 return history_dlg_reposition (DIALOG (w));
124
125 case MSG_NOTIFY:
126 {
127
128 WDialog *d = DIALOG (w);
129
130 switch (parm)
131 {
132 case CK_View:
133 d->ret_value = B_VIEW;
134 break;
135 case CK_Edit:
136 d->ret_value = B_EDIT;
137 break;
138 case CK_Enter:
139 d->ret_value = B_ENTER;
140 break;
141 default:
142 return MSG_NOT_HANDLED;
143 }
144
145 dlg_close (d);
146 return MSG_HANDLED;
147 }
148
149 default:
150 return dlg_default_callback (w, sender, msg, parm, data);
151 }
152 }
153
154
155
156 static void
157 history_create_item (history_descriptor_t *hd, void *data)
158 {
159 char *text = (char *) data;
160 size_t width;
161
162 width = str_term_width1 (text);
163 hd->max_width = MAX (width, hd->max_width);
164
165 listbox_add_item (hd->listbox, LISTBOX_APPEND_AT_END, 0, text, NULL, TRUE);
166 }
167
168
169
170 static void *
171 history_release_item (history_descriptor_t *hd, WLEntry *le)
172 {
173 void *text;
174
175 (void) hd;
176
177 text = le->text;
178 le->text = NULL;
179
180 return text;
181 }
182
183
184
185
186
187 void
188 history_descriptor_init (history_descriptor_t *hd, int y, int x, GList *history, int current)
189 {
190 hd->list = history;
191 hd->y = y;
192 hd->x = x;
193 hd->current = current;
194 hd->action = CK_IgnoreKey;
195 hd->text = NULL;
196 hd->max_width = 0;
197 hd->listbox = listbox_new (1, 1, 2, 2, TRUE, NULL);
198
199 hd->create = history_create_item;
200 hd->release = history_release_item;
201 hd->free = g_free;
202 }
203
204
205
206 void
207 history_show (history_descriptor_t *hd)
208 {
209 GList *z, *hi;
210 size_t count;
211 WDialog *query_dlg;
212 history_dlg_data hist_data;
213 int dlg_ret;
214
215 if (hd == NULL || hd->list == NULL)
216 return;
217
218 hd->max_width = str_term_width1 (_("History")) + 2;
219
220 for (z = hd->list; z != NULL; z = g_list_previous (z))
221 hd->create (hd, z->data);
222
223
224 count = listbox_get_length (hd->listbox);
225
226 hist_data.y = hd->y;
227 hist_data.x = hd->x;
228 hist_data.count = count;
229 hist_data.max_width = hd->max_width;
230
231 query_dlg =
232 dlg_create (TRUE, 0, 0, 4, 4, WPOS_KEEP_DEFAULT, TRUE, dialog_colors, history_dlg_callback,
233 NULL, "[History-query]", _("History"));
234 query_dlg->data.p = &hist_data;
235
236
237
238 group_add_widget_autopos (GROUP (query_dlg), hd->listbox, WPOS_KEEP_ALL, NULL);
239
240
241
242
243
244
245 send_message (query_dlg, NULL, MSG_RESIZE, 0, NULL);
246
247 if (WIDGET (query_dlg)->rect.y < hd->y)
248 {
249
250
251 g_queue_reverse (hd->listbox->list);
252 if (hd->current < 0 || (size_t) hd->current >= count)
253 listbox_select_last (hd->listbox);
254 else
255 listbox_set_current (hd->listbox, count - 1 - (size_t) hd->current);
256 }
257 else
258 {
259
260 if (hd->current > 0)
261 listbox_set_current (hd->listbox, hd->current);
262 }
263
264 dlg_ret = dlg_run (query_dlg);
265 if (dlg_ret != B_CANCEL)
266 {
267 char *q;
268
269 switch (dlg_ret)
270 {
271 case B_EDIT:
272 hd->action = CK_Edit;
273 break;
274 case B_VIEW:
275 hd->action = CK_View;
276 break;
277 default:
278 hd->action = CK_Enter;
279 }
280
281 listbox_get_current (hd->listbox, &q, NULL);
282 hd->text = g_strdup (q);
283 }
284
285
286 z = NULL;
287 for (hi = listbox_get_first_link (hd->listbox); hi != NULL; hi = g_list_next (hi))
288
289 z = g_list_prepend (z, hd->release (hd, LENTRY (hi->data)));
290
291
292 if (WIDGET (query_dlg)->rect.y < hd->y)
293 z = g_list_reverse (z);
294
295 widget_destroy (WIDGET (query_dlg));
296
297 hd->list = g_list_first (hd->list);
298 g_list_free_full (hd->list, hd->free);
299 hd->list = g_list_last (z);
300 }
301
302