source: trunk/third/libgnome/libgnome/gnome-help.c @ 20807

Revision 20807, 14.2 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20806, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; c-set-style: gnu indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/* gnome-help.c
3 * Copyright (C) 2001 Sid Vicious
4 * Copyright (C) 2001 Jonathan Blandford <jrb@alum.mit.edu>
5 * All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc.,  59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
20 */
21/*
22  @NOTATION@
23 */
24
25#include <config.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <unistd.h>
29
30#include <string.h>
31#include <glib.h>
32
33#include "gnome-i18nP.h"
34
35#include "gnome-program.h"
36#include "gnome-url.h"
37
38#include "gnome-help.h"
39
40static char *
41locate_help_file (const char *path, const char *doc_name)
42{
43        int i;
44        char *exts[] = { "", ".xml", ".docbook", ".sgml", ".html", NULL };
45        const GList *lang_list = gnome_i18n_get_language_list ("LC_MESSAGES");
46
47        for (;lang_list != NULL; lang_list = lang_list->next) {
48                const char *lang = lang_list->data;
49
50                /* This has to be a valid language AND a language with
51                 * no encoding postfix.  The language will come up without
52                 * encoding next */
53                if (lang == NULL ||
54                    strchr (lang, '.') != NULL)
55                        continue;
56
57                for (i = 0; exts[i] != NULL; i++) {
58                        char *name;
59                        char *full;
60
61                        name = g_strconcat (doc_name, exts[i], NULL);
62                        full = g_build_filename (path, lang, name, NULL);
63                        g_free (name);
64
65                        if (g_file_test (full, G_FILE_TEST_EXISTS))
66                                return full;
67
68                        g_free (full);
69                }
70        }
71
72        return NULL;
73}
74
75/**
76 * gnome_help_display:
77 * @file_name: The name of the help document to display.
78 * @link_id: Can be %NULL. If set, refers to an anchor or section id within the
79 * requested document.
80 * @error: A #GError instance that will hold the specifics of any error which
81 * occurs during processing, or %NULL
82 *
83 * Displays the help file specified by @file_name at location @link_id in the
84 * preferred help browser of the user.
85 *
86 * Returns: %TRUE on success, %FALSE otherwise (in which case @error will
87 * contain the actual error).
88 **/
89gboolean
90gnome_help_display (const char    *file_name,
91                    const char    *link_id,
92                    GError       **error)
93{
94        return gnome_help_display_with_doc_id (NULL, NULL, file_name, link_id, error);
95}
96
97/**
98 * gnome_help_display_with_doc_id_and_env:
99 * @program: The current application object, or %NULL for the default one.
100 * @doc_id: The document identifier, or %NULL to default to the application ID
101 * (app_id) of the specified @program.
102 * @file_name: The name of the help document to display.
103 * @link_id: Can be %NULL. If set, refers to an anchor or section id within the
104 * requested document.
105 * @envp: child's environment, or %NULL to inherit parent's.
106 * @error: A #GError instance that will hold the specifics of any error which
107 * occurs during processing, or %NULL
108 *
109 * Like gnome_display_with_doc_id(), but the the contents of @envp
110 * will become the url viewer's environment rather than inheriting
111 * from the parents environment.
112 *
113 * Returns: %TRUE on success, %FALSE otherwise (in which case @error will
114 * contain the actual error).
115 **/
116gboolean
117gnome_help_display_with_doc_id_and_env (GnomeProgram  *program,
118                                        const char    *doc_id,
119                                        const char    *file_name,
120                                        const char    *link_id,
121                                        char         **envp,
122                                        GError       **error)
123{
124        gchar *local_help_path;
125        gchar *global_help_path;
126        gchar *file;
127        struct stat local_help_st;
128        struct stat global_help_st;
129        gchar *uri;
130        gboolean retval;
131
132        g_return_val_if_fail (file_name != NULL, FALSE);
133
134        retval = FALSE;
135
136        local_help_path = NULL;
137        global_help_path = NULL;
138        file = NULL;
139        uri = NULL;
140
141        if (program == NULL)
142                program = gnome_program_get ();
143
144        if (doc_id == NULL)
145                doc_id = gnome_program_get_app_id (program);
146
147        /* Compute the local and global help paths */
148
149        local_help_path = gnome_program_locate_file (program,
150                                                     GNOME_FILE_DOMAIN_APP_HELP,
151                                                     "",
152                                                     FALSE /* only_if_exists */,
153                                                     NULL /* ret_locations */);
154
155        if (local_help_path == NULL) {
156                g_set_error (error,
157                             GNOME_HELP_ERROR,
158                             GNOME_HELP_ERROR_INTERNAL,
159                             _("Unable to find the GNOME_FILE_DOMAIN_APP_HELP domain"));
160                goto out;
161        }
162
163        global_help_path = gnome_program_locate_file (program,
164                                                      GNOME_FILE_DOMAIN_HELP,
165                                                      "",
166                                                      FALSE /* only_if_exists */,
167                                                      NULL /* ret_locations */);
168        if (global_help_path == NULL) {
169                g_set_error (error,
170                             GNOME_HELP_ERROR,
171                             GNOME_HELP_ERROR_INTERNAL,
172                             _("Unable to find the GNOME_FILE_DOMAIN_HELP domain."));
173                goto out;
174        }
175
176        /* Try to access the help paths, first the app-specific help path
177         * and then falling back to the global help path if the first one fails.
178         */
179
180        if (stat (local_help_path, &local_help_st) == 0) {
181                if (!S_ISDIR (local_help_st.st_mode)) {
182                        g_set_error (error,
183                                     GNOME_HELP_ERROR,
184                                     GNOME_HELP_ERROR_NOT_FOUND,
185                                     _("Unable to show help as %s is not a directory.  "
186                                       "Please check your installation."),
187                                     local_help_path);
188                        goto out;
189                }
190
191                file = locate_help_file (local_help_path, file_name);
192        }
193
194        if (file == NULL) {
195                if (stat (global_help_path, &global_help_st) == 0) {
196                        if (!S_ISDIR (global_help_st.st_mode)) {
197                                g_set_error (error,
198                                             GNOME_HELP_ERROR,
199                                             GNOME_HELP_ERROR_NOT_FOUND,
200                                             _("Unable to show help as %s is not a directory.  "
201                                               "Please check your installation."),
202                                             global_help_path);
203                                goto out;
204                        }
205                } else {
206                        g_set_error (error,
207                                     GNOME_HELP_ERROR,
208                                     GNOME_HELP_ERROR_NOT_FOUND,
209                                     _("Unable to find the help files in either %s "
210                                       "or %s.  Please check your installation"),
211                                     local_help_path,
212                                     global_help_path);
213                        goto out;
214                }
215
216                if (!(local_help_st.st_dev == global_help_st.st_dev
217                      && local_help_st.st_ino == global_help_st.st_ino))
218                        file = locate_help_file (global_help_path, file_name);
219        }
220
221        if (file == NULL) {
222                g_set_error (error,
223                             GNOME_HELP_ERROR,
224                             GNOME_HELP_ERROR_NOT_FOUND,
225                             _("Unable to find the help files in either %s "
226                               "or %s.  Please check your installation"),
227                             local_help_path,
228                             global_help_path);
229                goto out;
230        }
231
232        /* Now that we have a file name, try to display it in the help browser */
233
234        if (link_id)
235                uri = g_strconcat ("ghelp://", file, "?", link_id, NULL);
236        else
237                uri = g_strconcat ("ghelp://", file, NULL);
238
239        retval = gnome_help_display_uri_with_env (uri, envp, error);
240
241 out:
242
243        g_free (local_help_path);
244        g_free (global_help_path);
245        g_free (file);
246        g_free (uri);
247
248        return retval;
249}
250
251/**
252 * gnome_help_display_with_doc_id
253 * @program: The current application object, or %NULL for the default one.
254 * @doc_id: The document identifier, or %NULL to default to the application ID
255 * (app_id) of the specified @program.
256 * @file_name: The name of the help document to display.
257 * @link_id: Can be %NULL. If set, refers to an anchor or section id within the
258 * requested document.
259 * @error: A #GError instance that will hold the specifics of any error which
260 * occurs during processing, or %NULL
261 *
262 * Displays the help file specified by @file_name at location @link_id within
263 * the @doc_id domain in the preferred help browser of the user.  Most of the
264 * time, you want to call gnome_help_display() instead.
265 *
266 * This function will display the help through creating a "ghelp" URI, by
267 * looking for @file_name in the applications installed help location (found by
268 * #GNOME_FILE_DOMAIN_APP_HELP) and its app_id.  The resulting URI is roughly
269 * in the form "ghelp:appid/file_name?link_id".  If a matching file cannot be
270 * found, %FALSE is returned and @error is set.
271 *
272 * Please note that this only displays application help.  To display help files
273 * from the global GNOME domain, you will want to use
274 * gnome_help_display_desktop().
275 *
276 * Returns: %TRUE on success, %FALSE otherwise (in which case @error will
277 * contain the actual error).
278 **/
279gboolean
280gnome_help_display_with_doc_id (GnomeProgram  *program,
281                                const char    *doc_id,
282                                const char    *file_name,
283                                const char    *link_id,
284                                GError       **error)
285{
286        return gnome_help_display_with_doc_id_and_env (
287                        program, doc_id, file_name, link_id, NULL, error);
288}
289
290/**
291 * gnome_help_display_desktop_with_env:
292 * @program: The current application object, or %NULL for the default one.
293 * @doc_id: The name of the help file relative to the system's help domain
294 * (#GNOME_FILE_DOMAIN_HELP).
295 * @file_name: The name of the help document to display.
296 * @link_id: Can be %NULL. If set, refers to an anchor or section id within the
297 * requested document.
298 * @envp: child's environment, or %NULL to inherit parent's.
299 * @error: A #GError instance that will hold the specifics of any error which
300 * occurs during processing, or %NULL
301 *
302 * Like gnome_help_display_desktop(), but the the contents of @envp
303 * will become the url viewer's environment rather than inheriting
304 * from the parents environment.
305 *
306 * Returns: %TRUE on success, %FALSE otherwise (in which case @error will
307 * contain the actual error).
308 */
309gboolean
310gnome_help_display_desktop_with_env (GnomeProgram  *program,
311                                     const char    *doc_id,
312                                     const char    *file_name,
313                                     const char    *link_id,
314                                     char         **envp,
315                                     GError       **error)
316{
317        GSList *ret_locations, *li;
318        char *file;
319        gboolean retval;
320        char *url;
321
322        g_return_val_if_fail (doc_id != NULL, FALSE);
323        g_return_val_if_fail (file_name != NULL, FALSE);
324
325        if (program == NULL)
326                program = gnome_program_get ();
327
328        ret_locations = NULL;
329        gnome_program_locate_file (program,
330                                   GNOME_FILE_DOMAIN_HELP,
331                                   doc_id,
332                                   FALSE /* only_if_exists */,
333                                   &ret_locations);
334
335        if (ret_locations == NULL) {
336                g_set_error (error,
337                             GNOME_HELP_ERROR,
338                             GNOME_HELP_ERROR_NOT_FOUND,
339                             _("Unable to find doc_id %s in the help path"),
340                             doc_id);
341                return FALSE;
342        }
343
344        file = NULL;
345        for (li = ret_locations; li != NULL; li = li->next) {
346                char *path = li->data;
347
348                file = locate_help_file (path, file_name);
349                if (file != NULL)
350                        break;
351        }
352
353        g_slist_foreach (ret_locations, (GFunc)g_free, NULL);
354        g_slist_free (ret_locations);
355
356        if (file == NULL) {
357                g_set_error (error,
358                             GNOME_HELP_ERROR,
359                             GNOME_HELP_ERROR_NOT_FOUND,
360                             _("Help document %s/%s not found"),
361                             doc_id,
362                             file_name);
363                return FALSE;
364        }
365
366        if (link_id != NULL) {
367                url = g_strconcat ("ghelp://", file, "?", link_id, NULL);
368        } else {
369                url = g_strconcat ("ghelp://", file, NULL);
370        }
371
372        retval = gnome_help_display_uri_with_env (url, envp, error);
373
374        g_free (file);
375        g_free (url);
376       
377        return retval;
378}
379
380/**
381 * gnome_help_display_desktop
382 * @program: The current application object, or %NULL for the default one.
383 * @doc_id: The name of the help file relative to the system's help domain
384 * (#GNOME_FILE_DOMAIN_HELP).
385 * @file_name: The name of the help document to display.
386 * @link_id: Can be %NULL. If set, refers to an anchor or section id within the
387 * requested document.
388 * @error: A #GError instance that will hold the specifics of any error which
389 * occurs during processing, or %NULL
390 *
391 * Displays the GNOME system help file specified by @file_name at location
392 * @link_id in the preferred help browser of the user.  This is done by creating
393 * a "ghelp" URI, by looking for @file_name in the system help domain
394 * (#GNOME_FILE_DOMAIN_HELP) and it's app_id.  This domain is determined when
395 * the library is compiled.  If a matching file cannot be found, %FALSE is
396 * returned and @error is set.
397 *
398 * Please note that this only displays system help.  To display help files
399 * for an application, you will want to use gnome_help_display().
400 *
401 * Returns: %TRUE on success, %FALSE otherwise (in which case @error will
402 * contain the actual error).
403 */
404gboolean
405gnome_help_display_desktop (GnomeProgram  *program,
406                            const char    *doc_id,
407                            const char    *file_name,
408                            const char    *link_id,
409                            GError       **error)
410{
411        return gnome_help_display_desktop_with_env (
412                        program, doc_id, file_name, link_id, NULL, error);
413}
414
415/**
416 * gnome_help_display_uri_with_env:
417 * @help_uri: The URI to display.
418 * @envp: child's environment, or %NULL to inherit parent's.
419 * @error: A #GError instance that will hold the specifics of any error which
420 * occurs during processing, or %NULL
421 *
422 * Like gnome_help_display_uri(), but the the contents of @envp
423 * will become the help viewer's environment rather than inheriting
424 * from the parents environment.
425 *
426 * Returns: %TRUE on success, %FALSE otherwise (in which case @error will
427 * contain the actual error).
428 */
429gboolean
430gnome_help_display_uri_with_env (const char  *help_uri,
431                                 char       **envp,
432                                 GError     **error)
433{
434        GError *real_error;
435        gboolean retval;
436
437        real_error = NULL;
438        retval = gnome_url_show_with_env (help_uri, envp, &real_error);
439
440        if (real_error != NULL)
441                g_propagate_error (error, real_error);
442
443        return retval;
444}
445
446/**
447 * gnome_help_display_uri:
448 * @help_uri: The URI to display.
449 * @error: A #GError instance that will hold the specifics of any error which
450 * occurs during processing, or %NULL
451 *
452 * Displays @help_uri in the user's preferred viewer. You should never need to
453 * call this function directly in code, since it is just a wrapper for
454 * gnome_url_show() and consequently the viewer used to display the results
455 * depends upon the scheme of the URI (so it is not strictly a help-only
456 * function).
457 *
458 * Returns: %TRUE on success, %FALSE otherwise (in which case @error will
459 * contain the actual error).
460 */
461gboolean
462gnome_help_display_uri (const char  *help_uri,
463                        GError     **error)
464{
465        return gnome_help_display_uri_with_env (help_uri, NULL, error);
466}
467
468/**
469 * gnome_help_error_quark:
470 *
471 * Returns: A #GQuark representing the domain of gnome-help errors.
472 */
473GQuark
474gnome_help_error_quark (void)
475{
476        static GQuark error_quark = 0;
477
478        if (error_quark == 0)
479                error_quark =
480                        g_quark_from_static_string ("gnome-help-error-quark");
481
482        return error_quark;
483}
Note: See TracBrowser for help on using the repository browser.