2004-08-30 02:36:30 +08:00
|
|
|
/* LIBGIMP - The GIMP Library
|
|
|
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
|
|
|
*
|
|
|
|
* gimpprogress.c
|
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This library is free software: you can redistribute it and/or
|
2004-08-30 02:36:30 +08:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
2009-01-18 06:28:01 +08:00
|
|
|
* version 3 of the License, or (at your option) any later version.
|
2004-08-30 02:36:30 +08:00
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2009-01-18 06:28:01 +08:00
|
|
|
* License along with this library. If not, see
|
2018-07-12 05:27:07 +08:00
|
|
|
* <https://www.gnu.org/licenses/>.
|
2004-08-30 02:36:30 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2013-10-15 07:58:39 +08:00
|
|
|
#include <gio/gio.h>
|
2005-09-10 02:07:31 +08:00
|
|
|
|
2012-05-03 06:54:21 +08:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
|
|
|
|
2005-09-10 02:07:31 +08:00
|
|
|
#include "gimpprogress.h"
|
|
|
|
|
2004-08-30 02:36:30 +08:00
|
|
|
#include "gimp.h"
|
|
|
|
|
|
|
|
|
2007-05-22 22:04:35 +08:00
|
|
|
typedef struct
|
2004-08-30 02:36:30 +08:00
|
|
|
{
|
2005-09-10 02:07:31 +08:00
|
|
|
gchar *progress_callback;
|
|
|
|
GimpProgressVtable vtable;
|
|
|
|
gpointer data;
|
2007-05-22 22:04:35 +08:00
|
|
|
} GimpProgressData;
|
2004-08-30 02:36:30 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* local function prototypes */
|
|
|
|
|
2007-05-22 22:04:35 +08:00
|
|
|
static void gimp_progress_data_free (GimpProgressData *data);
|
|
|
|
|
|
|
|
static void gimp_temp_progress_run (const gchar *name,
|
|
|
|
gint nparams,
|
|
|
|
const GimpParam *param,
|
|
|
|
gint *nreturn_vals,
|
|
|
|
GimpParam **return_vals);
|
2004-08-30 02:36:30 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* private variables */
|
|
|
|
|
2007-05-04 18:19:50 +08:00
|
|
|
static GHashTable * gimp_progress_ht = NULL;
|
|
|
|
static gdouble gimp_progress_current = 0.0;
|
|
|
|
static const gdouble gimp_progress_step = (1.0 / 256.0);
|
2004-08-30 02:36:30 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* public functions */
|
|
|
|
|
2005-09-10 02:07:31 +08:00
|
|
|
/**
|
|
|
|
* gimp_progress_install_vtable:
|
|
|
|
* @vtable: a pointer to a @GimpProgressVtable.
|
|
|
|
* @user_data: a pointer that is passed as user_data to all vtable functions.
|
|
|
|
*
|
|
|
|
* Return value: the name of the temporary procedure that's been installed
|
|
|
|
*
|
2015-06-01 03:18:09 +08:00
|
|
|
* Since: 2.4
|
2005-09-10 02:07:31 +08:00
|
|
|
**/
|
|
|
|
const gchar *
|
|
|
|
gimp_progress_install_vtable (const GimpProgressVtable *vtable,
|
|
|
|
gpointer user_data)
|
2004-08-30 02:36:30 +08:00
|
|
|
{
|
|
|
|
static const GimpParamDef args[] =
|
|
|
|
{
|
|
|
|
{ GIMP_PDB_INT32, "command", "" },
|
|
|
|
{ GIMP_PDB_STRING, "text", "" },
|
|
|
|
{ GIMP_PDB_FLOAT, "value", "" }
|
|
|
|
};
|
|
|
|
|
2005-09-10 02:07:31 +08:00
|
|
|
static const GimpParamDef values[] =
|
|
|
|
{
|
|
|
|
{ GIMP_PDB_FLOAT, "value", "" }
|
|
|
|
};
|
|
|
|
|
2004-08-30 02:36:30 +08:00
|
|
|
gchar *progress_callback;
|
|
|
|
|
2005-09-10 02:07:31 +08:00
|
|
|
g_return_val_if_fail (vtable != NULL, NULL);
|
|
|
|
g_return_val_if_fail (vtable->start != NULL, NULL);
|
|
|
|
g_return_val_if_fail (vtable->end != NULL, NULL);
|
|
|
|
g_return_val_if_fail (vtable->set_text != NULL, NULL);
|
|
|
|
g_return_val_if_fail (vtable->set_value != NULL, NULL);
|
2004-08-30 02:36:30 +08:00
|
|
|
|
|
|
|
progress_callback = gimp_procedural_db_temp_name ();
|
|
|
|
|
|
|
|
gimp_install_temp_proc (progress_callback,
|
2006-04-12 18:53:28 +08:00
|
|
|
"Temporary progress callback procedure",
|
|
|
|
"",
|
2007-01-03 22:34:50 +08:00
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
2006-04-12 18:53:28 +08:00
|
|
|
NULL,
|
2007-01-03 22:34:50 +08:00
|
|
|
"",
|
2006-04-12 18:53:28 +08:00
|
|
|
GIMP_TEMPORARY,
|
|
|
|
G_N_ELEMENTS (args), G_N_ELEMENTS (values),
|
|
|
|
args, values,
|
|
|
|
gimp_temp_progress_run);
|
2004-08-30 02:36:30 +08:00
|
|
|
|
|
|
|
if (_gimp_progress_install (progress_callback))
|
|
|
|
{
|
|
|
|
GimpProgressData *progress_data;
|
|
|
|
|
|
|
|
gimp_extension_enable (); /* Allow callbacks to be watched */
|
|
|
|
|
|
|
|
/* Now add to hash table so we can find it again */
|
|
|
|
if (! gimp_progress_ht)
|
2007-05-22 22:04:35 +08:00
|
|
|
{
|
|
|
|
gimp_progress_ht =
|
|
|
|
g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
|
|
g_free,
|
|
|
|
(GDestroyNotify) gimp_progress_data_free);
|
|
|
|
}
|
2004-08-30 02:36:30 +08:00
|
|
|
|
2007-05-22 22:04:35 +08:00
|
|
|
progress_data = g_slice_new0 (GimpProgressData);
|
2004-08-30 02:36:30 +08:00
|
|
|
|
|
|
|
progress_data->progress_callback = progress_callback;
|
2005-09-10 02:07:31 +08:00
|
|
|
progress_data->vtable.start = vtable->start;
|
|
|
|
progress_data->vtable.end = vtable->end;
|
|
|
|
progress_data->vtable.set_text = vtable->set_text;
|
|
|
|
progress_data->vtable.set_value = vtable->set_value;
|
|
|
|
progress_data->vtable.pulse = vtable->pulse;
|
|
|
|
progress_data->vtable.get_window = vtable->get_window;
|
2004-08-30 02:36:30 +08:00
|
|
|
progress_data->data = user_data;
|
|
|
|
|
|
|
|
g_hash_table_insert (gimp_progress_ht, progress_callback, progress_data);
|
|
|
|
|
|
|
|
return progress_callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_uninstall_temp_proc (progress_callback);
|
|
|
|
g_free (progress_callback);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-08-31 03:19:02 +08:00
|
|
|
/**
|
|
|
|
* gimp_progress_uninstall:
|
|
|
|
* @progress_callback: the name of the temporary procedure to uninstall
|
|
|
|
*
|
|
|
|
* Uninstalls a temporary progress procedure that was installed using
|
|
|
|
* gimp_progress_install().
|
|
|
|
*
|
|
|
|
* Return value: the @user_data that was passed to gimp_progress_install().
|
|
|
|
*
|
2015-06-01 03:18:09 +08:00
|
|
|
* Since: 2.2
|
2004-08-31 03:19:02 +08:00
|
|
|
**/
|
2004-08-31 02:36:43 +08:00
|
|
|
gpointer
|
2004-08-30 02:36:30 +08:00
|
|
|
gimp_progress_uninstall (const gchar *progress_callback)
|
|
|
|
{
|
|
|
|
GimpProgressData *progress_data;
|
2004-08-31 02:36:43 +08:00
|
|
|
gpointer user_data;
|
2004-08-30 02:36:30 +08:00
|
|
|
|
2004-08-31 02:36:43 +08:00
|
|
|
g_return_val_if_fail (progress_callback != NULL, NULL);
|
|
|
|
g_return_val_if_fail (gimp_progress_ht != NULL, NULL);
|
2004-08-30 02:36:30 +08:00
|
|
|
|
|
|
|
progress_data = g_hash_table_lookup (gimp_progress_ht, progress_callback);
|
|
|
|
|
|
|
|
if (! progress_data)
|
|
|
|
{
|
|
|
|
g_warning ("Can't find internal progress data");
|
2004-08-31 02:36:43 +08:00
|
|
|
return NULL;
|
2004-08-30 02:36:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_gimp_progress_uninstall (progress_callback);
|
|
|
|
gimp_uninstall_temp_proc (progress_callback);
|
|
|
|
|
2004-08-31 02:36:43 +08:00
|
|
|
user_data = progress_data->data;
|
|
|
|
|
2004-08-30 02:36:30 +08:00
|
|
|
g_hash_table_remove (gimp_progress_ht, progress_callback);
|
2004-08-31 02:36:43 +08:00
|
|
|
|
|
|
|
return user_data;
|
2004-08-30 02:36:30 +08:00
|
|
|
}
|
|
|
|
|
2006-02-20 15:35:42 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_progress_init:
|
|
|
|
* @message: Message to use in the progress dialog.
|
|
|
|
*
|
|
|
|
* Initializes the progress bar for the current plug-in.
|
|
|
|
*
|
|
|
|
* Initializes the progress bar for the current plug-in. It is only
|
|
|
|
* valid to call this procedure from a plug-in.
|
|
|
|
*
|
|
|
|
* Returns: TRUE on success.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gimp_progress_init (const gchar *message)
|
|
|
|
{
|
|
|
|
gimp_progress_current = 0.0;
|
|
|
|
|
2006-03-27 02:15:58 +08:00
|
|
|
return _gimp_progress_init (message, gimp_default_display ());
|
2006-02-20 15:35:42 +08:00
|
|
|
}
|
|
|
|
|
2005-02-13 08:11:24 +08:00
|
|
|
/**
|
2005-09-30 02:34:08 +08:00
|
|
|
* gimp_progress_init_printf:
|
|
|
|
* @format: a standard printf() format string
|
2011-11-26 04:39:55 +08:00
|
|
|
* @...: arguments for @format
|
2005-09-30 02:34:08 +08:00
|
|
|
*
|
|
|
|
* Initializes the progress bar for the current plug-in.
|
|
|
|
*
|
|
|
|
* Initializes the progress bar for the current plug-in. It is only
|
|
|
|
* valid to call this procedure from a plug-in.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE on success.
|
|
|
|
*
|
2015-06-01 03:18:09 +08:00
|
|
|
* Since: 2.4
|
2005-09-30 02:34:08 +08:00
|
|
|
**/
|
|
|
|
gboolean
|
|
|
|
gimp_progress_init_printf (const gchar *format,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
gchar *text;
|
|
|
|
gboolean retval;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
g_return_val_if_fail (format != NULL, FALSE);
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
text = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
retval = gimp_progress_init (text);
|
|
|
|
|
|
|
|
g_free (text);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gimp_progress_set_text_printf:
|
2005-02-13 08:11:24 +08:00
|
|
|
* @format: a standard printf() format string
|
2011-11-26 04:39:55 +08:00
|
|
|
* @...: arguments for @format
|
2005-02-13 08:11:24 +08:00
|
|
|
*
|
|
|
|
* Changes the text in the progress bar for the current plug-in.
|
|
|
|
*
|
2012-11-11 22:50:25 +08:00
|
|
|
* This function changes the text in the progress bar for the current
|
|
|
|
* plug-in. Unlike gimp_progress_init() it does not change the
|
2005-02-13 08:11:24 +08:00
|
|
|
* displayed value.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE on success.
|
|
|
|
*
|
2015-06-01 03:18:09 +08:00
|
|
|
* Since: 2.4
|
2005-02-13 08:11:24 +08:00
|
|
|
**/
|
2005-02-13 09:43:07 +08:00
|
|
|
gboolean
|
2005-09-30 02:34:08 +08:00
|
|
|
gimp_progress_set_text_printf (const gchar *format,
|
|
|
|
...)
|
2005-02-13 08:11:24 +08:00
|
|
|
{
|
|
|
|
gchar *text;
|
|
|
|
gboolean retval;
|
|
|
|
va_list args;
|
|
|
|
|
2005-02-13 21:28:48 +08:00
|
|
|
g_return_val_if_fail (format != NULL, FALSE);
|
2005-02-13 08:11:24 +08:00
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
text = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
2005-09-30 02:34:08 +08:00
|
|
|
retval = gimp_progress_set_text (text);
|
2005-02-13 08:11:24 +08:00
|
|
|
|
|
|
|
g_free (text);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2006-02-20 15:35:42 +08:00
|
|
|
/**
|
|
|
|
* gimp_progress_update:
|
|
|
|
* @percentage: Percentage of progress completed (in the range from 0.0 to 1.0).
|
|
|
|
*
|
|
|
|
* Updates the progress bar for the current plug-in.
|
|
|
|
*
|
|
|
|
* Returns: TRUE on success.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gimp_progress_update (gdouble percentage)
|
|
|
|
{
|
|
|
|
gboolean changed;
|
|
|
|
|
|
|
|
if (percentage <= 0.0)
|
|
|
|
{
|
|
|
|
changed = (gimp_progress_current != 0.0);
|
|
|
|
percentage = 0.0;
|
|
|
|
}
|
|
|
|
else if (percentage >= 1.0)
|
|
|
|
{
|
|
|
|
changed = (gimp_progress_current != 1.0);
|
|
|
|
percentage = 1.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
changed =
|
|
|
|
(fabs (gimp_progress_current - percentage) > gimp_progress_step);
|
2007-05-04 18:19:50 +08:00
|
|
|
|
|
|
|
#ifdef GIMP_UNSTABLE
|
|
|
|
if (! changed)
|
|
|
|
{
|
|
|
|
static gboolean warned = FALSE;
|
2007-05-04 18:31:53 +08:00
|
|
|
static gint count = 0;
|
2007-05-04 18:19:50 +08:00
|
|
|
|
2007-05-04 18:31:53 +08:00
|
|
|
count++;
|
|
|
|
|
|
|
|
if (count > 3 && ! warned)
|
2007-05-04 18:19:50 +08:00
|
|
|
{
|
|
|
|
g_printerr ("%s is updating the progress too often\n",
|
|
|
|
g_get_prgname ());
|
|
|
|
warned = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2006-02-20 15:35:42 +08:00
|
|
|
}
|
|
|
|
|
2007-05-04 18:19:50 +08:00
|
|
|
/* Suppress the update if the change was only marginal. */
|
2006-02-20 15:35:42 +08:00
|
|
|
if (! changed)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
gimp_progress_current = percentage;
|
|
|
|
|
|
|
|
return _gimp_progress_update (gimp_progress_current);
|
|
|
|
}
|
|
|
|
|
2004-08-30 02:36:30 +08:00
|
|
|
|
|
|
|
/* private functions */
|
|
|
|
|
2007-05-22 22:04:35 +08:00
|
|
|
static void
|
|
|
|
gimp_progress_data_free (GimpProgressData *data)
|
|
|
|
{
|
|
|
|
g_slice_free (GimpProgressData, data);
|
|
|
|
}
|
|
|
|
|
2004-08-30 02:36:30 +08:00
|
|
|
static void
|
|
|
|
gimp_temp_progress_run (const gchar *name,
|
|
|
|
gint nparams,
|
|
|
|
const GimpParam *param,
|
|
|
|
gint *nreturn_vals,
|
|
|
|
GimpParam **return_vals)
|
|
|
|
{
|
2005-09-10 02:07:31 +08:00
|
|
|
static GimpParam values[2];
|
2004-08-30 02:36:30 +08:00
|
|
|
GimpProgressData *progress_data;
|
|
|
|
|
2005-09-10 02:07:31 +08:00
|
|
|
*nreturn_vals = 1;
|
|
|
|
*return_vals = values;
|
|
|
|
|
|
|
|
values[0].type = GIMP_PDB_STATUS;
|
|
|
|
values[0].data.d_status = GIMP_PDB_SUCCESS;
|
|
|
|
|
2004-08-30 02:36:30 +08:00
|
|
|
progress_data = g_hash_table_lookup (gimp_progress_ht, name);
|
|
|
|
|
|
|
|
if (! progress_data)
|
|
|
|
{
|
|
|
|
g_warning ("Can't find internal progress data");
|
2005-09-10 02:07:31 +08:00
|
|
|
|
|
|
|
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
2004-08-30 02:36:30 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-30 22:57:24 +08:00
|
|
|
GimpProgressCommand command = param[0].data.d_int32;
|
2004-08-30 02:36:30 +08:00
|
|
|
|
2004-08-30 22:57:24 +08:00
|
|
|
switch (command)
|
2004-08-30 02:36:30 +08:00
|
|
|
{
|
2004-08-30 22:57:24 +08:00
|
|
|
case GIMP_PROGRESS_COMMAND_START:
|
2005-09-10 02:07:31 +08:00
|
|
|
progress_data->vtable.start (param[1].data.d_string,
|
|
|
|
param[2].data.d_float != 0.0,
|
|
|
|
progress_data->data);
|
2004-08-30 02:36:30 +08:00
|
|
|
break;
|
|
|
|
|
2004-08-30 22:57:24 +08:00
|
|
|
case GIMP_PROGRESS_COMMAND_END:
|
2005-09-10 02:07:31 +08:00
|
|
|
progress_data->vtable.end (progress_data->data);
|
2004-08-30 02:36:30 +08:00
|
|
|
break;
|
|
|
|
|
2004-08-30 22:57:24 +08:00
|
|
|
case GIMP_PROGRESS_COMMAND_SET_TEXT:
|
2005-09-10 02:07:31 +08:00
|
|
|
progress_data->vtable.set_text (param[1].data.d_string,
|
|
|
|
progress_data->data);
|
2004-08-30 02:36:30 +08:00
|
|
|
break;
|
|
|
|
|
2004-08-30 22:57:24 +08:00
|
|
|
case GIMP_PROGRESS_COMMAND_SET_VALUE:
|
2005-09-10 02:07:31 +08:00
|
|
|
progress_data->vtable.set_value (param[2].data.d_float,
|
|
|
|
progress_data->data);
|
2004-08-30 02:36:30 +08:00
|
|
|
break;
|
|
|
|
|
2005-02-12 23:46:31 +08:00
|
|
|
case GIMP_PROGRESS_COMMAND_PULSE:
|
2005-09-10 02:07:31 +08:00
|
|
|
if (progress_data->vtable.pulse)
|
|
|
|
progress_data->vtable.pulse (progress_data->data);
|
|
|
|
else
|
|
|
|
progress_data->vtable.set_value (-1, progress_data->data);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_PROGRESS_COMMAND_GET_WINDOW:
|
|
|
|
*nreturn_vals = 2;
|
|
|
|
values[1].type = GIMP_PDB_FLOAT;
|
|
|
|
|
|
|
|
if (progress_data->vtable.get_window)
|
|
|
|
values[1].data.d_float =
|
|
|
|
(gdouble) progress_data->vtable.get_window (progress_data->data);
|
|
|
|
else
|
|
|
|
values[1].data.d_float = 0;
|
2005-02-12 23:46:31 +08:00
|
|
|
break;
|
|
|
|
|
2004-08-30 02:36:30 +08:00
|
|
|
default:
|
2005-09-10 02:07:31 +08:00
|
|
|
values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
|
2004-08-30 02:36:30 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|