This source file includes following definitions.
- search_string
- search_string_node
- search_char_node
- move_forward2
- move_backward2
- move_forward
- move_backward
- move_to_top
- move_to_bottom
- help_follow_link
- select_next_link
- select_prev_link
- start_link_area
- end_link_area
- clear_link_areas
- help_print_word
- help_show
- help_help
- help_index
- help_back
- help_next_link
- help_prev_link
- help_next_node
- help_prev_node
- help_select_link
- help_execute_cmd
- help_handle_key
- help_callback
- interactive_display_finish
- translate_file
- md_callback
- help_mouse_callback
- mousedispatch_new
- help_interactive_display
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #include <config.h>
51
52 #include <errno.h>
53 #include <limits.h>
54 #include <stdio.h>
55 #include <sys/types.h>
56 #include <sys/stat.h>
57
58 #include "lib/global.h"
59
60 #include "lib/tty/tty.h"
61 #include "lib/skin.h"
62 #include "lib/strutil.h"
63 #include "lib/fileloc.h"
64 #include "lib/util.h"
65 #include "lib/widget.h"
66 #include "lib/event-types.h"
67
68 #include "keybind-defaults.h"
69 #include "help.h"
70
71
72
73
74
75 #define MAXLINKNAME 80
76 #define HISTORY_SIZE 20
77 #define HELP_WINDOW_WIDTH MIN(80, COLS - 16)
78
79 #define STRING_LINK_START "\01"
80 #define STRING_LINK_POINTER "\02"
81 #define STRING_LINK_END "\03"
82 #define STRING_NODE_END "\04"
83
84
85
86
87 typedef struct Link_Area
88 {
89 int x1, y1, x2, y2;
90 const char *link_name;
91 } Link_Area;
92
93
94
95 static char *fdata = NULL;
96 static int help_lines;
97 static int history_ptr;
98 static const char *main_node;
99 static const char *last_shown = NULL;
100 static gboolean end_of_node = FALSE;
101 static const char *currentpoint;
102 static const char *selected_item;
103
104
105 static WDialog *whelp;
106
107 static struct
108 {
109 const char *page;
110 const char *link;
111 } history[HISTORY_SIZE];
112
113 static GSList *link_area = NULL;
114 static gboolean inside_link_area = FALSE;
115
116 static cb_ret_t help_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data);
117
118
119
120
121
122
123
124 static const char *
125 search_string (const char *start, const char *text)
126 {
127 const char *result = NULL;
128 char *local_text = g_strdup (text);
129 char *d = local_text;
130 const char *e = start;
131
132
133
134 while (*d != '\0')
135 {
136 if (*d == '\n')
137 *d = ' ';
138 str_next_char (&d);
139 }
140
141
142 for (d = local_text; *e; e++)
143 {
144 if (*d == *e)
145 d++;
146 else
147 d = local_text;
148 if (*d == '\0')
149 {
150 result = e + 1;
151 break;
152 }
153 }
154
155 g_free (local_text);
156 return result;
157 }
158
159
160
161
162
163
164
165 static const char *
166 search_string_node (const char *start, const char *text)
167 {
168 const char *d = text;
169 const char *e = start;
170
171 if (start != NULL)
172 for (; *e && *e != CHAR_NODE_END; e++)
173 {
174 if (*d == *e)
175 d++;
176 else
177 d = text;
178 if (*d == '\0')
179 return e + 1;
180 }
181
182 return NULL;
183 }
184
185
186
187
188
189
190 static const char *
191 search_char_node (const char *start, char the_char, int direction)
192 {
193 const char *e;
194
195 for (e = start; (*e != '\0') && (*e != CHAR_NODE_END); e += direction)
196 if (*e == the_char)
197 return e;
198
199 return NULL;
200 }
201
202
203
204
205 static const char *
206 move_forward2 (const char *c, int lines)
207 {
208 const char *p;
209 int line;
210
211 currentpoint = c;
212 for (line = 0, p = currentpoint; (*p != '\0') && (*p != CHAR_NODE_END); str_cnext_char (&p))
213 {
214 if (line == lines)
215 return currentpoint = p;
216
217 if (*p == '\n')
218 line++;
219 }
220 return currentpoint = c;
221 }
222
223
224
225 static const char *
226 move_backward2 (const char *c, int lines)
227 {
228 const char *p;
229 int line;
230
231 currentpoint = c;
232 for (line = 0, p = currentpoint; (*p != '\0') && ((int) (p - fdata) >= 0); str_cprev_char (&p))
233 {
234 if (*p == CHAR_NODE_END)
235 {
236
237
238 while (*p != ']')
239 str_cnext_char (&p);
240 return currentpoint = p + 2;
241 }
242
243 if (*(p - 1) == '\n')
244 line++;
245 if (line == lines)
246 return currentpoint = p;
247 }
248 return currentpoint = c;
249 }
250
251
252
253 static void
254 move_forward (int i)
255 {
256 if (!end_of_node)
257 currentpoint = move_forward2 (currentpoint, i);
258 }
259
260
261
262 static void
263 move_backward (int i)
264 {
265 currentpoint = move_backward2 (currentpoint, ++i);
266 }
267
268
269
270 static void
271 move_to_top (void)
272 {
273 while (((int) (currentpoint > fdata) > 0) && (*currentpoint != CHAR_NODE_END))
274 currentpoint--;
275
276 while (*currentpoint != ']')
277 currentpoint++;
278 currentpoint = currentpoint + 2;
279 selected_item = NULL;
280 }
281
282
283
284 static void
285 move_to_bottom (void)
286 {
287 while ((*currentpoint != '\0') && (*currentpoint != CHAR_NODE_END))
288 currentpoint++;
289 currentpoint--;
290 move_backward (1);
291 }
292
293
294
295 static const char *
296 help_follow_link (const char *start, const char *lc_selected_item)
297 {
298 const char *p;
299
300 if (lc_selected_item == NULL)
301 return start;
302
303 for (p = lc_selected_item; *p && *p != CHAR_NODE_END && *p != CHAR_LINK_POINTER; p++)
304 ;
305 if (*p == CHAR_LINK_POINTER)
306 {
307 int i;
308 char link_name[MAXLINKNAME];
309
310 link_name[0] = '[';
311 for (i = 1; *p != CHAR_LINK_END && *p && *p != CHAR_NODE_END && i < MAXLINKNAME - 3;)
312 link_name[i++] = *++p;
313 link_name[i - 1] = ']';
314 link_name[i] = '\0';
315 p = search_string (fdata, link_name);
316 if (p != NULL)
317 {
318 p += 1;
319 return p;
320 }
321 }
322
323
324 return _("Help file format error\n");
325 }
326
327
328
329 static const char *
330 select_next_link (const char *current_link)
331 {
332 const char *p;
333
334 if (current_link == NULL)
335 return NULL;
336
337 p = search_string_node (current_link, STRING_LINK_END);
338 if (p == NULL)
339 return NULL;
340 p = search_string_node (p, STRING_LINK_START);
341 if (p == NULL)
342 return NULL;
343 return p - 1;
344 }
345
346
347
348 static const char *
349 select_prev_link (const char *current_link)
350 {
351 return current_link == NULL ? NULL : search_char_node (current_link - 1, CHAR_LINK_START, -1);
352 }
353
354
355
356 static void
357 start_link_area (int x, int y, const char *link_name)
358 {
359 Link_Area *la;
360
361 if (inside_link_area)
362 message (D_NORMAL, _("Warning"), "%s", _("Internal bug: Double start of link area"));
363
364
365 la = g_new (Link_Area, 1);
366
367 la->x1 = x;
368 la->y1 = y;
369
370 la->link_name = link_name;
371 link_area = g_slist_prepend (link_area, la);
372
373 inside_link_area = TRUE;
374 }
375
376
377
378 static void
379 end_link_area (int x, int y)
380 {
381 if (inside_link_area)
382 {
383 Link_Area *la = (Link_Area *) link_area->data;
384
385 la->x2 = x;
386 la->y2 = y;
387 inside_link_area = FALSE;
388 }
389 }
390
391
392
393 static void
394 clear_link_areas (void)
395 {
396 g_slist_free_full (link_area, g_free);
397 link_area = NULL;
398 inside_link_area = FALSE;
399 }
400
401
402
403 static void
404 help_print_word (WDialog * h, GString * word, int *col, int *line, gboolean add_space)
405 {
406 if (*line >= help_lines)
407 g_string_set_size (word, 0);
408 else
409 {
410 int w;
411
412 w = str_term_width1 (word->str);
413 if (*col + w >= HELP_WINDOW_WIDTH)
414 {
415 *col = 0;
416 (*line)++;
417 }
418
419 if (*line >= help_lines)
420 g_string_set_size (word, 0);
421 else
422 {
423 widget_move (h, *line + 2, *col + 2);
424 tty_print_string (word->str);
425 g_string_set_size (word, 0);
426 *col += w;
427 }
428 }
429
430 if (add_space)
431 {
432 if (*col < HELP_WINDOW_WIDTH - 1)
433 {
434 tty_print_char (' ');
435 (*col)++;
436 }
437 else
438 {
439 *col = 0;
440 (*line)++;
441 }
442 }
443 }
444
445
446
447 static void
448 help_show (WDialog * h, const char *paint_start)
449 {
450 const char *p, *n;
451 int col, line, c;
452 gboolean painting = TRUE;
453 gboolean acs;
454 gboolean repeat_paint;
455 int active_col, active_line;
456 char buff[MB_LEN_MAX + 1];
457 GString *word;
458
459 word = g_string_sized_new (32);
460
461 tty_setcolor (HELP_NORMAL_COLOR);
462 do
463 {
464 line = col = active_col = active_line = 0;
465 repeat_paint = FALSE;
466 acs = FALSE;
467
468 clear_link_areas ();
469 if ((int) (selected_item - paint_start) < 0)
470 selected_item = NULL;
471
472 p = paint_start;
473 n = paint_start;
474 while ((n[0] != '\0') && (n[0] != CHAR_NODE_END) && (line < help_lines))
475 {
476 p = n;
477 n = str_cget_next_char (p);
478 memcpy (buff, p, n - p);
479 buff[n - p] = '\0';
480
481 c = (unsigned char) buff[0];
482 switch (c)
483 {
484 case CHAR_LINK_START:
485 if (selected_item == NULL)
486 selected_item = p;
487 if (p != selected_item)
488 tty_setcolor (HELP_LINK_COLOR);
489 else
490 {
491 tty_setcolor (HELP_SLINK_COLOR);
492
493
494 active_col = col + 2;
495 active_line = line + 2;
496 }
497 start_link_area (col, line, p);
498 break;
499 case CHAR_LINK_POINTER:
500 painting = FALSE;
501 break;
502 case CHAR_LINK_END:
503 painting = TRUE;
504 help_print_word (h, word, &col, &line, FALSE);
505 end_link_area (col - 1, line);
506 tty_setcolor (HELP_NORMAL_COLOR);
507 break;
508 case CHAR_ALTERNATE:
509 acs = TRUE;
510 break;
511 case CHAR_NORMAL:
512 acs = FALSE;
513 break;
514 case CHAR_VERSION:
515 widget_move (h, line + 2, col + 2);
516 tty_print_string (VERSION);
517 col += str_term_width1 (VERSION);
518 break;
519 case CHAR_FONT_BOLD:
520 tty_setcolor (HELP_BOLD_COLOR);
521 break;
522 case CHAR_FONT_ITALIC:
523 tty_setcolor (HELP_ITALIC_COLOR);
524 break;
525 case CHAR_FONT_NORMAL:
526 help_print_word (h, word, &col, &line, FALSE);
527 tty_setcolor (HELP_NORMAL_COLOR);
528 break;
529 case '\n':
530 if (painting)
531 help_print_word (h, word, &col, &line, FALSE);
532 line++;
533 col = 0;
534 break;
535 case ' ':
536 case '\t':
537
538 if (painting)
539 {
540 help_print_word (h, word, &col, &line, c == ' ');
541 if (c == '\t')
542 {
543 col = (col / 8 + 1) * 8;
544 if (col >= HELP_WINDOW_WIDTH)
545 {
546 line++;
547 col = 8;
548 }
549 }
550 }
551 break;
552 default:
553 if (painting && (line < help_lines))
554 {
555 if (!acs)
556
557 g_string_append (word, buff);
558 else if (col < HELP_WINDOW_WIDTH)
559 {
560 widget_move (h, line + 2, col + 2);
561
562 if ((c == ' ') || (c == '.'))
563 tty_print_char (c);
564 else
565 #ifndef HAVE_SLANG
566 tty_print_char (acs_map[c]);
567 #else
568 SLsmg_draw_object (WIDGET (h)->y + line + 2, WIDGET (h)->x + col + 2,
569 c);
570 #endif
571 col++;
572 }
573 }
574 }
575 }
576
577
578 if (n[0] == CHAR_NODE_END)
579 help_print_word (h, word, &col, &line, FALSE);
580
581 last_shown = p;
582 end_of_node = line < help_lines;
583 tty_setcolor (HELP_NORMAL_COLOR);
584 if ((int) (selected_item - last_shown) >= 0)
585 {
586 if ((link_area == NULL) || (link_area->data == NULL))
587 selected_item = NULL;
588 else
589 {
590 selected_item = ((Link_Area *) link_area->data)->link_name;
591 repeat_paint = TRUE;
592 }
593 }
594 }
595 while (repeat_paint);
596
597 g_string_free (word, TRUE);
598
599
600 if (active_col)
601 widget_move (h, active_line, active_col);
602 }
603
604
605
606
607 static void
608 help_help (WDialog * h)
609 {
610 const char *p;
611
612 history_ptr = (history_ptr + 1) % HISTORY_SIZE;
613 history[history_ptr].page = currentpoint;
614 history[history_ptr].link = selected_item;
615
616 p = search_string (fdata, "[How to use help]");
617 if (p != NULL)
618 {
619 currentpoint = p + 1;
620 selected_item = NULL;
621 send_message (h, NULL, MSG_DRAW, 0, NULL);
622 }
623 }
624
625
626
627 static void
628 help_index (WDialog * h)
629 {
630 const char *new_item;
631
632 new_item = search_string (fdata, "[Contents]");
633
634 if (new_item == NULL)
635 message (D_ERROR, MSG_ERROR, _("Cannot find node %s in help file"), "[Contents]");
636 else
637 {
638 history_ptr = (history_ptr + 1) % HISTORY_SIZE;
639 history[history_ptr].page = currentpoint;
640 history[history_ptr].link = selected_item;
641
642 currentpoint = new_item + 1;
643 selected_item = NULL;
644 send_message (h, NULL, MSG_DRAW, 0, NULL);
645 }
646 }
647
648
649
650 static void
651 help_back (WDialog * h)
652 {
653 currentpoint = history[history_ptr].page;
654 selected_item = history[history_ptr].link;
655 history_ptr--;
656 if (history_ptr < 0)
657 history_ptr = HISTORY_SIZE - 1;
658
659 send_message (h, NULL, MSG_DRAW, 0, NULL);
660 }
661
662
663
664 static void
665 help_next_link (gboolean move_down)
666 {
667 const char *new_item;
668
669 new_item = select_next_link (selected_item);
670 if (new_item != NULL)
671 {
672 selected_item = new_item;
673 if ((int) (selected_item - last_shown) >= 0)
674 {
675 if (move_down)
676 move_forward (1);
677 else
678 selected_item = NULL;
679 }
680 }
681 else if (move_down)
682 move_forward (1);
683 else
684 selected_item = NULL;
685 }
686
687
688
689 static void
690 help_prev_link (gboolean move_up)
691 {
692 const char *new_item;
693
694 new_item = select_prev_link (selected_item);
695 selected_item = new_item;
696 if ((selected_item == NULL) || (selected_item < currentpoint))
697 {
698 if (move_up)
699 move_backward (1);
700 else if ((link_area != NULL) && (link_area->data != NULL))
701 selected_item = ((Link_Area *) link_area->data)->link_name;
702 else
703 selected_item = NULL;
704 }
705 }
706
707
708
709 static void
710 help_next_node (void)
711 {
712 const char *new_item;
713
714 new_item = currentpoint;
715 while ((*new_item != '\0') && (*new_item != CHAR_NODE_END))
716 new_item++;
717
718 if (*++new_item == '[')
719 while (*++new_item != '\0')
720 if ((*new_item == ']') && (*++new_item != '\0') && (*++new_item != '\0'))
721 {
722 currentpoint = new_item;
723 selected_item = NULL;
724 break;
725 }
726 }
727
728
729
730 static void
731 help_prev_node (void)
732 {
733 const char *new_item;
734
735 new_item = currentpoint;
736 while (((int) (new_item - fdata) > 1) && (*new_item != CHAR_NODE_END))
737 new_item--;
738 new_item--;
739 while (((int) (new_item - fdata) > 0) && (*new_item != CHAR_NODE_END))
740 new_item--;
741 while (*new_item != ']')
742 new_item++;
743 currentpoint = new_item + 2;
744 selected_item = NULL;
745 }
746
747
748
749 static void
750 help_select_link (void)
751 {
752
753 if (selected_item == NULL)
754 {
755 #ifdef WE_WANT_TO_GO_BACKWARD_ON_KEY_RIGHT
756
757
758
759
760
761 history_ptr--;
762 if (history_ptr < 0)
763 history_ptr = HISTORY_SIZE - 1;
764
765 currentpoint = history[history_ptr].page;
766 selected_item = history[history_ptr].link;
767 #endif
768 }
769 else
770 {
771 history_ptr = (history_ptr + 1) % HISTORY_SIZE;
772 history[history_ptr].page = currentpoint;
773 history[history_ptr].link = selected_item;
774 currentpoint = help_follow_link (currentpoint, selected_item);
775 }
776
777 selected_item = NULL;
778 }
779
780
781
782 static cb_ret_t
783 help_execute_cmd (long command)
784 {
785 cb_ret_t ret = MSG_HANDLED;
786
787 switch (command)
788 {
789 case CK_Help:
790 help_help (whelp);
791 break;
792 case CK_Index:
793 help_index (whelp);
794 break;
795 case CK_Back:
796 help_back (whelp);
797 break;
798 case CK_Up:
799 help_prev_link (TRUE);
800 break;
801 case CK_Down:
802 help_next_link (TRUE);
803 break;
804 case CK_PageDown:
805 move_forward (help_lines - 1);
806 break;
807 case CK_PageUp:
808 move_backward (help_lines - 1);
809 break;
810 case CK_HalfPageDown:
811 move_forward (help_lines / 2);
812 break;
813 case CK_HalfPageUp:
814 move_backward (help_lines / 2);
815 break;
816 case CK_Top:
817 move_to_top ();
818 break;
819 case CK_Bottom:
820 move_to_bottom ();
821 break;
822 case CK_Enter:
823 help_select_link ();
824 break;
825 case CK_LinkNext:
826 help_next_link (FALSE);
827 break;
828 case CK_LinkPrev:
829 help_prev_link (FALSE);
830 break;
831 case CK_NodeNext:
832 help_next_node ();
833 break;
834 case CK_NodePrev:
835 help_prev_node ();
836 break;
837 case CK_Quit:
838 dlg_stop (whelp);
839 break;
840 default:
841 ret = MSG_NOT_HANDLED;
842 }
843
844 return ret;
845 }
846
847
848
849 static cb_ret_t
850 help_handle_key (WDialog * h, int c)
851 {
852 long command;
853
854 command = keybind_lookup_keymap_command (help_map, c);
855 if ((command == CK_IgnoreKey) || (help_execute_cmd (command) == MSG_NOT_HANDLED))
856 return MSG_NOT_HANDLED;
857
858 send_message (h, NULL, MSG_DRAW, 0, NULL);
859 return MSG_HANDLED;
860 }
861
862
863
864 static cb_ret_t
865 help_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
866 {
867 WDialog *h = DIALOG (w);
868
869 switch (msg)
870 {
871 case MSG_RESIZE:
872 {
873 WButtonBar *bb;
874
875 help_lines = MIN (LINES - 4, MAX (2 * LINES / 3, 18));
876 dlg_set_size (h, help_lines + 4, HELP_WINDOW_WIDTH + 4);
877 bb = find_buttonbar (h);
878 widget_set_size (WIDGET (bb), LINES - 1, 0, 1, COLS);
879 return MSG_HANDLED;
880 }
881
882 case MSG_DRAW:
883 dlg_default_repaint (h);
884 help_show (h, currentpoint);
885 return MSG_HANDLED;
886
887 case MSG_KEY:
888 return help_handle_key (h, parm);
889
890 case MSG_ACTION:
891
892 return help_execute_cmd (parm);
893
894 default:
895 return dlg_default_callback (w, sender, msg, parm, data);
896 }
897 }
898
899
900
901 static void
902 interactive_display_finish (void)
903 {
904 clear_link_areas ();
905 }
906
907
908
909
910 static void
911 translate_file (char *filedata)
912 {
913 GIConv conv;
914 GString *translated_data;
915
916
917 translated_data = g_string_sized_new (32 * 1024);
918
919 conv = str_crt_conv_from ("UTF-8");
920
921 if (conv == INVALID_CONV)
922 g_string_free (translated_data, TRUE);
923 else
924 {
925 g_free (fdata);
926
927 if (str_convert (conv, filedata, translated_data) != ESTR_FAILURE)
928 fdata = g_string_free (translated_data, FALSE);
929 else
930 {
931 fdata = NULL;
932 g_string_free (translated_data, TRUE);
933 }
934 str_close_conv (conv);
935 }
936 }
937
938
939
940 static cb_ret_t
941 md_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
942 {
943 switch (msg)
944 {
945 case MSG_RESIZE:
946 w->lines = help_lines;
947 return MSG_HANDLED;
948
949 default:
950 return widget_default_callback (w, sender, msg, parm, data);
951 }
952 }
953
954
955
956 static void
957 help_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event)
958 {
959 int x, y;
960 GSList *current_area;
961
962 if (msg != MSG_MOUSE_CLICK)
963 return;
964
965 if ((event->buttons & GPM_B_RIGHT) != 0)
966 {
967
968 help_back (whelp);
969 return;
970 }
971
972
973
974
975 x = event->x - 1;
976 y = event->y - 1;
977
978
979 for (current_area = link_area; current_area != NULL; current_area = g_slist_next (current_area))
980 {
981 Link_Area *la = (Link_Area *) current_area->data;
982
983
984 if (y == la->y1 && x >= la->x1 && y == la->y2 && x <= la->x2)
985 break;
986
987
988 if (la->y1 + 1 == la->y2)
989 {
990
991 if ((y == la->y1 && x >= la->x1) || (y == la->y2 && x <= la->x2))
992 break;
993 }
994
995 }
996
997
998 if (current_area != NULL)
999 {
1000 Link_Area *la = (Link_Area *) current_area->data;
1001
1002
1003 history_ptr = (history_ptr + 1) % HISTORY_SIZE;
1004 history[history_ptr].page = currentpoint;
1005 history[history_ptr].link = la->link_name;
1006 currentpoint = help_follow_link (currentpoint, la->link_name);
1007 selected_item = NULL;
1008 }
1009 else if (y < 0)
1010 move_backward (help_lines - 1);
1011 else if (y >= help_lines)
1012 move_forward (help_lines - 1);
1013 else if (y < help_lines / 2)
1014 move_backward (1);
1015 else
1016 move_forward (1);
1017
1018
1019 send_message (w->owner, NULL, MSG_DRAW, 0, NULL);
1020 }
1021
1022
1023
1024 static Widget *
1025 mousedispatch_new (int y, int x, int yl, int xl)
1026 {
1027 Widget *w;
1028
1029 w = g_new0 (Widget, 1);
1030 widget_init (w, y, x, yl, xl, md_callback, help_mouse_callback);
1031 w->options |= WOP_SELECTABLE | WOP_WANT_CURSOR;
1032
1033 return w;
1034 }
1035
1036
1037
1038
1039
1040
1041 gboolean
1042 help_interactive_display (const gchar * event_group_name, const gchar * event_name,
1043 gpointer init_data, gpointer data)
1044 {
1045 const dlg_colors_t help_colors = {
1046 HELP_NORMAL_COLOR,
1047 0,
1048 HELP_BOLD_COLOR,
1049 0,
1050 HELP_TITLE_COLOR
1051 };
1052
1053 WButtonBar *help_bar;
1054 Widget *md;
1055 char *hlpfile = NULL;
1056 char *filedata;
1057 ev_help_t *event_data = (ev_help_t *) data;
1058
1059 (void) event_group_name;
1060 (void) event_name;
1061 (void) init_data;
1062
1063 if (event_data->filename != NULL)
1064 g_file_get_contents (event_data->filename, &filedata, NULL, NULL);
1065 else
1066 filedata = load_mc_home_file (mc_global.share_data_dir, MC_HELP, &hlpfile, NULL);
1067
1068 if (filedata == NULL)
1069 message (D_ERROR, MSG_ERROR, _("Cannot open file %s\n%s"),
1070 event_data->filename ? event_data->filename : hlpfile, unix_error_string (errno));
1071
1072 g_free (hlpfile);
1073
1074 if (filedata == NULL)
1075 return TRUE;
1076
1077 translate_file (filedata);
1078
1079 g_free (filedata);
1080
1081 if (fdata == NULL)
1082 return TRUE;
1083
1084 if ((event_data->node == NULL) || (*event_data->node == '\0'))
1085 event_data->node = "[main]";
1086
1087 main_node = search_string (fdata, event_data->node);
1088
1089 if (main_node == NULL)
1090 {
1091 message (D_ERROR, MSG_ERROR, _("Cannot find node %s in help file"), event_data->node);
1092
1093
1094 main_node = search_string (fdata, "[main]");
1095 if (main_node == NULL)
1096 {
1097 interactive_display_finish ();
1098 return TRUE;
1099 }
1100 }
1101
1102 help_lines = MIN (LINES - 4, MAX (2 * LINES / 3, 18));
1103
1104 whelp =
1105 dlg_create (TRUE, 0, 0, help_lines + 4, HELP_WINDOW_WIDTH + 4, WPOS_CENTER | WPOS_TRYUP,
1106 FALSE, help_colors, help_callback, NULL, "[Help]", _("Help"));
1107 widget_want_tab (WIDGET (whelp), TRUE);
1108
1109 selected_item = search_string_node (main_node, STRING_LINK_START) - 1;
1110 currentpoint = main_node + 1;
1111
1112 for (history_ptr = HISTORY_SIZE; history_ptr;)
1113 {
1114 history_ptr--;
1115 history[history_ptr].page = currentpoint;
1116 history[history_ptr].link = selected_item;
1117 }
1118
1119 help_bar = buttonbar_new (TRUE);
1120 WIDGET (help_bar)->y -= WIDGET (whelp)->y;
1121 WIDGET (help_bar)->x -= WIDGET (whelp)->x;
1122
1123 md = mousedispatch_new (1, 1, help_lines, HELP_WINDOW_WIDTH - 2);
1124
1125 add_widget (whelp, md);
1126 add_widget (whelp, help_bar);
1127
1128 buttonbar_set_label (help_bar, 1, Q_ ("ButtonBar|Help"), help_map, NULL);
1129 buttonbar_set_label (help_bar, 2, Q_ ("ButtonBar|Index"), help_map, NULL);
1130 buttonbar_set_label (help_bar, 3, Q_ ("ButtonBar|Prev"), help_map, NULL);
1131 buttonbar_set_label (help_bar, 4, "", help_map, NULL);
1132 buttonbar_set_label (help_bar, 5, "", help_map, NULL);
1133 buttonbar_set_label (help_bar, 6, "", help_map, NULL);
1134 buttonbar_set_label (help_bar, 7, "", help_map, NULL);
1135 buttonbar_set_label (help_bar, 8, "", help_map, NULL);
1136 buttonbar_set_label (help_bar, 9, "", help_map, NULL);
1137 buttonbar_set_label (help_bar, 10, Q_ ("ButtonBar|Quit"), help_map, NULL);
1138
1139 dlg_run (whelp);
1140 interactive_display_finish ();
1141 dlg_destroy (whelp);
1142 return TRUE;
1143 }
1144
1145