Finished some work that Brix started on the help system. It's now possibly

2004-03-09  Sven Neumann  <sven@gimp.org>

	Finished some work that Brix started on the help system. It's
	now possibly to use an external web-browser for context help
	(bug #136081):

	* configure.in
	* plug-ins/Makefile.am
	* plug-ins/help/Makefile.am
	* plug-ins/help/domain.[ch]
	* plug-ins/help/help.c: new plug-in that does the help domain
	management. Most of this used to live in the helpbrowser plug-in.

	* plug-ins/helpbrowser/Makefile.am
	* plug-ins/helpbrowser/domain.[ch]: removed these two files here.

	* plug-ins/helpbrowser/helpbrowser.c: changed accordingly.

	* app/widgets/gimphelp.c: use the new help plug-in.
This commit is contained in:
Sven Neumann 2004-03-09 01:37:56 +00:00 committed by Sven Neumann
parent b4f3e1a856
commit 55d14fd0f0
15 changed files with 1920 additions and 303 deletions

View File

@ -1,3 +1,23 @@
2004-03-09 Sven Neumann <sven@gimp.org>
Finished some work that Brix started on the help system. It's
now possibly to use an external web-browser for context help
(bug #136081):
* configure.in
* plug-ins/Makefile.am
* plug-ins/help/Makefile.am
* plug-ins/help/domain.[ch]
* plug-ins/help/help.c: new plug-in that does the help domain
management. Most of this used to live in the helpbrowser plug-in.
* plug-ins/helpbrowser/Makefile.am
* plug-ins/helpbrowser/domain.[ch]: removed these two files here.
* plug-ins/helpbrowser/helpbrowser.c: changed accordingly.
* app/widgets/gimphelp.c: use the new help plug-in.
2004-03-08 Sven Neumann <sven@gimp.org>
* app/gui/convert-dialog.c (indexed_palette_select_palette): added

View File

@ -2,7 +2,8 @@
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimphelp.c
* Copyright (C) 1999-2000 Michael Natterer <mitch@gimp.org>
* Copyright (C) 1999-2004 Michael Natterer <mitch@gimp.org>
* Henrik Brix Andersen <brix@gimp.org>
*
* 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
@ -49,9 +50,8 @@
#include "gimp-intl.h"
#ifndef G_OS_WIN32
#define DEBUG_HELP
#endif
typedef struct _GimpIdleHelp GimpIdleHelp;
@ -66,15 +66,13 @@ struct _GimpIdleHelp
/* local function prototypes */
static gint gimp_idle_help (gpointer data);
static gboolean gimp_help_internal (Gimp *gimp,
const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id);
static void gimp_help_web_browser (Gimp *gimp,
const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id);
static gint gimp_idle_help (gpointer data);
static gboolean gimp_help_internal (Gimp *gimp);
static void gimp_help_call (Gimp *gimp,
const gchar *procedure,
const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id);
/* public functions */
@ -88,9 +86,7 @@ gimp_help (Gimp *gimp,
if (GIMP_GUI_CONFIG (gimp->config)->use_help)
{
GimpIdleHelp *idle_help;
idle_help = g_new0 (GimpIdleHelp, 1);
GimpIdleHelp *idle_help = g_new0 (GimpIdleHelp, 1);
idle_help->gimp = gimp;
@ -112,38 +108,37 @@ gimp_help (Gimp *gimp,
static gboolean
gimp_idle_help (gpointer data)
{
GimpIdleHelp *idle_help = data;
GimpHelpBrowserType browser;
browser = GIMP_GUI_CONFIG (idle_help->gimp->config)->help_browser;
GimpIdleHelp *idle_help = data;
const gchar *procedure = NULL;
#ifdef DEBUG_HELP
g_print ("Help Domain: %s\n",
idle_help->help_domain ? idle_help->help_domain : "NULL");
g_print ("Help ID: %s\n\n",
idle_help->help_id ? idle_help->help_id : "NULL");
#endif /* DEBUG_HELP */
g_printerr ("Help Domain: %s\n",
idle_help->help_domain ? idle_help->help_domain : "NULL");
g_printerr ("Help ID: %s\n\n",
idle_help->help_id ? idle_help->help_id : "NULL");
#endif
switch (browser)
switch (GIMP_GUI_CONFIG (idle_help->gimp->config)->help_browser)
{
case GIMP_HELP_BROWSER_GIMP:
if (gimp_help_internal (idle_help->gimp,
idle_help->help_domain,
idle_help->help_locale,
idle_help->help_id))
break;
if (gimp_help_internal (idle_help->gimp))
{
procedure = "extension_gimp_help_browser_temp";
break;
}
case GIMP_HELP_BROWSER_WEB_BROWSER:
gimp_help_web_browser (idle_help->gimp,
idle_help->help_domain,
idle_help->help_locale,
idle_help->help_id);
break;
default:
/* FIXME: should check for procedure availability */
procedure = "plug_in_web_browser";
break;
}
gimp_help_call (idle_help->gimp,
procedure,
idle_help->help_domain,
idle_help->help_locale,
idle_help->help_id);
g_free (idle_help->help_domain);
g_free (idle_help->help_locale);
g_free (idle_help->help_id);
@ -168,10 +163,7 @@ gimp_help_internal_not_found_callback (GtkWidget *widget,
}
static gboolean
gimp_help_internal (Gimp *gimp,
const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id)
gimp_help_internal (Gimp *gimp)
{
ProcRecord *proc_rec;
@ -187,10 +179,7 @@ gimp_help_internal (Gimp *gimp,
if (proc_rec == NULL)
{
Argument *args = NULL;
gint n_domains = 0;
gchar **help_domains = NULL;
gchar **help_uris = NULL;
Argument *args = NULL;
proc_rec = procedural_db_lookup (gimp, "extension_gimp_help_browser");
@ -217,21 +206,12 @@ gimp_help_internal (Gimp *gimp,
!= GIMP_HELP_BROWSER_WEB_BROWSER);
}
n_domains = plug_ins_help_domains (gimp, &help_domains, &help_uris);
args = g_new (Argument, 1);
args = g_new (Argument, 5);
args[0].arg_type = GIMP_PDB_INT32;
args[0].value.pdb_int = GIMP_RUN_INTERACTIVE;
args[1].arg_type = GIMP_PDB_INT32;
args[1].value.pdb_int = n_domains;
args[2].arg_type = GIMP_PDB_STRINGARRAY;
args[2].value.pdb_pointer = help_domains;
args[3].arg_type = GIMP_PDB_INT32;
args[3].value.pdb_int = n_domains;
args[4].arg_type = GIMP_PDB_STRINGARRAY;
args[4].value.pdb_pointer = help_uris;
args[0].arg_type = GIMP_PDB_INT32;
args[0].value.pdb_int = GIMP_RUN_INTERACTIVE;
plug_in_run (gimp, proc_rec, args, 5, FALSE, TRUE, -1);
plug_in_run (gimp, proc_rec, args, 1, FALSE, TRUE, -1);
procedural_db_destroy_args (args, 5);
}
@ -258,22 +238,6 @@ gimp_help_internal (Gimp *gimp,
return (GIMP_GUI_CONFIG (gimp->config)->help_browser
!= GIMP_HELP_BROWSER_WEB_BROWSER);
}
else
{
Argument *return_vals;
gint nreturn_vals;
return_vals =
procedural_db_run_proc (gimp,
"extension_gimp_help_browser_temp",
&nreturn_vals,
GIMP_PDB_STRING, help_domain,
GIMP_PDB_STRING, help_locale,
GIMP_PDB_STRING, help_id,
GIMP_PDB_END);
procedural_db_destroy_args (return_vals, nreturn_vals);
}
busy = FALSE;
@ -281,43 +245,80 @@ gimp_help_internal (Gimp *gimp,
}
static void
gimp_help_web_browser (Gimp *gimp,
const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id)
gimp_help_call (Gimp *gimp,
const gchar *procedure,
const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id)
{
Argument *return_vals;
gint nreturn_vals;
gchar *url;
ProcRecord *proc_rec;
if (! help_id)
help_id = GIMP_HELP_MAIN;
/* Check if a help parser is already running */
proc_rec = procedural_db_lookup (gimp, "extension_gimp_help_temp");
if (! help_domain)
if (proc_rec == NULL)
{
url = g_strconcat ("file:",
gimp_data_directory (), "/help/",
help_locale, "/",
help_id,
NULL);
Argument *args = NULL;
gint n_domains = 0;
gchar **help_domains = NULL;
gchar **help_uris = NULL;
proc_rec = procedural_db_lookup (gimp, "extension_gimp_help");
if (proc_rec == NULL)
{
/* FIXME: error msg */
return;
}
n_domains = plug_ins_help_domains (gimp, &help_domains, &help_uris);
args = g_new (Argument, 4);
args[0].arg_type = GIMP_PDB_INT32;
args[0].value.pdb_int = n_domains;
args[1].arg_type = GIMP_PDB_STRINGARRAY;
args[1].value.pdb_pointer = help_domains;
args[2].arg_type = GIMP_PDB_INT32;
args[2].value.pdb_int = n_domains;
args[3].arg_type = GIMP_PDB_STRINGARRAY;
args[3].value.pdb_pointer = help_uris;
plug_in_run (gimp, proc_rec, args, 4, FALSE, TRUE, -1);
procedural_db_destroy_args (args, 4);
}
/* Check if the help parser started properly */
proc_rec = procedural_db_lookup (gimp, "extension_gimp_help_temp");
if (proc_rec == NULL)
{
/* FIXME: error msg */
return;
}
else
{
url = g_strconcat ("file:",
help_domain, "/",
help_locale, "/",
help_id,
NULL);
Argument *return_vals;
gint n_return_vals;
#ifdef DEBUG_HELP
g_printerr ("Calling help via %s: %s %s %s\n",
procedure,
help_domain ? help_domain : NULL,
help_locale ? help_locale : NULL,
help_id ? help_id : NULL);
#endif
return_vals =
procedural_db_run_proc (gimp,
"extension_gimp_help_temp",
&n_return_vals,
GIMP_PDB_STRING, procedure,
GIMP_PDB_STRING, help_domain,
GIMP_PDB_STRING, help_locale,
GIMP_PDB_STRING, help_id,
GIMP_PDB_END);
procedural_db_destroy_args (return_vals, n_return_vals);
}
return_vals =
procedural_db_run_proc (gimp,
"plug_in_web_browser",
&nreturn_vals,
GIMP_PDB_STRING, url,
GIMP_PDB_END);
procedural_db_destroy_args (return_vals, nreturn_vals);
g_free (url);
}

View File

@ -1549,6 +1549,7 @@ plug-ins/gimpressionist/Makefile
plug-ins/gimpressionist/Brushes/Makefile
plug-ins/gimpressionist/Paper/Makefile
plug-ins/gimpressionist/Presets/Makefile
plug-ins/help/Makefile
plug-ins/helpbrowser/Makefile
plug-ins/ifscompose/Makefile
plug-ins/imagemap/Makefile

View File

@ -42,6 +42,7 @@ SUBDIRS = \
gflare \
gfli \
gimpressionist \
help \
$(helpbrowser) \
ifscompose \
imagemap \

25
plug-ins/help/Makefile.am Normal file
View File

@ -0,0 +1,25 @@
## Process this file with automake to produce Makefile.in
libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la
libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
libexecdir = $(gimpplugindir)/plug-ins
libexec_PROGRAMS = help
help_SOURCES = \
domain.c \
domain.h \
help.c
INCLUDES = \
-I$(top_srcdir) \
$(GLIB_CFLAGS) \
-I$(includedir)
LDADD = \
$(libgimp) \
$(libgimpbase) \
$(GLIB_LIBS) \
$(RT_LIBS) \
$(INTLLIBS)

View File

@ -68,8 +68,8 @@ domain_register (const gchar *domain_name,
g_return_if_fail (domain_name != NULL);
g_return_if_fail (domain_uri != NULL);
g_print ("helpbrowser: registering help domain \"%s\" with base uri \"%s\"\n",
domain_name, domain_uri);
g_printerr ("help: registering help domain \"%s\" with base uri \"%s\"\n",
domain_name, domain_uri);
if (! domain_hash)
domain_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
@ -83,7 +83,7 @@ domain_register (const gchar *domain_name,
HelpDomain *
domain_lookup (const gchar *domain_name)
{
g_return_val_if_fail (domain_name != NULL, NULL);
g_return_val_if_fail (domain_name, NULL);
if (domain_hash)
return g_hash_table_lookup (domain_hash, domain_name);
@ -406,8 +406,8 @@ domain_parser_parse_namespace (DomainParser *parser,
g_free (parser->id_attr_name);
parser->id_attr_name = g_strdup_printf ("%s:id", *names + 6);
g_print ("domain parser: id attribute name for \"%s\" is \"%s\"\n",
parser->domain->help_domain, parser->id_attr_name);
g_printerr ("help: id attribute name for \"%s\" is \"%s\"\n",
parser->domain->help_domain, parser->id_attr_name);
}
names++;
@ -446,6 +446,6 @@ domain_parser_parse_item (DomainParser *parser,
g_hash_table_insert (parser->domain->help_id_mapping,
g_strdup (id), g_strdup (ref));
g_print ("domain parser: added mapping \"%s\" -> \"%s\"\n", id, ref);
g_printerr ("help: added mapping \"%s\" -> \"%s\"\n", id, ref);
}
}

View File

@ -26,7 +26,7 @@
#define __DOMAIN_H__
#define GIMP_HELP_DEFAULT_DOMAIN "http://www.gimp.org/help"
#define GIMP_HELP_DEFAULT_DOMAIN "http://www.gimp.org/help"
typedef struct _HelpDomain HelpDomain;

451
plug-ins/help/gimphelp.c Normal file
View File

@ -0,0 +1,451 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* The GIMP Help Browser
* Copyright (C) 1999-2003 Sven Neumann <sven@gimp.org>
* Michael Natterer <mitch@gimp.org>
*
* domain.c
*
* 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "domain.h"
#include "libgimp/stdplugins-intl.h"
struct _HelpDomain
{
gchar *help_domain;
gchar *help_uri;
GHashTable *help_id_mapping;
};
/* local function prototypes */
HelpDomain * domain_new (const gchar *domain_name,
const gchar *domain_uri);
void domain_free (HelpDomain *domain);
gboolean domain_parse (HelpDomain *domain,
GError **error);
/* private variables */
static GHashTable *domain_hash = NULL;
/* public functions */
void
domain_register (const gchar *domain_name,
const gchar *domain_uri)
{
g_return_if_fail (domain_name != NULL);
g_return_if_fail (domain_uri != NULL);
g_printerr ("help: registering help domain \"%s\" with base uri \"%s\"\n",
domain_name, domain_uri);
if (! domain_hash)
domain_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify ) domain_free);
g_hash_table_insert (domain_hash,
g_strdup (domain_name),
domain_new (domain_name, domain_uri));
}
HelpDomain *
domain_lookup (const gchar *domain_name)
{
g_return_val_if_fail (domain_name, NULL);
if (domain_hash)
return g_hash_table_lookup (domain_hash, domain_name);
return NULL;
}
gchar *
domain_map (HelpDomain *domain,
const gchar *help_locale,
const gchar *help_id)
{
const gchar *ref;
gchar *full_uri;
g_return_val_if_fail (domain != NULL, NULL);
g_return_val_if_fail (help_locale != NULL, NULL);
g_return_val_if_fail (help_id != NULL, NULL);
if (! domain->help_id_mapping)
{
GError *error = NULL;
if (! domain_parse (domain, &error) || error)
{
if (! domain->help_id_mapping)
g_message (_("Failed to open help files:\n%s"), error->message);
else
g_message (_("Parse error in help domain:\n%s\n\n"
"(Added entires before error anyway)"), error->message);
if (error)
g_clear_error (&error);
}
if (! domain->help_id_mapping)
return NULL;
}
ref = g_hash_table_lookup (domain->help_id_mapping, help_id);
if (! ref)
{
g_message (_("Help ID '%s' unknown"), help_id);
return NULL;
}
full_uri = g_strconcat (domain->help_uri, "/",
help_locale, "/",
ref, NULL);
return full_uri;
}
/* private functions */
HelpDomain *
domain_new (const gchar *domain_name,
const gchar *domain_uri)
{
HelpDomain *domain;
domain = g_new0 (HelpDomain, 1);
domain->help_domain = g_strdup (domain_name);
domain->help_uri = g_strdup (domain_uri);
return domain;
}
void
domain_free (HelpDomain *domain)
{
g_return_if_fail (domain != NULL);
if (domain->help_id_mapping)
g_hash_table_destroy (domain->help_id_mapping);
g_free (domain->help_domain);
g_free (domain->help_uri);
g_free (domain);
}
/* the domain mapping parser */
typedef enum
{
DOMAIN_START,
DOMAIN_IN_HELP,
DOMAIN_IN_ITEM,
DOMAIN_IN_UNKNOWN
} DomainParserState;
typedef struct
{
const gchar *filename;
DomainParserState state;
DomainParserState last_known_state;
gint markup_depth;
gint unknown_depth;
GString *value;
HelpDomain *domain;
gchar *id_attr_name;
} DomainParser;
static void domain_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error);
static void domain_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error);
static void domain_parser_error (GMarkupParseContext *context,
GError *error,
gpointer user_data);
static void domain_parser_start_unknown (DomainParser *parser);
static void domain_parser_end_unknown (DomainParser *parser);
static void domain_parser_parse_namespace (DomainParser *parser,
const gchar **names,
const gchar **values);
static void domain_parser_parse_item (DomainParser *parser,
const gchar **names,
const gchar **values);
static const GMarkupParser markup_parser =
{
domain_parser_start_element,
domain_parser_end_element,
NULL, /* characters */
NULL, /* passthrough */
domain_parser_error
};
gboolean
domain_parse (HelpDomain *domain,
GError **error)
{
GMarkupParseContext *context;
DomainParser *parser;
gchar *base_dir;
gchar *filename;
FILE *fp;
gsize bytes;
gchar buf[4096];
g_return_val_if_fail (domain != NULL, FALSE);
g_return_val_if_fail (domain->help_id_mapping == NULL, FALSE);
base_dir = g_filename_from_uri (domain->help_uri, NULL, NULL);
filename = g_build_filename (base_dir, "gimp-help.xml", NULL);
g_free (base_dir);
fp = fopen (filename, "r");
if (! fp)
{
gchar *msg;
gchar *msg2;
if (! strcmp (domain->help_domain, GIMP_HELP_DEFAULT_DOMAIN))
msg = _("The GIMP help files are not installed.");
else
msg = _("The requested help files are not installed.");
msg2 = g_strdup_printf (_("Could not open '%s' for reading: %s"),
gimp_filename_to_utf8 (filename),
g_strerror (errno));
g_set_error (error, 0, 0, "%s\n\n%s\n\n%s",
msg, msg2, _("Please check your installation."));
g_free (msg2);
g_free (filename);
return FALSE;
}
parser = g_new0 (DomainParser, 1);
parser->filename = filename;
parser->value = g_string_new (NULL);
parser->id_attr_name = g_strdup ("id");
parser->domain = domain;
context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);
while ((bytes = fread (buf, sizeof (gchar), sizeof (buf), fp)) > 0 &&
g_markup_parse_context_parse (context, buf, bytes, error))
;
if (error == NULL || *error == NULL)
g_markup_parse_context_end_parse (context, error);
fclose (fp);
g_markup_parse_context_free (context);
g_string_free (parser->value, TRUE);
g_free (parser->id_attr_name);
g_free (parser);
g_free (filename);
return (domain->help_id_mapping != NULL);
}
static void
domain_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
DomainParser *parser = (DomainParser *) user_data;
switch (parser->state)
{
case DOMAIN_START:
if (strcmp (element_name, "gimp-help") == 0)
{
parser->state = DOMAIN_IN_HELP;
domain_parser_parse_namespace (parser, attribute_names,
attribute_values);
}
else
domain_parser_start_unknown (parser);
break;
case DOMAIN_IN_HELP:
if (strcmp (element_name, "help-item") == 0)
{
parser->state = DOMAIN_IN_ITEM;
domain_parser_parse_item (parser, attribute_names,
attribute_values);
}
else
domain_parser_start_unknown (parser);
break;
case DOMAIN_IN_ITEM:
case DOMAIN_IN_UNKNOWN:
domain_parser_start_unknown (parser);
break;
}
}
static void
domain_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error)
{
DomainParser *parser = (DomainParser *) user_data;
switch (parser->state)
{
case DOMAIN_START:
g_warning ("domain_parser: This shouldn't happen.");
break;
case DOMAIN_IN_HELP:
parser->state = DOMAIN_START;
break;
case DOMAIN_IN_ITEM:
parser->state = DOMAIN_IN_HELP;
break;
case DOMAIN_IN_UNKNOWN:
domain_parser_end_unknown (parser);
break;
}
}
static void
domain_parser_error (GMarkupParseContext *context,
GError *error,
gpointer user_data)
{
DomainParser *parser = (DomainParser *) user_data;
g_warning ("%s: %s", parser->filename, error->message);
}
static void
domain_parser_start_unknown (DomainParser *parser)
{
if (parser->unknown_depth == 0)
parser->last_known_state = parser->state;
parser->state = DOMAIN_IN_UNKNOWN;
parser->unknown_depth++;
}
static void
domain_parser_end_unknown (DomainParser *parser)
{
g_assert (parser->unknown_depth > 0 && parser->state == DOMAIN_IN_UNKNOWN);
parser->unknown_depth--;
if (parser->unknown_depth == 0)
parser->state = parser->last_known_state;
}
static void
domain_parser_parse_namespace (DomainParser *parser,
const gchar **names,
const gchar **values)
{
while (*names && *values)
{
if (! strncmp (*names, "xmlns:", 6) &&
! strcmp (*values, parser->domain->help_domain))
{
g_free (parser->id_attr_name);
parser->id_attr_name = g_strdup_printf ("%s:id", *names + 6);
g_printerr ("help: id attribute name for \"%s\" is \"%s\"\n",
parser->domain->help_domain, parser->id_attr_name);
}
names++;
values++;
}
}
static void
domain_parser_parse_item (DomainParser *parser,
const gchar **names,
const gchar **values)
{
const gchar *id = NULL;
const gchar *ref = NULL;
while (*names && *values)
{
if (! strcmp (*names, parser->id_attr_name))
id = *values;
if (! strcmp (*names, "ref"))
ref = *values;
names++;
values++;
}
if (id && ref)
{
if (! parser->domain->help_id_mapping)
parser->domain->help_id_mapping = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_free);
g_hash_table_insert (parser->domain->help_id_mapping,
g_strdup (id), g_strdup (ref));
g_printerr ("help: added mapping \"%s\" -> \"%s\"\n", id, ref);
}
}

View File

@ -0,0 +1,451 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* The GIMP Help Browser
* Copyright (C) 1999-2003 Sven Neumann <sven@gimp.org>
* Michael Natterer <mitch@gimp.org>
*
* domain.c
*
* 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "domain.h"
#include "libgimp/stdplugins-intl.h"
struct _HelpDomain
{
gchar *help_domain;
gchar *help_uri;
GHashTable *help_id_mapping;
};
/* local function prototypes */
HelpDomain * domain_new (const gchar *domain_name,
const gchar *domain_uri);
void domain_free (HelpDomain *domain);
gboolean domain_parse (HelpDomain *domain,
GError **error);
/* private variables */
static GHashTable *domain_hash = NULL;
/* public functions */
void
domain_register (const gchar *domain_name,
const gchar *domain_uri)
{
g_return_if_fail (domain_name != NULL);
g_return_if_fail (domain_uri != NULL);
g_printerr ("help: registering help domain \"%s\" with base uri \"%s\"\n",
domain_name, domain_uri);
if (! domain_hash)
domain_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify ) domain_free);
g_hash_table_insert (domain_hash,
g_strdup (domain_name),
domain_new (domain_name, domain_uri));
}
HelpDomain *
domain_lookup (const gchar *domain_name)
{
g_return_val_if_fail (domain_name, NULL);
if (domain_hash)
return g_hash_table_lookup (domain_hash, domain_name);
return NULL;
}
gchar *
domain_map (HelpDomain *domain,
const gchar *help_locale,
const gchar *help_id)
{
const gchar *ref;
gchar *full_uri;
g_return_val_if_fail (domain != NULL, NULL);
g_return_val_if_fail (help_locale != NULL, NULL);
g_return_val_if_fail (help_id != NULL, NULL);
if (! domain->help_id_mapping)
{
GError *error = NULL;
if (! domain_parse (domain, &error) || error)
{
if (! domain->help_id_mapping)
g_message (_("Failed to open help files:\n%s"), error->message);
else
g_message (_("Parse error in help domain:\n%s\n\n"
"(Added entires before error anyway)"), error->message);
if (error)
g_clear_error (&error);
}
if (! domain->help_id_mapping)
return NULL;
}
ref = g_hash_table_lookup (domain->help_id_mapping, help_id);
if (! ref)
{
g_message (_("Help ID '%s' unknown"), help_id);
return NULL;
}
full_uri = g_strconcat (domain->help_uri, "/",
help_locale, "/",
ref, NULL);
return full_uri;
}
/* private functions */
HelpDomain *
domain_new (const gchar *domain_name,
const gchar *domain_uri)
{
HelpDomain *domain;
domain = g_new0 (HelpDomain, 1);
domain->help_domain = g_strdup (domain_name);
domain->help_uri = g_strdup (domain_uri);
return domain;
}
void
domain_free (HelpDomain *domain)
{
g_return_if_fail (domain != NULL);
if (domain->help_id_mapping)
g_hash_table_destroy (domain->help_id_mapping);
g_free (domain->help_domain);
g_free (domain->help_uri);
g_free (domain);
}
/* the domain mapping parser */
typedef enum
{
DOMAIN_START,
DOMAIN_IN_HELP,
DOMAIN_IN_ITEM,
DOMAIN_IN_UNKNOWN
} DomainParserState;
typedef struct
{
const gchar *filename;
DomainParserState state;
DomainParserState last_known_state;
gint markup_depth;
gint unknown_depth;
GString *value;
HelpDomain *domain;
gchar *id_attr_name;
} DomainParser;
static void domain_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error);
static void domain_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error);
static void domain_parser_error (GMarkupParseContext *context,
GError *error,
gpointer user_data);
static void domain_parser_start_unknown (DomainParser *parser);
static void domain_parser_end_unknown (DomainParser *parser);
static void domain_parser_parse_namespace (DomainParser *parser,
const gchar **names,
const gchar **values);
static void domain_parser_parse_item (DomainParser *parser,
const gchar **names,
const gchar **values);
static const GMarkupParser markup_parser =
{
domain_parser_start_element,
domain_parser_end_element,
NULL, /* characters */
NULL, /* passthrough */
domain_parser_error
};
gboolean
domain_parse (HelpDomain *domain,
GError **error)
{
GMarkupParseContext *context;
DomainParser *parser;
gchar *base_dir;
gchar *filename;
FILE *fp;
gsize bytes;
gchar buf[4096];
g_return_val_if_fail (domain != NULL, FALSE);
g_return_val_if_fail (domain->help_id_mapping == NULL, FALSE);
base_dir = g_filename_from_uri (domain->help_uri, NULL, NULL);
filename = g_build_filename (base_dir, "gimp-help.xml", NULL);
g_free (base_dir);
fp = fopen (filename, "r");
if (! fp)
{
gchar *msg;
gchar *msg2;
if (! strcmp (domain->help_domain, GIMP_HELP_DEFAULT_DOMAIN))
msg = _("The GIMP help files are not installed.");
else
msg = _("The requested help files are not installed.");
msg2 = g_strdup_printf (_("Could not open '%s' for reading: %s"),
gimp_filename_to_utf8 (filename),
g_strerror (errno));
g_set_error (error, 0, 0, "%s\n\n%s\n\n%s",
msg, msg2, _("Please check your installation."));
g_free (msg2);
g_free (filename);
return FALSE;
}
parser = g_new0 (DomainParser, 1);
parser->filename = filename;
parser->value = g_string_new (NULL);
parser->id_attr_name = g_strdup ("id");
parser->domain = domain;
context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);
while ((bytes = fread (buf, sizeof (gchar), sizeof (buf), fp)) > 0 &&
g_markup_parse_context_parse (context, buf, bytes, error))
;
if (error == NULL || *error == NULL)
g_markup_parse_context_end_parse (context, error);
fclose (fp);
g_markup_parse_context_free (context);
g_string_free (parser->value, TRUE);
g_free (parser->id_attr_name);
g_free (parser);
g_free (filename);
return (domain->help_id_mapping != NULL);
}
static void
domain_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
DomainParser *parser = (DomainParser *) user_data;
switch (parser->state)
{
case DOMAIN_START:
if (strcmp (element_name, "gimp-help") == 0)
{
parser->state = DOMAIN_IN_HELP;
domain_parser_parse_namespace (parser, attribute_names,
attribute_values);
}
else
domain_parser_start_unknown (parser);
break;
case DOMAIN_IN_HELP:
if (strcmp (element_name, "help-item") == 0)
{
parser->state = DOMAIN_IN_ITEM;
domain_parser_parse_item (parser, attribute_names,
attribute_values);
}
else
domain_parser_start_unknown (parser);
break;
case DOMAIN_IN_ITEM:
case DOMAIN_IN_UNKNOWN:
domain_parser_start_unknown (parser);
break;
}
}
static void
domain_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error)
{
DomainParser *parser = (DomainParser *) user_data;
switch (parser->state)
{
case DOMAIN_START:
g_warning ("domain_parser: This shouldn't happen.");
break;
case DOMAIN_IN_HELP:
parser->state = DOMAIN_START;
break;
case DOMAIN_IN_ITEM:
parser->state = DOMAIN_IN_HELP;
break;
case DOMAIN_IN_UNKNOWN:
domain_parser_end_unknown (parser);
break;
}
}
static void
domain_parser_error (GMarkupParseContext *context,
GError *error,
gpointer user_data)
{
DomainParser *parser = (DomainParser *) user_data;
g_warning ("%s: %s", parser->filename, error->message);
}
static void
domain_parser_start_unknown (DomainParser *parser)
{
if (parser->unknown_depth == 0)
parser->last_known_state = parser->state;
parser->state = DOMAIN_IN_UNKNOWN;
parser->unknown_depth++;
}
static void
domain_parser_end_unknown (DomainParser *parser)
{
g_assert (parser->unknown_depth > 0 && parser->state == DOMAIN_IN_UNKNOWN);
parser->unknown_depth--;
if (parser->unknown_depth == 0)
parser->state = parser->last_known_state;
}
static void
domain_parser_parse_namespace (DomainParser *parser,
const gchar **names,
const gchar **values)
{
while (*names && *values)
{
if (! strncmp (*names, "xmlns:", 6) &&
! strcmp (*values, parser->domain->help_domain))
{
g_free (parser->id_attr_name);
parser->id_attr_name = g_strdup_printf ("%s:id", *names + 6);
g_printerr ("help: id attribute name for \"%s\" is \"%s\"\n",
parser->domain->help_domain, parser->id_attr_name);
}
names++;
values++;
}
}
static void
domain_parser_parse_item (DomainParser *parser,
const gchar **names,
const gchar **values)
{
const gchar *id = NULL;
const gchar *ref = NULL;
while (*names && *values)
{
if (! strcmp (*names, parser->id_attr_name))
id = *values;
if (! strcmp (*names, "ref"))
ref = *values;
names++;
values++;
}
if (id && ref)
{
if (! parser->domain->help_id_mapping)
parser->domain->help_id_mapping = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_free);
g_hash_table_insert (parser->domain->help_id_mapping,
g_strdup (id), g_strdup (ref));
g_printerr ("help: added mapping \"%s\" -> \"%s\"\n", id, ref);
}
}

View File

@ -0,0 +1,451 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* The GIMP Help Browser
* Copyright (C) 1999-2003 Sven Neumann <sven@gimp.org>
* Michael Natterer <mitch@gimp.org>
*
* domain.c
*
* 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "domain.h"
#include "libgimp/stdplugins-intl.h"
struct _HelpDomain
{
gchar *help_domain;
gchar *help_uri;
GHashTable *help_id_mapping;
};
/* local function prototypes */
HelpDomain * domain_new (const gchar *domain_name,
const gchar *domain_uri);
void domain_free (HelpDomain *domain);
gboolean domain_parse (HelpDomain *domain,
GError **error);
/* private variables */
static GHashTable *domain_hash = NULL;
/* public functions */
void
domain_register (const gchar *domain_name,
const gchar *domain_uri)
{
g_return_if_fail (domain_name != NULL);
g_return_if_fail (domain_uri != NULL);
g_printerr ("help: registering help domain \"%s\" with base uri \"%s\"\n",
domain_name, domain_uri);
if (! domain_hash)
domain_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify ) domain_free);
g_hash_table_insert (domain_hash,
g_strdup (domain_name),
domain_new (domain_name, domain_uri));
}
HelpDomain *
domain_lookup (const gchar *domain_name)
{
g_return_val_if_fail (domain_name, NULL);
if (domain_hash)
return g_hash_table_lookup (domain_hash, domain_name);
return NULL;
}
gchar *
domain_map (HelpDomain *domain,
const gchar *help_locale,
const gchar *help_id)
{
const gchar *ref;
gchar *full_uri;
g_return_val_if_fail (domain != NULL, NULL);
g_return_val_if_fail (help_locale != NULL, NULL);
g_return_val_if_fail (help_id != NULL, NULL);
if (! domain->help_id_mapping)
{
GError *error = NULL;
if (! domain_parse (domain, &error) || error)
{
if (! domain->help_id_mapping)
g_message (_("Failed to open help files:\n%s"), error->message);
else
g_message (_("Parse error in help domain:\n%s\n\n"
"(Added entires before error anyway)"), error->message);
if (error)
g_clear_error (&error);
}
if (! domain->help_id_mapping)
return NULL;
}
ref = g_hash_table_lookup (domain->help_id_mapping, help_id);
if (! ref)
{
g_message (_("Help ID '%s' unknown"), help_id);
return NULL;
}
full_uri = g_strconcat (domain->help_uri, "/",
help_locale, "/",
ref, NULL);
return full_uri;
}
/* private functions */
HelpDomain *
domain_new (const gchar *domain_name,
const gchar *domain_uri)
{
HelpDomain *domain;
domain = g_new0 (HelpDomain, 1);
domain->help_domain = g_strdup (domain_name);
domain->help_uri = g_strdup (domain_uri);
return domain;
}
void
domain_free (HelpDomain *domain)
{
g_return_if_fail (domain != NULL);
if (domain->help_id_mapping)
g_hash_table_destroy (domain->help_id_mapping);
g_free (domain->help_domain);
g_free (domain->help_uri);
g_free (domain);
}
/* the domain mapping parser */
typedef enum
{
DOMAIN_START,
DOMAIN_IN_HELP,
DOMAIN_IN_ITEM,
DOMAIN_IN_UNKNOWN
} DomainParserState;
typedef struct
{
const gchar *filename;
DomainParserState state;
DomainParserState last_known_state;
gint markup_depth;
gint unknown_depth;
GString *value;
HelpDomain *domain;
gchar *id_attr_name;
} DomainParser;
static void domain_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error);
static void domain_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error);
static void domain_parser_error (GMarkupParseContext *context,
GError *error,
gpointer user_data);
static void domain_parser_start_unknown (DomainParser *parser);
static void domain_parser_end_unknown (DomainParser *parser);
static void domain_parser_parse_namespace (DomainParser *parser,
const gchar **names,
const gchar **values);
static void domain_parser_parse_item (DomainParser *parser,
const gchar **names,
const gchar **values);
static const GMarkupParser markup_parser =
{
domain_parser_start_element,
domain_parser_end_element,
NULL, /* characters */
NULL, /* passthrough */
domain_parser_error
};
gboolean
domain_parse (HelpDomain *domain,
GError **error)
{
GMarkupParseContext *context;
DomainParser *parser;
gchar *base_dir;
gchar *filename;
FILE *fp;
gsize bytes;
gchar buf[4096];
g_return_val_if_fail (domain != NULL, FALSE);
g_return_val_if_fail (domain->help_id_mapping == NULL, FALSE);
base_dir = g_filename_from_uri (domain->help_uri, NULL, NULL);
filename = g_build_filename (base_dir, "gimp-help.xml", NULL);
g_free (base_dir);
fp = fopen (filename, "r");
if (! fp)
{
gchar *msg;
gchar *msg2;
if (! strcmp (domain->help_domain, GIMP_HELP_DEFAULT_DOMAIN))
msg = _("The GIMP help files are not installed.");
else
msg = _("The requested help files are not installed.");
msg2 = g_strdup_printf (_("Could not open '%s' for reading: %s"),
gimp_filename_to_utf8 (filename),
g_strerror (errno));
g_set_error (error, 0, 0, "%s\n\n%s\n\n%s",
msg, msg2, _("Please check your installation."));
g_free (msg2);
g_free (filename);
return FALSE;
}
parser = g_new0 (DomainParser, 1);
parser->filename = filename;
parser->value = g_string_new (NULL);
parser->id_attr_name = g_strdup ("id");
parser->domain = domain;
context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);
while ((bytes = fread (buf, sizeof (gchar), sizeof (buf), fp)) > 0 &&
g_markup_parse_context_parse (context, buf, bytes, error))
;
if (error == NULL || *error == NULL)
g_markup_parse_context_end_parse (context, error);
fclose (fp);
g_markup_parse_context_free (context);
g_string_free (parser->value, TRUE);
g_free (parser->id_attr_name);
g_free (parser);
g_free (filename);
return (domain->help_id_mapping != NULL);
}
static void
domain_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
DomainParser *parser = (DomainParser *) user_data;
switch (parser->state)
{
case DOMAIN_START:
if (strcmp (element_name, "gimp-help") == 0)
{
parser->state = DOMAIN_IN_HELP;
domain_parser_parse_namespace (parser, attribute_names,
attribute_values);
}
else
domain_parser_start_unknown (parser);
break;
case DOMAIN_IN_HELP:
if (strcmp (element_name, "help-item") == 0)
{
parser->state = DOMAIN_IN_ITEM;
domain_parser_parse_item (parser, attribute_names,
attribute_values);
}
else
domain_parser_start_unknown (parser);
break;
case DOMAIN_IN_ITEM:
case DOMAIN_IN_UNKNOWN:
domain_parser_start_unknown (parser);
break;
}
}
static void
domain_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error)
{
DomainParser *parser = (DomainParser *) user_data;
switch (parser->state)
{
case DOMAIN_START:
g_warning ("domain_parser: This shouldn't happen.");
break;
case DOMAIN_IN_HELP:
parser->state = DOMAIN_START;
break;
case DOMAIN_IN_ITEM:
parser->state = DOMAIN_IN_HELP;
break;
case DOMAIN_IN_UNKNOWN:
domain_parser_end_unknown (parser);
break;
}
}
static void
domain_parser_error (GMarkupParseContext *context,
GError *error,
gpointer user_data)
{
DomainParser *parser = (DomainParser *) user_data;
g_warning ("%s: %s", parser->filename, error->message);
}
static void
domain_parser_start_unknown (DomainParser *parser)
{
if (parser->unknown_depth == 0)
parser->last_known_state = parser->state;
parser->state = DOMAIN_IN_UNKNOWN;
parser->unknown_depth++;
}
static void
domain_parser_end_unknown (DomainParser *parser)
{
g_assert (parser->unknown_depth > 0 && parser->state == DOMAIN_IN_UNKNOWN);
parser->unknown_depth--;
if (parser->unknown_depth == 0)
parser->state = parser->last_known_state;
}
static void
domain_parser_parse_namespace (DomainParser *parser,
const gchar **names,
const gchar **values)
{
while (*names && *values)
{
if (! strncmp (*names, "xmlns:", 6) &&
! strcmp (*values, parser->domain->help_domain))
{
g_free (parser->id_attr_name);
parser->id_attr_name = g_strdup_printf ("%s:id", *names + 6);
g_printerr ("help: id attribute name for \"%s\" is \"%s\"\n",
parser->domain->help_domain, parser->id_attr_name);
}
names++;
values++;
}
}
static void
domain_parser_parse_item (DomainParser *parser,
const gchar **names,
const gchar **values)
{
const gchar *id = NULL;
const gchar *ref = NULL;
while (*names && *values)
{
if (! strcmp (*names, parser->id_attr_name))
id = *values;
if (! strcmp (*names, "ref"))
ref = *values;
names++;
values++;
}
if (id && ref)
{
if (! parser->domain->help_id_mapping)
parser->domain->help_id_mapping = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_free);
g_hash_table_insert (parser->domain->help_id_mapping,
g_strdup (id), g_strdup (ref));
g_printerr ("help: added mapping \"%s\" -> \"%s\"\n", id, ref);
}
}

338
plug-ins/help/help.c Normal file
View File

@ -0,0 +1,338 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* The GIMP Help plug-in
* Copyright (C) 1999-2004 Sven Neumann <sven@gimp.org>
* Michael Natterer <mitch@gimp.org>
* Henrik Brix Andersen <brix@gimp.org>
*
* Some code & ideas stolen from the GNOME help browser.
*
* 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <string.h> /* strlen */
#include <glib.h>
#include "libgimp/gimp.h"
#include "domain.h"
/* defines */
#define GIMP_HELP_EXT_NAME "extension_gimp_help"
#define GIMP_HELP_TEMP_EXT_NAME "extension_gimp_help_temp"
#define GIMP_HELP_PREFIX "help"
#define GIMP_HELP_ENV_URI "GIMP2_HELP_URI"
#define GIMP_HELP_DEFAULT_LOCALE "C"
#define GIMP_HELP_DEFAULT_ID "gimp-main"
typedef struct
{
gchar *procedure;
gchar *help_domain;
gchar *help_locale;
gchar *help_id;
} IdleHelp;
/* forward declarations */
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void temp_proc_install (void);
static void temp_proc_run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void load_help (const gchar *procedure,
const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id);
static gboolean load_help_idle (gpointer data);
/* local variables */
GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
MAIN ()
static void
query (void)
{
static GimpParamDef args[] =
{
{ GIMP_PDB_INT32, "num_domain_names", "" },
{ GIMP_PDB_STRINGARRAY, "domain_names", "" },
{ GIMP_PDB_INT32, "num_domain_uris", "" },
{ GIMP_PDB_STRINGARRAY, "domain_uris", "" }
};
gimp_install_procedure (GIMP_HELP_EXT_NAME,
"", /* FIXME */
"", /* FIXME */
"Sven Neumann <sven@gimp.org>, "
"Michael Natterer <mitch@gimp.org>, "
"Henrik Brix Andersen <brix@gimp.org>",
"Sven Neumann, Michael Natterer & Henrik Brix Andersen",
"1999-2004",
NULL,
"",
GIMP_EXTENSION,
G_N_ELEMENTS (args), 0,
args, NULL);
}
static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
const gchar *default_env_domain_uri;
gchar *default_domain_uri;
/* set default values */
default_env_domain_uri = g_getenv (GIMP_HELP_ENV_URI);
if (default_env_domain_uri)
{
default_domain_uri = g_strdup (default_env_domain_uri);
}
else
{
gchar *help_root = g_build_filename (gimp_data_directory (),
GIMP_HELP_PREFIX,
NULL);
default_domain_uri = g_filename_to_uri (help_root, NULL, NULL);
g_free (help_root);
}
/* make sure all the arguments are there */
if (nparams == 4)
{
gint num_domain_names = param[0].data.d_int32;
gchar **domain_names = param[1].data.d_stringarray;
gint num_domain_uris = param[2].data.d_int32;
gchar **domain_uris = param[3].data.d_stringarray;
if (num_domain_names == num_domain_uris)
{
gint i;
domain_register (GIMP_HELP_DEFAULT_DOMAIN, default_domain_uri);
for (i = 0; i < num_domain_names; i++)
{
domain_register (domain_names[i], domain_uris[i]);
}
}
else
{
g_printerr ("help: number of names doesn't match number of URIs.\n");
status = GIMP_PDB_CALLING_ERROR;
}
}
else
{
g_printerr ("help: wrong number of arguments in procedure call.\n");
status = GIMP_PDB_CALLING_ERROR;
}
g_free (default_domain_uri);
if (status == GIMP_PDB_SUCCESS)
{
GMainLoop *loop;
temp_proc_install ();
gimp_extension_ack ();
gimp_extension_enable ();
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
*nreturn_vals = 1;
*return_vals = values;
}
static void
temp_proc_install (void)
{
static GimpParamDef args[] =
{
{ GIMP_PDB_STRING, "procedure", "The procedure of the browser to use" },
{ GIMP_PDB_STRING, "help_domain", "Help domain to use" },
{ GIMP_PDB_STRING, "help_locale", "Language to use" },
{ GIMP_PDB_STRING, "help_id", "Help ID to open" }
};
gimp_install_temp_proc (GIMP_HELP_TEMP_EXT_NAME,
"DON'T USE THIS ONE",
"(Temporary procedure)",
"Sven Neumann <sven@gimp.org>, "
"Michael Natterer <mitch@gimp.org>"
"Henrik Brix Andersen <brix@gimp.org",
"Sven Neumann, Michael Natterer & Henrik Brix Andersen",
"1999-2004",
NULL,
"",
GIMP_TEMPORARY,
G_N_ELEMENTS (args), 0,
args, NULL,
temp_proc_run);
}
static void
temp_proc_run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
const gchar *procedure = ""; /* FIXME */
const gchar *help_domain = GIMP_HELP_DEFAULT_DOMAIN;
const gchar *help_locale = GIMP_HELP_DEFAULT_LOCALE;
const gchar *help_id = GIMP_HELP_DEFAULT_ID;
*nreturn_vals = 1;
*return_vals = values;
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
/* make sure all the arguments are there */
if (nparams == 4)
{
if (param[0].data.d_string && strlen (param[0].data.d_string))
procedure = param[0].data.d_string;
if (param[1].data.d_string && strlen (param[1].data.d_string))
help_domain = param[1].data.d_string;
if (param[2].data.d_string && strlen (param[2].data.d_string))
help_locale = param[2].data.d_string;
if (param[3].data.d_string && strlen (param[3].data.d_string))
help_id = param[3].data.d_string;
}
load_help (procedure, help_domain, help_locale, help_id);
}
static void
load_help (const gchar *procedure,
const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id)
{
IdleHelp *idle_help;
idle_help = g_new0 (IdleHelp, 1);
idle_help->procedure = g_strdup (procedure);
idle_help->help_domain = g_strdup (help_domain);
idle_help->help_locale = g_strdup (help_locale);
idle_help->help_id = g_strdup (help_id);
g_idle_add (load_help_idle, idle_help);
}
static gboolean
load_help_idle (gpointer data)
{
IdleHelp *idle_help;
HelpDomain *domain;
gchar *full_uri;
idle_help = (IdleHelp *) data;
g_printerr ("help: got a request for %s %s %s\n",
idle_help->help_domain,
idle_help->help_locale,
idle_help->help_id);
domain = domain_lookup (idle_help->help_domain);
if (domain)
{
full_uri = domain_map (domain,
idle_help->help_locale,
idle_help->help_id);
if (full_uri)
{
GimpParam *return_vals;
gint n_return_vals;
g_printerr ("help: calling '%s' for '%s'\n",
idle_help->procedure, full_uri);
return_vals = gimp_run_procedure (idle_help->procedure,
&n_return_vals,
GIMP_PDB_STRING, full_uri,
GIMP_PDB_END);
gimp_destroy_params (return_vals, n_return_vals);
g_free (full_uri);
}
}
g_free (idle_help->procedure);
g_free (idle_help->help_domain);
g_free (idle_help->help_locale);
g_free (idle_help->help_id);
g_free (idle_help);
return FALSE;
}

View File

@ -14,8 +14,6 @@ helpbrowser_SOURCES = \
helpbrowser.c \
dialog.c \
dialog.h \
domain.c \
domain.h \
queue.c \
queue.h \
uri.c \

View File

@ -2,8 +2,9 @@
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* The GIMP Help Browser
* Copyright (C) 1999-2002 Sven Neumann <sven@gimp.org>
* Copyright (C) 1999-2004 Sven Neumann <sven@gimp.org>
* Michael Natterer <mitch@gimp.org>
* Henrik Brix Andersen <brix@gimp.org>
*
* Some code & ideas stolen from the GNOME help browser.
*
@ -24,55 +25,38 @@
#include "config.h"
#include <string.h>
#include <string.h> /* strlen, strcmp */
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "dialog.h"
#include "domain.h"
#include "libgimp/stdplugins-intl.h"
/* defines */
#define GIMP_HELP_EXT_NAME "extension_gimp_help_browser"
#define GIMP_HELP_TEMP_EXT_NAME "extension_gimp_help_browser_temp"
#define GIMP_HELP_PREFIX "help"
typedef struct
{
gchar *help_domain;
gchar *help_locale;
gchar *help_id;
} IdleHelp;
#define GIMP_HELP_BROWSER_EXT_NAME "extension_gimp_help_browser"
#define GIMP_HELP_BROWSER_TEMP_EXT_NAME "extension_gimp_help_browser_temp"
/* forward declarations */
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void temp_proc_install (void);
static void temp_proc_run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static void load_help (const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id);
static gboolean load_help_idle (gpointer data);
static void temp_proc_install (void);
static void temp_proc_run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
/* local variables */
@ -93,21 +77,18 @@ query (void)
{
static GimpParamDef args[] =
{
{ GIMP_PDB_INT32, "run_mode", "Interactive" },
{ GIMP_PDB_INT32, "num_domain_names", "" },
{ GIMP_PDB_STRINGARRAY, "domain_names", "" },
{ GIMP_PDB_INT32, "num_domain_uris", "" },
{ GIMP_PDB_STRINGARRAY, "domain_uris", "" }
{ GIMP_PDB_INT32, "run_mode", "Interactive" },
};
gimp_install_procedure (GIMP_HELP_EXT_NAME,
gimp_install_procedure (GIMP_HELP_BROWSER_EXT_NAME,
"Browse the GIMP help pages",
"A small and simple HTML browser optimized for "
"browsing the GIMP help pages.",
"Sven Neumann <sven@gimp.org>, "
"Michael Natterer <mitch@gimp.org>",
"Sven Neumann & Michael Natterer",
"1999-2003",
"Michael Natterer <mitch@gimp.org>"
"Henrik Brix Andersen <brix@gimp.org>",
"Sven Neumann, Michael Natterer & Henrik Brix Andersen",
"1999-2004",
NULL,
"",
GIMP_EXTENSION,
@ -122,11 +103,10 @@ run (const gchar *name,
gint *nreturn_vals,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpRunMode run_mode;
GimpRunMode run_mode = param[0].data.d_int32;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
run_mode = param[0].data.d_int32;
static GimpParam values[1];
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
@ -136,70 +116,13 @@ run (const gchar *name,
INIT_I18N ();
if (strcmp (name, GIMP_HELP_EXT_NAME) == 0)
switch (run_mode)
{
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
case GIMP_RUN_NONINTERACTIVE:
case GIMP_RUN_WITH_LAST_VALS:
{
const gchar *default_env_domain_uri;
gchar *default_domain_uri;
/* set default values */
default_env_domain_uri = g_getenv ("GIMP2_HELP_URI");
if (default_env_domain_uri)
{
default_domain_uri = g_strdup (default_env_domain_uri);
}
else
{
gchar *help_root;
help_root = g_build_filename (gimp_data_directory (),
GIMP_HELP_PREFIX, NULL);
default_domain_uri = g_filename_to_uri (help_root, NULL, NULL);
g_free (help_root);
}
/* Make sure all the arguments are there! */
if (nparams == 5)
{
if (param[1].data.d_int32 == param[3].data.d_int32)
{
gint i;
domain_register (GIMP_HELP_DEFAULT_DOMAIN,
default_domain_uri);
for (i = 0; i < param[1].data.d_int32; i++)
domain_register (param[2].data.d_stringarray[i],
param[4].data.d_stringarray[i]);
}
else
{
status = GIMP_PDB_CALLING_ERROR;
}
}
else
{
status = GIMP_PDB_CALLING_ERROR;
}
g_free (default_domain_uri);
}
break;
default:
status = GIMP_PDB_CALLING_ERROR;
break;
}
if (status == GIMP_PDB_SUCCESS)
case GIMP_RUN_INTERACTIVE:
case GIMP_RUN_NONINTERACTIVE:
case GIMP_RUN_WITH_LAST_VALS:
/* Make sure all the arguments are there! */
if (nparams == 1)
{
browser_dialog_open ();
@ -213,10 +136,15 @@ run (const gchar *name,
gtk_main ();
}
}
else
{
else
{
status = GIMP_PDB_CALLING_ERROR;
}
break;
default:
status = GIMP_PDB_CALLING_ERROR;
break;
}
values[0].data.d_status = status;
@ -227,18 +155,17 @@ temp_proc_install (void)
{
static GimpParamDef args[] =
{
{ GIMP_PDB_STRING, "help_domain", "Help domain to use" },
{ GIMP_PDB_STRING, "help_locale", "Language to use" },
{ GIMP_PDB_STRING, "help_id", "Help ID to open" }
{ GIMP_PDB_STRING, "uri", "Full uri of the file to open" }
};
gimp_install_temp_proc (GIMP_HELP_TEMP_EXT_NAME,
gimp_install_temp_proc (GIMP_HELP_BROWSER_TEMP_EXT_NAME,
"DON'T USE THIS ONE",
"(Temporary procedure)",
"Sven Neumann <sven@gimp.org>, "
"Michael Natterer <mitch@gimp.org>",
"Sven Neumann & Michael Natterer",
"1999-2003",
"Michael Natterer <mitch@gimp.org>"
"Henrik Brix Andersen <brix@gimp.org>",
"Sven Neumann, Michael Natterer & Henrik Brix Andersen",
"1999-2004",
NULL,
"",
GIMP_TEMPORARY,
@ -254,80 +181,29 @@ temp_proc_run (const gchar *name,
gint *nreturn_vals,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
const gchar *help_domain = GIMP_HELP_DEFAULT_DOMAIN;
const gchar *help_locale = "C";
const gchar *help_id = "gimp-main";
/* Make sure all the arguments are there! */
if (nparams == 3)
{
if (param[0].data.d_string && strlen (param[0].data.d_string))
help_domain = param[0].data.d_string;
if (param[1].data.d_string && strlen (param[1].data.d_string))
help_locale = param[1].data.d_string;
if (param[2].data.d_string && strlen (param[2].data.d_string))
help_id = param[2].data.d_string;
}
load_help (help_domain, help_locale, help_id);
static GimpParam values[1];
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
*nreturn_vals = 1;
*return_vals = values;
/* make sure all the arguments are there */
if (nparams == 1)
{
if (param[0].data.d_string && strlen (param[0].data.d_string))
{
browser_dialog_load (param[0].data.d_string, TRUE);
}
else
{
status = GIMP_PDB_CALLING_ERROR;
}
}
else
{
status = GIMP_PDB_CALLING_ERROR;
}
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
}
static void
load_help (const gchar *help_domain,
const gchar *help_locale,
const gchar *help_id)
{
IdleHelp *idle_help;
idle_help = g_new0 (IdleHelp, 1);
idle_help->help_domain = g_strdup (help_domain);
idle_help->help_locale = g_strdup (help_locale);
idle_help->help_id = g_strdup (help_id);
g_idle_add (load_help_idle, idle_help); /* frees idle_help */
}
static gboolean
load_help_idle (gpointer data)
{
IdleHelp *idle_help;
HelpDomain *domain;
idle_help = (IdleHelp *) data;
domain = domain_lookup (idle_help->help_domain);
if (domain)
{
gchar *full_uri;
full_uri = domain_map (domain,
idle_help->help_locale,
idle_help->help_id);
if (full_uri)
{
browser_dialog_load (full_uri, TRUE);
g_free (full_uri);
}
}
g_free (idle_help->help_domain);
g_free (idle_help->help_locale);
g_free (idle_help->help_id);
g_free (idle_help);
return FALSE;
}

View File

@ -1,3 +1,7 @@
2004-03-09 Sven Neumann <sven@gimp.org>
* POTFILES.in: plug-ins/helpbrowser/domain.c -> plug-ins/help/domain.c
2004-03-08 Duarte Loreto <happyguy_pt@hotmail.com>
* pt.po: Updated Portuguese translation.

View File

@ -180,8 +180,8 @@ plug-ins/gimpressionist/preview.c
plug-ins/gimpressionist/repaint.c
plug-ins/gimpressionist/size.c
plug-ins/gimpressionist/sizemap.c
plug-ins/help/domain.c
plug-ins/helpbrowser/dialog.c
plug-ins/helpbrowser/domain.c
plug-ins/helpbrowser/helpbrowser.c
plug-ins/ifscompose/ifscompose.c
plug-ins/imagemap/imap_about.c