gimpplugin-progress.c 10.2 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4
 * gimpplugin-progress.c
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9 10 11 12 13 14 15 16
 * (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
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 19 20 21 22 23 24 25 26
 */

#include "config.h"

#include <glib-object.h>

#include "plug-in-types.h"

#include "core/gimp.h"
27
#include "core/gimpparamspecs.h"
28 29 30
#include "core/gimppdbprogress.h"
#include "core/gimpprogress.h"

31
#include "pdb/gimppdb.h"
32
#include "pdb/gimppdberror.h"
33

34 35 36
#include "gimpplugin.h"
#include "gimpplugin-progress.h"
#include "gimppluginmanager.h"
37
#include "gimptemporaryprocedure.h"
38

39 40
#include "gimp-intl.h"

41 42 43

/*  local function prototypes  */

44 45
static void   gimp_plug_in_progress_cancel_callback (GimpProgress *progress,
                                                     GimpPlugIn   *plug_in);
46 47 48 49


/*  public functions  */

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
gint
gimp_plug_in_progress_attach (GimpProgress *progress)
{
  gint attach_count;

  g_return_val_if_fail (GIMP_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
gimp_plug_in_progress_detach (GimpProgress *progress)
{
  gint attach_count;

  g_return_val_if_fail (GIMP_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;
}

88
void
89 90 91
gimp_plug_in_progress_start (GimpPlugIn  *plug_in,
                             const gchar *message,
                             GimpObject  *display)
92
{
93
  GimpPlugInProcFrame *proc_frame;
94

95
  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
96
  g_return_if_fail (display == NULL || GIMP_IS_OBJECT (display));
97

98
  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
99 100 101

  if (! proc_frame->progress)
    {
102 103
      proc_frame->progress = gimp_new_progress (plug_in->manager->gimp,
                                                display);
104 105 106 107 108 109

      if (proc_frame->progress)
        {
          proc_frame->progress_created = TRUE;

          g_object_ref (proc_frame->progress);
110 111

          gimp_plug_in_progress_attach (proc_frame->progress);
112 113 114 115 116 117
        }
    }

  if (proc_frame->progress)
    {
      if (! proc_frame->progress_cancel_id)
118 119 120 121 122 123 124 125 126
        {
          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 (gimp_plug_in_progress_cancel_callback),
                              plug_in);
        }
127 128 129

      if (gimp_progress_is_active (proc_frame->progress))
        {
130 131 132 133 134
          if (message)
            gimp_progress_set_text (proc_frame->progress, message);

          if (gimp_progress_get_value (proc_frame->progress) > 0.0)
            gimp_progress_set_value (proc_frame->progress, 0.0);
135 136 137
        }
      else
        {
138 139 140 141 142 143 144 145
          gimp_progress_start (proc_frame->progress,
                               message ? message : "",
                               TRUE);
        }
    }
}

void
146 147
gimp_plug_in_progress_end (GimpPlugIn          *plug_in,
                           GimpPlugInProcFrame *proc_frame)
148
{
149
  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
150
  g_return_if_fail (proc_frame != NULL);
151 152 153 154 155 156 157 158

  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;
159 160 161

          g_object_remove_weak_pointer (G_OBJECT (proc_frame->progress),
                                        (gpointer) &proc_frame->progress);
162 163
        }

164 165
      if (gimp_plug_in_progress_detach (proc_frame->progress) < 1 &&
          gimp_progress_is_active (proc_frame->progress))
166 167 168
        {
          gimp_progress_end (proc_frame->progress);
        }
169 170 171

      if (proc_frame->progress_created)
        {
172
          gimp_free_progress (plug_in->manager->gimp, proc_frame->progress);
173 174
          g_object_unref (proc_frame->progress);
          proc_frame->progress = NULL;
175 176 177 178 179
        }
    }
}

void
180 181
gimp_plug_in_progress_set_text (GimpPlugIn  *plug_in,
                                const gchar *message)
182
{
183
  GimpPlugInProcFrame *proc_frame;
184

185
  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
186

187
  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
188 189 190 191 192 193

  if (proc_frame->progress)
    gimp_progress_set_text (proc_frame->progress, message);
}

void
194 195
gimp_plug_in_progress_set_value (GimpPlugIn *plug_in,
                                 gdouble     percentage)
196
{
197
  GimpPlugInProcFrame *proc_frame;
198

199
  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
200

201
  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
202 203 204 205 206

  if (! proc_frame->progress                           ||
      ! gimp_progress_is_active (proc_frame->progress) ||
      ! proc_frame->progress_cancel_id)
    {
207
      gimp_plug_in_progress_start (plug_in, NULL, NULL);
208 209 210 211 212 213 214
    }

  if (proc_frame->progress && gimp_progress_is_active (proc_frame->progress))
    gimp_progress_set_value (proc_frame->progress, percentage);
}

void
215
gimp_plug_in_progress_pulse (GimpPlugIn *plug_in)
216
{
217
  GimpPlugInProcFrame *proc_frame;
218

219
  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
220

221
  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
222

223 224 225
  if (! proc_frame->progress                           ||
      ! gimp_progress_is_active (proc_frame->progress) ||
      ! proc_frame->progress_cancel_id)
226
    {
227
      gimp_plug_in_progress_start (plug_in, NULL, NULL);
228
    }
229

230 231 232
  if (proc_frame->progress && gimp_progress_is_active (proc_frame->progress))
    gimp_progress_pulse (proc_frame->progress);
}
233

234
guint32
235
gimp_plug_in_progress_get_window_id (GimpPlugIn *plug_in)
236
{
237
  GimpPlugInProcFrame *proc_frame;
238

239
  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), 0);
240

241
  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
242 243

  if (proc_frame->progress)
244
    return gimp_progress_get_window_id (proc_frame->progress);
245 246

  return 0;
247 248 249
}

gboolean
250 251
gimp_plug_in_progress_install (GimpPlugIn  *plug_in,
                               const gchar *progress_callback)
252
{
253 254
  GimpPlugInProcFrame *proc_frame;
  GimpProcedure       *procedure;
255

256
  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
257 258
  g_return_val_if_fail (progress_callback != NULL, FALSE);

259 260
  procedure = gimp_pdb_lookup_procedure (plug_in->manager->gimp->pdb,
                                         progress_callback);
261

262 263 264 265 266 267
  if (! GIMP_IS_TEMPORARY_PROCEDURE (procedure)                ||
      GIMP_TEMPORARY_PROCEDURE (procedure)->plug_in != plug_in ||
      procedure->num_args                           != 3       ||
      ! GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0])          ||
      ! G_IS_PARAM_SPEC_STRING   (procedure->args[1])          ||
      ! G_IS_PARAM_SPEC_DOUBLE   (procedure->args[2]))
268 269 270 271
    {
      return FALSE;
    }

272
  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
273 274 275

  if (proc_frame->progress)
    {
276
      gimp_plug_in_progress_end (plug_in, proc_frame);
277 278 279 280 281 282 283 284 285

      if (proc_frame->progress)
        {
          g_object_unref (proc_frame->progress);
          proc_frame->progress = NULL;
        }
    }

  proc_frame->progress = g_object_new (GIMP_TYPE_PDB_PROGRESS,
286
                                       "pdb",           plug_in->manager->gimp->pdb,
287 288 289 290
                                       "context",       proc_frame->main_context,
                                       "callback-name", progress_callback,
                                       NULL);

291 292
  gimp_plug_in_progress_attach (proc_frame->progress);

293 294 295 296
  return TRUE;
}

gboolean
297 298
gimp_plug_in_progress_uninstall (GimpPlugIn  *plug_in,
                                 const gchar *progress_callback)
299
{
300
  GimpPlugInProcFrame *proc_frame;
301

302
  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
303 304
  g_return_val_if_fail (progress_callback != NULL, FALSE);

305
  proc_frame = gimp_plug_in_get_proc_frame (plug_in);
306 307 308

  if (GIMP_IS_PDB_PROGRESS (proc_frame->progress))
    {
309
      gimp_plug_in_progress_end (plug_in, proc_frame);
310 311 312 313 314 315 316 317 318 319
      g_object_unref (proc_frame->progress);
      proc_frame->progress = NULL;

      return TRUE;
    }

  return FALSE;
}

gboolean
320 321
gimp_plug_in_progress_cancel (GimpPlugIn  *plug_in,
                              const gchar *progress_callback)
322
{
323
  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
324 325 326 327 328 329 330 331
  g_return_val_if_fail (progress_callback != NULL, FALSE);

  return FALSE;
}


/*  private functions  */

332 333 334 335 336 337
static GValueArray *
get_cancel_return_values (GimpProcedure *procedure)
{
  GValueArray *return_vals;
  GError      *error;

338
  error = g_error_new_literal (GIMP_PDB_ERROR, GIMP_PDB_ERROR_CANCELLED,
339 340 341 342 343 344 345
                               _("Cancelled"));
  return_vals = gimp_procedure_get_return_values (procedure, FALSE, error);
  g_error_free (error);

  return return_vals;
}

346
static void
347 348
gimp_plug_in_progress_cancel_callback (GimpProgress *progress,
                                       GimpPlugIn   *plug_in)
349
{
350 351
  GimpPlugInProcFrame *proc_frame = &plug_in->main_proc_frame;
  GList               *list;
352 353 354

  if (proc_frame->main_loop)
    {
355 356
      proc_frame->return_vals =
        get_cancel_return_values (proc_frame->procedure);
357 358 359 360 361 362 363 364
    }

  for (list = plug_in->temp_proc_frames; list; list = g_list_next (list))
    {
      proc_frame = list->data;

      if (proc_frame->main_loop)
        {
365 366
          proc_frame->return_vals =
            get_cancel_return_values (proc_frame->procedure);
367 368 369
        }
    }

370
  gimp_plug_in_close (plug_in, TRUE);
371
}