[gimp] libgimp, libgimpwidgets: supporting GFile properties in…
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] libgimp, libgimpwidgets: supporting GFile properties in…
- Date: Fri, 17 Jun 2022 15:18:40 +0000 (UTC)
commit 42143881d821528b1c2a09590d49dd1b49037354
Author: Jehan <jehan girinstud io>
Date: Fri Jun 17 15:08:16 2022 +0200
libgimp, libgimpwidgets: supporting GFile properties in…
… GimpProcedureDialog.
- gimp_prop_file_chooser_button_new() now works also with properties
G_PARAM_SPEC_OBJECT having a value_type == G_TYPE_FILE (additionally
to GIMP_PARAM_SPEC_CONFIG_PATH properties).
- gimp_procedure_dialog_get_widget() will now create a
GtkFileChooserButton in open mode for such a GFile property.
- New gimp_procedure_dialog_get_file_chooser() API to create
GtkFileChooserButton for GFile properties in other modes.
Current limitation: GtkFileChooserButton doesn't have a label. This
should be fixed, probably by creating another custom widget with would
be a labelized file chooser button.
libgimp/gimpproceduredialog.c | 79 +++++++++++++++++++++++++++
libgimp/gimpproceduredialog.h | 3 ++
libgimp/gimpui.def | 1 +
libgimpwidgets/gimppropwidgets.c | 112 +++++++++++++++++++++++++++++----------
4 files changed, 166 insertions(+), 29 deletions(-)
---
diff --git a/libgimp/gimpproceduredialog.c b/libgimp/gimpproceduredialog.c
index 88bb885360..f92b919046 100644
--- a/libgimp/gimpproceduredialog.c
+++ b/libgimp/gimpproceduredialog.c
@@ -562,6 +562,11 @@ gimp_procedure_dialog_new (GimpProcedure *procedure,
* non-editable color area with a label.
* * %GIMP_TYPE_COLOR_BUTTON: a color button with no label.
* * %GIMP_TYPE_COLOR_AREA: a color area with no label.
+ * - %G_TYPE_PARAM_FILE:
+ * * %GTK_FILE_CHOOSER_BUTTON (default): generic file chooser button
+ * in %GTK_FILE_CHOOSER_ACTION_OPEN mode. Please use
+ * gimp_procedure_dialog_get_file_chooser() to create buttons in
+ * other modes.
*
* If the @widget_type is not supported for the actual type of
* @property, the function will fail. To keep the default, set to
@@ -714,6 +719,12 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
gtk_widget_set_hexpand (widget, FALSE);
}
}
+ else if (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type == G_TYPE_FILE)
+ {
+ widget = gimp_prop_file_chooser_button_new (G_OBJECT (dialog->priv->config),
+ property, NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN);
+ }
else
{
g_warning ("%s: parameter %s has non supported type %s",
@@ -1204,6 +1215,74 @@ gimp_procedure_dialog_get_label (GimpProcedureDialog *dialog,
return label;
}
+/**
+ * gimp_procedure_dialog_get_file_chooser:
+ * @dialog: the associated #GimpProcedureDialog.
+ * @property: name of the %GimpParamConfigPath or %GParamObject of value
+ * type %GFile property to build a #GtkFileChooserButton for.
+ * It must be a property of the #GimpProcedure @dialog has
+ * been created for.
+ * @action: The open mode for the widget.
+ *
+ * Creates a new %GtkFileChooserButton for @property which must
+ * necessarily be a config path or %GFile property.
+ * This can be used instead of gimp_procedure_dialog_get_widget() in
+ * particular if you want to create a button in non-open modes (i.e. to
+ * save files, and select or create folders).
+ *
+ * If a widget has already been created for this procedure, it will be
+ * returned instead (whatever its actual widget type).
+ *
+ * Returns: (transfer none): the #GtkWidget representing @property. The
+ * object belongs to @dialog and must not be
+ * freed.
+ */
+GtkWidget *
+gimp_procedure_dialog_get_file_chooser (GimpProcedureDialog *dialog,
+ const gchar *property,
+ GtkFileChooserAction action)
+{
+ GtkWidget *widget = NULL;
+ GParamSpec *pspec;
+
+ g_return_val_if_fail (GIMP_IS_PROCEDURE_DIALOG (dialog), NULL);
+ g_return_val_if_fail (property != NULL, NULL);
+
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (dialog->priv->config),
+ property);
+
+ if (! pspec)
+ {
+ g_warning ("%s: parameter %s does not exist.",
+ G_STRFUNC, property);
+ return NULL;
+ }
+
+ g_return_val_if_fail (GIMP_IS_PARAM_SPEC_CONFIG_PATH (pspec) ||
+ (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type != G_TYPE_FILE),
+ NULL);
+
+ /* First check if it already exists. */
+ widget = g_hash_table_lookup (dialog->priv->widgets, property);
+
+ if (widget)
+ return widget;
+
+ widget = gimp_prop_file_chooser_button_new (G_OBJECT (dialog->priv->config),
+ property, NULL, action);
+
+ /* TODO: make is a file chooser with label. */
+ /*gtk_size_group_add_widget (dialog->priv->label_group,
+ gimp_labeled_get_label (GIMP_LABELED (widget)));
+
+ gimp_procedure_dialog_check_mnemonic (dialog, widget, property, NULL);*/
+ g_hash_table_insert (dialog->priv->widgets, g_strdup (property), widget);
+ if (g_object_is_floating (widget))
+ g_object_ref_sink (widget);
+
+ return widget;
+}
+
/**
* gimp_procedure_dialog_fill:
* @dialog: the #GimpProcedureDialog.
diff --git a/libgimp/gimpproceduredialog.h b/libgimp/gimpproceduredialog.h
index dd2e4c5d3d..d977a065eb 100644
--- a/libgimp/gimpproceduredialog.h
+++ b/libgimp/gimpproceduredialog.h
@@ -97,6 +97,9 @@ GtkWidget * gimp_procedure_dialog_get_scale_entry (GimpProcedureDialog *dialog
GtkWidget * gimp_procedure_dialog_get_label (GimpProcedureDialog *dialog,
const gchar *label_id,
const gchar *text);
+GtkWidget * gimp_procedure_dialog_get_file_chooser (GimpProcedureDialog *dialog,
+ const gchar *property,
+ GtkFileChooserAction action);
GtkWidget * gimp_procedure_dialog_fill_box (GimpProcedureDialog *dialog,
const gchar *container_id,
diff --git a/libgimp/gimpui.def b/libgimp/gimpui.def
index 47563dc704..0ac1946f58 100644
--- a/libgimp/gimpui.def
+++ b/libgimp/gimpui.def
@@ -48,6 +48,7 @@ EXPORTS
gimp_procedure_dialog_fill_frame
gimp_procedure_dialog_fill_list
gimp_procedure_dialog_get_color_widget
+ gimp_procedure_dialog_get_file_chooser
gimp_procedure_dialog_get_int_combo
gimp_procedure_dialog_get_int_radio
gimp_procedure_dialog_get_label
diff --git a/libgimpwidgets/gimppropwidgets.c b/libgimpwidgets/gimppropwidgets.c
index ed43aa2c5d..a6f23af92a 100644
--- a/libgimpwidgets/gimppropwidgets.c
+++ b/libgimpwidgets/gimppropwidgets.c
@@ -2639,10 +2639,12 @@ static void gimp_prop_file_chooser_button_notify (GObject *confi
* gimp_prop_file_chooser_button_new:
* @config: object to which property is attached.
* @property_name: name of path property.
- * @title: the title of the browse dialog.
+ * @title: (nullable): the title of the browse dialog.
* @action: the open mode for the widget.
*
* Creates a #GtkFileChooserButton to edit the specified path property.
+ * @property_name must represent either a GIMP_PARAM_SPEC_CONFIG_PATH or
+ * a G_PARAM_SPEC_OBJECT where `value_type == G_TYPE_FILE`.
*
* Note that #GtkFileChooserButton implements the #GtkFileChooser
* interface; you can use the #GtkFileChooser API with it.
@@ -2663,10 +2665,27 @@ gimp_prop_file_chooser_button_new (GObject *config,
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (property_name != NULL, NULL);
- param_spec = check_param_spec_w (config, property_name,
- GIMP_TYPE_PARAM_CONFIG_PATH, G_STRFUNC);
+ param_spec = find_param_spec (config, property_name, G_STRFUNC);
if (! param_spec)
- return NULL;
+ {
+ g_warning ("%s: %s has no property named '%s'",
+ G_STRFUNC, g_type_name (G_TYPE_FROM_INSTANCE (config)),
+ property_name);
+ return NULL;
+ }
+
+ if (! GIMP_IS_PARAM_SPEC_CONFIG_PATH (param_spec) &&
+ (! G_IS_PARAM_SPEC_OBJECT (param_spec) || param_spec->value_type != G_TYPE_FILE))
+ {
+ g_warning ("%s: property '%s' of %s is neither a GIMP_PARAM_SPEC_CONFIG_PATH "
+ "nor a G_PARAM_SPEC_OBJECT of value type G_TYPE_FILE.",
+ G_STRFUNC, param_spec->name,
+ g_type_name (param_spec->owner_type));
+ return NULL;
+ }
+
+ if (! title)
+ title = g_param_spec_get_nick (param_spec);
button = gtk_file_chooser_button_new (title, action);
@@ -2719,17 +2738,27 @@ gimp_prop_file_chooser_button_setup (GtkWidget *button,
GObject *config,
GParamSpec *param_spec)
{
- gchar *value;
GFile *file = NULL;
- g_object_get (config,
- param_spec->name, &value,
- NULL);
+ if (GIMP_IS_PARAM_SPEC_CONFIG_PATH (param_spec))
+ {
+ gchar *value;
- if (value)
+ g_object_get (config,
+ param_spec->name, &value,
+ NULL);
+
+ if (value)
+ {
+ file = gimp_file_new_for_config_path (value, NULL);
+ g_free (value);
+ }
+ }
+ else /* G_FILE */
{
- file = gimp_file_new_for_config_path (value, NULL);
- g_free (value);
+ g_object_get (config,
+ param_spec->name, &file,
+ NULL);
}
if (file)
@@ -2766,8 +2795,6 @@ gimp_prop_file_chooser_button_callback (GtkFileChooser *button,
{
GParamSpec *param_spec;
GFile *file;
- gchar *value = NULL;
- gchar *v;
param_spec = get_param_spec (G_OBJECT (button));
if (! param_spec)
@@ -2775,29 +2802,56 @@ gimp_prop_file_chooser_button_callback (GtkFileChooser *button,
file = gtk_file_chooser_get_file (button);
- if (file)
+ if (GIMP_IS_PARAM_SPEC_CONFIG_PATH (param_spec))
{
- value = gimp_file_get_config_path (file, NULL);
- g_object_unref (file);
- }
+ gchar *value = NULL;
+ gchar *v;
- g_object_get (config, param_spec->name, &v, NULL);
+ if (file)
+ {
+ value = gimp_file_get_config_path (file, NULL);
+ g_object_unref (file);
+ }
- if (g_strcmp0 (v, value))
- {
- g_signal_handlers_block_by_func (config,
- gimp_prop_file_chooser_button_notify,
- button);
+ g_object_get (config, param_spec->name, &v, NULL);
- g_object_set (config, param_spec->name, value, NULL);
+ if (g_strcmp0 (v, value))
+ {
+ g_signal_handlers_block_by_func (config,
+ gimp_prop_file_chooser_button_notify,
+ button);
- g_signal_handlers_unblock_by_func (config,
- gimp_prop_file_chooser_button_notify,
- button);
+ g_object_set (config, param_spec->name, value, NULL);
+
+ g_signal_handlers_unblock_by_func (config,
+ gimp_prop_file_chooser_button_notify,
+ button);
+ }
+
+ g_free (value);
+ g_free (v);
}
+ else /* G_FILE */
+ {
+ GFile *f = NULL;
- g_free (value);
- g_free (v);
+ g_object_get (config, param_spec->name, &f, NULL);
+
+ if (! f || ! file || ! g_file_equal (f, file))
+ {
+ g_signal_handlers_block_by_func (config,
+ gimp_prop_file_chooser_button_notify,
+ button);
+
+ g_object_set (config, param_spec->name, file, NULL);
+
+ g_signal_handlers_unblock_by_func (config,
+ gimp_prop_file_chooser_button_notify,
+ button);
+ }
+ g_clear_object (&f);
+ }
+ g_clear_object (&file);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]