PIKApp/app/plug-in/pikaplugin-proc.c

677 lines
22 KiB
C

/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* pikaplugin-proc.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 3 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, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
#include "libpikabase/pikabase.h"
#include "plug-in-types.h"
#include "core/pikaparamspecs.h"
#include "pdb/pikapdberror.h"
#include "pikaplugin.h"
#include "pikaplugin-proc.h"
#include "pikaplugindef.h"
#include "pikapluginmanager.h"
#include "pikapluginmanager-file.h"
#include "pikapluginprocedure.h"
#include "pika-intl.h"
/* local function prototypes */
static PikaPlugInProcedure * pika_plug_in_proc_find (PikaPlugIn *plug_in,
const gchar *proc_name);
/* public functions */
gboolean
pika_plug_in_set_proc_image_types (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *image_types,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register images types "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_plug_in_procedure_set_image_types (proc, image_types);
return TRUE;
}
gboolean
pika_plug_in_set_proc_sensitivity_mask (PikaPlugIn *plug_in,
const gchar *proc_name,
gint sensitivity_mask,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register the sensitivity mask \"%x\" "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
sensitivity_mask, proc_name);
return FALSE;
}
pika_plug_in_procedure_set_sensitivity_mask (proc, sensitivity_mask);
return TRUE;
}
gboolean
pika_plug_in_set_proc_menu_label (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *menu_label,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
g_return_val_if_fail (menu_label != NULL && strlen (menu_label), FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register the menu label \"%s\" "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
menu_label, proc_name);
return FALSE;
}
return pika_plug_in_procedure_set_menu_label (proc, menu_label, error);
}
gboolean
pika_plug_in_add_proc_menu_path (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *menu_path,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
g_return_val_if_fail (menu_path != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register the menu item \"%s\" "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
menu_path, proc_name);
return FALSE;
}
return pika_plug_in_procedure_add_menu_path (proc, menu_path, error);
}
gboolean
pika_plug_in_set_proc_icon (PikaPlugIn *plug_in,
const gchar *proc_name,
PikaIconType type,
const guint8 *data,
gint data_length,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to set the icon "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
return pika_plug_in_procedure_set_icon (proc, type, data, data_length,
error);
}
gboolean
pika_plug_in_set_proc_help (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *blurb,
const gchar *help,
const gchar *help_id,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register help "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_procedure_set_help (PIKA_PROCEDURE (proc),
blurb, help, help_id);
return TRUE;
}
gboolean
pika_plug_in_set_proc_attribution (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *authors,
const gchar *copyright,
const gchar *date,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register the attribution "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_procedure_set_attribution (PIKA_PROCEDURE (proc),
authors, copyright, date);
return TRUE;
}
static inline gboolean
PIKA_IS_PARAM_SPEC_RUN_MODE (GParamSpec *pspec)
{
return (G_IS_PARAM_SPEC_ENUM (pspec) &&
pspec->value_type == PIKA_TYPE_RUN_MODE);
}
static inline gboolean
PIKA_IS_PARAM_SPEC_FILE (GParamSpec *pspec)
{
return (G_IS_PARAM_SPEC_OBJECT (pspec) &&
pspec->value_type == G_TYPE_FILE);
}
gboolean
pika_plug_in_set_file_proc_load_handler (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *extensions,
const gchar *prefixes,
const gchar *magics,
GError **error)
{
PikaPlugInProcedure *proc;
PikaProcedure *procedure;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register procedure \"%s\" "
"as load handler.\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
procedure = PIKA_PROCEDURE (proc);
if (((procedure->num_args < 2) ||
(procedure->num_values < 1) ||
! PIKA_IS_PARAM_SPEC_RUN_MODE (procedure->args[0]) ||
! PIKA_IS_PARAM_SPEC_FILE (procedure->args[1]) ||
(! proc->generic_file_proc &&
! PIKA_IS_PARAM_SPEC_IMAGE (procedure->values[0]))))
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_FAILED,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register procedure \"%s\" "
"as load handler which does not take the standard "
"load procedure arguments: "
"(PikaRunMode, GFile) -> (PikaImage)",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_plug_in_procedure_set_file_proc (proc, extensions, prefixes, magics);
pika_plug_in_manager_add_load_procedure (plug_in->manager, proc);
return TRUE;
}
gboolean
pika_plug_in_set_file_proc_save_handler (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *extensions,
const gchar *prefixes,
GError **error)
{
PikaPlugInProcedure *proc;
PikaProcedure *procedure;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register procedure \"%s\" "
"as save handler.\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
procedure = PIKA_PROCEDURE (proc);
if ((procedure->num_args < 5) ||
! PIKA_IS_PARAM_SPEC_RUN_MODE (procedure->args[0]) ||
! PIKA_IS_PARAM_SPEC_IMAGE (procedure->args[1]) ||
! G_IS_PARAM_SPEC_INT (procedure->args[2]) ||
! PIKA_IS_PARAM_SPEC_OBJECT_ARRAY (procedure->args[3]) ||
! PIKA_IS_PARAM_SPEC_FILE (procedure->args[4]))
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_FAILED,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register procedure \"%s\" "
"as save handler which does not take the standard "
"save procedure arguments:\n"
"(PikaRunMode, PikaImage, int [array size], PikaDrawable Array, GFile)",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_plug_in_procedure_set_file_proc (proc, extensions, prefixes, NULL);
pika_plug_in_manager_add_save_procedure (plug_in->manager, proc);
return TRUE;
}
gboolean
pika_plug_in_set_file_proc_priority (PikaPlugIn *plug_in,
const gchar *proc_name,
gint priority,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register the priority "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_plug_in_procedure_set_priority (proc, priority);
return TRUE;
}
gboolean
pika_plug_in_set_file_proc_mime_types (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *mime_types,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register mime types "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_plug_in_procedure_set_mime_types (proc, mime_types);
return TRUE;
}
gboolean
pika_plug_in_set_file_proc_handles_remote (PikaPlugIn *plug_in,
const gchar *proc_name,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register 'handles remote' "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_plug_in_procedure_set_handles_remote (proc);
return TRUE;
}
gboolean
pika_plug_in_set_file_proc_handles_raw (PikaPlugIn *plug_in,
const gchar *proc_name,
GError **error)
{
PikaPlugInProcedure *proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register 'handles raw' "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_plug_in_procedure_set_handles_raw (proc);
return TRUE;
}
gboolean
pika_plug_in_set_file_proc_thumb_loader (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *thumb_proc_name,
GError **error)
{
PikaPlugInProcedure *proc;
PikaPlugInProcedure *thumb_proc;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
g_return_val_if_fail (thumb_proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
thumb_proc = pika_plug_in_proc_find (plug_in, thumb_proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register a thumbnail loader "
"for procedure \"%s\".\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
if (! thumb_proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register a procedure \"%s\" "
"as thumbnail loader.\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
thumb_proc_name);
return FALSE;
}
pika_plug_in_procedure_set_thumb_loader (proc, thumb_proc_name);
return TRUE;
}
gboolean
pika_plug_in_set_batch_interpreter (PikaPlugIn *plug_in,
const gchar *proc_name,
const gchar *interpreter_name,
GError **error)
{
PikaPlugInProcedure *proc;
PikaProcedure *procedure;
g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE);
g_return_val_if_fail (proc_name != NULL, FALSE);
proc = pika_plug_in_proc_find (plug_in, proc_name);
if (! proc)
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_PROCEDURE_NOT_FOUND,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register procedure \"%s\" "
"as a 'batch interpreter'.\n"
"It has however not installed that procedure. "
"This is not allowed.",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
procedure = PIKA_PROCEDURE (proc);
if (procedure->num_args < 2 ||
! PIKA_IS_PARAM_SPEC_RUN_MODE (procedure->args[0]) ||
! G_IS_PARAM_SPEC_STRING (procedure->args[1]))
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_FAILED,
"Plug-in \"%s\"\n(%s)\n"
"attempted to register procedure \"%s\" "
"as a batch interpreter which does not take the standard "
"batch interpreter procedure arguments: "
"(PikaRunMode, gchar *) -> ()",
pika_object_get_name (plug_in),
pika_file_get_utf8_name (plug_in->file),
proc_name);
return FALSE;
}
pika_plug_in_procedure_set_batch_interpreter (proc, interpreter_name);
pika_plug_in_manager_add_batch_procedure (plug_in->manager, proc);
return TRUE;
}
/* private functions */
static PikaPlugInProcedure *
pika_plug_in_proc_find (PikaPlugIn *plug_in,
const gchar *proc_name)
{
PikaPlugInProcedure *proc = NULL;
if (plug_in->plug_in_def)
proc = pika_plug_in_procedure_find (plug_in->plug_in_def->procedures,
proc_name);
if (! proc)
proc = pika_plug_in_procedure_find (plug_in->temp_procedures, proc_name);
return proc;
}