* src/gnome/window-help.c: moved to src/gnome-utils.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@5876 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Rob Browning
2001-11-16 20:37:27 +00:00
parent fecdc073a7
commit 17cb565a57

View File

@@ -1,780 +0,0 @@
/********************************************************************\
* window-help.c -- a help window for hypertext help. *
* Copyright (C) 1997 Robin D. Clark *
* Copyright (C) 1998 Linas Vepstas *
* Copyright (C) 1999 Jeremy Collins ( gtk-xmhtml port ) *
* Copyright (C) 2000 Dave Peticolas *
* Copyright (C) 2000 Bill Gribble *
* *
* 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, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
* Boston, MA 02111-1307, USA gnu@gnu.org *
* *
\********************************************************************/
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <gnome.h>
#include <guile/gh.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
/* needed for db.h with 'gcc -ansi -pedantic' */
#ifndef _BSD_SOURCE
# define _BSD_SOURCE 1
#endif
#ifdef PREFER_DB1
#ifdef HAVE_DB1_DB_H
# include <db1/db.h>
#else
# ifdef HAVE_DB_185_H
# include <db_185.h>
# else
# include <db.h>
# endif
#endif
#else
#ifdef HAVE_DB_185_H
# include <db_185.h>
#else
# ifdef HAVE_DB_H
# include <db.h>
# else
# include <db1/db.h>
# endif
#endif
#endif
#include "file-utils.h"
#include "dialog-utils.h"
#include "gnc-component-manager.h"
#include "gnc-engine-util.h"
#include "gnc-html-history.h"
#include "gnc-html.h"
#include "window-help.h"
#define WINDOW_HELP_CM_CLASS "window-help"
struct _gnc_help_window {
GtkWidget * toplevel;
GtkWidget * toolbar;
GtkWidget * statusbar;
GtkWidget * statusbar_hbox;
GtkWidget * html_vbox;
GtkWidget * topics_tree;
GtkWidget * paned;
GtkWidget * search_entry;
GtkWidget * search_results;
GtkWidget * type_pixmap;
DB * index_db;
gnc_html * html;
};
/* This static indicates the debugging module that this .o belongs to. */
static short module = MOD_GUI;
static gint last_width = 0;
static gint last_height = 0;
/********************************************************************
* gnc_help_window_check_urltype
* is it OK to show a certain URLType in this window?
********************************************************************/
static int
gnc_help_window_check_urltype(URLType t) {
switch (t) {
case URL_TYPE_FILE:
case URL_TYPE_HELP:
case URL_TYPE_HTTP:
case URL_TYPE_SECURE:
return TRUE;
break;
default:
return FALSE;
}
}
/********************************************************************
* gnc_help_window_check_urltype
* is it OK to show a certain URLType in this window?
********************************************************************/
static void
gnc_help_window_url_flyover(gnc_html * html, const gchar * url,
gpointer data) {
gnc_help_window * help = (gnc_help_window *)data;
gtk_statusbar_pop(GTK_STATUSBAR(help->statusbar), 1);
if(url) {
gtk_statusbar_push(GTK_STATUSBAR(help->statusbar),
1, url);
}
}
/********************************************************************
* after-load cb : enable/disable history buttons
********************************************************************/
static void
gnc_help_window_set_back_button(gnc_help_window * win, int enabled) {
GtkToolbar * tb = GTK_TOOLBAR(win->toolbar);
gtk_widget_set_sensitive
(GTK_WIDGET(((GtkToolbarChild *)g_list_nth_data(tb->children, 0))->widget),
enabled);
}
static void
gnc_help_window_set_fwd_button(gnc_help_window * win, int enabled) {
GtkToolbar * tb = GTK_TOOLBAR(win->toolbar);
gtk_widget_set_sensitive
(GTK_WIDGET(((GtkToolbarChild *)g_list_nth_data(tb->children, 1))->widget),
enabled);
}
static gint
compare_locations (gconstpointer a, gconstpointer b)
{
return safe_strcmp (a, b);
}
static void
gnc_help_show_topic (gnc_help_window *help, const char * location)
{
GtkCTreeNode *node, *n;
GtkCTree *ctree;
GtkCTreeRow *row;
gint rownum;
ctree = GTK_CTREE (help->topics_tree);
rownum = GTK_CLIST(ctree)->focus_row;
node = gtk_ctree_node_nth (ctree, rownum);
if (node)
{
char *node_loc;
node_loc = gtk_ctree_node_get_row_data (ctree, node);
if (safe_strcmp (location, node_loc) != 0)
{
char *help_loc;
help_loc = g_strconcat ("gnc-help:", location, NULL);
if (safe_strcmp (help_loc, node_loc) != 0)
node = NULL;
g_free (help_loc);
}
}
if (!node)
node = gtk_ctree_find_by_row_data_custom (ctree, NULL,
(gpointer) location,
compare_locations);
if (!node)
{
char *help_loc = g_strconcat ("gnc-help:", location, NULL);
node = gtk_ctree_find_by_row_data_custom (ctree, NULL, help_loc,
compare_locations);
g_free (help_loc);
}
if (!node)
{
gtk_ctree_unselect_recursive (ctree, NULL);
return;
}
/* Select it */
gtk_signal_handler_block_by_data (GTK_OBJECT (ctree), help);
gtk_ctree_select (ctree, node);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (ctree), help);
/* Expand all the parents */
row = GTK_CTREE_ROW (node);
while ((n = row->parent) != NULL)
{
gtk_ctree_expand (ctree, n);
row = GTK_CTREE_ROW (n);
}
/* Make sure it's visible */
if (gtk_ctree_node_is_visible(ctree, node) != GTK_VISIBILITY_FULL)
gtk_ctree_node_moveto(ctree, node, 0, 0.5, 0.0);
}
static void
gnc_help_window_load_cb(gnc_html * html, URLType type,
const gchar * location, const gchar * label,
gpointer data) {
gnc_help_window * win = data;
if(gnc_html_history_forward_p(gnc_html_get_history(win->html))) {
gnc_help_window_set_fwd_button(win, TRUE);
}
else {
gnc_help_window_set_fwd_button(win, FALSE);
}
if(gnc_html_history_back_p(gnc_html_get_history(win->html))) {
gnc_help_window_set_back_button(win, TRUE);
}
else {
gnc_help_window_set_back_button(win, FALSE);
}
gnc_help_show_topic (win, location);
}
/********************************************************************
* toolbar callbacks
********************************************************************/
static int
gnc_help_window_fwd_cb(GtkWidget * w, gpointer data) {
gnc_help_window * help = data;
gnc_html_history_node * node;
gnc_html_history_forward(gnc_html_get_history(help->html));
node = gnc_html_history_get_current(gnc_html_get_history(help->html));
gnc_html_show_url(help->html, node->type, node->location, node->label, 0);
return TRUE;
}
static int
gnc_help_window_back_cb(GtkWidget * w, gpointer data) {
gnc_help_window * help = data;
gnc_html_history_node * node;
gnc_html_history_back(gnc_html_get_history(help->html));
node = gnc_html_history_get_current(gnc_html_get_history(help->html));
gnc_html_show_url(help->html, node->type, node->location, node->label, 0);
return TRUE;
}
static int
gnc_help_window_stop_button_cb(GtkWidget * w, gpointer data) {
gnc_help_window * help = data;
gnc_html_cancel(help->html);
return TRUE;
}
static int
gnc_help_window_reload_button_cb(GtkWidget * w, gpointer data) {
gnc_help_window * help = data;
gnc_html_reload(help->html);
return TRUE;
}
static void
goto_string_cb(char * string, gpointer data) {
if(!data) return;
if(!string) {
*(char **)data = NULL;
}
else {
*(char **)data = g_strdup(string);
}
}
static int
gnc_help_window_goto_button_cb(GtkWidget * w, gpointer data) {
gnc_help_window * help = data;
int retval = -1;
char * url = NULL;
URLType type;
char * location = NULL;
char * label = NULL;
GtkWidget * dlg = gnome_request_dialog(FALSE,
_("Enter URI to load:"), "", 250,
&goto_string_cb, &url,
GTK_WINDOW (help->toplevel));
retval = gnome_dialog_run_and_close(GNOME_DIALOG(dlg));
if((retval == 0) && url && (strlen(url) > 0)) {
type = gnc_html_parse_url(help->html, url, &location, &label);
gnc_html_show_url(help->html, type, location, label, 0);
g_free(location);
g_free(label);
}
if(url) {
g_free(url);
}
return TRUE;
}
/********************************************************************
* topics-browser callbacks
* silly tree building and clicking stuff
********************************************************************/
static void
gnc_help_window_topic_select_cb(GtkCTree * tree, GtkCTreeNode * row, int col,
gpointer user_data) {
gnc_help_window * wind = user_data;
URLType type;
char * location = NULL;
char * label = NULL;
char * url = gtk_ctree_node_get_row_data(tree, row);
if(url && strlen(url) > 0) {
type = gnc_html_parse_url(wind->html, url, &location, &label);
gnc_html_show_url(wind->html, type, location, label, 0);
g_free(location);
g_free(label);
}
}
static void
free_url_cb(gpointer user_data) {
if(user_data) free(user_data);
}
static void
topics_add_children(SCM topics, GtkCTree * tree, GtkCTreeNode * parent,
gnc_help_window * help) {
SCM this_topic;
SCM subtopics;
GtkCTreeNode * node;
char * topic_str;
char * ctopics[1];
char * curl = NULL;
gboolean leafnode;
if(!gh_list_p(topics)) return;
for(; !gh_null_p(topics); topics = gh_cdr(topics)) {
this_topic = gh_car(topics);
if(!gh_list_p(this_topic)) continue;
if(!gh_null_p(gh_cdr(this_topic)) && !gh_null_p(gh_cddr(this_topic))) {
subtopics = gh_caddr(this_topic);
}
else {
subtopics = SCM_BOOL_F;
}
topic_str = gh_scm2newstr(gh_car(this_topic), NULL);
ctopics[0] = _(topic_str);
if(!gh_null_p(gh_cdr(this_topic))) {
curl = gh_scm2newstr(gh_cadr(this_topic), NULL);
}
if(gh_list_p(subtopics)) {
leafnode = FALSE;
}
else {
leafnode = TRUE;
}
node = gtk_ctree_insert_node(GTK_CTREE(tree),
GTK_CTREE_NODE(parent), NULL,
ctopics, 1,
NULL, NULL, NULL, NULL,
leafnode, FALSE);
gtk_ctree_node_set_row_data_full(GTK_CTREE(tree),
GTK_CTREE_NODE(node), curl,
free_url_cb);
free(topic_str);
if(gh_list_p(subtopics)) {
topics_add_children(subtopics, tree, node, help);
}
}
}
static void
gnc_help_window_load_topics(gnc_help_window * help, const gchar * file)
{
SCM topics;
SCM load_topics = gh_eval_str("gnc:load-help-topics");
/* FIXME: when we drop support older guiles, drop the (char *) coercion. */
topics = gh_call1(load_topics, gh_str02scm((char *) file));
topics_add_children(topics, GTK_CTREE(help->topics_tree), NULL, help);
gtk_ctree_expand_to_depth (GTK_CTREE(help->topics_tree), NULL, 1);
gtk_widget_show_all(help->topics_tree);
}
static void
gnc_help_window_destroy_cb(GtkWidget * w, gpointer data) {
gnc_help_window * help = data;
gnc_unregister_gui_component_by_data (WINDOW_HELP_CM_CLASS, help);
/* close the help index db */
if(help->index_db) {
help->index_db->close(help->index_db);
}
gnc_html_destroy(help->html);
help->html = NULL;
help->toplevel = NULL;
help->statusbar = NULL;
help->html_vbox = NULL;
help->topics_tree = NULL;
g_free(help);
}
static void
gnc_help_window_close_cb(GtkWidget * w, gpointer data) {
gnc_help_window * help = data;
gnc_close_gui_component_by_data (WINDOW_HELP_CM_CLASS, help);
}
static void
gnc_help_window_print_cb(GtkWidget * w, gpointer data) {
gnc_help_window * help = data;
gnc_html_print(help->html);
}
static void
item_destroy_cb(GtkListItem * li, gpointer user_data) {
gpointer x = gtk_object_get_user_data(GTK_OBJECT(li));
g_free(x);
}
static void
show_search_results(gnc_help_window * help, const char * matches,
int match_len) {
const char * current;
const char * end;
char * this_link=NULL;
int link_len;
GList * results = NULL;
GtkWidget * listitem;
if(!matches) {
if(GTK_LIST(help->search_results)->children) {
gtk_list_remove_items(GTK_LIST(help->search_results),
GTK_LIST(help->search_results)->children);
}
return;
}
current = matches;
while((end = strchr(current, '\n')) != NULL) {
link_len = end - current;
this_link = g_new0(char, link_len + 1);
strncpy(this_link, current, link_len);
listitem = gtk_list_item_new_with_label(this_link);
gtk_object_set_user_data(GTK_OBJECT(listitem), this_link);
gtk_signal_connect(GTK_OBJECT(listitem), "destroy",
GTK_SIGNAL_FUNC(item_destroy_cb), NULL);
gtk_widget_show(listitem);
results = g_list_append(results, listitem);
current = end+1;
}
/* get rid of the old items */
if(GTK_LIST(help->search_results)->children) {
gtk_list_remove_items(GTK_LIST(help->search_results),
GTK_LIST(help->search_results)->children);
}
/* add the new ones */
if(results) {
gtk_list_append_items(GTK_LIST(help->search_results),
results);
}
}
static void
gnc_help_window_search_button_cb(GtkButton * button, gpointer data) {
gnc_help_window * help = data;
char * search_string =
gtk_entry_get_text(GTK_ENTRY(help->search_entry));
DBT key, value;
int err=1;
/* initialize search key/value */
memset(&key, 0, sizeof(DBT));
memset(&value, 0, sizeof(DBT));
key.data = search_string;
key.size = strlen(search_string);
/* do the search */
if(help->index_db) {
err = help->index_db->get(help->index_db, &key, &value, 0);
}
if(err == 0) {
/* the data in the DB is a newline-separated list of filenames */
show_search_results(help, value.data, value.size);
}
}
static void
gnc_help_window_search_help_button_cb(GtkButton * button, gpointer data) {
#if 0
gnc_help_window * help = data;
#endif
printf("help on help\n");
}
static void
gnc_help_window_search_result_select_cb(GtkWidget * list, GtkWidget * child,
gpointer user_data) {
gnc_help_window * help = user_data;
char * helpfile = gtk_object_get_user_data(GTK_OBJECT(child));
gnc_help_window_show_help(help, helpfile, NULL);
}
static void
close_handler (gpointer user_data)
{
gnc_help_window *help = user_data;
gdk_window_get_geometry (GTK_WIDGET(help->toplevel)->window, NULL, NULL,
&last_width, &last_height, NULL);
gnc_save_window_size ("help_win", last_width, last_height);
gnc_help_window_destroy (help);
}
/********************************************************************
* gnc_help_window_new
* allocates and opens up a help window
********************************************************************/
gnc_help_window *
gnc_help_window_new (void) {
gnc_help_window * help = g_new0(gnc_help_window, 1);
char * indexfile;
GnomeUIInfo toolbar_data[] =
{
{ GNOME_APP_UI_ITEM,
N_("Back"),
N_("Move back one step in the history"),
gnc_help_window_back_cb, help,
NULL,
GNOME_APP_PIXMAP_STOCK,
GNOME_STOCK_PIXMAP_BACK,
0, 0, NULL
},
{ GNOME_APP_UI_ITEM,
N_("Forward"),
N_("Move forward one step in the history"),
gnc_help_window_fwd_cb, help,
NULL,
GNOME_APP_PIXMAP_STOCK,
GNOME_STOCK_PIXMAP_FORWARD,
0, 0, NULL
},
GNOMEUIINFO_SEPARATOR,
{ GNOME_APP_UI_ITEM,
N_("Reload"),
N_("Reload the current document"),
gnc_help_window_reload_button_cb, help,
NULL,
GNOME_APP_PIXMAP_STOCK,
GNOME_STOCK_PIXMAP_REFRESH,
0, 0, NULL
},
{ GNOME_APP_UI_ITEM,
N_("Open"),
N_("Open a new document"),
gnc_help_window_goto_button_cb, help,
NULL,
GNOME_APP_PIXMAP_STOCK,
GNOME_STOCK_PIXMAP_OPEN,
0, 0, NULL
},
{ GNOME_APP_UI_ITEM,
N_("Stop"),
N_("Cancel outstanding HTML requests"),
gnc_help_window_stop_button_cb, help,
NULL,
GNOME_APP_PIXMAP_STOCK,
GNOME_STOCK_PIXMAP_STOP,
0, 0, NULL
},
GNOMEUIINFO_SEPARATOR,
{ GNOME_APP_UI_ITEM,
N_("Print"),
N_("Print Help window"),
gnc_help_window_print_cb, help,
NULL,
GNOME_APP_PIXMAP_STOCK,
GNOME_STOCK_PIXMAP_PRINT,
0, 0, NULL
},
GNOMEUIINFO_SEPARATOR,
{ GNOME_APP_UI_ITEM,
N_("Close"),
N_("Close this Help window"),
gnc_help_window_close_cb, help,
NULL,
GNOME_APP_PIXMAP_STOCK,
GNOME_STOCK_PIXMAP_CLOSE,
0, 0, NULL
},
GNOMEUIINFO_END
};
GladeXML *xml;
xml = gnc_glade_xml_new ("help.glade", "Help Window");
help->toplevel = glade_xml_get_widget (xml, "Help Window");
gnc_register_gui_component (WINDOW_HELP_CM_CLASS, NULL, close_handler, help);
help->toolbar = glade_xml_get_widget (xml, "help_toolbar");
help->statusbar = glade_xml_get_widget (xml, "help_statusbar");
help->statusbar_hbox = glade_xml_get_widget (xml, "statusbar_hbox");
help->html_vbox = glade_xml_get_widget (xml, "help_html_vbox");
help->topics_tree = glade_xml_get_widget (xml, "help_topics_tree");
help->paned = glade_xml_get_widget (xml, "help_paned");
help->search_entry = glade_xml_get_widget (xml, "help_search_entry");
help->search_results = glade_xml_get_widget (xml, "search_results_list");
help->type_pixmap = glade_xml_get_widget (xml, "file_type_pixmap");
help->html = gnc_html_new();
glade_xml_signal_connect_data
(xml, "gnc_help_window_search_button_cb",
GTK_SIGNAL_FUNC (gnc_help_window_search_button_cb), help);
glade_xml_signal_connect_data
(xml, "gnc_help_window_search_help_button_cb",
GTK_SIGNAL_FUNC (gnc_help_window_search_help_button_cb), help);
gnome_app_fill_toolbar(GTK_TOOLBAR(help->toolbar), toolbar_data, NULL);
gtk_box_pack_start(GTK_BOX(help->html_vbox),
gnc_html_get_widget(help->html),
TRUE, TRUE, 0);
gtk_paned_set_position(GTK_PANED(help->paned), 200);
gnc_html_set_urltype_cb(help->html, gnc_help_window_check_urltype);
gnc_html_set_flyover_cb(help->html, gnc_help_window_url_flyover,
(gpointer)help);
gnc_html_set_load_cb(help->html, gnc_help_window_load_cb,
(gpointer)help);
gnc_help_window_load_topics(help, "help-topics-index.scm");
gtk_signal_connect(GTK_OBJECT(help->toplevel), "destroy",
GTK_SIGNAL_FUNC(gnc_help_window_destroy_cb),
(gpointer)help);
gtk_signal_connect(GTK_OBJECT(help->topics_tree), "tree_select_row",
GTK_SIGNAL_FUNC(gnc_help_window_topic_select_cb),
(gpointer)help);
gtk_signal_connect(GTK_OBJECT(help->search_results), "select_child",
GTK_SIGNAL_FUNC(gnc_help_window_search_result_select_cb),
(gpointer)help);
indexfile = gncFindFile("help-search-index.db");
help->index_db = dbopen(indexfile, O_RDONLY, 0644, DB_HASH, NULL);
if (!help->index_db) {
PERR("Failed to open help index DB '%s' : %s\n",
indexfile ? indexfile : "(null)",
strerror(errno) ? strerror(errno) : "");
}
g_free(indexfile);
if (last_width == 0)
gnc_get_window_size("help_win", &last_width, &last_height);
gtk_window_set_default_size(GTK_WINDOW(help->toplevel),
last_width, last_height);
gnc_window_adjust_for_screen (GTK_WINDOW(help->toplevel));
gtk_widget_show_all(help->toplevel);
return help;
}
/********************************************************************
* gnc_help_window_destroy
* delete a help window
********************************************************************/
void
gnc_help_window_destroy(gnc_help_window * help) {
if (!help) return;
gnc_unregister_gui_component_by_data (WINDOW_HELP_CM_CLASS, help);
gtk_signal_disconnect_by_func(GTK_OBJECT(help->toplevel),
GTK_SIGNAL_FUNC(gnc_help_window_destroy_cb),
(gpointer)help);
/* close the help index db */
if(help->index_db) {
help->index_db->close(help->index_db);
}
/* take care of the gnc-html object specially */
gtk_widget_ref(gnc_html_get_widget(help->html));
gnc_html_destroy(help->html);
gtk_widget_destroy(GTK_WIDGET(help->toplevel));
}
void
gnc_help_window_show_help(gnc_help_window * help, const char * location,
const char * label) {
gnc_html_show_url(help->html, URL_TYPE_FILE, location, label, 0);
}
/********************************************************************
* compatibility stuff (temporary)
********************************************************************/
void
helpWindow(GtkWidget * parent, const char * title, const char * htmlfile) {
gnc_help_window * help = gnc_help_window_new();
gnc_help_window_show_help(help, htmlfile, NULL);
}