1998-02-27 07:54:42 +03:00
|
|
|
/* Hypertext file browser.
|
2007-09-26 14:22:25 +04:00
|
|
|
Copyright (C) 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
|
|
|
2005, 2006, 2007 Free Software Foundation, Inc.
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2005-05-27 07:35:10 +04:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2005-02-08 12:04:03 +03:00
|
|
|
*/
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
|
2009-02-05 21:28:18 +03:00
|
|
|
/** \file help.c
|
|
|
|
* \brief Source: hypertext file browser
|
|
|
|
*
|
|
|
|
* Implements the hypertext file viewer.
|
|
|
|
* The hypertext file is a file that may have one or more nodes. Each
|
|
|
|
* node ends with a ^D character and starts with a bracket, then the
|
|
|
|
* name of the node and then a closing bracket. Right after the closing
|
|
|
|
* bracket a newline is placed. This newline is not to be displayed by
|
|
|
|
* the help viewer and must be skipped - its sole purpose is to faciliate
|
|
|
|
* the work of the people managing the help file template (xnc.hlp) .
|
|
|
|
*
|
|
|
|
* Links in the hypertext file are specified like this: the text that
|
|
|
|
* will be highlighted should have a leading ^A, then it comes the
|
|
|
|
* text, then a ^B indicating that highlighting is done, then the name
|
|
|
|
* of the node you want to link to and then a ^C.
|
|
|
|
*
|
|
|
|
* The file must contain a ^D at the beginning and at the end of the
|
|
|
|
* file or the program will not be able to detect the end of file.
|
|
|
|
*
|
|
|
|
* Lazyness/widgeting attack: This file does use the dialog manager
|
|
|
|
* and uses mainly the dialog to achieve the help work. there is only
|
|
|
|
* one specialized widget and it's only used to forward the mouse messages
|
|
|
|
* to the appropiate routine.
|
|
|
|
*/
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
|
|
|
|
#include <errno.h>
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2001-09-03 09:07:40 +04:00
|
|
|
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 04:08:30 +03:00
|
|
|
#include "global.h"
|
2009-05-09 19:17:57 +04:00
|
|
|
|
2009-05-08 14:01:05 +04:00
|
|
|
#include "../src/tty/tty.h"
|
|
|
|
#include "../src/tty/color.h"
|
|
|
|
#include "../src/tty/mouse.h"
|
|
|
|
#include "../src/tty/key.h" /* For mi_getch() */
|
2009-05-09 19:17:57 +04:00
|
|
|
#include "../src/tty/win.h"
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
#include "help.h"
|
2003-10-25 03:20:30 +04:00
|
|
|
#include "dialog.h" /* For Dlg_head */
|
1998-02-27 07:54:42 +03:00
|
|
|
#include "widget.h" /* For Widget */
|
2002-09-02 11:48:01 +04:00
|
|
|
#include "wtools.h" /* For common_dialog_repaint() */
|
2008-12-29 02:12:21 +03:00
|
|
|
#include "strutil.h"
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
#define MAXLINKNAME 80
|
|
|
|
#define HISTORY_SIZE 20
|
2002-09-22 21:03:28 +04:00
|
|
|
#define HELP_WINDOW_WIDTH (HELP_TEXT_WIDTH + 4)
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-09-22 21:03:28 +04:00
|
|
|
#define STRING_LINK_START "\01"
|
|
|
|
#define STRING_LINK_POINTER "\02"
|
|
|
|
#define STRING_LINK_END "\03"
|
|
|
|
#define STRING_NODE_END "\04"
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-04-24 20:40:18 +04:00
|
|
|
static char *data = NULL; /* Pointer to the loaded data file */
|
2002-09-02 06:40:22 +04:00
|
|
|
static int help_lines; /* Lines in help viewer */
|
1998-02-27 07:54:42 +03:00
|
|
|
static int history_ptr; /* For the history queue */
|
2004-08-30 03:39:38 +04:00
|
|
|
static const char *main_node; /* The main node */
|
|
|
|
static const char *last_shown = NULL; /* Last byte shown in a screen */
|
1998-02-27 07:54:42 +03:00
|
|
|
static int end_of_node = 0; /* Flag: the last character of the node shown? */
|
2006-12-31 02:03:48 +03:00
|
|
|
static const char *currentpoint;
|
2004-08-30 03:39:38 +04:00
|
|
|
static const char *selected_item;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* The widget variables */
|
|
|
|
static Dlg_head *whelp;
|
|
|
|
|
|
|
|
static struct {
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *page; /* Pointer to the selected page */
|
|
|
|
const char *link; /* Pointer to the selected link */
|
1998-02-27 07:54:42 +03:00
|
|
|
} history [HISTORY_SIZE];
|
|
|
|
|
|
|
|
/* Link areas for the mouse */
|
|
|
|
typedef struct Link_Area {
|
|
|
|
int x1, y1, x2, y2;
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *link_name;
|
1998-02-27 07:54:42 +03:00
|
|
|
struct Link_Area *next;
|
|
|
|
} Link_Area;
|
|
|
|
|
|
|
|
static Link_Area *link_area = NULL;
|
|
|
|
static int inside_link_area = 0;
|
|
|
|
|
2003-09-08 01:24:01 +04:00
|
|
|
static cb_ret_t help_callback (struct Dlg_head *h, dlg_msg_t, int parm);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* returns the position where text was found in the start buffer */
|
|
|
|
/* or 0 if not found */
|
2004-08-30 03:39:38 +04:00
|
|
|
static const char *
|
2004-09-18 18:30:58 +04:00
|
|
|
search_string (const char *start, const char *text)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2004-09-18 18:30:58 +04:00
|
|
|
const char *result = NULL;
|
2009-02-06 01:40:32 +03:00
|
|
|
char *local_text = g_strdup (text);
|
2004-09-18 18:30:58 +04:00
|
|
|
char *d = local_text;
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *e = start;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* fmt sometimes replaces a space with a newline in the help file */
|
|
|
|
/* Replace the newlines in the link name with spaces to correct the situation */
|
|
|
|
while (*d){
|
|
|
|
if (*d == '\n')
|
|
|
|
*d = ' ';
|
2008-12-29 02:12:21 +03:00
|
|
|
str_next_char (&d);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
/* Do search */
|
2004-09-18 18:30:58 +04:00
|
|
|
for (d = local_text; *e; e++){
|
1998-02-27 07:54:42 +03:00
|
|
|
if (*d == *e)
|
|
|
|
d++;
|
|
|
|
else
|
2004-09-18 18:30:58 +04:00
|
|
|
d = local_text;
|
|
|
|
if (!*d) {
|
|
|
|
result = e + 1;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2004-09-18 18:30:58 +04:00
|
|
|
cleanup:
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (local_text);
|
2004-09-18 18:30:58 +04:00
|
|
|
return result;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Searches text in the buffer pointed by start. Search ends */
|
|
|
|
/* if the CHAR_NODE_END is found in the text. Returns 0 on failure */
|
2004-08-30 03:39:38 +04:00
|
|
|
static const char *search_string_node (const char *start, const char *text)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *d = text;
|
|
|
|
const char *e = start;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
if (!start)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for (; *e && *e != CHAR_NODE_END; e++){
|
|
|
|
if (*d == *e)
|
|
|
|
d++;
|
|
|
|
else
|
|
|
|
d = text;
|
|
|
|
if (!*d)
|
|
|
|
return e+1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Searches the_char in the buffer pointer by start and searches */
|
|
|
|
/* it can search forward (direction = 1) or backward (direction = -1) */
|
2004-08-30 03:39:38 +04:00
|
|
|
static const char *search_char_node (const char *start, char the_char, int direction)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *e;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
e = start;
|
|
|
|
|
|
|
|
for (; *e && (*e != CHAR_NODE_END); e += direction){
|
|
|
|
if (*e == the_char)
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns the new current pointer when moved lines lines */
|
2004-08-30 03:39:38 +04:00
|
|
|
static const char *move_forward2 (const char *c, int lines)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *p;
|
1998-02-27 07:54:42 +03:00
|
|
|
int line;
|
|
|
|
|
|
|
|
currentpoint = c;
|
2008-12-29 02:12:21 +03:00
|
|
|
for (line = 0, p = currentpoint; *p && *p != CHAR_NODE_END;
|
|
|
|
str_cnext_char (&p)){
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (line == lines)
|
|
|
|
return currentpoint = p;
|
|
|
|
if (*p == '\n')
|
|
|
|
line++;
|
|
|
|
}
|
|
|
|
return currentpoint = c;
|
|
|
|
}
|
|
|
|
|
2004-08-30 03:39:38 +04:00
|
|
|
static const char *move_backward2 (const char *c, int lines)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *p;
|
1998-02-27 07:54:42 +03:00
|
|
|
int line;
|
|
|
|
|
|
|
|
currentpoint = c;
|
2008-12-29 02:12:21 +03:00
|
|
|
for (line = 0, p = currentpoint; *p && p >= data;
|
|
|
|
str_cprev_char (&p)) {
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (*p == CHAR_NODE_END)
|
|
|
|
{
|
|
|
|
/* We reached the beginning of the node */
|
|
|
|
/* Skip the node headers */
|
2008-12-29 02:12:21 +03:00
|
|
|
while (*p != ']') str_cnext_char (&p);
|
2007-01-20 14:40:45 +03:00
|
|
|
return currentpoint = p + 2; /* Skip the newline following the start of the node */
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
if (*(p - 1) == '\n')
|
|
|
|
line++;
|
|
|
|
if (line == lines)
|
|
|
|
return currentpoint = p;
|
|
|
|
}
|
|
|
|
return currentpoint = c;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void move_forward (int i)
|
|
|
|
{
|
|
|
|
if (end_of_node)
|
|
|
|
return;
|
|
|
|
currentpoint = move_forward2 (currentpoint, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void move_backward (int i)
|
|
|
|
{
|
|
|
|
currentpoint = move_backward2 (currentpoint, ++i);
|
|
|
|
}
|
|
|
|
|
2005-05-23 14:15:45 +04:00
|
|
|
static void move_to_top (void)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
while (currentpoint > data && *currentpoint != CHAR_NODE_END)
|
|
|
|
currentpoint--;
|
|
|
|
while (*currentpoint != ']')
|
|
|
|
currentpoint++;
|
2007-01-20 14:40:45 +03:00
|
|
|
currentpoint = currentpoint + 2; /* Skip the newline following the start of the node */
|
1998-02-27 07:54:42 +03:00
|
|
|
selected_item = NULL;
|
|
|
|
}
|
|
|
|
|
2005-05-23 14:15:45 +04:00
|
|
|
static void move_to_bottom (void)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
while (*currentpoint && *currentpoint != CHAR_NODE_END)
|
|
|
|
currentpoint++;
|
|
|
|
currentpoint--;
|
|
|
|
move_backward (help_lines - 1);
|
|
|
|
}
|
|
|
|
|
2004-08-30 03:39:38 +04:00
|
|
|
static const char *help_follow_link (const char *start, const char *selected_item)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
char link_name [MAXLINKNAME];
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *p;
|
1998-02-27 07:54:42 +03:00
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
if (!selected_item)
|
|
|
|
return start;
|
|
|
|
|
|
|
|
for (p = selected_item; *p && *p != CHAR_NODE_END && *p != CHAR_LINK_POINTER; p++)
|
|
|
|
;
|
|
|
|
if (*p == CHAR_LINK_POINTER){
|
|
|
|
link_name [0] = '[';
|
|
|
|
for (i = 1; *p != CHAR_LINK_END && *p && *p != CHAR_NODE_END && i < MAXLINKNAME-3; )
|
|
|
|
link_name [i++] = *++p;
|
|
|
|
link_name [i-1] = ']';
|
|
|
|
link_name [i] = 0;
|
|
|
|
p = search_string (data, link_name);
|
2007-01-20 14:40:45 +03:00
|
|
|
if (p) {
|
|
|
|
p += 1; /* Skip the newline following the start of the node */
|
1998-02-27 07:54:42 +03:00
|
|
|
return p;
|
2007-01-20 14:40:45 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2002-11-12 20:46:54 +03:00
|
|
|
|
|
|
|
/* Create a replacement page with the error message */
|
|
|
|
return _(" Help file format error\n");
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-02-09 01:33:52 +03:00
|
|
|
static const char *select_next_link (const char *current_link)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *p;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
if (!current_link)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
p = search_string_node (current_link, STRING_LINK_END);
|
|
|
|
if (!p)
|
|
|
|
return NULL;
|
|
|
|
p = search_string_node (p, STRING_LINK_START);
|
|
|
|
if (!p)
|
|
|
|
return NULL;
|
|
|
|
return p - 1;
|
|
|
|
}
|
|
|
|
|
2006-12-31 02:03:48 +03:00
|
|
|
static const char *select_prev_link (const char *current_link)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
if (!current_link)
|
|
|
|
return 0;
|
2006-12-31 02:03:48 +03:00
|
|
|
|
|
|
|
return search_char_node (current_link - 1, CHAR_LINK_START, -1);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2004-08-30 03:39:38 +04:00
|
|
|
static void start_link_area (int x, int y, const char *link_name)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
Link_Area *new;
|
|
|
|
|
|
|
|
if (inside_link_area)
|
2009-01-10 16:13:56 +03:00
|
|
|
message (D_NORMAL, _("Warning"), _(" Internal bug: Double start of link area "));
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Allocate memory for a new link area */
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 04:08:30 +03:00
|
|
|
new = g_new (Link_Area, 1);
|
1998-02-27 07:54:42 +03:00
|
|
|
new->next = link_area;
|
|
|
|
link_area = new;
|
|
|
|
|
|
|
|
/* Save the beginning coordinates of the link area */
|
|
|
|
link_area->x1 = x;
|
|
|
|
link_area->y1 = y;
|
|
|
|
|
|
|
|
/* Save the name of the destination anchor */
|
|
|
|
link_area->link_name = link_name;
|
|
|
|
|
|
|
|
inside_link_area = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void end_link_area (int x, int y)
|
|
|
|
{
|
|
|
|
if (inside_link_area){
|
|
|
|
/* Save the end coordinates of the link area */
|
|
|
|
link_area->x2 = x;
|
|
|
|
link_area->y2 = y;
|
|
|
|
|
|
|
|
inside_link_area = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void clear_link_areas (void)
|
|
|
|
{
|
|
|
|
Link_Area *current;
|
|
|
|
|
|
|
|
while (link_area){
|
|
|
|
current = link_area;
|
|
|
|
link_area = current -> next;
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (current);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
inside_link_area = 0;
|
|
|
|
}
|
|
|
|
|
2004-08-30 03:39:38 +04:00
|
|
|
static void help_show (Dlg_head *h, const char *paint_start)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2008-12-29 02:12:21 +03:00
|
|
|
const char *p, *n;
|
|
|
|
int col, line, c, w;
|
1998-02-27 07:54:42 +03:00
|
|
|
int painting = 1;
|
|
|
|
int acs; /* Flag: Alternate character set active? */
|
|
|
|
int repeat_paint;
|
|
|
|
int active_col, active_line;/* Active link position */
|
2008-12-29 02:12:21 +03:00
|
|
|
static char buff[MB_LEN_MAX + 1];
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-09-02 11:48:01 +04:00
|
|
|
attrset (HELP_NORMAL_COLOR);
|
1998-02-27 07:54:42 +03:00
|
|
|
do {
|
|
|
|
|
|
|
|
line = col = acs = active_col = active_line = repeat_paint = 0;
|
|
|
|
|
|
|
|
clear_link_areas ();
|
|
|
|
if (selected_item < paint_start)
|
|
|
|
selected_item = NULL;
|
|
|
|
|
2008-12-29 02:12:21 +03:00
|
|
|
p = paint_start;
|
|
|
|
n = paint_start;
|
|
|
|
while (n[0] != '\0' && n[0] != CHAR_NODE_END && line < help_lines) {
|
|
|
|
p = n;
|
|
|
|
n = str_cget_next_char (p);
|
|
|
|
memcpy (buff, p, n - p);
|
|
|
|
buff[n - p] = '\0';
|
|
|
|
c = (unsigned char) buff[0];
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
switch (c){
|
|
|
|
case CHAR_LINK_START:
|
|
|
|
if (selected_item == NULL)
|
|
|
|
selected_item = p;
|
|
|
|
if (p == selected_item){
|
|
|
|
attrset (HELP_SLINK_COLOR);
|
|
|
|
|
|
|
|
/* Store the coordinates of the link */
|
|
|
|
active_col = col + 2;
|
|
|
|
active_line = line + 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
attrset (HELP_LINK_COLOR);
|
|
|
|
start_link_area (col, line, p);
|
|
|
|
break;
|
|
|
|
case CHAR_LINK_POINTER:
|
|
|
|
painting = 0;
|
|
|
|
end_link_area (col - 1, line);
|
|
|
|
break;
|
|
|
|
case CHAR_LINK_END:
|
|
|
|
painting = 1;
|
|
|
|
attrset (HELP_NORMAL_COLOR);
|
|
|
|
break;
|
|
|
|
case CHAR_ALTERNATE:
|
|
|
|
acs = 1;
|
|
|
|
break;
|
|
|
|
case CHAR_NORMAL:
|
|
|
|
acs = 0;
|
|
|
|
break;
|
|
|
|
case CHAR_VERSION:
|
|
|
|
dlg_move (h, line+2, col+2);
|
|
|
|
addstr (VERSION);
|
2008-12-29 02:12:21 +03:00
|
|
|
col += str_term_width1 (VERSION);
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
2002-09-22 20:40:33 +04:00
|
|
|
case CHAR_FONT_BOLD:
|
1998-02-27 07:54:42 +03:00
|
|
|
attrset (HELP_BOLD_COLOR);
|
|
|
|
break;
|
2002-09-22 20:40:33 +04:00
|
|
|
case CHAR_FONT_ITALIC:
|
1998-02-27 07:54:42 +03:00
|
|
|
attrset (HELP_ITALIC_COLOR);
|
|
|
|
break;
|
2002-09-22 20:40:33 +04:00
|
|
|
case CHAR_FONT_NORMAL:
|
1998-02-27 07:54:42 +03:00
|
|
|
attrset (HELP_NORMAL_COLOR);
|
|
|
|
break;
|
|
|
|
case '\n':
|
|
|
|
line++;
|
|
|
|
col = 0;
|
|
|
|
break;
|
|
|
|
case '\t':
|
2008-12-29 02:12:21 +03:00
|
|
|
col = (col / 8 + 1) * 8;
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (!painting)
|
|
|
|
continue;
|
2008-12-29 02:12:21 +03:00
|
|
|
w = str_term_width1 (buff);
|
|
|
|
if (col + w > HELP_WINDOW_WIDTH)
|
1998-02-27 07:54:42 +03:00
|
|
|
continue;
|
|
|
|
|
|
|
|
dlg_move (h, line+2, col+2);
|
|
|
|
if (acs){
|
|
|
|
if (c == ' ' || c == '.')
|
|
|
|
addch (c);
|
|
|
|
else
|
|
|
|
#ifndef HAVE_SLANG
|
1998-03-24 02:06:36 +03:00
|
|
|
addch (acs_map [c]);
|
|
|
|
#else
|
|
|
|
SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c);
|
|
|
|
#endif
|
2008-12-29 02:12:21 +03:00
|
|
|
} else {
|
|
|
|
addstr (buff);
|
|
|
|
}
|
|
|
|
col+= w;
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
last_shown = p;
|
|
|
|
end_of_node = line < help_lines;
|
|
|
|
attrset (HELP_NORMAL_COLOR);
|
|
|
|
if (selected_item >= last_shown){
|
|
|
|
if (link_area != NULL){
|
|
|
|
selected_item = link_area->link_name;
|
|
|
|
repeat_paint = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
selected_item = NULL;
|
|
|
|
}
|
|
|
|
} while (repeat_paint);
|
|
|
|
|
|
|
|
/* Position the cursor over a nice link */
|
|
|
|
if (active_col)
|
|
|
|
dlg_move (h, active_line, active_col);
|
|
|
|
}
|
|
|
|
|
2005-05-23 20:27:33 +04:00
|
|
|
static int
|
2005-07-22 13:29:50 +04:00
|
|
|
help_event (Gpm_Event *event, void *vp)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-07-22 13:29:50 +04:00
|
|
|
Widget *w = vp;
|
1998-02-27 07:54:42 +03:00
|
|
|
Link_Area *current_area;
|
|
|
|
|
|
|
|
if (! (event->type & GPM_UP))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* The event is relative to the dialog window, adjust it: */
|
2004-11-20 00:04:04 +03:00
|
|
|
event->x -= 2;
|
1998-02-27 07:54:42 +03:00
|
|
|
event->y -= 2;
|
2004-11-20 00:04:04 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (event->buttons & GPM_B_RIGHT){
|
2006-12-31 02:03:48 +03:00
|
|
|
currentpoint = history [history_ptr].page;
|
1998-02-27 07:54:42 +03:00
|
|
|
selected_item = history [history_ptr].link;
|
|
|
|
history_ptr--;
|
|
|
|
if (history_ptr < 0)
|
|
|
|
history_ptr = HISTORY_SIZE-1;
|
|
|
|
|
2003-09-08 01:24:01 +04:00
|
|
|
help_callback (w->parent, DLG_DRAW, 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Test whether the mouse click is inside one of the link areas */
|
|
|
|
current_area = link_area;
|
|
|
|
while (current_area)
|
|
|
|
{
|
|
|
|
/* Test one line link area */
|
|
|
|
if (event->y == current_area->y1 && event->x >= current_area->x1 &&
|
|
|
|
event->y == current_area->y2 && event->x <= current_area->x2)
|
|
|
|
break;
|
|
|
|
/* Test two line link area */
|
|
|
|
if (current_area->y1 + 1 == current_area->y2){
|
|
|
|
/* The first line */
|
|
|
|
if (event->y == current_area->y1 && event->x >= current_area->x1)
|
|
|
|
break;
|
|
|
|
/* The second line */
|
|
|
|
if (event->y == current_area->y2 && event->x <= current_area->x2)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Mouse will not work with link areas of more than two lines */
|
|
|
|
|
|
|
|
current_area = current_area -> next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Test whether a link area was found */
|
|
|
|
if (current_area){
|
|
|
|
/* The click was inside a link area -> follow the link */
|
|
|
|
history_ptr = (history_ptr+1) % HISTORY_SIZE;
|
|
|
|
history [history_ptr].page = currentpoint;
|
|
|
|
history [history_ptr].link = current_area->link_name;
|
2006-12-31 02:03:48 +03:00
|
|
|
currentpoint = help_follow_link (currentpoint, current_area->link_name);
|
1998-02-27 07:54:42 +03:00
|
|
|
selected_item = NULL;
|
|
|
|
} else{
|
|
|
|
if (event->y < 0)
|
|
|
|
move_backward (help_lines - 1);
|
|
|
|
else if (event->y >= help_lines)
|
|
|
|
move_forward (help_lines - 1);
|
|
|
|
else if (event->y < help_lines/2)
|
|
|
|
move_backward (1);
|
|
|
|
else
|
|
|
|
move_forward (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Show the new node */
|
2003-09-08 01:24:01 +04:00
|
|
|
help_callback (w->parent, DLG_DRAW, 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* show help */
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
2005-07-22 13:29:50 +04:00
|
|
|
help_help_cmd (void *vp)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-07-22 13:29:50 +04:00
|
|
|
Dlg_head *h = vp;
|
2005-07-22 12:41:45 +04:00
|
|
|
const char *p;
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
history_ptr = (history_ptr+1) % HISTORY_SIZE;
|
|
|
|
history [history_ptr].page = currentpoint;
|
|
|
|
history [history_ptr].link = selected_item;
|
2005-07-22 12:41:45 +04:00
|
|
|
|
|
|
|
p = search_string(data, "[How to use help]");
|
|
|
|
if (p == NULL)
|
|
|
|
return;
|
|
|
|
|
2007-01-20 14:40:45 +03:00
|
|
|
currentpoint = p + 1; /* Skip the newline following the start of the node */
|
1998-02-27 07:54:42 +03:00
|
|
|
selected_item = NULL;
|
2003-09-08 01:24:01 +04:00
|
|
|
help_callback (h, DLG_DRAW, 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
2005-07-22 13:29:50 +04:00
|
|
|
help_index_cmd (void *vp)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-07-22 13:29:50 +04:00
|
|
|
Dlg_head *h = vp;
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *new_item;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-09-03 11:15:01 +04:00
|
|
|
if (!(new_item = search_string (data, "[Contents]"))) {
|
2009-01-10 16:13:56 +03:00
|
|
|
message (D_ERROR, MSG_ERROR, _(" Cannot find node %s in help file "),
|
2002-09-03 11:15:01 +04:00
|
|
|
"[Contents]");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
history_ptr = (history_ptr + 1) % HISTORY_SIZE;
|
|
|
|
history[history_ptr].page = currentpoint;
|
|
|
|
history[history_ptr].link = selected_item;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2007-01-20 14:40:45 +03:00
|
|
|
currentpoint = new_item + 1; /* Skip the newline following the start of the node */
|
1998-02-27 07:54:42 +03:00
|
|
|
selected_item = NULL;
|
2003-09-08 01:24:01 +04:00
|
|
|
help_callback (h, DLG_DRAW, 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-07-22 13:29:50 +04:00
|
|
|
static void help_quit_cmd (void *vp)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-07-22 13:29:50 +04:00
|
|
|
dlg_stop ((Dlg_head *) vp);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-07-22 13:29:50 +04:00
|
|
|
static void prev_node_cmd (void *vp)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-07-22 13:29:50 +04:00
|
|
|
Dlg_head *h = vp;
|
2006-12-31 02:03:48 +03:00
|
|
|
currentpoint = history [history_ptr].page;
|
1998-02-27 07:54:42 +03:00
|
|
|
selected_item = history [history_ptr].link;
|
|
|
|
history_ptr--;
|
|
|
|
if (history_ptr < 0)
|
|
|
|
history_ptr = HISTORY_SIZE-1;
|
|
|
|
|
2003-09-08 01:24:01 +04:00
|
|
|
help_callback (h, DLG_DRAW, 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2003-09-11 02:48:54 +04:00
|
|
|
static cb_ret_t
|
|
|
|
md_callback (Widget *w, widget_msg_t msg, int parm)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-02-09 01:33:52 +03:00
|
|
|
(void) w;
|
2003-09-11 02:48:54 +04:00
|
|
|
return default_proc (msg, parm);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2003-09-10 22:21:40 +04:00
|
|
|
static Widget *
|
|
|
|
mousedispatch_new (int y, int x, int yl, int xl)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 04:08:30 +03:00
|
|
|
Widget *w = g_new (Widget, 1);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-05-23 20:27:33 +04:00
|
|
|
init_widget (w, y, x, yl, xl, md_callback, help_event);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
2005-07-22 13:29:50 +04:00
|
|
|
static void help_cmk_move_backward(void *vp, int lines) {
|
|
|
|
(void) &vp;
|
2005-05-23 14:15:45 +04:00
|
|
|
move_backward(lines);
|
|
|
|
}
|
2005-07-22 13:29:50 +04:00
|
|
|
static void help_cmk_move_forward(void *vp, int lines) {
|
|
|
|
(void) &vp;
|
2005-05-23 14:15:45 +04:00
|
|
|
move_forward(lines);
|
|
|
|
}
|
2005-07-22 13:29:50 +04:00
|
|
|
static void help_cmk_moveto_top(void *vp, int lines) {
|
|
|
|
(void) &vp;
|
2005-05-23 14:15:45 +04:00
|
|
|
(void) &lines;
|
|
|
|
move_to_top();
|
|
|
|
}
|
2005-07-22 13:29:50 +04:00
|
|
|
static void help_cmk_moveto_bottom(void *vp, int lines) {
|
|
|
|
(void) &vp;
|
2005-05-23 14:15:45 +04:00
|
|
|
(void) &lines;
|
|
|
|
move_to_bottom();
|
|
|
|
}
|
|
|
|
|
2003-09-08 01:24:01 +04:00
|
|
|
static cb_ret_t
|
|
|
|
help_handle_key (struct Dlg_head *h, int c)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2004-08-30 03:39:38 +04:00
|
|
|
const char *new_item;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
if (c != KEY_UP && c != KEY_DOWN &&
|
2005-05-23 14:15:45 +04:00
|
|
|
check_movement_keys (c, help_lines, NULL,
|
|
|
|
help_cmk_move_backward,
|
|
|
|
help_cmk_move_forward,
|
|
|
|
help_cmk_moveto_top,
|
|
|
|
help_cmk_moveto_bottom)) {
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Nothing */;
|
2005-05-23 14:15:45 +04:00
|
|
|
} else switch (c){
|
1998-02-27 07:54:42 +03:00
|
|
|
case 'l':
|
|
|
|
case KEY_LEFT:
|
|
|
|
prev_node_cmd (h);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '\n':
|
|
|
|
case KEY_RIGHT:
|
|
|
|
/* follow link */
|
|
|
|
if (!selected_item){
|
|
|
|
#ifdef WE_WANT_TO_GO_BACKWARD_ON_KEY_RIGHT
|
|
|
|
/* Is there any reason why the right key would take us
|
|
|
|
* backward if there are no links selected?, I agree
|
|
|
|
* with Torben than doing nothing in this case is better
|
|
|
|
*/
|
|
|
|
/* If there are no links, go backward in history */
|
|
|
|
history_ptr--;
|
|
|
|
if (history_ptr < 0)
|
|
|
|
history_ptr = HISTORY_SIZE-1;
|
|
|
|
|
2006-12-31 02:03:48 +03:00
|
|
|
currentpoint = history [history_ptr].page;
|
1998-02-27 07:54:42 +03:00
|
|
|
selected_item = history [history_ptr].link;
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
history_ptr = (history_ptr+1) % HISTORY_SIZE;
|
|
|
|
history [history_ptr].page = currentpoint;
|
|
|
|
history [history_ptr].link = selected_item;
|
2007-01-20 14:40:45 +03:00
|
|
|
currentpoint = help_follow_link (currentpoint, selected_item);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
selected_item = NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_DOWN:
|
|
|
|
case '\t':
|
2005-02-09 01:33:52 +03:00
|
|
|
new_item = select_next_link (selected_item);
|
1998-02-27 07:54:42 +03:00
|
|
|
if (new_item){
|
|
|
|
selected_item = new_item;
|
|
|
|
if (selected_item >= last_shown){
|
|
|
|
if (c == KEY_DOWN)
|
|
|
|
move_forward (1);
|
|
|
|
else
|
|
|
|
selected_item = NULL;
|
|
|
|
}
|
|
|
|
} else if (c == KEY_DOWN)
|
|
|
|
move_forward (1);
|
|
|
|
else
|
|
|
|
selected_item = NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_UP:
|
|
|
|
case ALT ('\t'):
|
|
|
|
/* select previous link */
|
2006-12-31 02:03:48 +03:00
|
|
|
new_item = select_prev_link (selected_item);
|
1998-02-27 07:54:42 +03:00
|
|
|
selected_item = new_item;
|
2006-12-31 02:03:48 +03:00
|
|
|
if (selected_item == NULL || selected_item < currentpoint) {
|
1998-02-27 07:54:42 +03:00
|
|
|
if (c == KEY_UP)
|
|
|
|
move_backward (1);
|
|
|
|
else{
|
|
|
|
if (link_area != NULL)
|
|
|
|
selected_item = link_area->link_name;
|
|
|
|
else
|
|
|
|
selected_item = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'n':
|
|
|
|
/* Next node */
|
|
|
|
new_item = currentpoint;
|
|
|
|
while (*new_item && *new_item != CHAR_NODE_END)
|
|
|
|
new_item++;
|
|
|
|
if (*++new_item == '['){
|
2002-09-05 10:51:46 +04:00
|
|
|
while (*++new_item) {
|
2002-09-05 10:55:50 +04:00
|
|
|
if (*new_item == ']' && *++new_item && *++new_item) {
|
2002-09-05 10:51:46 +04:00
|
|
|
currentpoint = new_item;
|
|
|
|
selected_item = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'p':
|
|
|
|
/* Previous node */
|
|
|
|
new_item = currentpoint;
|
|
|
|
while (new_item > data + 1 && *new_item != CHAR_NODE_END)
|
|
|
|
new_item--;
|
|
|
|
new_item--;
|
|
|
|
while (new_item > data && *new_item != CHAR_NODE_END)
|
|
|
|
new_item--;
|
|
|
|
while (*new_item != ']')
|
|
|
|
new_item++;
|
|
|
|
currentpoint = new_item + 2;
|
|
|
|
selected_item = NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'c':
|
|
|
|
help_index_cmd (h);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ESC_CHAR:
|
|
|
|
case XCTRL('g'):
|
1998-03-14 03:42:23 +03:00
|
|
|
dlg_stop (h);
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-09-08 01:24:01 +04:00
|
|
|
return MSG_NOT_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
}
|
2003-09-08 01:24:01 +04:00
|
|
|
help_callback (h, DLG_DRAW, 0);
|
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2003-09-08 01:24:01 +04:00
|
|
|
static cb_ret_t
|
|
|
|
help_callback (struct Dlg_head *h, dlg_msg_t msg, int parm)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2003-09-08 01:24:01 +04:00
|
|
|
switch (msg) {
|
1998-02-27 07:54:42 +03:00
|
|
|
case DLG_DRAW:
|
2002-09-02 11:48:01 +04:00
|
|
|
common_dialog_repaint (h);
|
2002-11-13 07:01:04 +03:00
|
|
|
help_show (h, currentpoint);
|
2003-09-08 01:24:01 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
case DLG_KEY:
|
2003-09-08 01:24:01 +04:00
|
|
|
return help_handle_key (h, parm);
|
|
|
|
|
|
|
|
default:
|
|
|
|
return default_dlg_callback (h, msg, parm);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
|
|
|
interactive_display_finish (void)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
clear_link_areas ();
|
2008-12-29 02:12:21 +03:00
|
|
|
}
|
|
|
|
|
2009-04-14 14:29:01 +04:00
|
|
|
/* translate help file into terminal encoding */
|
2008-12-29 02:12:21 +03:00
|
|
|
static void
|
|
|
|
translate_file (char *filedata)
|
|
|
|
{
|
2009-04-14 14:29:01 +04:00
|
|
|
GIConv conv;
|
|
|
|
GString *translated_data;
|
|
|
|
|
|
|
|
translated_data = g_string_new ("");
|
|
|
|
|
2008-12-29 02:12:21 +03:00
|
|
|
conv = str_crt_conv_from ("UTF-8");
|
2009-04-14 14:29:01 +04:00
|
|
|
|
2008-12-29 02:12:21 +03:00
|
|
|
if (conv != INVALID_CONV) {
|
2009-04-24 20:40:18 +04:00
|
|
|
g_free (data);
|
|
|
|
|
2008-12-29 02:12:21 +03:00
|
|
|
if (str_convert (conv, filedata, translated_data) != ESTR_FAILURE) {
|
2009-04-14 14:29:01 +04:00
|
|
|
data = translated_data->str;
|
2009-04-24 20:40:18 +04:00
|
|
|
g_string_free (translated_data, FALSE);
|
2008-12-29 02:12:21 +03:00
|
|
|
} else {
|
|
|
|
data = NULL;
|
2009-04-24 20:40:18 +04:00
|
|
|
g_string_free (translated_data, TRUE);
|
2008-12-29 02:12:21 +03:00
|
|
|
}
|
|
|
|
str_close_conv (conv);
|
2009-04-24 20:40:18 +04:00
|
|
|
} else
|
|
|
|
g_string_free (translated_data, TRUE);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
void
|
2004-08-29 20:42:40 +04:00
|
|
|
interactive_display (const char *filename, const char *node)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2002-09-03 10:53:11 +04:00
|
|
|
WButtonBar *help_bar;
|
|
|
|
Widget *md;
|
2004-08-30 03:39:38 +04:00
|
|
|
char *hlpfile = NULL;
|
2008-12-29 02:12:21 +03:00
|
|
|
char *filedata;
|
2001-06-09 11:13:46 +04:00
|
|
|
|
|
|
|
if (filename)
|
2008-12-29 02:12:21 +03:00
|
|
|
filedata = load_file (filename);
|
2001-06-09 11:13:46 +04:00
|
|
|
else
|
2008-12-29 02:12:21 +03:00
|
|
|
filedata = load_mc_home_file ("mc.hlp", &hlpfile);
|
2001-06-09 11:13:46 +04:00
|
|
|
|
2009-04-24 20:40:18 +04:00
|
|
|
if (filedata == NULL) {
|
2009-01-10 16:13:56 +03:00
|
|
|
message (D_ERROR, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile,
|
2002-09-03 10:53:11 +04:00
|
|
|
unix_error_string (errno));
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2001-06-09 11:13:46 +04:00
|
|
|
|
|
|
|
if (!filename)
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (hlpfile);
|
2001-06-09 11:13:46 +04:00
|
|
|
|
2008-12-29 02:12:21 +03:00
|
|
|
if (filedata == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
translate_file (filedata);
|
2008-12-29 02:12:21 +03:00
|
|
|
|
2008-12-29 02:12:21 +03:00
|
|
|
g_free (filedata);
|
|
|
|
|
2001-06-09 11:13:46 +04:00
|
|
|
if (!data)
|
|
|
|
return;
|
|
|
|
|
2002-09-03 10:53:11 +04:00
|
|
|
if (!node || !*node)
|
|
|
|
node = "[main]";
|
|
|
|
|
|
|
|
if (!(main_node = search_string (data, node))) {
|
2009-01-10 16:13:56 +03:00
|
|
|
message (D_ERROR, MSG_ERROR, _(" Cannot find node %s in help file "),
|
2002-09-03 10:53:11 +04:00
|
|
|
node);
|
2002-09-03 11:22:23 +04:00
|
|
|
|
|
|
|
/* Fallback to [main], return if it also cannot be found */
|
|
|
|
main_node = search_string (data, "[main]");
|
|
|
|
if (!main_node) {
|
|
|
|
interactive_display_finish ();
|
|
|
|
return;
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-09-02 06:40:22 +04:00
|
|
|
help_lines = min (LINES - 4, max (2 * LINES / 3, 18));
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-09-03 10:53:11 +04:00
|
|
|
whelp =
|
|
|
|
create_dlg (0, 0, help_lines + 4, HELP_WINDOW_WIDTH + 4,
|
|
|
|
dialog_colors, help_callback, "[Help]", _("Help"),
|
2003-09-13 02:16:32 +04:00
|
|
|
DLG_TRYUP | DLG_CENTER | DLG_WANT_TAB);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
1998-09-22 17:06:59 +04:00
|
|
|
selected_item = search_string_node (main_node, STRING_LINK_START) - 1;
|
2007-01-20 14:40:45 +03:00
|
|
|
currentpoint = main_node + 1; /* Skip the newline following the start of the node */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-09-03 10:53:11 +04:00
|
|
|
for (history_ptr = HISTORY_SIZE; history_ptr;) {
|
1998-02-27 07:54:42 +03:00
|
|
|
history_ptr--;
|
2002-09-03 10:53:11 +04:00
|
|
|
history[history_ptr].page = currentpoint;
|
|
|
|
history[history_ptr].link = selected_item;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-08-22 03:02:19 +04:00
|
|
|
help_bar = buttonbar_new (1);
|
2005-06-14 17:02:30 +04:00
|
|
|
((Widget *) help_bar)->y -= whelp->y;
|
|
|
|
((Widget *) help_bar)->x -= whelp->x;
|
2002-09-03 10:53:11 +04:00
|
|
|
|
|
|
|
md = mousedispatch_new (1, 1, help_lines, HELP_WINDOW_WIDTH - 2);
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
add_widget (whelp, md);
|
2003-09-13 02:16:32 +04:00
|
|
|
add_widget (whelp, help_bar);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-05-23 20:27:33 +04:00
|
|
|
buttonbar_set_label_data (whelp, 1, _("Help"), help_help_cmd, whelp);
|
|
|
|
buttonbar_set_label_data (whelp, 2, _("Index"), help_index_cmd, whelp);
|
|
|
|
buttonbar_set_label_data (whelp, 3, _("Prev"), prev_node_cmd, whelp);
|
2005-06-14 15:34:28 +04:00
|
|
|
buttonbar_clear_label (whelp, 4);
|
|
|
|
buttonbar_clear_label (whelp, 5);
|
|
|
|
buttonbar_clear_label (whelp, 6);
|
|
|
|
buttonbar_clear_label (whelp, 7);
|
|
|
|
buttonbar_clear_label (whelp, 8);
|
|
|
|
buttonbar_clear_label (whelp, 9);
|
2005-02-08 12:53:51 +03:00
|
|
|
buttonbar_set_label_data (whelp, 10, _("Quit"), help_quit_cmd, whelp);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
run_dlg (whelp);
|
|
|
|
interactive_display_finish ();
|
|
|
|
destroy_dlg (whelp);
|
|
|
|
}
|