gboolean
gimp_plug_in_manager_register_save_handler (GimpPlugInManager *manager,
                                            const gchar       *name,
                                            const gchar       *extensions,
                                            const gchar       *prefixes)
{
  GimpPlugInProcedure *file_proc;
  GimpProcedure       *procedure;
  GSList              *list;

  g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
  g_return_val_if_fail (name != NULL, FALSE);

  if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
    list = manager->current_plug_in->plug_in_def->procedures;
  else
    list = manager->plug_in_procedures;

  file_proc = gimp_plug_in_procedure_find (list, name);

  if (! file_proc)
    {
      gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR,
                    "attempt to register nonexistent save handler \"%s\"",
                    name);
      return FALSE;
    }

  procedure = GIMP_PROCEDURE (file_proc);

  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]))
    {
      gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR,
                    "save handler \"%s\" does not take the standard "
                    "save handler args", name);
      return FALSE;
    }

  gimp_plug_in_procedure_set_file_proc (file_proc,
                                        extensions, prefixes, NULL);

  if (file_procedure_in_group (file_proc, FILE_PROCEDURE_GROUP_SAVE))
    {
      if (! g_slist_find (manager->save_procs, file_proc))
        manager->save_procs = g_slist_prepend (manager->save_procs, file_proc);
    }

  if (file_procedure_in_group (file_proc, FILE_PROCEDURE_GROUP_EXPORT))
    {
      if (! g_slist_find (manager->export_procs, file_proc))
        manager->export_procs = g_slist_prepend (manager->export_procs, file_proc);
    }

  return TRUE;
}
gboolean
gimp_plug_in_manager_register_load_handler (GimpPlugInManager *manager,
                                            const gchar       *name,
                                            const gchar       *extensions,
                                            const gchar       *prefixes,
                                            const gchar       *magics)
{
  GimpPlugInProcedure *file_proc;
  GimpProcedure       *procedure;
  GSList              *list;

  g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), FALSE);
  g_return_val_if_fail (name != NULL, FALSE);

  if (manager->current_plug_in && manager->current_plug_in->plug_in_def)
    list = manager->current_plug_in->plug_in_def->procedures;
  else
    list = manager->plug_in_procedures;

  file_proc = gimp_plug_in_procedure_find (list, name);

  if (! file_proc)
    {
      gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR,
                    "attempt to register nonexistent load handler \"%s\"",
                    name);
      return FALSE;
    }

  procedure = GIMP_PROCEDURE (file_proc);

  if ((procedure->num_args   < 3)                        ||
      (procedure->num_values < 1)                        ||
      ! GIMP_IS_PARAM_SPEC_INT32    (procedure->args[0]) ||
      ! G_IS_PARAM_SPEC_STRING      (procedure->args[1]) ||
      ! G_IS_PARAM_SPEC_STRING      (procedure->args[2]) ||
      ! GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->values[0]))
    {
      gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR,
                    "load handler \"%s\" does not take the standard "
                    "load handler args", name);
      return FALSE;
    }

  gimp_plug_in_procedure_set_file_proc (file_proc,
                                        extensions, prefixes, magics);

  if (! g_slist_find (manager->load_procs, file_proc))
    manager->load_procs = g_slist_prepend (manager->load_procs, file_proc);

  return TRUE;
}
Exemple #3
0
static void
rec_make_absolute_pathnames (SfiRec       *rec,
                             const gchar  *path_prefix,
                             SfiRecFields  fields)
{
  guint i;
  for (i = 0; i < fields.n_fields; i++)
    {
      GParamSpec *pspec = fields.fields[i];
      if (G_IS_PARAM_SPEC_STRING (pspec) &&
          g_param_spec_check_option (pspec, "filename"))
        {
          GValue *value = sfi_rec_get (rec, pspec->name);
          if (value && G_VALUE_HOLDS_STRING (value))
            {
              const gchar *str = g_value_get_string (value);
              if (str && strlen (str))
                sfi_value_take_string (value, sfi_path_get_filename (str, path_prefix));
            }
        }
      else if (SFI_IS_PSPEC_REC (pspec))
        {
          GValue *value = sfi_rec_get (rec, pspec->name);
          SfiRec *crec = value ? sfi_value_get_rec (value) : NULL;
          if (crec)
            rec_make_absolute_pathnames (crec, path_prefix, sfi_pspec_get_rec_fields (pspec));
        }
    }
}
Exemple #4
0
gboolean
stetic_param_spec_get_default (GParamSpec *pspec, GValue *value)
{
	g_value_init (value, pspec->value_type);

	if (G_IS_PARAM_SPEC_CHAR (pspec))
		g_value_set_char (value, G_PARAM_SPEC_CHAR (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_UCHAR (pspec))
		g_value_set_uchar (value, G_PARAM_SPEC_UCHAR (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_INT (pspec))
		g_value_set_int (value, G_PARAM_SPEC_INT (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_UINT (pspec))
		g_value_set_uint (value, G_PARAM_SPEC_UINT (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_LONG (pspec))
		g_value_set_long (value, G_PARAM_SPEC_LONG (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_ULONG (pspec))
		g_value_set_ulong (value, G_PARAM_SPEC_ULONG (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_INT64 (pspec))
		g_value_set_int64 (value, G_PARAM_SPEC_INT64 (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_UINT64 (pspec))
		g_value_set_uint64 (value, G_PARAM_SPEC_UINT64 (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_FLOAT (pspec))
		g_value_set_float (value, G_PARAM_SPEC_FLOAT (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
		g_value_set_double (value, G_PARAM_SPEC_DOUBLE (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
		g_value_set_boolean (value, G_PARAM_SPEC_BOOLEAN (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_UNICHAR (pspec))
		g_value_set_uint (value, G_PARAM_SPEC_UNICHAR (pspec)->default_value);
	else if (G_IS_PARAM_SPEC_STRING (pspec))
		g_value_set_static_string (value, G_PARAM_SPEC_STRING (pspec)->default_value);
	else
		return FALSE;
	return TRUE;
}
Exemple #5
0
static void
rec_make_relative_pathnames (SfiRec       *rec,
                             const gchar  *path_prefix,
                             SfiRecFields  fields)
{
  guint i, l = strlen (path_prefix);
  for (i = 0; i < fields.n_fields; i++)
    {
      GParamSpec *pspec = fields.fields[i];
      if (G_IS_PARAM_SPEC_STRING (pspec) &&
          g_param_spec_check_option (pspec, "filename"))
        {
          GValue *value = sfi_rec_get (rec, pspec->name);
          const gchar *str = value && G_VALUE_HOLDS_STRING (value) ? g_value_get_string (value) : NULL;
          if (str && strncmp (str, path_prefix, l) == 0)
            {
              const gchar *s = str + l;
              while (s[0] == G_DIR_SEPARATOR)
                s++;
              sfi_value_take_string (value, g_strdup (s));
            }
        }
      else if (SFI_IS_PSPEC_REC (pspec))
        {
          GValue *value = sfi_rec_get (rec, pspec->name);
          SfiRec *crec = value ? sfi_value_get_rec (value) : NULL;
          if (crec)
            rec_make_relative_pathnames (crec, path_prefix, sfi_pspec_get_rec_fields (pspec));
        }
    }
}
Exemple #6
0
static gpointer
qof_gobject_getter (gpointer data, QofParam *getter)
{
    GObject *gob = data;
    const char *str;

    GParamSpec *gps = getter->param_userdata;

    /* Note that the return type must actually be of type
     * getter->param_type but we just follow the hard-coded
     * mapping below ... */
    if (G_IS_PARAM_SPEC_STRING(gps))
    {
        GValue gval = {G_TYPE_INVALID};
        g_value_init (&gval, G_TYPE_STRING);
        g_object_get_property (gob, getter->param_name, &gval);

        str = g_value_get_string (&gval);
        return (gpointer) str;
    }
    else if (G_IS_PARAM_SPEC_INT(gps))
    {
        long ival;

        GValue gval = {G_TYPE_INVALID};
        g_value_init (&gval, G_TYPE_INT);
        g_object_get_property (gob, getter->param_name, &gval);

        ival = g_value_get_int (&gval);
        return (gpointer) ival;
    }
    else if (G_IS_PARAM_SPEC_UINT(gps))
    {
        long ival;
        GValue gval = {G_TYPE_INVALID};
        g_value_init (&gval, G_TYPE_UINT);
        g_object_get_property (gob, getter->param_name, &gval);

        ival = g_value_get_uint (&gval);
        return (gpointer) ival;
    }
    else if (G_IS_PARAM_SPEC_BOOLEAN(gps))
    {
        gboolean ival;

        GValue gval = {G_TYPE_INVALID};
        g_value_init (&gval, G_TYPE_BOOLEAN);
        g_object_get_property (gob, getter->param_name, &gval);

        ival = g_value_get_boolean (&gval);
        return GINT_TO_POINTER( ival);
    }

    PWARN ("unhandled parameter type %s for paramter %s",
           G_PARAM_SPEC_TYPE_NAME(gps), getter->param_name);
    return NULL;
}
Exemple #7
0
static GimpValueArray *
file_save_invoker (GimpProcedure         *procedure,
                   Gimp                  *gimp,
                   GimpContext           *context,
                   GimpProgress          *progress,
                   const GimpValueArray  *args,
                   GError               **error)
{
  GimpValueArray      *new_args;
  GimpValueArray      *return_vals;
  GimpPlugInProcedure *file_proc;
  GimpProcedure       *proc;
  gchar               *uri;
  gint                 i;

  uri = file_utils_filename_to_uri (gimp,
                                    g_value_get_string (gimp_value_array_index (args, 3)),
                                    error);

  if (! uri)
    return gimp_procedure_get_return_values (procedure, FALSE,
                                             error ? *error : NULL);

  file_proc =
    file_procedure_find (gimp->plug_in_manager->save_procs, uri, NULL);

  if (! file_proc)
    file_proc = file_procedure_find (gimp->plug_in_manager->export_procs, uri, error);

  g_free (uri);

  if (! file_proc)
    return gimp_procedure_get_return_values (procedure, FALSE,
                                             error ? *error : NULL);

  proc = GIMP_PROCEDURE (file_proc);

  new_args = gimp_procedure_get_arguments (proc);

  for (i = 0; i < 5; i++)
    g_value_transform (gimp_value_array_index (args, i),
                       gimp_value_array_index (new_args, i));

  for (i = 5; i < proc->num_args; i++)
    if (G_IS_PARAM_SPEC_STRING (proc->args[i]))
      g_value_set_static_string (gimp_value_array_index (new_args, i), "");

  return_vals =
    gimp_pdb_execute_procedure_by_name_args (gimp->pdb,
                                             context, progress, error,
                                             gimp_object_get_name (proc),
                                             new_args);

  gimp_value_array_unref (new_args);

  return return_vals;
}
gboolean
gimp_plug_in_progress_install (GimpPlugIn  *plug_in,
                               const gchar *progress_callback)
{
  GimpPlugInProcFrame *proc_frame;
  GimpProcedure       *procedure;

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

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

  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]))
    {
      return FALSE;
    }

  proc_frame = gimp_plug_in_get_proc_frame (plug_in);

  if (proc_frame->progress)
    {
      gimp_plug_in_progress_end (plug_in, proc_frame);

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

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

  gimp_plug_in_progress_attach (proc_frame->progress);

  return TRUE;
}
/* XXX Historical note, originally I tried (ab)using override properties
 *     in ESourceCamel, which redirected to the equivalent CamelSettings
 *     property.  Seemed to work at first, and I was proud of my clever
 *     hack, but it turns out g_object_class_list_properties() excludes
 *     override properties.  So the ESourceCamel properties were being
 *     skipped in source_load_from_key_file() (e-source.c). */
static GParamSpec *
param_spec_clone (GParamSpec *pspec)
{
	GParamSpec *clone;
	GParamFlags flags;
	const gchar *name, *nick, *blurb;

	name = g_param_spec_get_name (pspec);
	nick = g_param_spec_get_nick (pspec);
	blurb = g_param_spec_get_blurb (pspec);
	flags = (pspec->flags & ~(G_PARAM_STATIC_STRINGS));

	if (G_IS_PARAM_SPEC_BOOLEAN (pspec)) {
		GParamSpecBoolean *pspec_boolean = G_PARAM_SPEC_BOOLEAN (pspec);

		clone = g_param_spec_boolean (name, nick, blurb,
			pspec_boolean->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_CHAR (pspec)) {
		GParamSpecChar *pspec_char = G_PARAM_SPEC_CHAR (pspec);

		clone = g_param_spec_char (name, nick, blurb,
			pspec_char->minimum,
			pspec_char->maximum,
			pspec_char->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_UCHAR (pspec)) {
		GParamSpecUChar *pspec_uchar = G_PARAM_SPEC_UCHAR (pspec);

		clone = g_param_spec_uchar (name, nick, blurb,
			pspec_uchar->minimum,
			pspec_uchar->maximum,
			pspec_uchar->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_INT (pspec)) {
		GParamSpecInt *pspec_int = G_PARAM_SPEC_INT (pspec);

		clone = g_param_spec_int (name, nick, blurb,
			pspec_int->minimum,
			pspec_int->maximum,
			pspec_int->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_UINT (pspec)) {
		GParamSpecUInt *pspec_uint = G_PARAM_SPEC_UINT (pspec);

		clone = g_param_spec_uint (name, nick, blurb,
			pspec_uint->minimum,
			pspec_uint->maximum,
			pspec_uint->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_LONG (pspec)) {
		GParamSpecLong *pspec_long = G_PARAM_SPEC_LONG (pspec);

		clone = g_param_spec_long (name, nick, blurb,
			pspec_long->minimum,
			pspec_long->maximum,
			pspec_long->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_ULONG (pspec)) {
		GParamSpecULong *pspec_ulong = G_PARAM_SPEC_ULONG (pspec);

		clone = g_param_spec_ulong (name, nick, blurb,
			pspec_ulong->minimum,
			pspec_ulong->maximum,
			pspec_ulong->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_INT64 (pspec)) {
		GParamSpecInt64 *pspec_int64 = G_PARAM_SPEC_INT64 (pspec);

		clone = g_param_spec_int64 (name, nick, blurb,
			pspec_int64->minimum,
			pspec_int64->maximum,
			pspec_int64->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_UINT64 (pspec)) {
		GParamSpecUInt64 *pspec_uint64 = G_PARAM_SPEC_UINT64 (pspec);

		clone = g_param_spec_uint64 (name, nick, blurb,
			pspec_uint64->minimum,
			pspec_uint64->maximum,
			pspec_uint64->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_FLOAT (pspec)) {
		GParamSpecFloat *pspec_float = G_PARAM_SPEC_FLOAT (pspec);

		clone = g_param_spec_float (name, nick, blurb,
			pspec_float->minimum,
			pspec_float->maximum,
			pspec_float->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_DOUBLE (pspec)) {
		GParamSpecDouble *pspec_double = G_PARAM_SPEC_DOUBLE (pspec);

		clone = g_param_spec_double (name, nick, blurb,
			pspec_double->minimum,
			pspec_double->maximum,
			pspec_double->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_ENUM (pspec)) {
		GParamSpecEnum *pspec_enum = G_PARAM_SPEC_ENUM (pspec);

		clone = g_param_spec_enum (name, nick, blurb,
			pspec->value_type,
			pspec_enum->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_FLAGS (pspec)) {
		GParamSpecFlags *pspec_flags = G_PARAM_SPEC_FLAGS (pspec);

		clone = g_param_spec_flags (name, nick, blurb,
			pspec->value_type,
			pspec_flags->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_STRING (pspec)) {
		GParamSpecString *pspec_string = G_PARAM_SPEC_STRING (pspec);

		clone = g_param_spec_string (name, nick, blurb,
			pspec_string->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_PARAM (pspec)) {
		clone = g_param_spec_param (name, nick, blurb,
			pspec->value_type,
			flags);
	} else if (G_IS_PARAM_SPEC_BOXED (pspec)) {
		clone = g_param_spec_boxed (name, nick, blurb,
			pspec->value_type,
			flags);
	} else if (G_IS_PARAM_SPEC_POINTER (pspec)) {
		clone = g_param_spec_pointer (name, nick, blurb, flags);
	} else if (G_IS_PARAM_SPEC_OBJECT (pspec)) {
		clone = g_param_spec_object (name, nick, blurb,
			pspec->value_type,
			flags);
	} else if (G_IS_PARAM_SPEC_UNICHAR (pspec)) {
		GParamSpecUnichar *pspec_unichar = G_PARAM_SPEC_UNICHAR (pspec);

		clone = g_param_spec_unichar (name, nick, blurb,
			pspec_unichar->default_value,
			flags);
	} else if (G_IS_PARAM_SPEC_GTYPE (pspec)) {
		GParamSpecGType *pspec_gtype = G_PARAM_SPEC_GTYPE (pspec);

		clone = g_param_spec_gtype (name, nick, blurb,
			pspec_gtype->is_a_type,
			flags);
	} else if (G_IS_PARAM_SPEC_VARIANT (pspec)) {
		GParamSpecVariant *pspec_variant = G_PARAM_SPEC_VARIANT (pspec);

		clone = g_param_spec_variant (name, nick, blurb,
			pspec_variant->type,
			pspec_variant->default_value,
			flags);
	} else {
		g_warn_if_reached ();
	}

	return clone;
}
Exemple #10
0
GtkWidget *
gimp_prop_table_new (GObject              *config,
                     GType                 owner_type,
                     GimpContext          *context,
                     GimpCreatePickerFunc  create_picker_func,
                     gpointer              picker_creator)
{
  GtkWidget     *table;
  GtkSizeGroup  *size_group;
  GParamSpec   **param_specs;
  guint          n_param_specs;
  gint           i;
  gint           row = 0;
  GParamSpec    *last_pspec = NULL;
  GtkAdjustment *last_x_adj = NULL;
  gint           last_x_row = 0;

  g_return_val_if_fail (G_IS_OBJECT (config), NULL);
  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);

  param_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config),
                                                &n_param_specs);

  size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);

  table = gtk_table_new (3, 1, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  gtk_table_set_row_spacings (GTK_TABLE (table), 2);

  for (i = 0; i < n_param_specs; i++)
    {
      GParamSpec  *pspec  = param_specs[i];
      GtkWidget   *widget = NULL;
      const gchar *label  = NULL;

      /*  ignore properties of parent classes of owner_type  */
      if (! g_type_is_a (pspec->owner_type, owner_type))
        continue;

      if (G_IS_PARAM_SPEC_STRING (pspec))
        {
          static GQuark multiline_quark = 0;

          if (! multiline_quark)
            multiline_quark = g_quark_from_static_string ("multiline");

          if (GIMP_IS_PARAM_SPEC_CONFIG_PATH (pspec))
            {
              widget = gimp_prop_file_chooser_button_new (config,
                                                          pspec->name,
                                                          g_param_spec_get_nick (pspec),
                                                          GTK_FILE_CHOOSER_ACTION_OPEN);
            }
          else if (g_param_spec_get_qdata (pspec, multiline_quark))
            {
              GtkTextBuffer *buffer;
              GtkWidget     *view;

              buffer = gimp_prop_text_buffer_new (config, pspec->name, -1);
              view = gtk_text_view_new_with_buffer (buffer);

              widget = gtk_scrolled_window_new (NULL, NULL);
              gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget),
                                                   GTK_SHADOW_IN);
              gtk_container_add (GTK_CONTAINER (widget), view);
              gtk_widget_show (view);
            }
          else
            {
              widget = gimp_prop_entry_new (config, pspec->name, -1);
            }

          label  = g_param_spec_get_nick (pspec);
        }
      else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
        {
          widget = gimp_prop_check_button_new (config, pspec->name,
                                               g_param_spec_get_nick (pspec));
        }
      else if (G_IS_PARAM_SPEC_ENUM (pspec))
        {
          widget = gimp_prop_enum_combo_box_new (config, pspec->name, 0, 0);
          gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (widget),
                                        g_param_spec_get_nick (pspec));
        }
      else if (GEGL_IS_PARAM_SPEC_SEED (pspec))
        {
          GtkAdjustment *adj;
          GtkWidget     *scale;
          GtkWidget     *button;

          widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          scale = gimp_prop_spin_scale_new (config, pspec->name,
                                            g_param_spec_get_nick (pspec),
                                            1.0, 10.0, 0);
          gtk_box_pack_start (GTK_BOX (widget), scale, TRUE, TRUE, 0);
          gtk_widget_show (scale);

          button = gtk_button_new_with_label (_("New Seed"));
          gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
          gtk_widget_show (button);

          adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (scale));

          g_signal_connect (button, "clicked",
                            G_CALLBACK (gimp_prop_table_new_seed_clicked),
                            adj);
        }
      else if (G_IS_PARAM_SPEC_INT (pspec)   ||
               G_IS_PARAM_SPEC_UINT (pspec)  ||
               G_IS_PARAM_SPEC_FLOAT (pspec) ||
               G_IS_PARAM_SPEC_DOUBLE (pspec))
        {
          GtkAdjustment *adj;
          gdouble        value;
          gdouble        lower;
          gdouble        upper;
          gdouble        step   = 1.0;
          gdouble        page   = 10.0;
          gint           digits = (G_IS_PARAM_SPEC_FLOAT (pspec) ||
                                   G_IS_PARAM_SPEC_DOUBLE (pspec)) ? 2 : 0;

          if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
            {
              GeglParamSpecDouble *gspec = GEGL_PARAM_SPEC_DOUBLE (pspec);

              lower = gspec->ui_minimum;
              upper = gspec->ui_maximum;
            }
          else if (GEGL_IS_PARAM_SPEC_INT (pspec))
            {
              GeglParamSpecInt *gspec = GEGL_PARAM_SPEC_INT (pspec);

              lower = gspec->ui_minimum;
              upper = gspec->ui_maximum;
            }
          else
            {
              _gimp_prop_widgets_get_numeric_values (config, pspec,
                                                     &value, &lower, &upper,
                                                     G_STRFUNC);
            }

          if ((upper - lower < 10.0) &&
              (G_IS_PARAM_SPEC_FLOAT (pspec) ||
               G_IS_PARAM_SPEC_DOUBLE (pspec)))
            {
              step   = 0.1;
              page   = 1.0;
              digits = 3;
            }

          widget = gimp_prop_spin_scale_new (config, pspec->name,
                                             g_param_spec_get_nick (pspec),
                                             step, page, digits);

          adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget));

          if (g_str_has_suffix (pspec->name, "x") ||
              g_str_has_suffix (pspec->name, "width"))
            {
              last_pspec = pspec;
              last_x_adj = adj;
              last_x_row = row;
            }
          else if ((g_str_has_suffix (pspec->name, "y") ||
                    g_str_has_suffix (pspec->name, "height")) &&
                   last_pspec != NULL &&
                   last_x_adj != NULL &&
                   last_x_row == row - 1)
            {
              GtkWidget *chain = gimp_chain_button_new (GIMP_CHAIN_RIGHT);

              gtk_table_attach (GTK_TABLE (table), chain,
                                3, 4, last_x_row, row + 1,
                                GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
                                0, 0);
              gtk_widget_show (chain);

              if (gtk_adjustment_get_value (last_x_adj) ==
                  gtk_adjustment_get_value (adj))
                {
                  GBinding *binding;

                  gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (chain), TRUE);

                  binding = g_object_bind_property (last_x_adj, "value",
                                                    adj,        "value",
                                                    G_BINDING_BIDIRECTIONAL);

                  g_object_set_data (G_OBJECT (chain), "binding", binding);
                }

              g_signal_connect (chain, "toggled",
                                G_CALLBACK (gimp_prop_table_chain_toggled),
                                last_x_adj);

              g_object_set_data (G_OBJECT (last_x_adj), "y-adjustment", adj);

              if (create_picker_func)
                {
                  GtkWidget *button;
                  gchar     *pspec_name;

                  pspec_name = g_strconcat (last_pspec->name, ":",
                                            pspec->name, NULL);

                  button = create_picker_func (picker_creator,
                                               pspec_name,
                                               GIMP_STOCK_CURSOR,
                                               _("Pick coordinates from the image"));
                  gtk_table_attach (GTK_TABLE (table), button,
                                    4, 5, last_x_row, row + 1,
                                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL,
                                    0, 0);
                  gtk_widget_show (button);

                  g_object_weak_ref (G_OBJECT (button),
                                     (GWeakNotify) g_free, pspec_name);
                }
            }
        }
      else if (GIMP_IS_PARAM_SPEC_RGB (pspec))
        {
          GtkWidget *button;

          widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          button = gimp_prop_color_button_new (config, pspec->name,
                                               g_param_spec_get_nick (pspec),
                                               128, 24,
                                               GIMP_COLOR_AREA_SMALL_CHECKS);
          gimp_color_button_set_update (GIMP_COLOR_BUTTON (button), TRUE);
          gimp_color_panel_set_context (GIMP_COLOR_PANEL (button), context);
          gtk_box_pack_start (GTK_BOX (widget), button, TRUE, TRUE, 0);
          gtk_widget_show (button);

          if (create_picker_func)
            {
              button = create_picker_func (picker_creator,
                                           pspec->name,
                                           GIMP_STOCK_COLOR_PICKER_GRAY,
                                           _("Pick color from the image"));
              gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
              gtk_widget_show (button);
            }

          label = g_param_spec_get_nick (pspec);
        }
      else
        {
          g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
                     g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
        }

      if (widget)
        {
          if (label)
            {
              gimp_table_attach_aligned (GTK_TABLE (table), 0, row,
                                         label, 0.0, 0.5,
                                         widget, 2, FALSE);
            }
          else
            {
              gtk_table_attach_defaults (GTK_TABLE (table), widget,
                                         0, 3, row, row + 1);
              gtk_widget_show (widget);
            }

          row++;
        }
    }

  g_object_unref (size_group);

  g_free (param_specs);

  return table;
}
GtkWidget *
gimp_prop_widget_new_from_pspec (GObject               *config,
                                 GParamSpec            *pspec,
                                 GimpContext           *context,
                                 GimpCreatePickerFunc   create_picker_func,
                                 gpointer               picker_creator,
                                 const gchar          **label)
{
  GtkWidget *widget = NULL;

  g_return_val_if_fail (G_IS_OBJECT (config), NULL);
  g_return_val_if_fail (pspec != NULL, NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (label != NULL, NULL);

  *label = NULL;

  if (GEGL_IS_PARAM_SPEC_SEED (pspec))
    {
      GtkAdjustment *adj;
      GtkWidget     *spin;
      GtkWidget     *button;

      widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

      spin = gimp_prop_spin_button_new (config, pspec->name,
                                        1.0, 10.0, 0);
      gtk_box_pack_start (GTK_BOX (widget), spin, TRUE, TRUE, 0);
      gtk_widget_show (spin);

      button = gtk_button_new_with_label (_("New Seed"));
      gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
      gtk_widget_show (button);

      adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));

      g_signal_connect (button, "clicked",
                        G_CALLBACK (gimp_prop_widget_new_seed_clicked),
                        adj);

      *label = g_param_spec_get_nick (pspec);
    }
  else if (G_IS_PARAM_SPEC_INT (pspec)   ||
           G_IS_PARAM_SPEC_UINT (pspec)  ||
           G_IS_PARAM_SPEC_FLOAT (pspec) ||
           G_IS_PARAM_SPEC_DOUBLE (pspec))
    {
      gdouble lower;
      gdouble upper;
      gdouble step;
      gdouble page;
      gint    digits;

      if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
        {
          GeglParamSpecDouble *gspec = GEGL_PARAM_SPEC_DOUBLE (pspec);

          lower  = gspec->ui_minimum;
          upper  = gspec->ui_maximum;
          step   = gspec->ui_step_small;
          page   = gspec->ui_step_big;
          digits = gspec->ui_digits;
        }
      else if (GEGL_IS_PARAM_SPEC_INT (pspec))
        {
          GeglParamSpecInt *gspec = GEGL_PARAM_SPEC_INT (pspec);

          lower  = gspec->ui_minimum;
          upper  = gspec->ui_maximum;
          step   = gspec->ui_step_small;
          page   = gspec->ui_step_big;
          digits = 0;
        }
      else
        {
          gdouble value;

          _gimp_prop_widgets_get_numeric_values (config, pspec,
                                                 &value, &lower, &upper,
                                                 G_STRFUNC);

          if ((upper - lower <= 1.0) &&
              (G_IS_PARAM_SPEC_FLOAT (pspec) ||
               G_IS_PARAM_SPEC_DOUBLE (pspec)))
            {
              step   = 0.01;
              page   = 0.1;
              digits = 4;
            }
          else if ((upper - lower <= 10.0) &&
                   (G_IS_PARAM_SPEC_FLOAT (pspec) ||
                    G_IS_PARAM_SPEC_DOUBLE (pspec)))
            {
              step   = 0.1;
              page   = 1.0;
              digits = 3;
            }
          else
            {
              step   = 1.0;
              page   = 10.0;
              digits = (G_IS_PARAM_SPEC_FLOAT (pspec) ||
                        G_IS_PARAM_SPEC_DOUBLE (pspec)) ? 2 : 0;
            }
        }

      widget = gimp_prop_spin_scale_new (config, pspec->name, NULL,
                                         step, page, digits);

      if (HAS_KEY (pspec, "unit", "degree") &&
          (upper - lower) == 360.0)
        {
          GtkWidget *hbox;
          GtkWidget *dial;

          gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), TRUE);

          hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
          gtk_widget_show (widget);

          dial = gimp_prop_angle_dial_new (config, pspec->name);
          gtk_box_pack_start (GTK_BOX (hbox), dial, FALSE, FALSE, 0);
          gtk_widget_show (dial);

          widget = hbox;
        }
      else if (HAS_KEY (pspec, "unit", "kelvin"))
        {
          GtkWidget *hbox;
          GtkWidget *button;

          hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
          gtk_widget_show (widget);

          button = gimp_prop_kelvin_presets_new (config, pspec->name);
          gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
          gtk_widget_show (button);

          widget = hbox;
        }
    }
  else if (G_IS_PARAM_SPEC_STRING (pspec))
    {
      static GQuark multiline_quark = 0;

      if (! multiline_quark)
        multiline_quark = g_quark_from_static_string ("multiline");

      if (GIMP_IS_PARAM_SPEC_CONFIG_PATH (pspec))
        {
          widget =
            gimp_prop_file_chooser_button_new (config, pspec->name,
                                               g_param_spec_get_nick (pspec),
                                               GTK_FILE_CHOOSER_ACTION_OPEN);
        }
      else if (g_param_spec_get_qdata (pspec, multiline_quark))
        {
          GtkTextBuffer *buffer;
          GtkWidget     *view;

          buffer = gimp_prop_text_buffer_new (config, pspec->name, -1);
          view = gtk_text_view_new_with_buffer (buffer);
          g_object_unref (buffer);

          widget = gtk_scrolled_window_new (NULL, NULL);
          gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget),
                                               GTK_SHADOW_IN);
          gtk_container_add (GTK_CONTAINER (widget), view);
          gtk_widget_show (view);
        }
      else
        {
          widget = gimp_prop_entry_new (config, pspec->name, -1);
        }

      *label = g_param_spec_get_nick (pspec);
    }
  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
    {
      widget = gimp_prop_check_button_new (config, pspec->name,
                                           g_param_spec_get_nick (pspec));
    }
  else if (G_IS_PARAM_SPEC_ENUM (pspec))
    {
      widget = gimp_prop_enum_combo_box_new (config, pspec->name, 0, 0);
      gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (widget),
                                    g_param_spec_get_nick (pspec));
    }
  else if (GIMP_IS_PARAM_SPEC_RGB (pspec))
    {
      GtkWidget *button;

      widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

      button = gimp_prop_color_button_new (config, pspec->name,
                                           g_param_spec_get_nick (pspec),
                                           128, 24,
                                           GIMP_COLOR_AREA_SMALL_CHECKS);
      gimp_color_button_set_update (GIMP_COLOR_BUTTON (button), TRUE);
      gimp_color_panel_set_context (GIMP_COLOR_PANEL (button), context);
      gtk_box_pack_start (GTK_BOX (widget), button, TRUE, TRUE, 0);
      gtk_widget_show (button);

      if (create_picker_func)
        {
          button = create_picker_func (picker_creator,
                                       pspec->name,
                                       GIMP_STOCK_COLOR_PICKER_GRAY,
                                       _("Pick color from the image"));
          gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
          gtk_widget_show (button);
        }

      *label = g_param_spec_get_nick (pspec);
    }
  else
    {
      g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
                 g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
    }

  return widget;
}
Exemple #12
0
static GimpValueArray *
file_load_invoker (GimpProcedure         *procedure,
                   Gimp                  *gimp,
                   GimpContext           *context,
                   GimpProgress          *progress,
                   const GimpValueArray  *args,
                   GError               **error)
{
  GimpValueArray      *new_args;
  GimpValueArray      *return_vals;
  GimpPlugInProcedure *file_proc;
  GimpProcedure       *proc;
  gchar               *uri;
  gint                 i;

  uri = file_utils_filename_to_uri (gimp,
                                    g_value_get_string (gimp_value_array_index (args, 1)),
                                    error);

  if (! uri)
    return gimp_procedure_get_return_values (procedure, FALSE,
                                             error ? *error : NULL);

  file_proc =
    file_procedure_find (gimp->plug_in_manager->load_procs, uri, error);

  g_free (uri);

  if (! file_proc)
    return gimp_procedure_get_return_values (procedure, FALSE,
                                             error ? *error : NULL);

  proc = GIMP_PROCEDURE (file_proc);

  new_args = gimp_procedure_get_arguments (proc);

  for (i = 0; i < 3; i++)
    g_value_transform (gimp_value_array_index (args, i),
                       gimp_value_array_index (new_args, i));

  for (i = 3; i < proc->num_args; i++)
    if (G_IS_PARAM_SPEC_STRING (proc->args[i]))
      g_value_set_static_string (gimp_value_array_index (new_args, i), "");

  return_vals =
    gimp_pdb_execute_procedure_by_name_args (gimp->pdb,
                                             context, progress, error,
                                             gimp_object_get_name (proc),
                                             new_args);

  gimp_value_array_unref (new_args);

  if (g_value_get_enum (gimp_value_array_index (return_vals, 0)) ==
      GIMP_PDB_SUCCESS)
    {
      if (gimp_value_array_length (return_vals) > 1 &&
          GIMP_VALUE_HOLDS_IMAGE_ID (gimp_value_array_index (return_vals, 1)))
        {
          GimpImage *image =
            gimp_value_get_image (gimp_value_array_index (return_vals, 1),
                                  gimp);
          gimp_image_set_load_proc (image, file_proc);
        }
    }

  return return_vals;
}
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;
}
Exemple #14
0
/* --- test functions --- */
static void
pspec_select_value (GParamSpec *pspec,
                    GValue     *value,
                    double      dvalue)
{
  /* generate a value suitable for pspec */
  if (G_IS_PARAM_SPEC_CHAR (pspec))
    ASSIGN_VALUE (g_value_set_char, value, GParamSpecChar*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_UCHAR (pspec))
    ASSIGN_VALUE (g_value_set_uchar, value, GParamSpecUChar*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_INT (pspec))
    ASSIGN_VALUE (g_value_set_int, value, GParamSpecInt*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_UINT (pspec))
    ASSIGN_VALUE (g_value_set_uint, value, GParamSpecUInt*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_LONG (pspec))
    ASSIGN_VALUE (g_value_set_long, value, GParamSpecLong*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_ULONG (pspec))
    ASSIGN_VALUE (g_value_set_ulong, value, GParamSpecULong*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_INT64 (pspec))
    ASSIGN_VALUE (g_value_set_int64, value, GParamSpecInt64*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_UINT64 (pspec))
    ASSIGN_VALUE (g_value_set_uint64, value, GParamSpecUInt64*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_FLOAT (pspec))
    ASSIGN_VALUE (g_value_set_float, value, GParamSpecFloat*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
    ASSIGN_VALUE (g_value_set_double, value, GParamSpecDouble*, pspec, default_value, minimum, maximum, dvalue);
  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
    g_value_set_boolean (value, SELECT_VALUE (dvalue, ((GParamSpecBoolean*) pspec)->default_value, FALSE, TRUE));
  else if (G_IS_PARAM_SPEC_UNICHAR (pspec))
    g_value_set_uint (value, SELECT_VALUE (dvalue, ((GParamSpecUnichar*) pspec)->default_value, FALSE, TRUE));
  else if (G_IS_PARAM_SPEC_GTYPE (pspec))
    g_value_set_gtype (value, SELECT_VALUE ((int) dvalue, ((GParamSpecGType*) pspec)->is_a_type, 0, GTK_TYPE_WIDGET));
  else if (G_IS_PARAM_SPEC_STRING (pspec))
    {
      GParamSpecString *sspec = (GParamSpecString*) pspec;
      if (dvalue >= +2)
        g_value_set_string (value, sspec->default_value);
      if (dvalue > 0 && sspec->cset_first && sspec->cset_nth)
        g_value_take_string (value, g_strdup_printf ("%c%c", sspec->cset_first[0], sspec->cset_nth[0]));
      else /* if (sspec->ensure_non_null) */
        g_value_set_string (value, "");
    }
  else if (G_IS_PARAM_SPEC_ENUM (pspec))
    {
      GParamSpecEnum *espec = (GParamSpecEnum*) pspec;
      if (dvalue >= +2)
        g_value_set_enum (value, espec->default_value);
      if (dvalue >= 0 && dvalue <= 1)
        g_value_set_enum (value, espec->enum_class->values[(int) ((espec->enum_class->n_values - 1) * dvalue)].value);
      else if (dvalue <= -1)
        g_value_set_enum (value, espec->enum_class->values[g_test_rand_int_range (0, espec->enum_class->n_values)].value);
    }
  else if (G_IS_PARAM_SPEC_FLAGS (pspec))
    {
      GParamSpecFlags *fspec = (GParamSpecFlags*) pspec;
      if (dvalue >= +2)
        g_value_set_flags (value, fspec->default_value);
      if (dvalue >= 0 && dvalue <= 1)
        g_value_set_flags (value, fspec->flags_class->values[(int) ((fspec->flags_class->n_values - 1) * dvalue)].value);
      else if (dvalue <= -1)
        g_value_set_flags (value, fspec->flags_class->values[g_test_rand_int_range (0, fspec->flags_class->n_values)].value);
    }
  /* unimplemented:
   * G_IS_PARAM_SPEC_PARAM
   * G_IS_PARAM_SPEC_BOXED
   * G_IS_PARAM_SPEC_POINTER
   * G_IS_PARAM_SPEC_VALUE_ARRAY
   * G_IS_PARAM_SPEC_OBJECT
   */
}
GParamSpec *
gimp_param_spec_duplicate (GParamSpec *pspec)
{
  GParamSpec  *copy = NULL;
  GParamFlags  flags;

  g_return_val_if_fail (pspec != NULL, NULL);

  flags = pspec->flags | GIMP_CONFIG_PARAM_SERIALIZE;

  if (G_IS_PARAM_SPEC_STRING (pspec))
    {
      GParamSpecString *spec = G_PARAM_SPEC_STRING (pspec);

      if (GEGL_IS_PARAM_SPEC_FILE_PATH (pspec))
        {
          copy = gimp_param_spec_config_path (pspec->name,
                                              g_param_spec_get_nick (pspec),
                                              g_param_spec_get_blurb (pspec),
                                              GIMP_CONFIG_PATH_FILE,
                                              spec->default_value,
                                              flags);
        }
      else
        {
          static GQuark multiline_quark = 0;

          if (! multiline_quark)
            multiline_quark = g_quark_from_static_string ("multiline");

          copy = g_param_spec_string (pspec->name,
                                      g_param_spec_get_nick (pspec),
                                      g_param_spec_get_blurb (pspec),
                                      spec->default_value,
                                      flags);

          if (GEGL_IS_PARAM_SPEC_MULTILINE (pspec))
            {
              g_param_spec_set_qdata (copy, multiline_quark,
                                      GINT_TO_POINTER (TRUE));
            }
        }
    }
  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
    {
      GParamSpecBoolean *spec = G_PARAM_SPEC_BOOLEAN (pspec);

      copy = g_param_spec_boolean (pspec->name,
                                   g_param_spec_get_nick (pspec),
                                   g_param_spec_get_blurb (pspec),
                                   spec->default_value,
                                   flags);
    }
  else if (G_IS_PARAM_SPEC_ENUM (pspec))
    {
      GParamSpecEnum *spec = G_PARAM_SPEC_ENUM (pspec);

      copy = g_param_spec_enum (pspec->name,
                                g_param_spec_get_nick (pspec),
                                g_param_spec_get_blurb (pspec),
                                G_TYPE_FROM_CLASS (spec->enum_class),
                                spec->default_value,
                                flags);
    }
  else if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
    {
      GeglParamSpecDouble *gspec = GEGL_PARAM_SPEC_DOUBLE (pspec);
      GParamSpecDouble    *spec = G_PARAM_SPEC_DOUBLE (pspec);

      copy = gegl_param_spec_double (pspec->name,
                                     g_param_spec_get_nick (pspec),
                                     g_param_spec_get_blurb (pspec),
                                     spec->minimum,
                                     spec->maximum,
                                     spec->default_value,
                                     gspec->ui_minimum,
                                     gspec->ui_maximum,
                                     gspec->ui_gamma,
                                     flags);
    }
  else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
    {
      GParamSpecDouble *spec = G_PARAM_SPEC_DOUBLE (pspec);

      copy = g_param_spec_double (pspec->name,
                                  g_param_spec_get_nick (pspec),
                                  g_param_spec_get_blurb (pspec),
                                  spec->minimum,
                                  spec->maximum,
                                  spec->default_value,
                                  flags);
    }
  else if (G_IS_PARAM_SPEC_FLOAT (pspec))
    {
      GParamSpecFloat *spec = G_PARAM_SPEC_FLOAT (pspec);

      copy = g_param_spec_float (pspec->name,
                                 g_param_spec_get_nick (pspec),
                                 g_param_spec_get_blurb (pspec),
                                 spec->minimum,
                                 spec->maximum,
                                 spec->default_value,
                                 flags);
    }
  else if (GEGL_IS_PARAM_SPEC_INT (pspec))
    {
      GeglParamSpecInt *gspec = GEGL_PARAM_SPEC_INT (pspec);
      GParamSpecInt    *spec  = G_PARAM_SPEC_INT (pspec);

      copy = gegl_param_spec_int (pspec->name,
                                  g_param_spec_get_nick (pspec),
                                  g_param_spec_get_blurb (pspec),
                                  spec->minimum,
                                  spec->maximum,
                                  spec->default_value,
                                  gspec->ui_minimum,
                                  gspec->ui_maximum,
                                  gspec->ui_gamma,
                                  flags);
    }
  else if (GEGL_IS_PARAM_SPEC_SEED (pspec))
    {
      copy = gegl_param_spec_seed (pspec->name,
                                   g_param_spec_get_nick (pspec),
                                   g_param_spec_get_blurb (pspec),
                                   pspec->flags |
                                   GIMP_CONFIG_PARAM_SERIALIZE);
    }
  else if (G_IS_PARAM_SPEC_INT (pspec))
    {
      GParamSpecInt *spec = G_PARAM_SPEC_INT (pspec);

      copy = g_param_spec_int (pspec->name,
                               g_param_spec_get_nick (pspec),
                               g_param_spec_get_blurb (pspec),
                               spec->minimum,
                               spec->maximum,
                               spec->default_value,
                               flags);
    }
  else if (G_IS_PARAM_SPEC_UINT (pspec))
    {
      GParamSpecUInt *spec = G_PARAM_SPEC_UINT (pspec);

      copy = g_param_spec_uint (pspec->name,
                                g_param_spec_get_nick (pspec),
                                g_param_spec_get_blurb (pspec),
                                spec->minimum,
                                spec->maximum,
                                spec->default_value,
                                flags);
    }
  else if (GIMP_IS_PARAM_SPEC_RGB (pspec))
    {
      GValue  value = G_VALUE_INIT;
      GimpRGB color;

      g_value_init (&value, GIMP_TYPE_RGB);
      g_param_value_set_default (pspec, &value);
      gimp_value_get_rgb (&value, &color);
      g_value_unset (&value);

      copy = gimp_param_spec_rgb (pspec->name,
                                  g_param_spec_get_nick (pspec),
                                  g_param_spec_get_blurb (pspec),
                                  gimp_param_spec_rgb_has_alpha (pspec),
                                  &color,
                                  flags);
    }
  else if (GEGL_IS_PARAM_SPEC_COLOR (pspec))
    {
      GeglColor *gegl_color;
      GimpRGB    gimp_color;
      gdouble    r = 0.0;
      gdouble    g = 0.0;
      gdouble    b = 0.0;
      gdouble    a = 1.0;
      GValue     value = { 0, };

      g_value_init (&value, GEGL_TYPE_COLOR);
      g_param_value_set_default (pspec, &value);

      gegl_color = g_value_get_object (&value);
      if (gegl_color)
        gegl_color_get_rgba (gegl_color, &r, &g, &b, &a);

      gimp_rgba_set (&gimp_color, r, g, b, a);

      g_value_unset (&value);

      copy = gimp_param_spec_rgb (pspec->name,
                                  g_param_spec_get_nick (pspec),
                                  g_param_spec_get_blurb (pspec),
                                  TRUE,
                                  &gimp_color,
                                  flags);
    }
  else if (G_IS_PARAM_SPEC_OBJECT (pspec) ||
           G_IS_PARAM_SPEC_POINTER (pspec))
    {
      /*  silently ignore object properties  */
    }
  else
    {
      g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
                 g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
    }

  if (copy)
    {
      GQuark      quark = g_quark_from_static_string ("gegl-property-keys");
      GHashTable *keys  = g_param_spec_get_qdata (pspec, quark);

      if (keys)
        g_param_spec_set_qdata (copy, quark, g_hash_table_ref (keys));
    }

  return copy;
}
static void
terminal_profile_gsettings_changeset_add (TerminalProfile *profile,
        GSettings *changeset,
        GParamSpec *pspec)
{
	TerminalProfilePrivate *priv = profile->priv;
	char *key;
	const GValue *value;

	/* FIXME: do this? */
#if 0
	if (priv->locked[pspec->param_id])
		return;

	if (!g_settings_is_writable (priv->settings, gsettings_key, NULL))
		return;
#endif

	key = g_param_spec_get_qdata (pspec, gsettings_key_quark);
	if (!key)
		return;

	value = g_value_array_get_nth (priv->properties, pspec->param_id);

	_terminal_debug_print (TERMINAL_DEBUG_PROFILE,
	                       "Adding pspec %s with value %s to the GSettings changeset\n",
	                       pspec->name, g_strdup_value_contents (value));

	if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
		g_settings_set_boolean (changeset, key, g_value_get_boolean (value));
	else if (G_IS_PARAM_SPEC_STRING (pspec))
	{
		const char *str;

		str = g_value_get_string (value);
		g_settings_set_string (changeset, key, str ? str : "");
	}
	else if (G_IS_PARAM_SPEC_ENUM (pspec))
	{
		const GEnumValue *eval;

		eval = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, g_value_get_enum (value));

		g_settings_set_enum (changeset, key, eval->value);
	}
	else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == GDK_TYPE_COLOR)
	{
		GdkColor *color;
		char str[16];

		color = g_value_get_boxed (value);
		if (!color)
			goto cleanup;

		g_snprintf (str, sizeof (str),
		            "#%04X%04X%04X",
		            color->red,
		            color->green,
		            color->blue);

		g_settings_set_string (changeset, key, str);
	}
	else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == PANGO_TYPE_FONT_DESCRIPTION)
	{
		PangoFontDescription *font_desc;
		char *font;

		font_desc = g_value_get_boxed (value);
		if (!font_desc)
			goto cleanup;

		font = pango_font_description_to_string (font_desc);
		g_settings_set_string (changeset, key, font);
		g_free (font);
	}
	else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
		g_settings_set_double (changeset, key, g_value_get_double (value));
	else if (G_IS_PARAM_SPEC_INT (pspec))
		g_settings_set_int (changeset, key, g_value_get_int (value));
	else if (G_IS_PARAM_SPEC_VALUE_ARRAY (pspec) &&
	         G_PARAM_SPEC_VALUE_TYPE (G_PARAM_SPEC_VALUE_ARRAY (pspec)->element_spec) == GDK_TYPE_COLOR)
	{
		GValueArray *array;
		GString *string;
		guint n_colors, i;

		/* We need to do this ourselves, because the gtk_color_selection_palette_to_string
		 * does not carry all the bytes, and xterm's palette is messed up...
		 */

		array = g_value_get_boxed (value);
		if (!array)
			goto cleanup;

		n_colors = array->n_values;
		string = g_string_sized_new (n_colors * (1 /* # */ + 3 * 4) + n_colors /* : separators and terminating \0 */);
		for (i = 0; i < n_colors; ++i)
		{
			GdkColor *color;

			if (i > 0)
				g_string_append_c (string, ':');

			color = g_value_get_boxed (g_value_array_get_nth (array, i));
			if (!color)
				continue;

			g_string_append_printf (string,
			                        "#%04X%04X%04X",
			                        color->red,
			                        color->green,
			                        color->blue);
		}

		g_settings_set_string (changeset, key, string->str);
		g_string_free (string, TRUE);
	}
	else
		g_printerr ("Unhandled value type %s of pspec %s\n", g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), pspec->name);

cleanup:
	return;
}
static void
terminal_profile_gsettings_notify_cb (GSettings *settings,
                                      gchar *key,
                                      gpointer     user_data)
{
	TerminalProfile *profile = TERMINAL_PROFILE (user_data);
	TerminalProfilePrivate *priv = profile->priv;
	TerminalProfileClass *klass;
	GVariant *settings_value;
	GParamSpec *pspec;
	GValue value = { 0, };
	gboolean equal;
	gboolean force_set = FALSE;

	if (!key) return;

	_terminal_debug_print (TERMINAL_DEBUG_PROFILE,
	                       "GSettings notification for key %s [%s]\n",
	                       key,
	                       g_settings_is_writable (settings, key) ? "writable" : "LOCKED");

	klass = TERMINAL_PROFILE_GET_CLASS (profile);
	pspec = g_hash_table_lookup (klass->gsettings_keys, key);
	if (!pspec)
		return; /* ignore unknown keys, for future extensibility */

	priv->locked[pspec->param_id] = !g_settings_is_writable (settings, key);

	settings_value = g_settings_get_value (settings, key);
	if (!settings_value)
		return;

	g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));

	if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_BOOLEAN))
			goto out;

		g_value_set_boolean (&value, g_variant_get_boolean (settings_value));
	}
	else if (G_IS_PARAM_SPEC_STRING (pspec))
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		g_value_set_string (&value, g_variant_get_string (settings_value, NULL));
	}
	else if (G_IS_PARAM_SPEC_ENUM (pspec))
	{

		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		g_value_set_enum (&value, g_settings_get_enum (settings, key));
	}
	else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == GDK_TYPE_COLOR)
	{
		GdkColor color;

		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		if (!gdk_color_parse (g_variant_get_string (settings_value, NULL), &color))
			goto out;

		g_value_set_boxed (&value, &color);
	}
	else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == PANGO_TYPE_FONT_DESCRIPTION)
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		g_value_take_boxed (&value, pango_font_description_from_string (g_variant_get_string (settings_value, NULL)));
	}
	else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_DOUBLE))
			goto out;

		g_value_set_double (&value, g_variant_get_double (settings_value));
	}
	else if (G_IS_PARAM_SPEC_INT (pspec))
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_INT16) &&
		    !g_variant_is_of_type (settings_value, G_VARIANT_TYPE_INT32) &&
		    !g_variant_is_of_type (settings_value, G_VARIANT_TYPE_INT64))
			goto out;

		g_value_set_int (&value, g_settings_get_int(settings, key));
	}
	else if (G_IS_PARAM_SPEC_VALUE_ARRAY (pspec) &&
	         G_PARAM_SPEC_VALUE_TYPE (G_PARAM_SPEC_VALUE_ARRAY (pspec)->element_spec) == GDK_TYPE_COLOR)
	{
		char **color_strings;
		GdkColor *colors;
		int n_colors, i;

		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		color_strings = g_strsplit (g_variant_get_string (settings_value, NULL), ":", -1);
		if (!color_strings)
			goto out;

		n_colors = g_strv_length (color_strings);
		colors = g_new0 (GdkColor, n_colors);
		for (i = 0; i < n_colors; ++i)
		{
			if (!gdk_color_parse (color_strings[i], &colors[i]))
				continue; /* ignore errors */
		}
		g_strfreev (color_strings);

		/* We continue even with a palette size != TERMINAL_PALETTE_SIZE,
		 * so we can change the palette size in future versions without
		 * causing too many issues.
		 */
		set_value_from_palette (&value, colors, n_colors);
		g_free (colors);
	}
	else
	{
		g_printerr ("Unhandled value type %s of pspec %s\n", g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), pspec->name);
		goto out;
	}

	if (g_param_value_validate (pspec, &value))
	{
		_terminal_debug_print (TERMINAL_DEBUG_PROFILE,
		                       "Invalid value in GSettings for key %s was changed to comply with pspec %s\n",
		                       key, pspec->name);

		force_set = TRUE;
	}

	/* Only set the property if the value is different than our current value,
	 * so we don't go into an infinite loop.
	 */
	equal = values_equal (pspec, &value, g_value_array_get_nth (priv->properties, pspec->param_id));
#ifdef MATE_ENABLE_DEBUG
	_TERMINAL_DEBUG_IF (TERMINAL_DEBUG_PROFILE)
	{
		if (!equal)
			_terminal_debug_print (TERMINAL_DEBUG_PROFILE,
			                       "Setting property %s to a different value\n"
			                       "  now: %s\n"
			                       "  new: %s\n",
			                       pspec->name,
			                       g_strdup_value_contents (g_value_array_get_nth (priv->properties, pspec->param_id)),
			                       g_strdup_value_contents (&value));
	}
#endif

	if (!equal || force_set)
	{
		priv->gsettings_notification_pspec = pspec;
		g_object_set_property (G_OBJECT (profile), pspec->name, &value);
		priv->gsettings_notification_pspec = NULL;
	}

out:
	/* FIXME: if we arrive here through goto in the error cases,
	 * should we maybe reset the property to its default value?
	 */

	g_value_unset (&value);
	g_variant_unref (settings_value);
}
Exemple #18
0
void
qof_gobject_register (QofType e_type, GObjectClass *obclass)
{
    int i;
    int j;
    QofParam *qof_param_list, *qpar;
    QofObject *class_def;
    GParamSpec **prop_list, *gparam;
    guint n_props;

    /* Get the GObject properties, convert to QOF properties */
    prop_list = g_object_class_list_properties (obclass, &n_props);

    qof_param_list = g_new0 (QofParam, n_props);
    paramList = g_slist_prepend (paramList, qof_param_list);

    PINFO ("object %s has %d props", e_type, n_props);
    j = 0;
    for (i = 0; i < n_props; i++)
    {
        gparam = prop_list[i];
        qpar = &qof_param_list[j];

        PINFO ("param %d %s is type %s",
               i, gparam->name, G_PARAM_SPEC_TYPE_NAME(gparam));

        qpar->param_name = g_param_spec_get_name (gparam);
        qpar->param_getfcn = (QofAccessFunc)qof_gobject_getter;
        qpar->param_setfcn = NULL;
        qpar->param_userdata = gparam;
        if ((G_IS_PARAM_SPEC_INT(gparam))  ||
                (G_IS_PARAM_SPEC_UINT(gparam)) ||
                (G_IS_PARAM_SPEC_ENUM(gparam)) ||
                (G_IS_PARAM_SPEC_FLAGS(gparam)))
        {
            qpar->param_type = QOF_TYPE_INT32;
            j++;
        }
        else if ((G_IS_PARAM_SPEC_INT64(gparam)) ||
                 (G_IS_PARAM_SPEC_UINT64(gparam)))
        {
            qpar->param_type = QOF_TYPE_INT64;
            j++;
        }
        else if (G_IS_PARAM_SPEC_BOOLEAN(gparam))
        {
            qpar->param_type = QOF_TYPE_BOOLEAN;
            j++;
        }
        else if (G_IS_PARAM_SPEC_STRING(gparam))
        {
            qpar->param_type = QOF_TYPE_STRING;
            j++;
        }
        else if ((G_IS_PARAM_SPEC_POINTER(gparam)) ||
                 (G_IS_PARAM_SPEC_OBJECT(gparam)))
        {
            /* No-op, silently ignore.  Someday we should handle this ...  */
        }
        else if ((G_IS_PARAM_SPEC_FLOAT(gparam)) ||
                 (G_IS_PARAM_SPEC_DOUBLE(gparam)))
        {
            qpar->param_getfcn = (QofAccessFunc) qof_gobject_double_getter;
            qpar->param_type = QOF_TYPE_DOUBLE;
            j++;
        }
        else if (G_IS_PARAM_SPEC_CHAR(gparam))
        {
            qpar->param_type = QOF_TYPE_CHAR;
            j++;
        }
        else
        {
            PWARN ("Unknown/unhandled parameter type %s on %s:%s\n",
                   G_PARAM_SPEC_TYPE_NAME(gparam), e_type, qpar->param_name);
        }
    }

    /* NULL-terminated list! */
    qof_param_list[j].param_type = NULL;

    qof_class_register (e_type, NULL, qof_param_list);

    /* ------------------------------------------------------ */
    /* Now do the class itself */
    class_def = g_new0 (QofObject, 1);
    classList = g_slist_prepend (classList, class_def);

    class_def->interface_version = QOF_OBJECT_VERSION;
    class_def->e_type = e_type;
    /* We could let the user specify a "nick" here, but
     * the actual class name seems reasonable, e.g. for debugging. */
    class_def->type_label = G_OBJECT_CLASS_NAME (obclass);
    class_def->create = NULL;
    class_def->book_begin = NULL;
    class_def->book_end = NULL;
    class_def->is_dirty = NULL;
    class_def->mark_clean = NULL;
    class_def->foreach = qof_gobject_foreach;
    class_def->printable = NULL;
    class_def->version_cmp = NULL;

    qof_object_register (class_def);
}