/* 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-progress.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 . */ #include "config.h" #include #include #include "libpikabase/pikabase.h" #include "plug-in-types.h" #include "core/pika.h" #include "core/pikadisplay.h" #include "core/pikaparamspecs.h" #include "core/pikapdbprogress.h" #include "core/pikaprogress.h" #include "pdb/pikapdb.h" #include "pdb/pikapdberror.h" #include "pikaplugin.h" #include "pikaplugin-progress.h" #include "pikapluginmanager.h" #include "pikatemporaryprocedure.h" #include "pika-intl.h" /* local function prototypes */ static void pika_plug_in_progress_cancel_callback (PikaProgress *progress, PikaPlugIn *plug_in); /* public functions */ gint pika_plug_in_progress_attach (PikaProgress *progress) { gint attach_count; g_return_val_if_fail (PIKA_IS_PROGRESS (progress), 0); attach_count = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (progress), "plug-in-progress-attach-count")); attach_count++; g_object_set_data (G_OBJECT (progress), "plug-in-progress-attach-count", GINT_TO_POINTER (attach_count)); return attach_count; } gint pika_plug_in_progress_detach (PikaProgress *progress) { gint attach_count; g_return_val_if_fail (PIKA_IS_PROGRESS (progress), 0); attach_count = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (progress), "plug-in-progress-attach-count")); attach_count--; g_object_set_data (G_OBJECT (progress), "plug-in-progress-attach-count", GINT_TO_POINTER (attach_count)); return attach_count; } void pika_plug_in_progress_start (PikaPlugIn *plug_in, const gchar *message, PikaDisplay *display) { PikaPlugInProcFrame *proc_frame; g_return_if_fail (PIKA_IS_PLUG_IN (plug_in)); g_return_if_fail (display == NULL || PIKA_IS_DISPLAY (display)); proc_frame = pika_plug_in_get_proc_frame (plug_in); if (! proc_frame->progress) { proc_frame->progress = pika_new_progress (plug_in->manager->pika, display); if (proc_frame->progress) { proc_frame->progress_created = TRUE; g_object_ref (proc_frame->progress); pika_plug_in_progress_attach (proc_frame->progress); } } if (proc_frame->progress) { if (! proc_frame->progress_cancel_id) { g_object_add_weak_pointer (G_OBJECT (proc_frame->progress), (gpointer) &proc_frame->progress); proc_frame->progress_cancel_id = g_signal_connect (proc_frame->progress, "cancel", G_CALLBACK (pika_plug_in_progress_cancel_callback), plug_in); } if (pika_progress_is_active (proc_frame->progress)) { if (message) pika_progress_set_text_literal (proc_frame->progress, message); if (pika_progress_get_value (proc_frame->progress) > 0.0) pika_progress_set_value (proc_frame->progress, 0.0); } else { pika_progress_start (proc_frame->progress, TRUE, "%s", message ? message : ""); } } } void pika_plug_in_progress_end (PikaPlugIn *plug_in, PikaPlugInProcFrame *proc_frame) { g_return_if_fail (PIKA_IS_PLUG_IN (plug_in)); g_return_if_fail (proc_frame != NULL); if (proc_frame->progress) { if (proc_frame->progress_cancel_id) { g_signal_handler_disconnect (proc_frame->progress, proc_frame->progress_cancel_id); proc_frame->progress_cancel_id = 0; g_object_remove_weak_pointer (G_OBJECT (proc_frame->progress), (gpointer) &proc_frame->progress); } if (pika_plug_in_progress_detach (proc_frame->progress) < 1 && pika_progress_is_active (proc_frame->progress)) { pika_progress_end (proc_frame->progress); } if (proc_frame->progress_created) { pika_free_progress (plug_in->manager->pika, proc_frame->progress); g_clear_object (&proc_frame->progress); } } } void pika_plug_in_progress_set_text (PikaPlugIn *plug_in, const gchar *message) { PikaPlugInProcFrame *proc_frame; g_return_if_fail (PIKA_IS_PLUG_IN (plug_in)); proc_frame = pika_plug_in_get_proc_frame (plug_in); if (proc_frame->progress) pika_progress_set_text_literal (proc_frame->progress, message); } void pika_plug_in_progress_set_value (PikaPlugIn *plug_in, gdouble percentage) { PikaPlugInProcFrame *proc_frame; g_return_if_fail (PIKA_IS_PLUG_IN (plug_in)); proc_frame = pika_plug_in_get_proc_frame (plug_in); if (! proc_frame->progress || ! pika_progress_is_active (proc_frame->progress) || ! proc_frame->progress_cancel_id) { pika_plug_in_progress_start (plug_in, NULL, NULL); } if (proc_frame->progress && pika_progress_is_active (proc_frame->progress)) pika_progress_set_value (proc_frame->progress, percentage); } void pika_plug_in_progress_pulse (PikaPlugIn *plug_in) { PikaPlugInProcFrame *proc_frame; g_return_if_fail (PIKA_IS_PLUG_IN (plug_in)); proc_frame = pika_plug_in_get_proc_frame (plug_in); if (! proc_frame->progress || ! pika_progress_is_active (proc_frame->progress) || ! proc_frame->progress_cancel_id) { pika_plug_in_progress_start (plug_in, NULL, NULL); } if (proc_frame->progress && pika_progress_is_active (proc_frame->progress)) pika_progress_pulse (proc_frame->progress); } GBytes * pika_plug_in_progress_get_window_id (PikaPlugIn *plug_in) { PikaPlugInProcFrame *proc_frame; g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), 0); proc_frame = pika_plug_in_get_proc_frame (plug_in); if (proc_frame->progress) return pika_progress_get_window_id (proc_frame->progress); return 0; } gboolean pika_plug_in_progress_install (PikaPlugIn *plug_in, const gchar *progress_callback) { PikaPlugInProcFrame *proc_frame; PikaProcedure *procedure; g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE); g_return_val_if_fail (progress_callback != NULL, FALSE); procedure = pika_pdb_lookup_procedure (plug_in->manager->pika->pdb, progress_callback); if (! PIKA_IS_TEMPORARY_PROCEDURE (procedure) || PIKA_TEMPORARY_PROCEDURE (procedure)->plug_in != plug_in || procedure->num_args != 3 || ! G_IS_PARAM_SPEC_INT (procedure->args[0]) || ! G_IS_PARAM_SPEC_STRING (procedure->args[1]) || ! G_IS_PARAM_SPEC_DOUBLE (procedure->args[2])) { return FALSE; } proc_frame = pika_plug_in_get_proc_frame (plug_in); if (proc_frame->progress) { pika_plug_in_progress_end (plug_in, proc_frame); g_clear_object (&proc_frame->progress); } proc_frame->progress = g_object_new (PIKA_TYPE_PDB_PROGRESS, "pdb", plug_in->manager->pika->pdb, "context", proc_frame->main_context, "callback-name", progress_callback, NULL); pika_plug_in_progress_attach (proc_frame->progress); return TRUE; } gboolean pika_plug_in_progress_uninstall (PikaPlugIn *plug_in, const gchar *progress_callback) { PikaPlugInProcFrame *proc_frame; g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE); g_return_val_if_fail (progress_callback != NULL, FALSE); proc_frame = pika_plug_in_get_proc_frame (plug_in); if (PIKA_IS_PDB_PROGRESS (proc_frame->progress)) { pika_plug_in_progress_end (plug_in, proc_frame); g_clear_object (&proc_frame->progress); return TRUE; } return FALSE; } gboolean pika_plug_in_progress_cancel (PikaPlugIn *plug_in, const gchar *progress_callback) { g_return_val_if_fail (PIKA_IS_PLUG_IN (plug_in), FALSE); g_return_val_if_fail (progress_callback != NULL, FALSE); return FALSE; } /* private functions */ static PikaValueArray * get_cancel_return_values (PikaProcedure *procedure) { PikaValueArray *return_vals; GError *error; error = g_error_new_literal (PIKA_PDB_ERROR, PIKA_PDB_ERROR_CANCELLED, _("Cancelled")); return_vals = pika_procedure_get_return_values (procedure, FALSE, error); g_error_free (error); return return_vals; } static void pika_plug_in_progress_cancel_callback (PikaProgress *progress, PikaPlugIn *plug_in) { PikaPlugInProcFrame *proc_frame = &plug_in->main_proc_frame; GList *list; if (proc_frame->main_loop) { proc_frame->return_vals = get_cancel_return_values (proc_frame->procedure); } for (list = plug_in->temp_proc_frames; list; list = g_list_next (list)) { proc_frame = list->data; if (proc_frame->main_loop) { proc_frame->return_vals = get_cancel_return_values (proc_frame->procedure); } } pika_plug_in_close (plug_in, TRUE); }