1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * The GIMP Help plug-in
5 * Copyright (C) 1999-2008 Sven Neumann <sven@gimp.org>
6 * Michael Natterer <mitch@gimp.org>
7 * Henrik Brix Andersen <brix@gimp.org>
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23 /* This code is written so that it can also be compiled standalone.
24 * It shouldn't depend on libgimp.
25 */
26
27 #include "config.h"
28
29 #include <string.h>
30
31 #include <glib-object.h>
32 #include <gio/gio.h>
33
34 #include "libgimpbase/gimpbase.h"
35
36 #include "gimphelp.h"
37
38 #ifdef DISABLE_NLS
39 #define _(String) (String)
40 #else
41 #include "libgimp/stdplugins-intl.h"
42 #endif
43
44
45 /* local function prototypes */
46
47 static gboolean domain_locale_parse (GimpHelpDomain *domain,
48 GimpHelpLocale *locale,
49 GimpHelpProgress *progress,
50 GError **error);
51
52
53 /* public functions */
54
55 GimpHelpDomain *
gimp_help_domain_new(const gchar * domain_name,const gchar * domain_uri)56 gimp_help_domain_new (const gchar *domain_name,
57 const gchar *domain_uri)
58 {
59 GimpHelpDomain *domain = g_slice_new0 (GimpHelpDomain);
60
61 domain->help_domain = g_strdup (domain_name);
62 domain->help_uri = g_strdup (domain_uri);
63
64 if (domain_uri)
65 {
66 /* strip trailing slash */
67 if (g_str_has_suffix (domain->help_uri, "/"))
68 domain->help_uri[strlen (domain->help_uri) - 1] = '\0';
69 }
70
71 return domain;
72 }
73
74 void
gimp_help_domain_free(GimpHelpDomain * domain)75 gimp_help_domain_free (GimpHelpDomain *domain)
76 {
77 g_return_if_fail (domain != NULL);
78
79 if (domain->help_locales)
80 g_hash_table_destroy (domain->help_locales);
81
82 g_free (domain->help_domain);
83 g_free (domain->help_uri);
84
85 g_slice_free (GimpHelpDomain, domain);
86 }
87
88 GimpHelpLocale *
gimp_help_domain_lookup_locale(GimpHelpDomain * domain,const gchar * locale_id,GimpHelpProgress * progress)89 gimp_help_domain_lookup_locale (GimpHelpDomain *domain,
90 const gchar *locale_id,
91 GimpHelpProgress *progress)
92 {
93 GimpHelpLocale *locale = NULL;
94
95 if (domain->help_locales)
96 locale = g_hash_table_lookup (domain->help_locales, locale_id);
97 else
98 domain->help_locales =
99 g_hash_table_new_full (g_str_hash, g_str_equal,
100 g_free,
101 (GDestroyNotify) gimp_help_locale_free);
102
103 if (locale)
104 return locale;
105
106 locale = gimp_help_locale_new (locale_id);
107 g_hash_table_insert (domain->help_locales, g_strdup (locale_id), locale);
108
109 domain_locale_parse (domain, locale, progress, NULL);
110
111 return locale;
112 }
113
114 gchar *
gimp_help_domain_map(GimpHelpDomain * domain,GList * help_locales,const gchar * help_id,GimpHelpProgress * progress,GimpHelpLocale ** ret_locale,gboolean * fatal_error)115 gimp_help_domain_map (GimpHelpDomain *domain,
116 GList *help_locales,
117 const gchar *help_id,
118 GimpHelpProgress *progress,
119 GimpHelpLocale **ret_locale,
120 gboolean *fatal_error)
121 {
122 GimpHelpLocale *locale = NULL;
123 const gchar *ref = NULL;
124 GList *list;
125
126 g_return_val_if_fail (domain != NULL, NULL);
127 g_return_val_if_fail (help_locales != NULL, NULL);
128 g_return_val_if_fail (help_id != NULL, NULL);
129
130 if (fatal_error)
131 *fatal_error = FALSE;
132
133 /* first pass: look for a reference matching the help_id */
134 for (list = help_locales; list && !ref; list = list->next)
135 {
136 locale = gimp_help_domain_lookup_locale (domain,
137 (const gchar *) list->data,
138 progress);
139 ref = gimp_help_locale_map (locale, help_id);
140 }
141
142 /* second pass: look for a fallback */
143 for (list = help_locales; list && !ref; list = list->next)
144 {
145 locale = gimp_help_domain_lookup_locale (domain,
146 (const gchar *) list->data,
147 progress);
148 ref = locale->help_missing;
149 }
150
151 if (ret_locale)
152 *ret_locale = locale;
153
154 if (ref)
155 {
156 return g_strconcat (domain->help_uri, "/",
157 locale->locale_id, "/",
158 ref,
159 NULL);
160 }
161 else /* try to assemble a useful error message */
162 {
163 GError *error = NULL;
164
165 #ifdef GIMP_HELP_DEBUG
166 g_printerr ("help: help_id lookup and all fallbacks failed for '%s'\n",
167 help_id);
168 #endif
169
170 locale = gimp_help_domain_lookup_locale (domain,
171 GIMP_HELP_DEFAULT_LOCALE, NULL);
172
173 if (! domain_locale_parse (domain, locale, NULL, &error))
174 {
175 switch (error->code)
176 {
177 case G_IO_ERROR_NOT_FOUND:
178 if (domain->help_domain)
179 {
180 g_message (_("The help pages for '%s' are not available."),
181 domain->help_domain);
182 }
183 else
184 {
185 g_message ("%s\n\n%s",
186 _("The GIMP user manual is not available."),
187 /* TRANSLATORS: do not end the URL with a dot,
188 * it would be in the link. Because of
189 * technical limitations, make sure the URL
190 * ends with a space, a newline or is end of text.
191 * Cf. bug 762282.
192 */
193 _("Please install the additional help package "
194 "or use the online user manual at: "
195 "https://docs.gimp.org/"));
196 }
197 break;
198
199 case G_IO_ERROR_NOT_SUPPORTED:
200 g_message ("%s\n\n%s",
201 error->message,
202 _("Perhaps you are missing GIO backends and need "
203 "to install GVFS?"));
204 break;
205
206 case G_IO_ERROR_CANCELLED:
207 break;
208
209 default:
210 g_message ("%s", error->message);
211 break;
212 }
213
214 g_error_free (error);
215
216 if (fatal_error)
217 *fatal_error = TRUE;
218 }
219 else
220 {
221 g_message (_("Help ID '%s' unknown"), help_id);
222 }
223
224 return NULL;
225 }
226 }
227
228
229 /* private functions */
230
231 static gboolean
domain_locale_parse(GimpHelpDomain * domain,GimpHelpLocale * locale,GimpHelpProgress * progress,GError ** error)232 domain_locale_parse (GimpHelpDomain *domain,
233 GimpHelpLocale *locale,
234 GimpHelpProgress *progress,
235 GError **error)
236 {
237 gchar *uri;
238 gboolean success;
239
240 g_return_val_if_fail (domain != NULL, FALSE);
241 g_return_val_if_fail (locale != NULL, FALSE);
242 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
243
244 uri = g_strdup_printf ("%s/%s/gimp-help.xml",
245 domain->help_uri, locale->locale_id);
246
247 success = gimp_help_locale_parse (locale, uri, domain->help_domain,
248 progress, error);
249
250 g_free (uri);
251
252 return success;
253 }
254