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; }
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)); } } }
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; }
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)); } } }
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; }
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; }
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; }
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; }
/* --- 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); }
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); }