diff options
Diffstat (limited to '')
-rw-r--r-- | app/core/gimppdbprogress.c | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/app/core/gimppdbprogress.c b/app/core/gimppdbprogress.c new file mode 100644 index 0000000..85147e8 --- /dev/null +++ b/app/core/gimppdbprogress.c @@ -0,0 +1,408 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimppdbprogress.c + * Copyright (C) 2004 Michael Natterer <mitch@gimp.org> + * + * 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 <string.h> + +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gegl.h> + +#include "libgimpbase/gimpbase.h" + +#include "core-types.h" + +#include "core/gimpcontext.h" + +#include "pdb/gimppdb.h" + +#include "gimp.h" +#include "gimpparamspecs.h" +#include "gimppdbprogress.h" +#include "gimpprogress.h" + +#include "gimp-intl.h" + + +enum +{ + PROP_0, + PROP_PDB, + PROP_CONTEXT, + PROP_CALLBACK_NAME +}; + + +static void gimp_pdb_progress_class_init (GimpPdbProgressClass *klass); +static void gimp_pdb_progress_init (GimpPdbProgress *progress, + GimpPdbProgressClass *klass); +static void gimp_pdb_progress_progress_iface_init (GimpProgressInterface *iface); + +static void gimp_pdb_progress_constructed (GObject *object); +static void gimp_pdb_progress_dispose (GObject *object); +static void gimp_pdb_progress_finalize (GObject *object); +static void gimp_pdb_progress_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); + +static GimpProgress * gimp_pdb_progress_progress_start (GimpProgress *progress, + gboolean cancellable, + const gchar *message); +static void gimp_pdb_progress_progress_end (GimpProgress *progress); +static gboolean gimp_pdb_progress_progress_is_active (GimpProgress *progress); +static void gimp_pdb_progress_progress_set_text (GimpProgress *progress, + const gchar *message); +static void gimp_pdb_progress_progress_set_value (GimpProgress *progress, + gdouble percentage); +static gdouble gimp_pdb_progress_progress_get_value (GimpProgress *progress); +static void gimp_pdb_progress_progress_pulse (GimpProgress *progress); +static guint32 gimp_pdb_progress_progress_get_window_id (GimpProgress *progress); + + +static GObjectClass *parent_class = NULL; + + +GType +gimp_pdb_progress_get_type (void) +{ + static GType type = 0; + + if (! type) + { + const GTypeInfo info = + { + sizeof (GimpPdbProgressClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gimp_pdb_progress_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GimpPdbProgress), + 0, /* n_preallocs */ + (GInstanceInitFunc) gimp_pdb_progress_init, + }; + + const GInterfaceInfo progress_iface_info = + { + (GInterfaceInitFunc) gimp_pdb_progress_progress_iface_init, + NULL, /* iface_finalize */ + NULL /* iface_data */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, + "GimpPdbProgress", + &info, 0); + + g_type_add_interface_static (type, GIMP_TYPE_PROGRESS, + &progress_iface_info); + } + + return type; +} + +static void +gimp_pdb_progress_class_init (GimpPdbProgressClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->constructed = gimp_pdb_progress_constructed; + object_class->dispose = gimp_pdb_progress_dispose; + object_class->finalize = gimp_pdb_progress_finalize; + object_class->set_property = gimp_pdb_progress_set_property; + + g_object_class_install_property (object_class, PROP_PDB, + g_param_spec_object ("pdb", NULL, NULL, + GIMP_TYPE_PDB, + GIMP_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_CONTEXT, + g_param_spec_object ("context", NULL, NULL, + GIMP_TYPE_CONTEXT, + GIMP_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_CALLBACK_NAME, + g_param_spec_string ("callback-name", + NULL, NULL, + NULL, + GIMP_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +gimp_pdb_progress_init (GimpPdbProgress *progress, + GimpPdbProgressClass *klass) +{ + klass->progresses = g_list_prepend (klass->progresses, progress); +} + +static void +gimp_pdb_progress_progress_iface_init (GimpProgressInterface *iface) +{ + iface->start = gimp_pdb_progress_progress_start; + iface->end = gimp_pdb_progress_progress_end; + iface->is_active = gimp_pdb_progress_progress_is_active; + iface->set_text = gimp_pdb_progress_progress_set_text; + iface->set_value = gimp_pdb_progress_progress_set_value; + iface->get_value = gimp_pdb_progress_progress_get_value; + iface->pulse = gimp_pdb_progress_progress_pulse; + iface->get_window_id = gimp_pdb_progress_progress_get_window_id; +} + +static void +gimp_pdb_progress_constructed (GObject *object) +{ + GimpPdbProgress *progress = GIMP_PDB_PROGRESS (object); + + G_OBJECT_CLASS (parent_class)->constructed (object); + + gimp_assert (GIMP_IS_PDB (progress->pdb)); + gimp_assert (GIMP_IS_CONTEXT (progress->context)); +} + +static void +gimp_pdb_progress_dispose (GObject *object) +{ + GimpPdbProgressClass *klass = GIMP_PDB_PROGRESS_GET_CLASS (object); + + klass->progresses = g_list_remove (klass->progresses, object); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gimp_pdb_progress_finalize (GObject *object) +{ + GimpPdbProgress *progress = GIMP_PDB_PROGRESS (object); + + g_clear_object (&progress->pdb); + g_clear_object (&progress->context); + g_clear_pointer (&progress->callback_name, g_free); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gimp_pdb_progress_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpPdbProgress *progress = GIMP_PDB_PROGRESS (object); + + switch (property_id) + { + case PROP_PDB: + if (progress->pdb) + g_object_unref (progress->pdb); + progress->pdb = g_value_dup_object (value); + break; + + case PROP_CONTEXT: + if (progress->context) + g_object_unref (progress->context); + progress->context = g_value_dup_object (value); + break; + + case PROP_CALLBACK_NAME: + if (progress->callback_name) + g_free (progress->callback_name); + progress->callback_name = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static gdouble +gimp_pdb_progress_run_callback (GimpPdbProgress *progress, + GimpProgressCommand command, + const gchar *text, + gdouble value) +{ + gdouble retval = 0; + + if (progress->callback_name && ! progress->callback_busy) + { + GimpValueArray *return_vals; + + progress->callback_busy = TRUE; + + return_vals = + gimp_pdb_execute_procedure_by_name (progress->pdb, + progress->context, + NULL, NULL, + progress->callback_name, + GIMP_TYPE_INT32, command, + G_TYPE_STRING, text, + G_TYPE_DOUBLE, value, + G_TYPE_NONE); + + if (g_value_get_enum (gimp_value_array_index (return_vals, 0)) != + GIMP_PDB_SUCCESS) + { + gimp_message (progress->context->gimp, NULL, GIMP_MESSAGE_ERROR, + _("Unable to run %s callback. " + "The corresponding plug-in may have crashed."), + g_type_name (G_TYPE_FROM_INSTANCE (progress))); + } + else if (gimp_value_array_length (return_vals) >= 2 && + G_VALUE_HOLDS_DOUBLE (gimp_value_array_index (return_vals, 1))) + { + retval = g_value_get_double (gimp_value_array_index (return_vals, 1)); + } + + gimp_value_array_unref (return_vals); + + progress->callback_busy = FALSE; + } + + return retval; +} + +static GimpProgress * +gimp_pdb_progress_progress_start (GimpProgress *progress, + gboolean cancellable, + const gchar *message) +{ + GimpPdbProgress *pdb_progress = GIMP_PDB_PROGRESS (progress); + + if (! pdb_progress->active) + { + gimp_pdb_progress_run_callback (pdb_progress, + GIMP_PROGRESS_COMMAND_START, + message, 0.0); + + pdb_progress->active = TRUE; + pdb_progress->value = 0.0; + + return progress; + } + + return NULL; +} + +static void +gimp_pdb_progress_progress_end (GimpProgress *progress) +{ + GimpPdbProgress *pdb_progress = GIMP_PDB_PROGRESS (progress); + + if (pdb_progress->active) + { + gimp_pdb_progress_run_callback (pdb_progress, + GIMP_PROGRESS_COMMAND_END, + NULL, 0.0); + + pdb_progress->active = FALSE; + pdb_progress->value = 0.0; + } +} + +static gboolean +gimp_pdb_progress_progress_is_active (GimpProgress *progress) +{ + GimpPdbProgress *pdb_progress = GIMP_PDB_PROGRESS (progress); + + return pdb_progress->active; +} + +static void +gimp_pdb_progress_progress_set_text (GimpProgress *progress, + const gchar *message) +{ + GimpPdbProgress *pdb_progress = GIMP_PDB_PROGRESS (progress); + + if (pdb_progress->active) + gimp_pdb_progress_run_callback (pdb_progress, + GIMP_PROGRESS_COMMAND_SET_TEXT, + message, 0.0); +} + +static void +gimp_pdb_progress_progress_set_value (GimpProgress *progress, + gdouble percentage) +{ + GimpPdbProgress *pdb_progress = GIMP_PDB_PROGRESS (progress); + + if (pdb_progress->active) + { + gimp_pdb_progress_run_callback (pdb_progress, + GIMP_PROGRESS_COMMAND_SET_VALUE, + NULL, percentage); + pdb_progress->value = percentage; + } +} + +static gdouble +gimp_pdb_progress_progress_get_value (GimpProgress *progress) +{ + GimpPdbProgress *pdb_progress = GIMP_PDB_PROGRESS (progress); + + return pdb_progress->value; + +} + +static void +gimp_pdb_progress_progress_pulse (GimpProgress *progress) +{ + GimpPdbProgress *pdb_progress = GIMP_PDB_PROGRESS (progress); + + if (pdb_progress->active) + gimp_pdb_progress_run_callback (pdb_progress, + GIMP_PROGRESS_COMMAND_PULSE, + NULL, 0.0); +} + +static guint32 +gimp_pdb_progress_progress_get_window_id (GimpProgress *progress) +{ + GimpPdbProgress *pdb_progress = GIMP_PDB_PROGRESS (progress); + + return (guint32) + gimp_pdb_progress_run_callback (pdb_progress, + GIMP_PROGRESS_COMMAND_GET_WINDOW, + NULL, 0.0); +} + +GimpPdbProgress * +gimp_pdb_progress_get_by_callback (GimpPdbProgressClass *klass, + const gchar *callback_name) +{ + GList *list; + + g_return_val_if_fail (GIMP_IS_PDB_PROGRESS_CLASS (klass), NULL); + g_return_val_if_fail (callback_name != NULL, NULL); + + for (list = klass->progresses; list; list = g_list_next (list)) + { + GimpPdbProgress *progress = list->data; + + if (! g_strcmp0 (callback_name, progress->callback_name)) + return progress; + } + + return NULL; +} |