1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimppluginprocedure.c
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "config.h"
21
22 #include <string.h>
23
24 #include <gegl.h>
25 #include <gdk-pixbuf/gdk-pixbuf.h>
26
27 #include "libgimpbase/gimpbase.h"
28
29 #include "plug-in-types.h"
30
31 #include "gegl/gimp-babl-compat.h"
32
33 #include "core/gimp.h"
34 #include "core/gimp-memsize.h"
35 #include "core/gimpdrawable.h"
36 #include "core/gimpmarshal.h"
37 #include "core/gimpparamspecs.h"
38
39 #include "file/file-utils.h"
40
41 #define __YES_I_NEED_GIMP_PLUG_IN_MANAGER_CALL__
42 #include "gimppluginmanager-call.h"
43
44 #include "gimppluginerror.h"
45 #include "gimppluginprocedure.h"
46 #include "plug-in-menu-path.h"
47
48 #include "gimp-intl.h"
49
50
51 enum
52 {
53 MENU_PATH_ADDED,
54 LAST_SIGNAL
55 };
56
57
58 static void gimp_plug_in_procedure_finalize (GObject *object);
59
60 static gint64 gimp_plug_in_procedure_get_memsize (GimpObject *object,
61 gint64 *gui_size);
62
63 static gchar * gimp_plug_in_procedure_get_description (GimpViewable *viewable,
64 gchar **tooltip);
65
66 static const gchar * gimp_plug_in_procedure_get_label (GimpProcedure *procedure);
67 static const gchar * gimp_plug_in_procedure_get_menu_label
68 (GimpProcedure *procedure);
69 static const gchar * gimp_plug_in_procedure_get_blurb (GimpProcedure *procedure);
70 static const gchar * gimp_plug_in_procedure_get_help_id(GimpProcedure *procedure);
71 static gboolean gimp_plug_in_procedure_get_sensitive (GimpProcedure *procedure,
72 GimpObject *object,
73 const gchar **tooltip);
74 static GimpValueArray * gimp_plug_in_procedure_execute (GimpProcedure *procedure,
75 Gimp *gimp,
76 GimpContext *context,
77 GimpProgress *progress,
78 GimpValueArray *args,
79 GError **error);
80 static void gimp_plug_in_procedure_execute_async (GimpProcedure *procedure,
81 Gimp *gimp,
82 GimpContext *context,
83 GimpProgress *progress,
84 GimpValueArray *args,
85 GimpObject *display);
86
87 static GFile * gimp_plug_in_procedure_real_get_file (GimpPlugInProcedure *procedure);
88
89 static gboolean gimp_plug_in_procedure_validate_args (GimpPlugInProcedure *proc,
90 Gimp *gimp,
91 GimpValueArray *args,
92 GError **error);
93
94
95 G_DEFINE_TYPE (GimpPlugInProcedure, gimp_plug_in_procedure,
96 GIMP_TYPE_PROCEDURE)
97
98 #define parent_class gimp_plug_in_procedure_parent_class
99
100 static guint gimp_plug_in_procedure_signals[LAST_SIGNAL] = { 0 };
101
102
103 static void
gimp_plug_in_procedure_class_init(GimpPlugInProcedureClass * klass)104 gimp_plug_in_procedure_class_init (GimpPlugInProcedureClass *klass)
105 {
106 GObjectClass *object_class = G_OBJECT_CLASS (klass);
107 GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
108 GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
109 GimpProcedureClass *proc_class = GIMP_PROCEDURE_CLASS (klass);
110
111 gimp_plug_in_procedure_signals[MENU_PATH_ADDED] =
112 g_signal_new ("menu-path-added",
113 G_TYPE_FROM_CLASS (klass),
114 G_SIGNAL_RUN_FIRST,
115 G_STRUCT_OFFSET (GimpPlugInProcedureClass, menu_path_added),
116 NULL, NULL,
117 gimp_marshal_VOID__STRING,
118 G_TYPE_NONE, 1,
119 G_TYPE_STRING);
120
121 object_class->finalize = gimp_plug_in_procedure_finalize;
122
123 gimp_object_class->get_memsize = gimp_plug_in_procedure_get_memsize;
124
125 viewable_class->default_icon_name = "system-run";
126 viewable_class->get_description = gimp_plug_in_procedure_get_description;
127
128 proc_class->get_label = gimp_plug_in_procedure_get_label;
129 proc_class->get_menu_label = gimp_plug_in_procedure_get_menu_label;
130 proc_class->get_blurb = gimp_plug_in_procedure_get_blurb;
131 proc_class->get_help_id = gimp_plug_in_procedure_get_help_id;
132 proc_class->get_sensitive = gimp_plug_in_procedure_get_sensitive;
133 proc_class->execute = gimp_plug_in_procedure_execute;
134 proc_class->execute_async = gimp_plug_in_procedure_execute_async;
135
136 klass->get_file = gimp_plug_in_procedure_real_get_file;
137 klass->menu_path_added = NULL;
138 }
139
140 static void
gimp_plug_in_procedure_init(GimpPlugInProcedure * proc)141 gimp_plug_in_procedure_init (GimpPlugInProcedure *proc)
142 {
143 GIMP_PROCEDURE (proc)->proc_type = GIMP_PLUGIN;
144
145 proc->icon_data_length = -1;
146 }
147
148 static void
gimp_plug_in_procedure_finalize(GObject * object)149 gimp_plug_in_procedure_finalize (GObject *object)
150 {
151 GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (object);
152
153 g_object_unref (proc->file);
154 g_free (proc->menu_label);
155
156 g_list_free_full (proc->menu_paths, (GDestroyNotify) g_free);
157
158 g_free (proc->label);
159 g_free (proc->help_id);
160
161 g_free (proc->icon_data);
162 g_free (proc->image_types);
163 g_free (proc->image_types_tooltip);
164
165 g_free (proc->extensions);
166 g_free (proc->prefixes);
167 g_free (proc->magics);
168 g_free (proc->mime_types);
169
170 g_slist_free_full (proc->extensions_list, (GDestroyNotify) g_free);
171 g_slist_free_full (proc->prefixes_list, (GDestroyNotify) g_free);
172 g_slist_free_full (proc->magics_list, (GDestroyNotify) g_free);
173 g_slist_free_full (proc->mime_types_list, (GDestroyNotify) g_free);
174
175 g_free (proc->thumb_loader);
176
177 G_OBJECT_CLASS (parent_class)->finalize (object);
178 }
179
180 static gint64
gimp_plug_in_procedure_get_memsize(GimpObject * object,gint64 * gui_size)181 gimp_plug_in_procedure_get_memsize (GimpObject *object,
182 gint64 *gui_size)
183 {
184 GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (object);
185 gint64 memsize = 0;
186 GList *list;
187 GSList *slist;
188
189 memsize += gimp_g_object_get_memsize (G_OBJECT (proc->file));
190 memsize += gimp_string_get_memsize (proc->menu_label);
191
192 for (list = proc->menu_paths; list; list = g_list_next (list))
193 memsize += sizeof (GList) + gimp_string_get_memsize (list->data);
194
195 switch (proc->icon_type)
196 {
197 case GIMP_ICON_TYPE_ICON_NAME:
198 case GIMP_ICON_TYPE_IMAGE_FILE:
199 memsize += gimp_string_get_memsize ((const gchar *) proc->icon_data);
200 break;
201
202 case GIMP_ICON_TYPE_INLINE_PIXBUF:
203 memsize += proc->icon_data_length;
204 break;
205 }
206
207 memsize += gimp_string_get_memsize (proc->extensions);
208 memsize += gimp_string_get_memsize (proc->prefixes);
209 memsize += gimp_string_get_memsize (proc->magics);
210 memsize += gimp_string_get_memsize (proc->mime_types);
211 memsize += gimp_string_get_memsize (proc->thumb_loader);
212
213 for (slist = proc->extensions_list; slist; slist = g_slist_next (slist))
214 memsize += sizeof (GSList) + gimp_string_get_memsize (slist->data);
215
216 for (slist = proc->prefixes_list; slist; slist = g_slist_next (slist))
217 memsize += sizeof (GSList) + gimp_string_get_memsize (slist->data);
218
219 for (slist = proc->magics_list; slist; slist = g_slist_next (slist))
220 memsize += sizeof (GSList) + gimp_string_get_memsize (slist->data);
221
222 for (slist = proc->mime_types_list; slist; slist = g_slist_next (slist))
223 memsize += sizeof (GSList) + gimp_string_get_memsize (slist->data);
224
225 return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
226 gui_size);
227 }
228
229 static gchar *
gimp_plug_in_procedure_get_description(GimpViewable * viewable,gchar ** tooltip)230 gimp_plug_in_procedure_get_description (GimpViewable *viewable,
231 gchar **tooltip)
232 {
233 GimpProcedure *procedure = GIMP_PROCEDURE (viewable);
234
235 if (tooltip)
236 *tooltip = g_strdup (gimp_procedure_get_blurb (procedure));
237
238 return g_strdup (gimp_procedure_get_label (procedure));
239 }
240
241 static const gchar *
gimp_plug_in_procedure_get_label(GimpProcedure * procedure)242 gimp_plug_in_procedure_get_label (GimpProcedure *procedure)
243 {
244 GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (procedure);
245 const gchar *path;
246 gchar *stripped;
247 gchar *ellipsis;
248 gchar *label;
249
250 if (proc->label)
251 return proc->label;
252
253 if (proc->menu_label)
254 path = dgettext (gimp_plug_in_procedure_get_locale_domain (proc),
255 proc->menu_label);
256 else if (proc->menu_paths)
257 path = dgettext (gimp_plug_in_procedure_get_locale_domain (proc),
258 proc->menu_paths->data);
259 else
260 return NULL;
261
262 stripped = gimp_strip_uline (path);
263
264 if (proc->menu_label)
265 label = g_strdup (stripped);
266 else
267 label = g_path_get_basename (stripped);
268
269 g_free (stripped);
270
271 ellipsis = strstr (label, "...");
272
273 if (! ellipsis)
274 ellipsis = strstr (label, "\342\200\246" /* U+2026 HORIZONTAL ELLIPSIS */);
275
276 if (ellipsis && ellipsis == (label + strlen (label) - 3))
277 *ellipsis = '\0';
278
279 proc->label = label;
280
281 return proc->label;
282 }
283
284 static const gchar *
gimp_plug_in_procedure_get_menu_label(GimpProcedure * procedure)285 gimp_plug_in_procedure_get_menu_label (GimpProcedure *procedure)
286 {
287 GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (procedure);
288
289 if (proc->menu_label)
290 {
291 return dgettext (gimp_plug_in_procedure_get_locale_domain (proc),
292 proc->menu_label);
293 }
294 else if (proc->menu_paths)
295 {
296 const gchar *translated;
297
298 translated = dgettext (gimp_plug_in_procedure_get_locale_domain (proc),
299 proc->menu_paths->data);
300
301 translated = strrchr (translated, '/');
302
303 if (translated)
304 return translated + 1;
305 }
306
307 return GIMP_PROCEDURE_CLASS (parent_class)->get_menu_label (procedure);
308 }
309
310 static const gchar *
gimp_plug_in_procedure_get_blurb(GimpProcedure * procedure)311 gimp_plug_in_procedure_get_blurb (GimpProcedure *procedure)
312 {
313 GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (procedure);
314
315 /* do not to pass the empty string to gettext() */
316 if (procedure->blurb && strlen (procedure->blurb))
317 return dgettext (gimp_plug_in_procedure_get_locale_domain (proc),
318 procedure->blurb);
319
320 return NULL;
321 }
322
323 static const gchar *
gimp_plug_in_procedure_get_help_id(GimpProcedure * procedure)324 gimp_plug_in_procedure_get_help_id (GimpProcedure *procedure)
325 {
326 GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (procedure);
327 const gchar *domain;
328
329 if (proc->help_id)
330 return proc->help_id;
331
332 domain = gimp_plug_in_procedure_get_help_domain (proc);
333
334 if (domain)
335 proc->help_id = g_strconcat (domain, "?", gimp_object_get_name (proc), NULL);
336 else
337 proc->help_id = g_strdup (gimp_object_get_name (proc));
338
339 return proc->help_id;
340 }
341
342 static gboolean
gimp_plug_in_procedure_get_sensitive(GimpProcedure * procedure,GimpObject * object,const gchar ** tooltip)343 gimp_plug_in_procedure_get_sensitive (GimpProcedure *procedure,
344 GimpObject *object,
345 const gchar **tooltip)
346 {
347 GimpPlugInProcedure *proc = GIMP_PLUG_IN_PROCEDURE (procedure);
348 GimpDrawable *drawable;
349 GimpImageType image_type = -1;
350 gboolean sensitive = FALSE;
351
352 g_return_val_if_fail (object == NULL || GIMP_IS_DRAWABLE (object), FALSE);
353
354 drawable = GIMP_DRAWABLE (object);
355
356 if (drawable)
357 {
358 const Babl *format = gimp_drawable_get_format (drawable);
359
360 image_type = gimp_babl_format_get_image_type (format);
361 }
362
363 switch (image_type)
364 {
365 case GIMP_RGB_IMAGE:
366 sensitive = proc->image_types_val & GIMP_PLUG_IN_RGB_IMAGE;
367 break;
368 case GIMP_RGBA_IMAGE:
369 sensitive = proc->image_types_val & GIMP_PLUG_IN_RGBA_IMAGE;
370 break;
371 case GIMP_GRAY_IMAGE:
372 sensitive = proc->image_types_val & GIMP_PLUG_IN_GRAY_IMAGE;
373 break;
374 case GIMP_GRAYA_IMAGE:
375 sensitive = proc->image_types_val & GIMP_PLUG_IN_GRAYA_IMAGE;
376 break;
377 case GIMP_INDEXED_IMAGE:
378 sensitive = proc->image_types_val & GIMP_PLUG_IN_INDEXED_IMAGE;
379 break;
380 case GIMP_INDEXEDA_IMAGE:
381 sensitive = proc->image_types_val & GIMP_PLUG_IN_INDEXEDA_IMAGE;
382 break;
383 default:
384 break;
385 }
386
387 if (! sensitive)
388 *tooltip = proc->image_types_tooltip;
389
390 return sensitive ? TRUE : FALSE;
391 }
392
393 static GimpValueArray *
gimp_plug_in_procedure_execute(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,GimpValueArray * args,GError ** error)394 gimp_plug_in_procedure_execute (GimpProcedure *procedure,
395 Gimp *gimp,
396 GimpContext *context,
397 GimpProgress *progress,
398 GimpValueArray *args,
399 GError **error)
400 {
401 GimpPlugInProcedure *plug_in_procedure = GIMP_PLUG_IN_PROCEDURE (procedure);
402 GError *pdb_error = NULL;
403
404 if (! gimp_plug_in_procedure_validate_args (plug_in_procedure, gimp,
405 args, &pdb_error))
406 {
407 GimpValueArray *return_vals;
408
409 return_vals = gimp_procedure_get_return_values (procedure, FALSE,
410 pdb_error);
411 g_propagate_error (error, pdb_error);
412
413 return return_vals;
414 }
415
416 if (procedure->proc_type == GIMP_INTERNAL)
417 return GIMP_PROCEDURE_CLASS (parent_class)->execute (procedure, gimp,
418 context, progress,
419 args, error);
420
421 return gimp_plug_in_manager_call_run (gimp->plug_in_manager,
422 context, progress,
423 GIMP_PLUG_IN_PROCEDURE (procedure),
424 args, TRUE, NULL);
425 }
426
427 static void
gimp_plug_in_procedure_execute_async(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,GimpValueArray * args,GimpObject * display)428 gimp_plug_in_procedure_execute_async (GimpProcedure *procedure,
429 Gimp *gimp,
430 GimpContext *context,
431 GimpProgress *progress,
432 GimpValueArray *args,
433 GimpObject *display)
434 {
435 GimpPlugInProcedure *plug_in_procedure = GIMP_PLUG_IN_PROCEDURE (procedure);
436 GError *error = NULL;
437
438 if (gimp_plug_in_procedure_validate_args (plug_in_procedure, gimp,
439 args, &error))
440 {
441 GimpValueArray *return_vals;
442
443 return_vals = gimp_plug_in_manager_call_run (gimp->plug_in_manager,
444 context, progress,
445 plug_in_procedure,
446 args, FALSE, display);
447
448 if (return_vals)
449 {
450 gimp_plug_in_procedure_handle_return_values (plug_in_procedure,
451 gimp, progress,
452 return_vals);
453 gimp_value_array_unref (return_vals);
454 }
455 }
456 else
457 {
458 gimp_message_literal (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
459 error->message);
460 g_error_free (error);
461 }
462 }
463
464 static GFile *
gimp_plug_in_procedure_real_get_file(GimpPlugInProcedure * procedure)465 gimp_plug_in_procedure_real_get_file (GimpPlugInProcedure *procedure)
466 {
467 return procedure->file;
468 }
469
470 static gboolean
gimp_plug_in_procedure_validate_args(GimpPlugInProcedure * proc,Gimp * gimp,GimpValueArray * args,GError ** error)471 gimp_plug_in_procedure_validate_args (GimpPlugInProcedure *proc,
472 Gimp *gimp,
473 GimpValueArray *args,
474 GError **error)
475 {
476 if (proc->file_proc && proc->handles_uri)
477 {
478 /* for file procedures that handle URIs, make sure that the
479 * passed string actually is an URI, not just a file path
480 * (bug 758685)
481 */
482 GimpProcedure *procedure = GIMP_PROCEDURE (proc);
483 GValue *uri_value = NULL;
484
485 if ((procedure->num_args >= 3) &&
486 (procedure->num_values >= 1) &&
487 GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) &&
488 G_IS_PARAM_SPEC_STRING (procedure->args[1]) &&
489 G_IS_PARAM_SPEC_STRING (procedure->args[2]) &&
490 GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->values[0]))
491 {
492 uri_value = gimp_value_array_index (args, 1);
493 }
494 else if ((procedure->num_args >= 5) &&
495 GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) &&
496 GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) &&
497 GIMP_IS_PARAM_SPEC_DRAWABLE_ID (procedure->args[2]) &&
498 G_IS_PARAM_SPEC_STRING (procedure->args[3]) &&
499 G_IS_PARAM_SPEC_STRING (procedure->args[4]))
500 {
501 uri_value = gimp_value_array_index (args, 3);
502 }
503
504 if (uri_value)
505 {
506 GFile *file;
507
508 file = file_utils_filename_to_file (gimp,
509 g_value_get_string (uri_value),
510 error);
511
512 if (! file)
513 return FALSE;
514
515 g_value_take_string (uri_value, g_file_get_uri (file));
516 g_object_unref (file);
517 }
518 }
519
520 return TRUE;
521 }
522
523
524 /* public functions */
525
526 GimpProcedure *
gimp_plug_in_procedure_new(GimpPDBProcType proc_type,GFile * file)527 gimp_plug_in_procedure_new (GimpPDBProcType proc_type,
528 GFile *file)
529 {
530 GimpPlugInProcedure *proc;
531
532 g_return_val_if_fail (proc_type == GIMP_PLUGIN ||
533 proc_type == GIMP_EXTENSION, NULL);
534 g_return_val_if_fail (G_IS_FILE (file), NULL);
535
536 proc = g_object_new (GIMP_TYPE_PLUG_IN_PROCEDURE, NULL);
537
538 proc->file = g_object_ref (file);
539
540 GIMP_PROCEDURE (proc)->proc_type = proc_type;
541
542 return GIMP_PROCEDURE (proc);
543 }
544
545 GimpPlugInProcedure *
gimp_plug_in_procedure_find(GSList * list,const gchar * proc_name)546 gimp_plug_in_procedure_find (GSList *list,
547 const gchar *proc_name)
548 {
549 GSList *l;
550
551 for (l = list; l; l = g_slist_next (l))
552 {
553 GimpObject *object = l->data;
554
555 if (! strcmp (proc_name, gimp_object_get_name (object)))
556 return GIMP_PLUG_IN_PROCEDURE (object);
557 }
558
559 return NULL;
560 }
561
562 GFile *
gimp_plug_in_procedure_get_file(GimpPlugInProcedure * proc)563 gimp_plug_in_procedure_get_file (GimpPlugInProcedure *proc)
564 {
565 g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL);
566
567 return GIMP_PLUG_IN_PROCEDURE_GET_CLASS (proc)->get_file (proc);
568 }
569
570 void
gimp_plug_in_procedure_set_locale_domain(GimpPlugInProcedure * proc,const gchar * locale_domain)571 gimp_plug_in_procedure_set_locale_domain (GimpPlugInProcedure *proc,
572 const gchar *locale_domain)
573 {
574 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
575
576 proc->locale_domain = locale_domain ? g_quark_from_string (locale_domain) : 0;
577 }
578
579 const gchar *
gimp_plug_in_procedure_get_locale_domain(GimpPlugInProcedure * proc)580 gimp_plug_in_procedure_get_locale_domain (GimpPlugInProcedure *proc)
581 {
582 g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL);
583
584 return g_quark_to_string (proc->locale_domain);
585 }
586
587 void
gimp_plug_in_procedure_set_help_domain(GimpPlugInProcedure * proc,const gchar * help_domain)588 gimp_plug_in_procedure_set_help_domain (GimpPlugInProcedure *proc,
589 const gchar *help_domain)
590 {
591 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
592
593 proc->help_domain = help_domain ? g_quark_from_string (help_domain) : 0;
594 }
595
596 const gchar *
gimp_plug_in_procedure_get_help_domain(GimpPlugInProcedure * proc)597 gimp_plug_in_procedure_get_help_domain (GimpPlugInProcedure *proc)
598 {
599 g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL);
600
601 return g_quark_to_string (proc->help_domain);
602 }
603
604 gboolean
gimp_plug_in_procedure_add_menu_path(GimpPlugInProcedure * proc,const gchar * menu_path,GError ** error)605 gimp_plug_in_procedure_add_menu_path (GimpPlugInProcedure *proc,
606 const gchar *menu_path,
607 GError **error)
608 {
609 GimpProcedure *procedure;
610 gchar *basename = NULL;
611 const gchar *required = NULL;
612 gchar *p;
613 gchar *mapped_path;
614
615 g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), FALSE);
616 g_return_val_if_fail (menu_path != NULL, FALSE);
617 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
618
619 procedure = GIMP_PROCEDURE (proc);
620
621 p = strchr (menu_path, '>');
622 if (p == NULL || (*(++p) && *p != '/'))
623 {
624 basename = g_path_get_basename (gimp_file_get_utf8_name (proc->file));
625
626 g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED,
627 "Plug-in \"%s\"\n(%s)\n"
628 "attempted to install procedure \"%s\"\n"
629 "in the invalid menu location \"%s\".\n"
630 "The menu path must look like either \"<Prefix>\" "
631 "or \"<Prefix>/path/to/item\".",
632 basename, gimp_file_get_utf8_name (proc->file),
633 gimp_object_get_name (proc),
634 menu_path);
635 goto failure;
636 }
637
638 if (g_str_has_prefix (menu_path, "<Toolbox>") ||
639 g_str_has_prefix (menu_path, "<Image>"))
640 {
641 if ((procedure->num_args < 1) ||
642 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]))
643 {
644 required = "INT32";
645 goto failure;
646 }
647 }
648 else if (g_str_has_prefix (menu_path, "<Layers>"))
649 {
650 if ((procedure->num_args < 3) ||
651 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) ||
652 ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) ||
653 ! (G_TYPE_FROM_INSTANCE (procedure->args[2])
654 == GIMP_TYPE_PARAM_LAYER_ID ||
655 G_TYPE_FROM_INSTANCE (procedure->args[2])
656 == GIMP_TYPE_PARAM_DRAWABLE_ID))
657 {
658 required = "INT32, IMAGE, (LAYER | DRAWABLE)";
659 goto failure;
660 }
661 }
662 else if (g_str_has_prefix (menu_path, "<Channels>"))
663 {
664 if ((procedure->num_args < 3) ||
665 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) ||
666 ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) ||
667 ! (G_TYPE_FROM_INSTANCE (procedure->args[2])
668 == GIMP_TYPE_PARAM_CHANNEL_ID ||
669 G_TYPE_FROM_INSTANCE (procedure->args[2])
670 == GIMP_TYPE_PARAM_DRAWABLE_ID))
671 {
672 required = "INT32, IMAGE, (CHANNEL | DRAWABLE)";
673 goto failure;
674 }
675 }
676 else if (g_str_has_prefix (menu_path, "<Vectors>"))
677 {
678 if ((procedure->num_args < 3) ||
679 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) ||
680 ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) ||
681 ! GIMP_IS_PARAM_SPEC_VECTORS_ID (procedure->args[2]))
682 {
683 required = "INT32, IMAGE, VECTORS";
684 goto failure;
685 }
686 }
687 else if (g_str_has_prefix (menu_path, "<Colormap>"))
688 {
689 if ((procedure->num_args < 2) ||
690 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) ||
691 ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]))
692 {
693 required = "INT32, IMAGE";
694 goto failure;
695 }
696 }
697 else if (g_str_has_prefix (menu_path, "<Load>"))
698 {
699 if ((procedure->num_args < 3) ||
700 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) ||
701 ! G_IS_PARAM_SPEC_STRING (procedure->args[1]) ||
702 ! G_IS_PARAM_SPEC_STRING (procedure->args[2]))
703 {
704 required = "INT32, STRING, STRING";
705 goto failure;
706 }
707
708 if ((procedure->num_values < 1) ||
709 ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->values[0]))
710 {
711 required = "IMAGE";
712 goto failure;
713 }
714 }
715 else if (g_str_has_prefix (menu_path, "<Save>"))
716 {
717 if ((procedure->num_args < 5) ||
718 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) ||
719 ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) ||
720 ! GIMP_IS_PARAM_SPEC_DRAWABLE_ID (procedure->args[2]) ||
721 ! G_IS_PARAM_SPEC_STRING (procedure->args[3]) ||
722 ! G_IS_PARAM_SPEC_STRING (procedure->args[4]))
723 {
724 required = "INT32, IMAGE, DRAWABLE, STRING, STRING";
725 goto failure;
726 }
727 }
728 else if (g_str_has_prefix (menu_path, "<Brushes>") ||
729 g_str_has_prefix (menu_path, "<Dynamics>") ||
730 g_str_has_prefix (menu_path, "<MyPaintBrushes>") ||
731 g_str_has_prefix (menu_path, "<Gradients>") ||
732 g_str_has_prefix (menu_path, "<Palettes>") ||
733 g_str_has_prefix (menu_path, "<Patterns>") ||
734 g_str_has_prefix (menu_path, "<ToolPresets>") ||
735 g_str_has_prefix (menu_path, "<Fonts>") ||
736 g_str_has_prefix (menu_path, "<Buffers>"))
737 {
738 if ((procedure->num_args < 1) ||
739 ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]))
740 {
741 required = "INT32";
742 goto failure;
743 }
744 }
745 else
746 {
747 basename = g_path_get_basename (gimp_file_get_utf8_name (proc->file));
748
749 g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED,
750 "Plug-in \"%s\"\n(%s)\n"
751 "attempted to install procedure \"%s\" "
752 "in the invalid menu location \"%s\".\n"
753 "Use either \"<Image>\", "
754 "\"<Layers>\", \"<Channels>\", \"<Vectors>\", "
755 "\"<Colormap>\", \"<Brushes>\", \"<Dynamics>\", "
756 "\"<MyPaintBrushes>\", \"<Gradients>\", \"<Palettes>\", "
757 "\"<Patterns>\", \"<ToolPresets>\", \"<Fonts>\" "
758 "or \"<Buffers>\".",
759 basename, gimp_file_get_utf8_name (proc->file),
760 gimp_object_get_name (proc),
761 menu_path);
762 goto failure;
763 }
764
765 g_free (basename);
766
767 mapped_path = plug_in_menu_path_map (menu_path, NULL);
768
769 proc->menu_paths = g_list_append (proc->menu_paths, mapped_path);
770
771 g_signal_emit (proc, gimp_plug_in_procedure_signals[MENU_PATH_ADDED], 0,
772 mapped_path);
773
774 return TRUE;
775
776 failure:
777 if (required)
778 {
779 gchar *prefix = g_strdup (menu_path);
780
781 p = strchr (prefix, '>') + 1;
782 *p = '\0';
783
784 basename = g_path_get_basename (gimp_file_get_utf8_name (proc->file));
785
786 g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED,
787 "Plug-in \"%s\"\n(%s)\n\n"
788 "attempted to install %s procedure \"%s\" "
789 "which does not take the standard %s plug-in's "
790 "arguments: (%s).",
791 basename, gimp_file_get_utf8_name (proc->file),
792 prefix, gimp_object_get_name (proc), prefix,
793 required);
794
795 g_free (prefix);
796 }
797
798 g_free (basename);
799
800 return FALSE;
801 }
802
803 void
gimp_plug_in_procedure_set_icon(GimpPlugInProcedure * proc,GimpIconType icon_type,const guint8 * icon_data,gint icon_data_length)804 gimp_plug_in_procedure_set_icon (GimpPlugInProcedure *proc,
805 GimpIconType icon_type,
806 const guint8 *icon_data,
807 gint icon_data_length)
808 {
809 guint8 *data_copy = NULL;
810
811 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
812
813 switch (icon_type)
814 {
815 case GIMP_ICON_TYPE_ICON_NAME:
816 data_copy = (guint8 *) g_strdup ((gchar *) icon_data);
817 break;
818
819 case GIMP_ICON_TYPE_INLINE_PIXBUF:
820 data_copy = g_memdup (icon_data, icon_data_length);
821 break;
822
823 case GIMP_ICON_TYPE_IMAGE_FILE:
824 data_copy = (guint8 *) g_strdup ((gchar *) icon_data);
825 break;
826
827 default:
828 g_return_if_reached ();
829 }
830
831 gimp_plug_in_procedure_take_icon (proc, icon_type,
832 data_copy, icon_data_length);
833 }
834
835 void
gimp_plug_in_procedure_take_icon(GimpPlugInProcedure * proc,GimpIconType icon_type,guint8 * icon_data,gint icon_data_length)836 gimp_plug_in_procedure_take_icon (GimpPlugInProcedure *proc,
837 GimpIconType icon_type,
838 guint8 *icon_data,
839 gint icon_data_length)
840 {
841 const gchar *icon_name = NULL;
842 GdkPixbuf *icon_pixbuf = NULL;
843 GError *error = NULL;
844
845 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
846
847 if (proc->icon_data)
848 {
849 g_free (proc->icon_data);
850 proc->icon_data_length = -1;
851 proc->icon_data = NULL;
852 }
853
854 proc->icon_type = icon_type;
855
856 switch (proc->icon_type)
857 {
858 case GIMP_ICON_TYPE_ICON_NAME:
859 proc->icon_data_length = -1;
860 proc->icon_data = icon_data;
861
862 icon_name = (const gchar *) proc->icon_data;
863 break;
864
865 case GIMP_ICON_TYPE_INLINE_PIXBUF:
866 proc->icon_data_length = icon_data_length;
867 proc->icon_data = icon_data;
868
869 icon_pixbuf = gdk_pixbuf_new_from_inline (proc->icon_data_length,
870 proc->icon_data, TRUE, &error);
871 break;
872
873 case GIMP_ICON_TYPE_IMAGE_FILE:
874 proc->icon_data_length = -1;
875 proc->icon_data = icon_data;
876
877 icon_pixbuf = gdk_pixbuf_new_from_file ((gchar *) proc->icon_data,
878 &error);
879 break;
880 }
881
882 if (! icon_pixbuf && error)
883 {
884 g_printerr ("gimp_plug_in_procedure_take_icon: %s\n", error->message);
885 g_clear_error (&error);
886 }
887
888 gimp_viewable_set_icon_name (GIMP_VIEWABLE (proc), icon_name);
889 g_object_set (proc, "icon-pixbuf", icon_pixbuf, NULL);
890
891 if (icon_pixbuf)
892 g_object_unref (icon_pixbuf);
893 }
894
895 static GimpPlugInImageType
image_types_parse(const gchar * name,const gchar * image_types)896 image_types_parse (const gchar *name,
897 const gchar *image_types)
898 {
899 const gchar *type_spec = image_types;
900 GimpPlugInImageType types = 0;
901
902 /* If the plug_in registers with image_type == NULL or "", return 0
903 * By doing so it won't be touched by plug_in_set_menu_sensitivity()
904 */
905 if (! image_types)
906 return types;
907
908 while (*image_types)
909 {
910 while (*image_types &&
911 ((*image_types == ' ') ||
912 (*image_types == '\t') ||
913 (*image_types == ',')))
914 image_types++;
915
916 if (*image_types)
917 {
918 if (g_str_has_prefix (image_types, "RGBA"))
919 {
920 types |= GIMP_PLUG_IN_RGBA_IMAGE;
921 image_types += strlen ("RGBA");
922 }
923 else if (g_str_has_prefix (image_types, "RGB*"))
924 {
925 types |= GIMP_PLUG_IN_RGB_IMAGE | GIMP_PLUG_IN_RGBA_IMAGE;
926 image_types += strlen ("RGB*");
927 }
928 else if (g_str_has_prefix (image_types, "RGB"))
929 {
930 types |= GIMP_PLUG_IN_RGB_IMAGE;
931 image_types += strlen ("RGB");
932 }
933 else if (g_str_has_prefix (image_types, "GRAYA"))
934 {
935 types |= GIMP_PLUG_IN_GRAYA_IMAGE;
936 image_types += strlen ("GRAYA");
937 }
938 else if (g_str_has_prefix (image_types, "GRAY*"))
939 {
940 types |= GIMP_PLUG_IN_GRAY_IMAGE | GIMP_PLUG_IN_GRAYA_IMAGE;
941 image_types += strlen ("GRAY*");
942 }
943 else if (g_str_has_prefix (image_types, "GRAY"))
944 {
945 types |= GIMP_PLUG_IN_GRAY_IMAGE;
946 image_types += strlen ("GRAY");
947 }
948 else if (g_str_has_prefix (image_types, "INDEXEDA"))
949 {
950 types |= GIMP_PLUG_IN_INDEXEDA_IMAGE;
951 image_types += strlen ("INDEXEDA");
952 }
953 else if (g_str_has_prefix (image_types, "INDEXED*"))
954 {
955 types |= GIMP_PLUG_IN_INDEXED_IMAGE | GIMP_PLUG_IN_INDEXEDA_IMAGE;
956 image_types += strlen ("INDEXED*");
957 }
958 else if (g_str_has_prefix (image_types, "INDEXED"))
959 {
960 types |= GIMP_PLUG_IN_INDEXED_IMAGE;
961 image_types += strlen ("INDEXED");
962 }
963 else if (g_str_has_prefix (image_types, "*"))
964 {
965 types |= (GIMP_PLUG_IN_RGB_IMAGE | GIMP_PLUG_IN_RGBA_IMAGE |
966 GIMP_PLUG_IN_GRAY_IMAGE | GIMP_PLUG_IN_GRAYA_IMAGE |
967 GIMP_PLUG_IN_INDEXED_IMAGE | GIMP_PLUG_IN_INDEXEDA_IMAGE);
968 image_types += strlen ("*");
969 }
970 else
971 {
972 g_printerr ("%s: image-type contains unrecognizable parts:"
973 "'%s'\n", name, type_spec);
974
975 /* skip to next token */
976 while (*image_types &&
977 *image_types != ' ' &&
978 *image_types != '\t' &&
979 *image_types != ',')
980 {
981 image_types++;
982 }
983 }
984 }
985 }
986
987 return types;
988 }
989
990 void
gimp_plug_in_procedure_set_image_types(GimpPlugInProcedure * proc,const gchar * image_types)991 gimp_plug_in_procedure_set_image_types (GimpPlugInProcedure *proc,
992 const gchar *image_types)
993 {
994 GList *types = NULL;
995
996 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
997
998 if (proc->image_types)
999 g_free (proc->image_types);
1000
1001 proc->image_types = g_strdup (image_types);
1002 proc->image_types_val = image_types_parse (gimp_object_get_name (proc),
1003 proc->image_types);
1004
1005 g_clear_pointer (&proc->image_types_tooltip, g_free);
1006
1007 if (proc->image_types_val &
1008 (GIMP_PLUG_IN_RGB_IMAGE | GIMP_PLUG_IN_RGBA_IMAGE))
1009 {
1010 if ((proc->image_types_val & GIMP_PLUG_IN_RGB_IMAGE) &&
1011 (proc->image_types_val & GIMP_PLUG_IN_RGBA_IMAGE))
1012 {
1013 types = g_list_prepend (types, _("RGB"));
1014 }
1015 else if (proc->image_types_val & GIMP_PLUG_IN_RGB_IMAGE)
1016 {
1017 types = g_list_prepend (types, _("RGB without alpha"));
1018 }
1019 else
1020 {
1021 types = g_list_prepend (types, _("RGB with alpha"));
1022 }
1023 }
1024
1025 if (proc->image_types_val &
1026 (GIMP_PLUG_IN_GRAY_IMAGE | GIMP_PLUG_IN_GRAYA_IMAGE))
1027 {
1028 if ((proc->image_types_val & GIMP_PLUG_IN_GRAY_IMAGE) &&
1029 (proc->image_types_val & GIMP_PLUG_IN_GRAYA_IMAGE))
1030 {
1031 types = g_list_prepend (types, _("Grayscale"));
1032 }
1033 else if (proc->image_types_val & GIMP_PLUG_IN_GRAY_IMAGE)
1034 {
1035 types = g_list_prepend (types, _("Grayscale without alpha"));
1036 }
1037 else
1038 {
1039 types = g_list_prepend (types, _("Grayscale with alpha"));
1040 }
1041 }
1042
1043 if (proc->image_types_val &
1044 (GIMP_PLUG_IN_INDEXED_IMAGE | GIMP_PLUG_IN_INDEXEDA_IMAGE))
1045 {
1046 if ((proc->image_types_val & GIMP_PLUG_IN_INDEXED_IMAGE) &&
1047 (proc->image_types_val & GIMP_PLUG_IN_INDEXEDA_IMAGE))
1048 {
1049 types = g_list_prepend (types, _("Indexed"));
1050 }
1051 else if (proc->image_types_val & GIMP_PLUG_IN_INDEXED_IMAGE)
1052 {
1053 types = g_list_prepend (types, _("Indexed without alpha"));
1054 }
1055 else
1056 {
1057 types = g_list_prepend (types, _("Indexed with alpha"));
1058 }
1059 }
1060
1061 if (types)
1062 {
1063 GString *string;
1064 GList *list;
1065
1066 types = g_list_reverse (types);
1067
1068 string = g_string_new (gimp_procedure_get_blurb (GIMP_PROCEDURE (proc)));
1069
1070 g_string_append (string, "\n\n");
1071 g_string_append (string, _("This plug-in only works on the "
1072 "following layer types:"));
1073 g_string_append (string, "\n");
1074
1075 for (list = types; list; list = g_list_next (list))
1076 {
1077 g_string_append (string, list->data);
1078
1079 if (list->next)
1080 g_string_append (string, ", ");
1081 else
1082 g_string_append (string, ".");
1083 }
1084
1085 g_list_free (types);
1086
1087 proc->image_types_tooltip = g_string_free (string, FALSE);
1088 }
1089 }
1090
1091 static GSList *
extensions_parse(gchar * extensions)1092 extensions_parse (gchar *extensions)
1093 {
1094 GSList *list = NULL;
1095
1096 /* extensions can be NULL. Avoid calling strtok if it is. */
1097 if (extensions)
1098 {
1099 gchar *extension;
1100 gchar *next_token;
1101
1102 /* work on a copy */
1103 extensions = g_strdup (extensions);
1104
1105 next_token = extensions;
1106 extension = strtok (next_token, " \t,");
1107
1108 while (extension)
1109 {
1110 list = g_slist_prepend (list, g_strdup (extension));
1111 extension = strtok (NULL, " \t,");
1112 }
1113
1114 g_free (extensions);
1115 }
1116
1117 return g_slist_reverse (list);
1118 }
1119
1120 void
gimp_plug_in_procedure_set_file_proc(GimpPlugInProcedure * proc,const gchar * extensions,const gchar * prefixes,const gchar * magics)1121 gimp_plug_in_procedure_set_file_proc (GimpPlugInProcedure *proc,
1122 const gchar *extensions,
1123 const gchar *prefixes,
1124 const gchar *magics)
1125 {
1126 GSList *list;
1127
1128 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
1129
1130 proc->file_proc = TRUE;
1131
1132 /* extensions */
1133
1134 if (proc->extensions != extensions)
1135 {
1136 if (proc->extensions)
1137 g_free (proc->extensions);
1138
1139 proc->extensions = g_strdup (extensions);
1140 }
1141
1142 if (proc->extensions_list)
1143 g_slist_free_full (proc->extensions_list, (GDestroyNotify) g_free);
1144
1145 proc->extensions_list = extensions_parse (proc->extensions);
1146
1147 /* prefixes */
1148
1149 if (proc->prefixes != prefixes)
1150 {
1151 if (proc->prefixes)
1152 g_free (proc->prefixes);
1153
1154 proc->prefixes = g_strdup (prefixes);
1155 }
1156
1157 if (proc->prefixes_list)
1158 g_slist_free_full (proc->prefixes_list, (GDestroyNotify) g_free);
1159
1160 proc->prefixes_list = extensions_parse (proc->prefixes);
1161
1162 /* don't allow "file:" to be registered as prefix */
1163 for (list = proc->prefixes_list; list; list = g_slist_next (list))
1164 {
1165 const gchar *prefix = list->data;
1166
1167 if (prefix && strcmp (prefix, "file:") == 0)
1168 {
1169 g_free (list->data);
1170 proc->prefixes_list = g_slist_delete_link (proc->prefixes_list, list);
1171 break;
1172 }
1173 }
1174
1175 /* magics */
1176
1177 if (proc->magics != magics)
1178 {
1179 if (proc->magics)
1180 g_free (proc->magics);
1181
1182 proc->magics = g_strdup (magics);
1183 }
1184
1185 if (proc->magics_list)
1186 g_slist_free_full (proc->magics_list, (GDestroyNotify) g_free);
1187
1188 proc->magics_list = extensions_parse (proc->magics);
1189 }
1190
1191 void
gimp_plug_in_procedure_set_priority(GimpPlugInProcedure * proc,gint priority)1192 gimp_plug_in_procedure_set_priority (GimpPlugInProcedure *proc,
1193 gint priority)
1194 {
1195 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
1196
1197 proc->priority = priority;
1198 }
1199
1200 void
gimp_plug_in_procedure_set_mime_types(GimpPlugInProcedure * proc,const gchar * mime_types)1201 gimp_plug_in_procedure_set_mime_types (GimpPlugInProcedure *proc,
1202 const gchar *mime_types)
1203 {
1204 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
1205
1206 if (proc->mime_types != mime_types)
1207 {
1208 if (proc->mime_types)
1209 g_free (proc->mime_types);
1210
1211 proc->mime_types = g_strdup (mime_types);
1212 }
1213
1214 if (proc->mime_types_list)
1215 g_slist_free_full (proc->mime_types_list, (GDestroyNotify) g_free);
1216
1217 proc->mime_types_list = extensions_parse (proc->mime_types);
1218 }
1219
1220 void
gimp_plug_in_procedure_set_handles_uri(GimpPlugInProcedure * proc)1221 gimp_plug_in_procedure_set_handles_uri (GimpPlugInProcedure *proc)
1222 {
1223 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
1224
1225 proc->handles_uri = TRUE;
1226 }
1227
1228 void
gimp_plug_in_procedure_set_handles_raw(GimpPlugInProcedure * proc)1229 gimp_plug_in_procedure_set_handles_raw (GimpPlugInProcedure *proc)
1230 {
1231 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
1232
1233 proc->handles_raw = TRUE;
1234 }
1235
1236 void
gimp_plug_in_procedure_set_thumb_loader(GimpPlugInProcedure * proc,const gchar * thumb_loader)1237 gimp_plug_in_procedure_set_thumb_loader (GimpPlugInProcedure *proc,
1238 const gchar *thumb_loader)
1239 {
1240 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
1241
1242 if (proc->thumb_loader)
1243 g_free (proc->thumb_loader);
1244
1245 proc->thumb_loader = g_strdup (thumb_loader);
1246 }
1247
1248 void
gimp_plug_in_procedure_handle_return_values(GimpPlugInProcedure * proc,Gimp * gimp,GimpProgress * progress,GimpValueArray * return_vals)1249 gimp_plug_in_procedure_handle_return_values (GimpPlugInProcedure *proc,
1250 Gimp *gimp,
1251 GimpProgress *progress,
1252 GimpValueArray *return_vals)
1253 {
1254 g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc));
1255 g_return_if_fail (return_vals != NULL);
1256
1257 if (gimp_value_array_length (return_vals) == 0 ||
1258 G_VALUE_TYPE (gimp_value_array_index (return_vals, 0)) !=
1259 GIMP_TYPE_PDB_STATUS_TYPE)
1260 {
1261 return;
1262 }
1263
1264 switch (g_value_get_enum (gimp_value_array_index (return_vals, 0)))
1265 {
1266 case GIMP_PDB_SUCCESS:
1267 break;
1268
1269 case GIMP_PDB_CALLING_ERROR:
1270 if (gimp_value_array_length (return_vals) > 1 &&
1271 G_VALUE_HOLDS_STRING (gimp_value_array_index (return_vals, 1)))
1272 {
1273 gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
1274 _("Calling error for '%s':\n"
1275 "%s"),
1276 gimp_procedure_get_label (GIMP_PROCEDURE (proc)),
1277 g_value_get_string (gimp_value_array_index (return_vals, 1)));
1278 }
1279 break;
1280
1281 case GIMP_PDB_EXECUTION_ERROR:
1282 if (gimp_value_array_length (return_vals) > 1 &&
1283 G_VALUE_HOLDS_STRING (gimp_value_array_index (return_vals, 1)))
1284 {
1285 gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR,
1286 _("Execution error for '%s':\n"
1287 "%s"),
1288 gimp_procedure_get_label (GIMP_PROCEDURE (proc)),
1289 g_value_get_string (gimp_value_array_index (return_vals, 1)));
1290 }
1291 break;
1292 }
1293 }
1294