GdkPixbuf * gimp_plug_in_procedure_get_pixbuf (const GimpPlugInProcedure *proc) { GdkPixbuf *pixbuf = NULL; GError *error = NULL; g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL); switch (proc->icon_type) { case GIMP_ICON_TYPE_INLINE_PIXBUF: pixbuf = gdk_pixbuf_new_from_inline (proc->icon_data_length, proc->icon_data, TRUE, &error); break; case GIMP_ICON_TYPE_IMAGE_FILE: pixbuf = gdk_pixbuf_new_from_file ((gchar *) proc->icon_data, &error); break; default: break; } if (! pixbuf && error) { g_printerr ("%s\n", error->message); g_clear_error (&error); } return pixbuf; }
GimpPlugIn * gimp_plug_in_new (GimpPlugInManager *manager, GimpContext *context, GimpProgress *progress, GimpPlugInProcedure *procedure, const gchar *prog) { GimpPlugIn *plug_in; g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL); g_return_val_if_fail (GIMP_IS_PDB_CONTEXT (context), NULL); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL); g_return_val_if_fail (procedure == NULL || GIMP_IS_PLUG_IN_PROCEDURE (procedure), NULL); g_return_val_if_fail (prog == NULL || g_path_is_absolute (prog), NULL); g_return_val_if_fail ((procedure != NULL || prog != NULL) && ! (procedure != NULL && prog != NULL), NULL); plug_in = g_object_new (GIMP_TYPE_PLUG_IN, NULL); if (! prog) prog = gimp_plug_in_procedure_get_progname (procedure); gimp_object_take_name (GIMP_OBJECT (plug_in), g_filename_display_basename (prog)); plug_in->manager = manager; plug_in->prog = g_strdup (prog); gimp_plug_in_proc_frame_init (&plug_in->main_proc_frame, context, progress, procedure); return plug_in; }
void gimp_plug_in_procedure_set_icon (GimpPlugInProcedure *proc, GimpIconType icon_type, const guint8 *icon_data, gint icon_data_length) { g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); g_return_if_fail (icon_type == -1 || icon_data != NULL); g_return_if_fail (icon_type == -1 || icon_data_length > 0); if (proc->icon_data) { g_free (proc->icon_data); proc->icon_data_length = -1; proc->icon_data = NULL; } proc->icon_type = icon_type; switch (proc->icon_type) { case GIMP_ICON_TYPE_STOCK_ID: case GIMP_ICON_TYPE_IMAGE_FILE: proc->icon_data_length = -1; proc->icon_data = (guint8 *) g_strdup ((gchar *) icon_data); break; case GIMP_ICON_TYPE_INLINE_PIXBUF: proc->icon_data_length = icon_data_length; proc->icon_data = g_memdup (icon_data, icon_data_length); break; } }
const gchar * gimp_plug_in_procedure_get_help_domain (const GimpPlugInProcedure *proc) { g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL); return g_quark_to_string (proc->help_domain); }
GimpPlugIn * gimp_plug_in_new (GimpPlugInManager *manager, GimpContext *context, GimpProgress *progress, GimpPlugInProcedure *procedure, GFile *file) { GimpPlugIn *plug_in; g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL); g_return_val_if_fail (GIMP_IS_PDB_CONTEXT (context), NULL); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL); g_return_val_if_fail (procedure == NULL || GIMP_IS_PLUG_IN_PROCEDURE (procedure), NULL); g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL); g_return_val_if_fail ((procedure != NULL || file != NULL) && ! (procedure != NULL && file != NULL), NULL); plug_in = g_object_new (GIMP_TYPE_PLUG_IN, NULL); if (! file) file = gimp_plug_in_procedure_get_file (procedure); gimp_object_take_name (GIMP_OBJECT (plug_in), g_path_get_basename (gimp_file_get_utf8_name (file))); plug_in->manager = manager; plug_in->file = g_object_ref (file); gimp_plug_in_proc_frame_init (&plug_in->main_proc_frame, context, progress, procedure); return plug_in; }
static void plug_in_actions_register_procedure (GimpPDB *pdb, GimpProcedure *procedure, GimpActionGroup *group) { if (GIMP_IS_PLUG_IN_PROCEDURE (procedure)) { GimpPlugInProcedure *plug_in_proc = GIMP_PLUG_IN_PROCEDURE (procedure); g_signal_connect_object (plug_in_proc, "menu-path-added", G_CALLBACK (plug_in_actions_menu_path_added), group, 0); if ((plug_in_proc->menu_label || plug_in_proc->menu_paths) && ! plug_in_proc->file_proc) { #if 0 g_print ("%s: %s\n", G_STRFUNC, gimp_object_get_name (GIMP_OBJECT (procedure))); #endif plug_in_actions_add_proc (group, plug_in_proc); } } }
void gimp_plug_in_manager_history_add (GimpPlugInManager *manager, GimpPlugInProcedure *procedure) { GSList *list; gint history_size; g_return_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager)); g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (procedure)); /* return early if the procedure is already at the top */ if (manager->history && manager->history->data == procedure) return; history_size = gimp_plug_in_manager_history_size (manager); manager->history = g_slist_remove (manager->history, procedure); manager->history = g_slist_prepend (manager->history, procedure); list = g_slist_nth (manager->history, history_size); if (list) { manager->history = g_slist_remove_link (manager->history, list); g_slist_free (list); } gimp_plug_in_manager_history_changed (manager); }
static void plug_in_actions_unregister_procedure (GimpPDB *pdb, GimpProcedure *procedure, GimpActionGroup *group) { if (GIMP_IS_PLUG_IN_PROCEDURE (procedure)) { GimpPlugInProcedure *plug_in_proc = GIMP_PLUG_IN_PROCEDURE (procedure); g_signal_handlers_disconnect_by_func (plug_in_proc, plug_in_actions_menu_path_added, group); if ((plug_in_proc->menu_label || plug_in_proc->menu_paths) && ! plug_in_proc->file_proc) { GtkAction *action; #if 0 g_print ("%s: %s\n", G_STRFUNC, gimp_object_get_name (GIMP_OBJECT (procedure))); #endif action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), GIMP_OBJECT (procedure)->name); if (action) gtk_action_group_remove_action (GTK_ACTION_GROUP (group), action); } } }
void gimp_plug_in_def_add_procedure (GimpPlugInDef *plug_in_def, GimpPlugInProcedure *proc) { GimpPlugInProcedure *overridden; g_return_if_fail (GIMP_IS_PLUG_IN_DEF (plug_in_def)); g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); overridden = gimp_plug_in_procedure_find (plug_in_def->procedures, gimp_object_get_name (proc)); if (overridden) gimp_plug_in_def_remove_procedure (plug_in_def, overridden); proc->mtime = plug_in_def->mtime; gimp_plug_in_procedure_set_locale_domain (proc, plug_in_def->locale_domain_name); gimp_plug_in_procedure_set_help_domain (proc, plug_in_def->help_domain_name); plug_in_def->procedures = g_slist_append (plug_in_def->procedures, g_object_ref (proc)); }
static void plug_in_menus_register_procedure (GimpPDB *pdb, GimpProcedure *procedure, GimpUIManager *manager) { if (GIMP_IS_PLUG_IN_PROCEDURE (procedure)) { GimpPlugInProcedure *plug_in_proc = GIMP_PLUG_IN_PROCEDURE (procedure); g_signal_connect_object (plug_in_proc, "menu-path-added", G_CALLBACK (plug_in_menus_menu_path_added), manager, 0); if ((plug_in_proc->menu_label || plug_in_proc->menu_paths) && ! plug_in_proc->file_proc) { GList *list; GIMP_LOG (MENUS, "register procedure: %s", gimp_object_get_name (procedure)); for (list = plug_in_proc->menu_paths; list; list = g_list_next (list)) plug_in_menus_menu_path_added (plug_in_proc, list->data, manager); } } }
void gimp_plug_in_procedure_set_handles_uri (GimpPlugInProcedure *proc) { g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); proc->handles_uri = TRUE; }
const gchar * gimp_plug_in_procedure_get_progname (const GimpPlugInProcedure *proc) { g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL); return GIMP_PLUG_IN_PROCEDURE_GET_CLASS (proc)->get_progname (proc); }
void gimp_plug_in_procedure_set_help_domain (GimpPlugInProcedure *proc, const gchar *help_domain) { g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); proc->help_domain = help_domain ? g_quark_from_string (help_domain) : 0; }
void gimp_plug_in_def_remove_procedure (GimpPlugInDef *plug_in_def, GimpPlugInProcedure *proc) { g_return_if_fail (GIMP_IS_PLUG_IN_DEF (plug_in_def)); g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); plug_in_def->procedures = g_slist_remove (plug_in_def->procedures, proc); g_object_unref (proc); }
void gimp_plug_in_procedure_set_thumb_loader (GimpPlugInProcedure *proc, const gchar *thumb_loader) { g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); if (proc->thumb_loader) g_free (proc->thumb_loader); proc->thumb_loader = g_strdup (thumb_loader); }
void gimp_plug_in_procedure_set_mime_type (GimpPlugInProcedure *proc, const gchar *mime_type) { g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); if (proc->mime_type) g_free (proc->mime_type); proc->mime_type = g_strdup (mime_type); }
void gimp_plug_in_procedure_set_image_types (GimpPlugInProcedure *proc, const gchar *image_types) { g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); if (proc->image_types) g_free (proc->image_types); proc->image_types = g_strdup (image_types); proc->image_types_val = image_types_parse (gimp_object_get_name (proc), proc->image_types); }
const gchar * gimp_plug_in_procedure_get_stock_id (const GimpPlugInProcedure *proc) { g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL); switch (proc->icon_type) { case GIMP_ICON_TYPE_STOCK_ID: return (gchar *) proc->icon_data; default: return NULL; } }
gchar * gimp_plug_in_procedure_get_help_id (const GimpPlugInProcedure *proc) { const gchar *domain; g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL); domain = gimp_plug_in_procedure_get_help_domain (proc); if (domain) return g_strconcat (domain, "?", gimp_object_get_name (proc), NULL); return g_strdup (gimp_object_get_name (proc)); }
const gchar * gimp_plug_in_procedure_get_blurb (const GimpPlugInProcedure *proc) { GimpProcedure *procedure; g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL); procedure = GIMP_PROCEDURE (proc); /* do not to pass the empty string to gettext() */ if (procedure->blurb && strlen (procedure->blurb)) return dgettext (gimp_plug_in_procedure_get_locale_domain (proc), procedure->blurb); return NULL; }
void gimp_plug_in_procedure_handle_return_values (GimpPlugInProcedure *proc, Gimp *gimp, GimpProgress *progress, GimpValueArray *return_vals) { g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); g_return_if_fail (return_vals != NULL); if (! gimp_value_array_length (return_vals) > 0 || G_VALUE_TYPE (gimp_value_array_index (return_vals, 0)) != GIMP_TYPE_PDB_STATUS_TYPE) { return; } switch (g_value_get_enum (gimp_value_array_index (return_vals, 0))) { case GIMP_PDB_SUCCESS: break; case GIMP_PDB_CALLING_ERROR: if (gimp_value_array_length (return_vals) > 1 && G_VALUE_HOLDS_STRING (gimp_value_array_index (return_vals, 1))) { gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR, _("Calling error for '%s':\n" "%s"), gimp_plug_in_procedure_get_label (proc), g_value_get_string (gimp_value_array_index (return_vals, 1))); } break; case GIMP_PDB_EXECUTION_ERROR: if (gimp_value_array_length (return_vals) > 1 && G_VALUE_HOLDS_STRING (gimp_value_array_index (return_vals, 1))) { gimp_message (gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR, _("Execution error for '%s':\n" "%s"), gimp_plug_in_procedure_get_label (proc), g_value_get_string (gimp_value_array_index (return_vals, 1))); } break; } }
void gimp_plug_in_manager_history_remove (GimpPlugInManager *manager, GimpPlugInProcedure *procedure) { GSList *link; g_return_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager)); g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (procedure)); link = g_slist_find (manager->history, procedure); if (link) { manager->history = g_slist_delete_link (manager->history, link); gimp_plug_in_manager_history_changed (manager); } }
static void plug_in_menus_unregister_procedure (GimpPDB *pdb, GimpProcedure *procedure, GimpUIManager *manager) { if (GIMP_IS_PLUG_IN_PROCEDURE (procedure)) { GimpPlugInProcedure *plug_in_proc = GIMP_PLUG_IN_PROCEDURE (procedure); g_signal_handlers_disconnect_by_func (plug_in_proc, plug_in_menus_menu_path_added, manager); if ((plug_in_proc->menu_label || plug_in_proc->menu_paths) && ! plug_in_proc->file_proc) { GList *list; GIMP_LOG (MENUS, "unregister procedure: %s", gimp_object_get_name (procedure)); for (list = plug_in_proc->menu_paths; list; list = g_list_next (list)) { if (g_str_has_prefix (list->data, manager->name)) { gchar *merge_key; guint merge_id; merge_key = g_strdup_printf ("%s-merge-id", gimp_object_get_name (plug_in_proc)); merge_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (manager), merge_key)); g_free (merge_key); if (merge_id) gtk_ui_manager_remove_ui (GTK_UI_MANAGER (manager), merge_id); break; } } } } }
gboolean gimp_plug_in_procedure_get_sensitive (const GimpPlugInProcedure *proc, GimpDrawable *drawable) { GimpImageType image_type = -1; gboolean sensitive = FALSE; g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), FALSE); g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), FALSE); if (drawable) { const Babl *format = gimp_drawable_get_format (drawable); image_type = gimp_babl_format_get_image_type (format); } switch (image_type) { case GIMP_RGB_IMAGE: sensitive = proc->image_types_val & GIMP_PLUG_IN_RGB_IMAGE; break; case GIMP_RGBA_IMAGE: sensitive = proc->image_types_val & GIMP_PLUG_IN_RGBA_IMAGE; break; case GIMP_GRAY_IMAGE: sensitive = proc->image_types_val & GIMP_PLUG_IN_GRAY_IMAGE; break; case GIMP_GRAYA_IMAGE: sensitive = proc->image_types_val & GIMP_PLUG_IN_GRAYA_IMAGE; break; case GIMP_INDEXED_IMAGE: sensitive = proc->image_types_val & GIMP_PLUG_IN_INDEXED_IMAGE; break; case GIMP_INDEXEDA_IMAGE: sensitive = proc->image_types_val & GIMP_PLUG_IN_INDEXEDA_IMAGE; break; default: break; } return sensitive ? TRUE : FALSE; }
const gchar * gimp_plug_in_procedure_get_label (GimpPlugInProcedure *proc) { const gchar *path; gchar *stripped; gchar *ellipsis; gchar *label; g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), NULL); if (proc->label) return proc->label; if (proc->menu_label) path = dgettext (gimp_plug_in_procedure_get_locale_domain (proc), proc->menu_label); else if (proc->menu_paths) path = dgettext (gimp_plug_in_procedure_get_locale_domain (proc), proc->menu_paths->data); else return NULL; stripped = gimp_strip_uline (path); if (proc->menu_label) label = g_strdup (stripped); else label = g_path_get_basename (stripped); g_free (stripped); ellipsis = strstr (label, "..."); if (! ellipsis) ellipsis = strstr (label, "\342\200\246" /* U+2026 HORIZONTAL ELLIPSIS */); if (ellipsis && ellipsis == (label + strlen (label) - 3)) *ellipsis = '\0'; proc->label = label; return proc->label; }
GimpPDBStatusType file_save (Gimp *gimp, GimpImage *image, GimpProgress *progress, const gchar *uri, GimpPlugInProcedure *file_proc, GimpRunMode run_mode, gboolean change_saved_state, gboolean export_backward, gboolean export_forward, GError **error) { GimpDrawable *drawable; GimpValueArray *return_vals; GimpPDBStatusType status; gchar *filename; gint32 image_ID; gint32 drawable_ID; g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (uri != NULL, GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail ((export_backward && export_forward) == FALSE, GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (error == NULL || *error == NULL, GIMP_PDB_CALLING_ERROR); drawable = gimp_image_get_active_drawable (image); if (! drawable) return GIMP_PDB_EXECUTION_ERROR; filename = file_utils_filename_from_uri (uri); if (filename) { /* check if we are saving to a file */ if (g_file_test (filename, G_FILE_TEST_EXISTS)) { if (! g_file_test (filename, G_FILE_TEST_IS_REGULAR)) { g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Not a regular file")); status = GIMP_PDB_EXECUTION_ERROR; goto out; } if (g_access (filename, W_OK) != 0) { g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_ACCES, g_strerror (errno)); status = GIMP_PDB_EXECUTION_ERROR; goto out; } } if (file_proc->handles_uri) { g_free (filename); filename = g_strdup (uri); } } else { filename = g_strdup (uri); } /* ref the image, so it can't get deleted during save */ g_object_ref (image); image_ID = gimp_image_get_ID (image); drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable)); return_vals = gimp_pdb_execute_procedure_by_name (image->gimp->pdb, gimp_get_user_context (gimp), progress, error, gimp_object_get_name (file_proc), GIMP_TYPE_INT32, run_mode, GIMP_TYPE_IMAGE_ID, image_ID, GIMP_TYPE_DRAWABLE_ID, drawable_ID, G_TYPE_STRING, filename, G_TYPE_STRING, uri, G_TYPE_NONE); status = g_value_get_enum (gimp_value_array_index (return_vals, 0)); gimp_value_array_unref (return_vals); if (status == GIMP_PDB_SUCCESS) { GimpDocumentList *documents; GimpImagefile *imagefile; if (change_saved_state) { gimp_image_set_uri (image, uri); gimp_image_set_save_proc (image, file_proc); /* Forget the import source when we save. We interpret a * save as that the user is not interested in being able * to quickly export back to the original any longer */ gimp_image_set_imported_uri (image, NULL); gimp_image_clean_all (image); } else if (export_backward) { /* We exported the image back to its imported source, * change nothing about export/import flags, only set * the export state to clean */ gimp_image_export_clean_all (image); gimp_object_name_changed (GIMP_OBJECT (image)); } else if (export_forward) { /* Remember the last entered Export URI for the image. We * only need to do this explicitly when exporting. It * happens implicitly when saving since the GimpObject name * of a GimpImage is the last-save URI */ gimp_image_set_exported_uri (image, uri); /* An image can not be considered both exported and imported * at the same time, so stop consider it as imported now * that we consider it exported. */ gimp_image_set_imported_uri (image, NULL); gimp_image_export_clean_all (image); } if (export_backward || export_forward) gimp_image_exported (image, uri); else gimp_image_saved (image, uri); documents = GIMP_DOCUMENT_LIST (image->gimp->documents); imagefile = gimp_document_list_add_uri (documents, uri, file_proc->mime_type); /* only save a thumbnail if we are saving as XCF, see bug #25272 */ if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL) gimp_imagefile_save_thumbnail (imagefile, file_proc->mime_type, image); } else if (status != GIMP_PDB_CANCEL) { if (error && *error == NULL) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("%s plug-in could not save image"), gimp_plug_in_procedure_get_label (file_proc)); } } gimp_image_flush (image); g_object_unref (image); out: g_free (filename); return status; }
GimpValueArray * gimp_plug_in_manager_call_run (GimpPlugInManager *manager, GimpContext *context, GimpProgress *progress, GimpPlugInProcedure *procedure, GimpValueArray *args, gboolean synchronous, GimpObject *display) { GimpValueArray *return_vals = NULL; GimpPlugIn *plug_in; g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL); g_return_val_if_fail (GIMP_IS_PDB_CONTEXT (context), NULL); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL); g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (procedure), NULL); g_return_val_if_fail (args != NULL, NULL); g_return_val_if_fail (display == NULL || GIMP_IS_OBJECT (display), NULL); plug_in = gimp_plug_in_new (manager, context, progress, procedure, NULL); if (plug_in) { GimpCoreConfig *core_config = manager->gimp->config; GimpGeglConfig *gegl_config = GIMP_GEGL_CONFIG (core_config); GimpDisplayConfig *display_config = GIMP_DISPLAY_CONFIG (core_config); GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (core_config); GPConfig config; GPProcRun proc_run; gint display_ID; GObject *screen; gint monitor; if (! gimp_plug_in_open (plug_in, GIMP_PLUG_IN_CALL_RUN, FALSE)) { const gchar *name = gimp_object_get_name (plug_in); GError *error = g_error_new (GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_EXECUTION_FAILED, _("Failed to run plug-in \"%s\""), name); g_object_unref (plug_in); return_vals = gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure), FALSE, error); g_error_free (error); return return_vals; } display_ID = display ? gimp_get_display_ID (manager->gimp, display) : -1; config.version = GIMP_PROTOCOL_VERSION; config.tile_width = GIMP_PLUG_IN_TILE_WIDTH; config.tile_height = GIMP_PLUG_IN_TILE_HEIGHT; config.shm_ID = (manager->shm ? gimp_plug_in_shm_get_ID (manager->shm) : -1); config.check_size = display_config->transparency_size; config.check_type = display_config->transparency_type; config.show_help_button = (gui_config->use_help && gui_config->show_help_button); config.use_cpu_accel = manager->gimp->use_cpu_accel; config.use_opencl = gegl_config->use_opencl; config.gimp_reserved_6 = 0; config.gimp_reserved_7 = 0; config.gimp_reserved_8 = 0; config.install_cmap = FALSE; config.show_tooltips = gui_config->show_tooltips; config.min_colors = 144; config.gdisp_ID = display_ID; config.app_name = (gchar *) g_get_application_name (); config.wm_class = (gchar *) gimp_get_program_class (manager->gimp); config.display_name = gimp_get_display_name (manager->gimp, display_ID, &screen, &monitor); config.monitor_number = monitor; config.timestamp = gimp_get_user_time (manager->gimp); proc_run.name = GIMP_PROCEDURE (procedure)->original_name; proc_run.nparams = gimp_value_array_length (args); proc_run.params = plug_in_args_to_params (args, FALSE); if (! gp_config_write (plug_in->my_write, &config, plug_in) || ! gp_proc_run_write (plug_in->my_write, &proc_run, plug_in) || ! gimp_wire_flush (plug_in->my_write, plug_in)) { const gchar *name = gimp_object_get_name (plug_in); GError *error = g_error_new (GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_EXECUTION_FAILED, _("Failed to run plug-in \"%s\""), name); g_free (config.display_name); g_free (proc_run.params); g_object_unref (plug_in); return_vals = gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure), FALSE, error); g_error_free (error); return return_vals; } g_free (config.display_name); g_free (proc_run.params); /* If this is an extension, * wait for an installation-confirmation message */ if (GIMP_PROCEDURE (procedure)->proc_type == GIMP_EXTENSION) { plug_in->ext_main_loop = g_main_loop_new (NULL, FALSE); gimp_threads_leave (manager->gimp); g_main_loop_run (plug_in->ext_main_loop); gimp_threads_enter (manager->gimp); /* main_loop is quit in gimp_plug_in_handle_extension_ack() */ g_main_loop_unref (plug_in->ext_main_loop); plug_in->ext_main_loop = NULL; } /* If this plug-in is requested to run synchronously, * wait for its return values */ if (synchronous) { GimpPlugInProcFrame *proc_frame = &plug_in->main_proc_frame; proc_frame->main_loop = g_main_loop_new (NULL, FALSE); gimp_threads_leave (manager->gimp); g_main_loop_run (proc_frame->main_loop); gimp_threads_enter (manager->gimp); /* main_loop is quit in gimp_plug_in_handle_proc_return() */ g_main_loop_unref (proc_frame->main_loop); proc_frame->main_loop = NULL; return_vals = gimp_plug_in_proc_frame_get_return_values (proc_frame); } g_object_unref (plug_in); } return return_vals; }
GimpPDBStatusType file_save (Gimp *gimp, GimpImage *image, GimpProgress *progress, GFile *file, GimpPlugInProcedure *file_proc, GimpRunMode run_mode, gboolean change_saved_state, gboolean export_backward, gboolean export_forward, GError **error) { GimpDrawable *drawable; GimpValueArray *return_vals; GimpPDBStatusType status = GIMP_PDB_EXECUTION_ERROR; GFile *local_file = NULL; gchar *path = NULL; gchar *uri = NULL; gint32 image_ID; gint32 drawable_ID; GError *my_error = NULL; g_return_val_if_fail (GIMP_IS_GIMP (gimp), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (G_IS_FILE (file), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (file_proc), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail ((export_backward && export_forward) == FALSE, GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (error == NULL || *error == NULL, GIMP_PDB_CALLING_ERROR); /* ref image and file, so they can't get deleted during save */ g_object_ref (image); g_object_ref (file); drawable = gimp_image_get_active_drawable (image); if (! drawable) goto out; /* FIXME enable these tests for remote files again, needs testing */ if (g_file_is_native (file) && g_file_query_exists (file, NULL)) { GFileInfo *info; info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, G_FILE_QUERY_INFO_NONE, NULL, error); if (! info) goto out; if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR) { g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Not a regular file")); g_object_unref (info); goto out; } if (! g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) { g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Permission denied")); g_object_unref (info); goto out; } g_object_unref (info); } if (! g_file_is_native (file) && ! file_remote_mount_file (gimp, file, progress, &my_error)) { if (my_error) g_propagate_error (error, my_error); else status = GIMP_PDB_CANCEL; goto out; } if (! file_proc->handles_uri) { path = g_file_get_path (file); if (! path) { local_file = file_remote_upload_image_prepare (gimp, file, progress, &my_error); if (! local_file) { if (my_error) g_propagate_error (error, my_error); else status = GIMP_PDB_CANCEL; goto out; } path = g_file_get_path (local_file); } } if (! path) path = g_file_get_uri (file); uri = g_file_get_uri (file); image_ID = gimp_image_get_ID (image); drawable_ID = gimp_item_get_ID (GIMP_ITEM (drawable)); return_vals = gimp_pdb_execute_procedure_by_name (image->gimp->pdb, gimp_get_user_context (gimp), progress, error, gimp_object_get_name (file_proc), GIMP_TYPE_INT32, run_mode, GIMP_TYPE_IMAGE_ID, image_ID, GIMP_TYPE_DRAWABLE_ID, drawable_ID, G_TYPE_STRING, path, G_TYPE_STRING, uri, G_TYPE_NONE); status = g_value_get_enum (gimp_value_array_index (return_vals, 0)); gimp_value_array_unref (return_vals); if (local_file) { if (status == GIMP_PDB_SUCCESS) { GError *my_error = NULL; if (! file_remote_upload_image_finish (gimp, file, local_file, progress, &my_error)) { status = GIMP_PDB_EXECUTION_ERROR; if (my_error) g_propagate_error (error, my_error); else status = GIMP_PDB_CANCEL; } } g_file_delete (local_file, NULL, NULL); g_object_unref (local_file); } if (status == GIMP_PDB_SUCCESS) { GimpDocumentList *documents; GimpImagefile *imagefile; if (change_saved_state) { gimp_image_set_file (image, file); gimp_image_set_save_proc (image, file_proc); /* Forget the import source when we save. We interpret a * save as that the user is not interested in being able * to quickly export back to the original any longer */ gimp_image_set_imported_file (image, NULL); gimp_image_clean_all (image); } else if (export_backward) { /* We exported the image back to its imported source, * change nothing about export/import flags, only set * the export state to clean */ gimp_image_export_clean_all (image); gimp_object_name_changed (GIMP_OBJECT (image)); } else if (export_forward) { /* Remember the last entered Export URI for the image. We * only need to do this explicitly when exporting. It * happens implicitly when saving since the GimpObject name * of a GimpImage is the last-save URI */ gimp_image_set_exported_file (image, file); gimp_image_set_export_proc (image, file_proc); /* An image can not be considered both exported and imported * at the same time, so stop consider it as imported now * that we consider it exported. */ gimp_image_set_imported_file (image, NULL); gimp_image_export_clean_all (image); } if (export_backward || export_forward) gimp_image_exported (image, file); else gimp_image_saved (image, file); documents = GIMP_DOCUMENT_LIST (image->gimp->documents); imagefile = gimp_document_list_add_file (documents, file, file_proc->mime_type); /* only save a thumbnail if we are saving as XCF, see bug #25272 */ if (GIMP_PROCEDURE (file_proc)->proc_type == GIMP_INTERNAL) gimp_imagefile_save_thumbnail (imagefile, file_proc->mime_type, image, NULL); } else if (status != GIMP_PDB_CANCEL) { if (error && *error == NULL) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("%s plug-in could not save image"), gimp_plug_in_procedure_get_label (file_proc)); } } gimp_image_flush (image); out: g_object_unref (file); g_object_unref (image); g_free (path); g_free (uri); return status; }
gboolean gimp_plug_in_procedure_add_menu_path (GimpPlugInProcedure *proc, const gchar *menu_path, GError **error) { GimpProcedure *procedure; gchar *basename = NULL; const gchar *required = NULL; gchar *p; gchar *mapped_path; g_return_val_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc), FALSE); g_return_val_if_fail (menu_path != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); procedure = GIMP_PROCEDURE (proc); p = strchr (menu_path, '>'); if (p == NULL || (*(++p) && *p != '/')) { basename = g_filename_display_basename (proc->prog); g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED, "Plug-In \"%s\"\n(%s)\n" "attempted to install procedure \"%s\"\n" "in the invalid menu location \"%s\".\n" "The menu path must look like either \"<Prefix>\" " "or \"<Prefix>/path/to/item\".", basename, gimp_filename_to_utf8 (proc->prog), gimp_object_get_name (proc), menu_path); goto failure; } if (g_str_has_prefix (menu_path, "<Toolbox>") || g_str_has_prefix (menu_path, "<Image>")) { if ((procedure->num_args < 1) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0])) { required = "INT32"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Layers>")) { if ((procedure->num_args < 3) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) || ! (G_TYPE_FROM_INSTANCE (procedure->args[2]) == GIMP_TYPE_PARAM_LAYER_ID || G_TYPE_FROM_INSTANCE (procedure->args[2]) == GIMP_TYPE_PARAM_DRAWABLE_ID)) { required = "INT32, IMAGE, (LAYER | DRAWABLE)"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Channels>")) { if ((procedure->num_args < 3) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) || ! (G_TYPE_FROM_INSTANCE (procedure->args[2]) == GIMP_TYPE_PARAM_CHANNEL_ID || G_TYPE_FROM_INSTANCE (procedure->args[2]) == GIMP_TYPE_PARAM_DRAWABLE_ID)) { required = "INT32, IMAGE, (CHANNEL | DRAWABLE)"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Vectors>")) { if ((procedure->num_args < 3) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) || ! GIMP_IS_PARAM_SPEC_VECTORS_ID (procedure->args[2])) { required = "INT32, IMAGE, VECTORS"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Colormap>")) { if ((procedure->num_args < 2) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1])) { required = "INT32, IMAGE"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Load>")) { if ((procedure->num_args < 3) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[1]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[2])) { required = "INT32, STRING, STRING"; goto failure; } if ((procedure->num_values < 1) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->values[0])) { required = "IMAGE"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Save>")) { if ((procedure->num_args < 5) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) || ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]) || ! GIMP_IS_PARAM_SPEC_DRAWABLE_ID (procedure->args[2]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[3]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[4])) { required = "INT32, IMAGE, DRAWABLE, STRING, STRING"; goto failure; } } else if (g_str_has_prefix (menu_path, "<Brushes>") || g_str_has_prefix (menu_path, "<Gradients>") || g_str_has_prefix (menu_path, "<Palettes>") || g_str_has_prefix (menu_path, "<Patterns>") || g_str_has_prefix (menu_path, "<Fonts>") || g_str_has_prefix (menu_path, "<Buffers>")) { if ((procedure->num_args < 1) || ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0])) { required = "INT32"; goto failure; } } else { basename = g_filename_display_basename (proc->prog); g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED, "Plug-In \"%s\"\n(%s)\n" "attempted to install procedure \"%s\" " "in the invalid menu location \"%s\".\n" "Use either \"<Toolbox>\", \"<Image>\", " "\"<Layers>\", \"<Channels>\", \"<Vectors>\", " "\"<Colormap>\", \"<Load>\", \"<Save>\", " "\"<Brushes>\", \"<Gradients>\", \"<Palettes>\", " "\"<Patterns>\" or \"<Buffers>\".", basename, gimp_filename_to_utf8 (proc->prog), gimp_object_get_name (proc), menu_path); goto failure; } g_free (basename); mapped_path = plug_in_menu_path_map (menu_path, NULL); proc->menu_paths = g_list_append (proc->menu_paths, mapped_path); g_signal_emit (proc, gimp_plug_in_procedure_signals[MENU_PATH_ADDED], 0, mapped_path); return TRUE; failure: if (required) { gchar *prefix = g_strdup (menu_path); p = strchr (prefix, '>') + 1; *p = '\0'; basename = g_filename_display_basename (proc->prog); g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_FAILED, "Plug-In \"%s\"\n(%s)\n\n" "attempted to install %s procedure \"%s\" " "which does not take the standard %s Plug-In " "arguments: (%s).", basename, gimp_filename_to_utf8 (proc->prog), prefix, gimp_object_get_name (proc), prefix, required); g_free (prefix); } g_free (basename); return FALSE; }
void gimp_plug_in_procedure_set_file_proc (GimpPlugInProcedure *proc, const gchar *extensions, const gchar *prefixes, const gchar *magics) { GSList *list; g_return_if_fail (GIMP_IS_PLUG_IN_PROCEDURE (proc)); proc->file_proc = TRUE; /* extensions */ if (proc->extensions != extensions) { if (proc->extensions) g_free (proc->extensions); proc->extensions = g_strdup (extensions); } if (proc->extensions_list) g_slist_free_full (proc->extensions_list, (GDestroyNotify) g_free); proc->extensions_list = extensions_parse (proc->extensions); /* prefixes */ if (proc->prefixes != prefixes) { if (proc->prefixes) g_free (proc->prefixes); proc->prefixes = g_strdup (prefixes); } if (proc->prefixes_list) g_slist_free_full (proc->prefixes_list, (GDestroyNotify) g_free); proc->prefixes_list = extensions_parse (proc->prefixes); /* don't allow "file:" to be registered as prefix */ for (list = proc->prefixes_list; list; list = g_slist_next (list)) { const gchar *prefix = list->data; if (prefix && strcmp (prefix, "file:") == 0) { g_free (list->data); proc->prefixes_list = g_slist_delete_link (proc->prefixes_list, list); break; } } /* magics */ if (proc->magics != magics) { if (proc->magics) g_free (proc->magics); proc->magics = g_strdup (magics); } if (proc->magics_list) g_slist_free_full (proc->magics_list, (GDestroyNotify) g_free); proc->magics_list = extensions_parse (proc->magics); }