mirror of https://github.com/GNOME/gimp.git
libgimpwidgets: new GimpFileChooser widget.
This widget will replace our usage of GtkFileChooserButton, except that it has a title label and also it contains GUI implementation for the SAVE and CREATE_FOLDER actions (unlike the GTK button). Moreover this widget was removed in GTK4. So it is a good idea to start encapsulating such GTK widget anyway. I'm also adding a propwidget function to create such a widget bound to a GimpParamSpecFile property. New functions: - gimp_file_chooser_get_action - gimp_file_chooser_get_file - gimp_file_chooser_get_label - gimp_file_chooser_get_label_widget - gimp_file_chooser_get_title - gimp_file_chooser_get_type - gimp_file_chooser_new - gimp_file_chooser_set_action - gimp_file_chooser_set_file - gimp_file_chooser_set_label - gimp_file_chooser_set_title - gimp_prop_file_chooser_new
This commit is contained in:
parent
ed0d528bdc
commit
db2d3cffa2
|
@ -0,0 +1,751 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* gimpfilechooser.h
|
||||||
|
* Copyright (C) 2025 Jehan
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "libgimpbase/gimpbase.h"
|
||||||
|
|
||||||
|
#include "gimpicons.h"
|
||||||
|
#include "gimpwidgetstypes.h"
|
||||||
|
|
||||||
|
#include "gimpfilechooser.h"
|
||||||
|
|
||||||
|
#include "libgimp/libgimp-intl.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION: gimpfilechooser
|
||||||
|
* @title: GimpFileChooser
|
||||||
|
* @short_description: A widget allowing to select a file.
|
||||||
|
*
|
||||||
|
* The chooser contains an optional label and other interface allowing
|
||||||
|
* to select files for different use cases.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_ACTION,
|
||||||
|
PROP_LABEL,
|
||||||
|
PROP_TITLE,
|
||||||
|
PROP_FILE,
|
||||||
|
N_PROPS
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GimpFileChooser
|
||||||
|
{
|
||||||
|
GtkBox parent_instance;
|
||||||
|
|
||||||
|
GFile *file;
|
||||||
|
gchar *title;
|
||||||
|
gchar *label;
|
||||||
|
|
||||||
|
GimpFileChooserAction action;
|
||||||
|
GtkWidget *label_widget;
|
||||||
|
GtkWidget *button;
|
||||||
|
GtkWidget *entry;
|
||||||
|
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
gboolean invalid_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void gimp_file_chooser_constructed (GObject *object);
|
||||||
|
static void gimp_file_chooser_finalize (GObject *object);
|
||||||
|
|
||||||
|
static void gimp_file_chooser_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
static void gimp_file_chooser_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
static void gimp_file_chooser_button_selection_changed (GtkFileChooser *widget,
|
||||||
|
GimpFileChooser *chooser);
|
||||||
|
static void gimp_file_chooser_dialog_response (GtkDialog *dialog,
|
||||||
|
gint response_id,
|
||||||
|
GimpFileChooser *chooser);
|
||||||
|
static void gimp_file_chooser_button_clicked (GtkButton *button,
|
||||||
|
GimpFileChooser *chooser);
|
||||||
|
static void gimp_file_chooser_entry_text_notify (GtkEntry *entry,
|
||||||
|
const GParamSpec *pspec,
|
||||||
|
GimpFileChooser *chooser);
|
||||||
|
|
||||||
|
|
||||||
|
static GParamSpec *file_button_props[N_PROPS] = { NULL, };
|
||||||
|
|
||||||
|
/* Note: I initially wanted to implement the GtkFileChooser interface,
|
||||||
|
* but it looks like GTK made GtkFileChooserIface private. So it can't
|
||||||
|
* be implemented outside of core GTK widgets.
|
||||||
|
*/
|
||||||
|
G_DEFINE_FINAL_TYPE (GimpFileChooser, gimp_file_chooser, GTK_TYPE_BOX)
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_class_init (GimpFileChooserClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->constructed = gimp_file_chooser_constructed;
|
||||||
|
object_class->finalize = gimp_file_chooser_finalize;
|
||||||
|
object_class->set_property = gimp_file_chooser_set_property;
|
||||||
|
object_class->get_property = gimp_file_chooser_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GimpFileChooser:action:
|
||||||
|
*
|
||||||
|
* The action determining the chooser UI.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
file_button_props[PROP_ACTION] =
|
||||||
|
g_param_spec_enum ("action",
|
||||||
|
"Action",
|
||||||
|
"The action determining the chooser UI",
|
||||||
|
GIMP_TYPE_FILE_CHOOSER_ACTION,
|
||||||
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
|
GIMP_PARAM_READWRITE |
|
||||||
|
G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GimpFileChooser:label:
|
||||||
|
*
|
||||||
|
* Label text with mnemonic.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
file_button_props[PROP_LABEL] =
|
||||||
|
g_param_spec_string ("label",
|
||||||
|
"Label",
|
||||||
|
"The label to be used next to the button",
|
||||||
|
NULL,
|
||||||
|
GIMP_PARAM_READWRITE |
|
||||||
|
G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GimpFileChooser:title:
|
||||||
|
*
|
||||||
|
* The title to be used for the file selection popup dialog.
|
||||||
|
* If %NULL, the "label" property is used instead.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
file_button_props[PROP_TITLE] =
|
||||||
|
g_param_spec_string ("title",
|
||||||
|
"Title",
|
||||||
|
"The title to be used for the file selection popup dialog "
|
||||||
|
"and as placeholder text in file entry.",
|
||||||
|
"File Selection",
|
||||||
|
GIMP_PARAM_READWRITE |
|
||||||
|
G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GimpFileChooser:file:
|
||||||
|
*
|
||||||
|
* The currently selected file.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
file_button_props[PROP_FILE] =
|
||||||
|
gimp_param_spec_file ("file", "File",
|
||||||
|
"The currently selected file",
|
||||||
|
GIMP_FILE_CHOOSER_ACTION_ANY,
|
||||||
|
TRUE, NULL,
|
||||||
|
GIMP_PARAM_READWRITE |
|
||||||
|
G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class,
|
||||||
|
N_PROPS, file_button_props);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_init (GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
gtk_orientable_set_orientation (GTK_ORIENTABLE (chooser),
|
||||||
|
GTK_ORIENTATION_HORIZONTAL);
|
||||||
|
gtk_box_set_spacing (GTK_BOX (chooser), 6);
|
||||||
|
|
||||||
|
chooser->action = GIMP_FILE_CHOOSER_ACTION_OPEN;
|
||||||
|
chooser->button = NULL;
|
||||||
|
chooser->entry = NULL;
|
||||||
|
chooser->dialog = NULL;
|
||||||
|
chooser->file = NULL;
|
||||||
|
|
||||||
|
chooser->invalid_file = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
GimpFileChooser *chooser = GIMP_FILE_CHOOSER (object);
|
||||||
|
|
||||||
|
chooser->label_widget = gtk_label_new (NULL);
|
||||||
|
gtk_box_pack_start (GTK_BOX (chooser), chooser->label_widget, FALSE, FALSE, 0);
|
||||||
|
if (chooser->label)
|
||||||
|
gtk_label_set_text_with_mnemonic (GTK_LABEL (chooser->label_widget), chooser->label);
|
||||||
|
gtk_widget_set_visible (chooser->label_widget, chooser->label != NULL);
|
||||||
|
|
||||||
|
gimp_file_chooser_set_action (chooser, chooser->action);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gimp_file_chooser_parent_class)->constructed (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GimpFileChooser *chooser = GIMP_FILE_CHOOSER (object);
|
||||||
|
|
||||||
|
g_clear_pointer (&chooser->title, g_free);
|
||||||
|
g_clear_pointer (&chooser->label, g_free);
|
||||||
|
g_clear_object (&chooser->file);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gimp_file_chooser_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GimpFileChooser *chooser = GIMP_FILE_CHOOSER (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_ACTION:
|
||||||
|
gimp_file_chooser_set_action (chooser, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_LABEL:
|
||||||
|
gimp_file_chooser_set_label (chooser, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_TITLE:
|
||||||
|
gimp_file_chooser_set_title (chooser, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_FILE:
|
||||||
|
gimp_file_chooser_set_file (chooser, g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GimpFileChooser *chooser = GIMP_FILE_CHOOSER (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_ACTION:
|
||||||
|
g_value_set_enum (value, chooser->action);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_LABEL:
|
||||||
|
g_value_set_string (value, chooser->label);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_TITLE:
|
||||||
|
g_value_set_string (value, chooser->title);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_FILE:
|
||||||
|
g_value_set_object (value, chooser->file);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_new:
|
||||||
|
* @action: the action determining the UI created for this widget.
|
||||||
|
* @label: (nullable): Label or %NULL for no label.
|
||||||
|
* @title: (nullable): Title of the dialog to use or %NULL to reuse @label.
|
||||||
|
* @file: (nullable): Initial file.
|
||||||
|
*
|
||||||
|
* Creates a new #GtkWidget that lets a user choose a file according to
|
||||||
|
* @action.
|
||||||
|
*
|
||||||
|
* [enum@Gimp.FileChooserAction.ANY] is not a valid value for @action.
|
||||||
|
*
|
||||||
|
* Returns: A [class@GimpUi.FileChooser].
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
gimp_file_chooser_new (GimpFileChooserAction action,
|
||||||
|
const gchar *label,
|
||||||
|
const gchar *title,
|
||||||
|
GFile *file)
|
||||||
|
{
|
||||||
|
GtkWidget *chooser;
|
||||||
|
|
||||||
|
g_return_val_if_fail (action != GIMP_FILE_CHOOSER_ACTION_ANY, NULL);
|
||||||
|
g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
|
||||||
|
|
||||||
|
chooser = g_object_new (GIMP_TYPE_FILE_CHOOSER,
|
||||||
|
"action", action,
|
||||||
|
"label", label,
|
||||||
|
"title", title,
|
||||||
|
"file", file,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return chooser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_get_action:
|
||||||
|
* @chooser: A #GimpFileChooser
|
||||||
|
*
|
||||||
|
* Gets the current action.
|
||||||
|
*
|
||||||
|
* Returns: the action which determined the UI of @chooser.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
GimpFileChooserAction
|
||||||
|
gimp_file_chooser_get_action (GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GIMP_IS_FILE_CHOOSER (chooser), GIMP_FILE_CHOOSER_ACTION_ANY);
|
||||||
|
|
||||||
|
return chooser->action;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_set_action:
|
||||||
|
* @chooser: A #GimpFileChooser
|
||||||
|
* @action: Action to set.
|
||||||
|
*
|
||||||
|
* Changes how @chooser is set to select a file. It may completely
|
||||||
|
* change the internal widget structure so you should not depend on a
|
||||||
|
* specific widget composition.
|
||||||
|
*
|
||||||
|
* Warning: with GTK deprecations, we may have soon to change the
|
||||||
|
* internal implementation. So this is all the more reason for you not
|
||||||
|
* to rely on specific child widgets being present (e.g.: we use
|
||||||
|
* currently [class@Gtk.FileChooserButton] internally but it was removed
|
||||||
|
* in GTK4 so we will eventually replace it by custom code). We will
|
||||||
|
* also likely move to native file dialogs at some point.
|
||||||
|
*
|
||||||
|
* [enum@Gimp.FileChooserAction.ANY] is not a valid value for @action.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gimp_file_chooser_set_action (GimpFileChooser *chooser,
|
||||||
|
GimpFileChooserAction action)
|
||||||
|
{
|
||||||
|
gchar *uri_path = NULL;
|
||||||
|
|
||||||
|
g_return_if_fail (GIMP_IS_FILE_CHOOSER (chooser));
|
||||||
|
g_return_if_fail (action != GIMP_FILE_CHOOSER_ACTION_ANY);
|
||||||
|
|
||||||
|
if (chooser->button)
|
||||||
|
gtk_widget_destroy (chooser->button);
|
||||||
|
if (chooser->entry)
|
||||||
|
gtk_widget_destroy (chooser->entry);
|
||||||
|
if (chooser->dialog)
|
||||||
|
gtk_widget_destroy (chooser->dialog);
|
||||||
|
chooser->button = NULL;
|
||||||
|
chooser->entry = NULL;
|
||||||
|
chooser->dialog = NULL;
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case GIMP_FILE_CHOOSER_ACTION_OPEN:
|
||||||
|
case GIMP_FILE_CHOOSER_ACTION_SELECT_FOLDER:
|
||||||
|
chooser->button = gtk_file_chooser_button_new (chooser->title, (GtkFileChooserAction) action);
|
||||||
|
gtk_box_pack_start (GTK_BOX (chooser), chooser->button, FALSE, FALSE, 0);
|
||||||
|
g_signal_connect (chooser->button, "selection-changed",
|
||||||
|
G_CALLBACK (gimp_file_chooser_button_selection_changed),
|
||||||
|
chooser);
|
||||||
|
gtk_widget_set_visible (chooser->button, TRUE);
|
||||||
|
|
||||||
|
gtk_label_set_mnemonic_widget (GTK_LABEL (chooser->label_widget), chooser->button);
|
||||||
|
break;
|
||||||
|
case GIMP_FILE_CHOOSER_ACTION_SAVE:
|
||||||
|
case GIMP_FILE_CHOOSER_ACTION_CREATE_FOLDER:
|
||||||
|
chooser->entry = gtk_entry_new ();
|
||||||
|
gtk_box_pack_start (GTK_BOX (chooser), chooser->entry, TRUE, TRUE, 0);
|
||||||
|
if (chooser->file)
|
||||||
|
{
|
||||||
|
uri_path = g_file_get_path (chooser->file);
|
||||||
|
if (! uri_path)
|
||||||
|
uri_path = g_file_get_uri (chooser->file);
|
||||||
|
}
|
||||||
|
if (! uri_path)
|
||||||
|
uri_path = g_strdup ("");
|
||||||
|
gtk_entry_set_text (GTK_ENTRY (chooser->entry), uri_path);
|
||||||
|
g_signal_connect (chooser->entry, "notify::text",
|
||||||
|
G_CALLBACK (gimp_file_chooser_entry_text_notify),
|
||||||
|
chooser);
|
||||||
|
gtk_entry_set_placeholder_text (GTK_ENTRY (chooser->entry), chooser->title);
|
||||||
|
gtk_widget_set_visible (chooser->entry, TRUE);
|
||||||
|
|
||||||
|
chooser->button = gtk_button_new_from_icon_name (GIMP_ICON_FILE_MANAGER, GTK_ICON_SIZE_SMALL_TOOLBAR);
|
||||||
|
gtk_box_pack_start (GTK_BOX (chooser), chooser->button, FALSE, FALSE, 0);
|
||||||
|
gtk_widget_set_visible (chooser->button, TRUE);
|
||||||
|
g_signal_connect (chooser->button, "clicked",
|
||||||
|
G_CALLBACK (gimp_file_chooser_button_clicked),
|
||||||
|
chooser);
|
||||||
|
|
||||||
|
gtk_label_set_mnemonic_widget (GTK_LABEL (chooser->label_widget), chooser->entry);
|
||||||
|
break;
|
||||||
|
case GIMP_FILE_CHOOSER_ACTION_ANY:
|
||||||
|
g_return_if_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
chooser->action = action;
|
||||||
|
gimp_param_spec_file_set_action (file_button_props[PROP_FILE], action);
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (chooser), file_button_props[PROP_ACTION]);
|
||||||
|
|
||||||
|
g_free (uri_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_get_file:
|
||||||
|
* @chooser: A #GimpFileChooser
|
||||||
|
*
|
||||||
|
* Gets the currently selected file.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): an internal copy of the file which must not be freed.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
GFile *
|
||||||
|
gimp_file_chooser_get_file (GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GIMP_IS_FILE_CHOOSER (chooser), NULL);
|
||||||
|
|
||||||
|
return chooser->file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_set_file:
|
||||||
|
* @chooser: A #GimpFileChooser
|
||||||
|
* @file: File to set.
|
||||||
|
*
|
||||||
|
* Sets the currently selected file.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gimp_file_chooser_set_file (GimpFileChooser *chooser,
|
||||||
|
GFile *file)
|
||||||
|
{
|
||||||
|
GFile *current_file = NULL;
|
||||||
|
gchar *uri_path = NULL;
|
||||||
|
|
||||||
|
g_return_if_fail (GIMP_IS_FILE_CHOOSER (chooser));
|
||||||
|
g_return_if_fail (file == NULL || G_IS_FILE (file));
|
||||||
|
|
||||||
|
current_file = chooser->file ? g_object_ref (chooser->file) : NULL;
|
||||||
|
g_clear_object (&chooser->file);
|
||||||
|
chooser->file = file ? g_object_ref (file) : NULL;
|
||||||
|
|
||||||
|
if ((current_file != NULL && file == NULL) ||
|
||||||
|
(file != NULL && current_file == NULL) ||
|
||||||
|
(file != NULL && current_file != NULL && ! g_file_equal (file, current_file)))
|
||||||
|
{
|
||||||
|
switch (chooser->action)
|
||||||
|
{
|
||||||
|
case GTK_FILE_CHOOSER_ACTION_OPEN:
|
||||||
|
case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
|
||||||
|
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (chooser->button), file, NULL);
|
||||||
|
break;
|
||||||
|
case GTK_FILE_CHOOSER_ACTION_SAVE:
|
||||||
|
case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
|
||||||
|
if (chooser->dialog)
|
||||||
|
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (chooser->dialog), file, NULL);
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
uri_path = g_file_get_path (file);
|
||||||
|
if (! uri_path)
|
||||||
|
uri_path = g_file_get_uri (file);
|
||||||
|
}
|
||||||
|
if (! uri_path)
|
||||||
|
uri_path = g_strdup ("");
|
||||||
|
g_signal_handlers_block_by_func (chooser->entry,
|
||||||
|
G_CALLBACK (gimp_file_chooser_entry_text_notify),
|
||||||
|
chooser);
|
||||||
|
if (! chooser->invalid_file)
|
||||||
|
gtk_entry_set_text (GTK_ENTRY (chooser->entry), uri_path);
|
||||||
|
g_signal_handlers_unblock_by_func (chooser->entry,
|
||||||
|
G_CALLBACK (gimp_file_chooser_entry_text_notify),
|
||||||
|
chooser);
|
||||||
|
break;
|
||||||
|
case GIMP_FILE_CHOOSER_ACTION_ANY:
|
||||||
|
g_return_if_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (chooser), file_button_props[PROP_FILE]);
|
||||||
|
|
||||||
|
g_clear_object (¤t_file);
|
||||||
|
g_free (uri_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_get_label:
|
||||||
|
* @chooser: A #GimpFileChooser
|
||||||
|
*
|
||||||
|
* Gets the current label text. A %NULL label means that the label
|
||||||
|
* widget is hidden.
|
||||||
|
*
|
||||||
|
* Note: the label text may contain a mnemonic.
|
||||||
|
*
|
||||||
|
* Returns: (nullable): the label set.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
gimp_file_chooser_get_label (GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GIMP_IS_FILE_CHOOSER (chooser), NULL);
|
||||||
|
|
||||||
|
return chooser->label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_set_label:
|
||||||
|
* @chooser: A [class@FileChooser].
|
||||||
|
* @text: (nullable): Label text.
|
||||||
|
*
|
||||||
|
* Set the label text with mnemonic.
|
||||||
|
*
|
||||||
|
* Setting a %NULL label text will hide the label widget.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gimp_file_chooser_set_label (GimpFileChooser *chooser,
|
||||||
|
const gchar *text)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GIMP_IS_FILE_CHOOSER (chooser));
|
||||||
|
|
||||||
|
g_free (chooser->label);
|
||||||
|
chooser->label = g_strdup (text);
|
||||||
|
gtk_widget_set_visible (chooser->label_widget, text != NULL);
|
||||||
|
|
||||||
|
if (chooser->label_widget)
|
||||||
|
{
|
||||||
|
if (text != NULL)
|
||||||
|
gtk_label_set_text_with_mnemonic (GTK_LABEL (chooser->label_widget), text);
|
||||||
|
|
||||||
|
gtk_widget_set_visible (chooser->label_widget, text != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (chooser), file_button_props[PROP_LABEL]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_get_title:
|
||||||
|
* @chooser: A #GimpFileChooser
|
||||||
|
*
|
||||||
|
* Gets the text currently used for the file dialog's title and for
|
||||||
|
* entry's placeholder text.
|
||||||
|
*
|
||||||
|
* A %NULL value means that the file dialog uses default title and the
|
||||||
|
* entry has no placeholder text.
|
||||||
|
*
|
||||||
|
* Returns: (nullable): the text used for the title of @chooser's dialog.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
gimp_file_chooser_get_title (GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GIMP_IS_FILE_CHOOSER (chooser), NULL);
|
||||||
|
|
||||||
|
return chooser->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_set_title:
|
||||||
|
* @chooser: A [class@FileChooser].
|
||||||
|
* @text: (nullable): Dialog's title text.
|
||||||
|
*
|
||||||
|
* Set the text to be used for the file dialog's title and for entry's
|
||||||
|
* placeholder text.
|
||||||
|
*
|
||||||
|
* Setting a %NULL title @text will mean that the file dialog will use a
|
||||||
|
* generic title and there will be no placeholder text in the entry.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gimp_file_chooser_set_title (GimpFileChooser *chooser,
|
||||||
|
const gchar *text)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GIMP_IS_FILE_CHOOSER (chooser));
|
||||||
|
|
||||||
|
g_free (chooser->title);
|
||||||
|
chooser->title = g_strdup (text);
|
||||||
|
|
||||||
|
if (chooser->dialog)
|
||||||
|
gtk_window_set_title (GTK_WINDOW (chooser->dialog), chooser->title);
|
||||||
|
|
||||||
|
if (chooser->entry)
|
||||||
|
gtk_entry_set_placeholder_text (GTK_ENTRY (chooser->entry), chooser->title);
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (chooser), file_button_props[PROP_TITLE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_file_chooser_get_label_widget:
|
||||||
|
* @chooser: A [class@FileChooser].
|
||||||
|
*
|
||||||
|
* Returns the label widget. This can be useful for instance when
|
||||||
|
* aligning dialog's widgets with a [class@Gtk.SizeGroup].
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): the [class@Gtk.Widget] showing the label text.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
gimp_file_chooser_get_label_widget (GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GIMP_IS_FILE_CHOOSER (chooser), NULL);
|
||||||
|
|
||||||
|
return chooser->label_widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Private Functions */
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_button_selection_changed (GtkFileChooser *widget,
|
||||||
|
GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
GFile *file;
|
||||||
|
|
||||||
|
file = gtk_file_chooser_get_file (widget);
|
||||||
|
gimp_file_chooser_set_file (chooser, file);
|
||||||
|
g_clear_object (&file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_dialog_response (GtkDialog *dialog,
|
||||||
|
gint response_id,
|
||||||
|
GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
GFile *file = NULL;
|
||||||
|
|
||||||
|
switch (response_id)
|
||||||
|
{
|
||||||
|
case GTK_RESPONSE_OK:
|
||||||
|
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||||
|
gimp_file_chooser_set_file (chooser, file);
|
||||||
|
break;
|
||||||
|
case GTK_RESPONSE_CANCEL:
|
||||||
|
case GTK_RESPONSE_DELETE_EVENT:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||||
|
chooser->dialog = NULL;
|
||||||
|
|
||||||
|
g_clear_object (&file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_button_clicked (GtkButton *button,
|
||||||
|
GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
GtkWidget *toplevel;
|
||||||
|
|
||||||
|
if (chooser->dialog)
|
||||||
|
{
|
||||||
|
gtk_window_present (GTK_WINDOW (chooser->dialog));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (chooser));
|
||||||
|
chooser->dialog = gtk_file_chooser_dialog_new ((const gchar *) chooser->title,
|
||||||
|
GTK_WINDOW (toplevel),
|
||||||
|
(GtkFileChooserAction) chooser->action,
|
||||||
|
_("_OK"), GTK_RESPONSE_OK,
|
||||||
|
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||||
|
NULL);
|
||||||
|
if (chooser->file)
|
||||||
|
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (chooser->dialog), chooser->file, NULL);
|
||||||
|
|
||||||
|
g_signal_connect (chooser->dialog, "response",
|
||||||
|
G_CALLBACK (gimp_file_chooser_dialog_response),
|
||||||
|
chooser);
|
||||||
|
gtk_widget_set_visible (chooser->dialog, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_file_chooser_entry_text_notify (GtkEntry *entry,
|
||||||
|
const GParamSpec *pspec,
|
||||||
|
GimpFileChooser *chooser)
|
||||||
|
{
|
||||||
|
GParamSpec *chooser_pspec;
|
||||||
|
GFile *file;
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
|
||||||
|
chooser_pspec = file_button_props[PROP_FILE];
|
||||||
|
file = g_file_parse_name (gtk_entry_get_text (entry));
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (chooser_pspec));
|
||||||
|
g_value_set_object (&value, G_OBJECT (file));
|
||||||
|
|
||||||
|
if (! g_param_value_validate (chooser_pspec, &value))
|
||||||
|
{
|
||||||
|
gimp_file_chooser_set_file (chooser, file);
|
||||||
|
gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chooser->invalid_file = TRUE;
|
||||||
|
gimp_file_chooser_set_file (chooser, NULL);
|
||||||
|
chooser->invalid_file = FALSE;
|
||||||
|
/* XXX When not validating, I initially wanted to set the entry
|
||||||
|
* borders to the error_color from the current theme. But I
|
||||||
|
* settled with a simpler icon, which works well too IMO.
|
||||||
|
*/
|
||||||
|
gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, GIMP_ICON_WILBER_EEK);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
g_clear_object (&file);
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* gimpfilechooser.c
|
||||||
|
* Copyright (C) 2025 Jehan
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined (__GIMP_WIDGETS_H_INSIDE__) && !defined (GIMP_WIDGETS_COMPILATION)
|
||||||
|
#error "Only <libgimpwidgets/gimpwidgets.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __GIMP_FILE_CHOOSER_H__
|
||||||
|
#define __GIMP_FILE_CHOOSER_H__
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GIMP_TYPE_FILE_CHOOSER (gimp_file_chooser_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (GimpFileChooser, gimp_file_chooser, GIMP, FILE_CHOOSER, GtkBox)
|
||||||
|
|
||||||
|
|
||||||
|
GtkWidget * gimp_file_chooser_new (GimpFileChooserAction action,
|
||||||
|
const gchar *label,
|
||||||
|
const gchar *title,
|
||||||
|
GFile *file);
|
||||||
|
|
||||||
|
GimpFileChooserAction gimp_file_chooser_get_action (GimpFileChooser *chooser);
|
||||||
|
void gimp_file_chooser_set_action (GimpFileChooser *chooser,
|
||||||
|
GimpFileChooserAction action);
|
||||||
|
|
||||||
|
GFile * gimp_file_chooser_get_file (GimpFileChooser *chooser);
|
||||||
|
void gimp_file_chooser_set_file (GimpFileChooser *chooser,
|
||||||
|
GFile *file);
|
||||||
|
|
||||||
|
const gchar * gimp_file_chooser_get_label (GimpFileChooser *chooser);
|
||||||
|
void gimp_file_chooser_set_label (GimpFileChooser *chooser,
|
||||||
|
const gchar *text);
|
||||||
|
|
||||||
|
const gchar * gimp_file_chooser_get_title (GimpFileChooser *chooser);
|
||||||
|
void gimp_file_chooser_set_title (GimpFileChooser *chooser,
|
||||||
|
const gchar *text);
|
||||||
|
|
||||||
|
GtkWidget * gimp_file_chooser_get_label_widget (GimpFileChooser *chooser);
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GIMP_FILE_CHOOSER_H__ */
|
|
@ -2893,6 +2893,84 @@ static void gimp_prop_file_chooser_button_notify (GObject *confi
|
||||||
GtkFileChooser *button);
|
GtkFileChooser *button);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gimp_prop_file_chooser_new:
|
||||||
|
* @config: Object to which property is attached.
|
||||||
|
* @property_name: Name of a %GimpParamSpecFile property.
|
||||||
|
* @label: (nullable): Label of the widget.
|
||||||
|
* @title: (nullable): Title of the file dialog.
|
||||||
|
*
|
||||||
|
* Creates a [class@GimpUi.FileChooser] to edit the specified file
|
||||||
|
* property. @property_name must be a %GimpParamSpecFile with an action
|
||||||
|
* other than [enum@Gimp.FileChooserAction.ANY].
|
||||||
|
*
|
||||||
|
* If @label is %NULL, @property_name's `nick` text will be used
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): A new #GtkFileChooserButton.
|
||||||
|
*
|
||||||
|
* Since: 3.0
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
gimp_prop_file_chooser_new (GObject *config,
|
||||||
|
const gchar *property_name,
|
||||||
|
const gchar *label,
|
||||||
|
const gchar *title)
|
||||||
|
{
|
||||||
|
GimpFileChooserAction action;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
GtkWidget *widget;
|
||||||
|
GFile *file = NULL;
|
||||||
|
const gchar *tooltip;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
|
||||||
|
g_return_val_if_fail (property_name != NULL, NULL);
|
||||||
|
|
||||||
|
pspec = find_param_spec (config, property_name, G_STRFUNC);
|
||||||
|
if (! pspec)
|
||||||
|
{
|
||||||
|
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_FILE (pspec))
|
||||||
|
{
|
||||||
|
g_warning ("%s: property '%s' of %s is not a GIMP_PARAM_SPEC_FILE.",
|
||||||
|
G_STRFUNC, pspec->name, g_type_name (pspec->owner_type));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
action = gimp_param_spec_file_get_action (pspec);
|
||||||
|
if (action == GIMP_FILE_CHOOSER_ACTION_ANY)
|
||||||
|
{
|
||||||
|
g_warning ("%s: property '%s' of %s must not use action GIMP_FILE_CHOOSER_ACTION_ANY.",
|
||||||
|
G_STRFUNC, pspec->name, g_type_name (pspec->owner_type));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! label)
|
||||||
|
label = g_param_spec_get_nick (pspec);
|
||||||
|
|
||||||
|
g_object_get (config,
|
||||||
|
property_name, &file,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
widget = gimp_file_chooser_new (action, label, title, file);
|
||||||
|
|
||||||
|
tooltip = g_param_spec_get_blurb (pspec);
|
||||||
|
gimp_help_set_help_data (widget, tooltip, NULL);
|
||||||
|
|
||||||
|
g_object_bind_property (config, property_name,
|
||||||
|
widget, "file",
|
||||||
|
G_BINDING_BIDIRECTIONAL);
|
||||||
|
|
||||||
|
g_clear_object (&file);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gimp_prop_file_chooser_button_new:
|
* gimp_prop_file_chooser_button_new:
|
||||||
* @config: object to which property is attached.
|
* @config: object to which property is attached.
|
||||||
|
|
|
@ -174,6 +174,11 @@ GtkWidget * gimp_prop_choice_radio_frame_new (GObject *config,
|
||||||
|
|
||||||
/* GimpParamPath */
|
/* GimpParamPath */
|
||||||
|
|
||||||
|
GtkWidget * gimp_prop_file_chooser_new (GObject *config,
|
||||||
|
const gchar *property_name,
|
||||||
|
const gchar *label,
|
||||||
|
const gchar *title);
|
||||||
|
|
||||||
GtkWidget * gimp_prop_file_chooser_button_new (GObject *config,
|
GtkWidget * gimp_prop_file_chooser_button_new (GObject *config,
|
||||||
const gchar *property_name,
|
const gchar *property_name,
|
||||||
const gchar *title,
|
const gchar *title,
|
||||||
|
|
|
@ -194,6 +194,17 @@ EXPORTS
|
||||||
gimp_enum_store_new_with_values_valist
|
gimp_enum_store_new_with_values_valist
|
||||||
gimp_enum_store_set_icon_prefix
|
gimp_enum_store_set_icon_prefix
|
||||||
gimp_event_triggers_context_menu
|
gimp_event_triggers_context_menu
|
||||||
|
gimp_file_chooser_get_action
|
||||||
|
gimp_file_chooser_get_file
|
||||||
|
gimp_file_chooser_get_label
|
||||||
|
gimp_file_chooser_get_label_widget
|
||||||
|
gimp_file_chooser_get_title
|
||||||
|
gimp_file_chooser_get_type
|
||||||
|
gimp_file_chooser_new
|
||||||
|
gimp_file_chooser_set_action
|
||||||
|
gimp_file_chooser_set_file
|
||||||
|
gimp_file_chooser_set_label
|
||||||
|
gimp_file_chooser_set_title
|
||||||
gimp_float_adjustment_update
|
gimp_float_adjustment_update
|
||||||
gimp_frame_get_type
|
gimp_frame_get_type
|
||||||
gimp_frame_new
|
gimp_frame_new
|
||||||
|
@ -383,6 +394,7 @@ EXPORTS
|
||||||
gimp_prop_expander_new
|
gimp_prop_expander_new
|
||||||
gimp_prop_file_chooser_button_new
|
gimp_prop_file_chooser_button_new
|
||||||
gimp_prop_file_chooser_button_new_with_dialog
|
gimp_prop_file_chooser_button_new_with_dialog
|
||||||
|
gimp_prop_file_chooser_new
|
||||||
gimp_prop_hscale_new
|
gimp_prop_hscale_new
|
||||||
gimp_prop_icon_image_new
|
gimp_prop_icon_image_new
|
||||||
gimp_prop_int_combo_box_new
|
gimp_prop_int_combo_box_new
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include <libgimpwidgets/gimpenumlabel.h>
|
#include <libgimpwidgets/gimpenumlabel.h>
|
||||||
#include <libgimpwidgets/gimpenumstore.h>
|
#include <libgimpwidgets/gimpenumstore.h>
|
||||||
#include <libgimpwidgets/gimpenumwidgets.h>
|
#include <libgimpwidgets/gimpenumwidgets.h>
|
||||||
|
#include <libgimpwidgets/gimpfilechooser.h>
|
||||||
#include <libgimpwidgets/gimpframe.h>
|
#include <libgimpwidgets/gimpframe.h>
|
||||||
#include <libgimpwidgets/gimphelpui.h>
|
#include <libgimpwidgets/gimphelpui.h>
|
||||||
#include <libgimpwidgets/gimphintbox.h>
|
#include <libgimpwidgets/gimphintbox.h>
|
||||||
|
|
|
@ -57,6 +57,7 @@ typedef struct _GimpDialog GimpDialog;
|
||||||
typedef struct _GimpEnumStore GimpEnumStore;
|
typedef struct _GimpEnumStore GimpEnumStore;
|
||||||
typedef struct _GimpEnumComboBox GimpEnumComboBox;
|
typedef struct _GimpEnumComboBox GimpEnumComboBox;
|
||||||
typedef struct _GimpEnumLabel GimpEnumLabel;
|
typedef struct _GimpEnumLabel GimpEnumLabel;
|
||||||
|
typedef struct _GimpFileChooser GimpFileChooser;
|
||||||
typedef struct _GimpFileEntry GimpFileEntry;
|
typedef struct _GimpFileEntry GimpFileEntry;
|
||||||
typedef struct _GimpFrame GimpFrame;
|
typedef struct _GimpFrame GimpFrame;
|
||||||
typedef struct _GimpHintBox GimpHintBox;
|
typedef struct _GimpHintBox GimpHintBox;
|
||||||
|
|
|
@ -51,6 +51,7 @@ libgimpwidgets_sources_introspectable = files(
|
||||||
'gimpenumlabel.c',
|
'gimpenumlabel.c',
|
||||||
'gimpenumstore.c',
|
'gimpenumstore.c',
|
||||||
'gimpenumwidgets.c',
|
'gimpenumwidgets.c',
|
||||||
|
'gimpfilechooser.c',
|
||||||
'gimpframe.c',
|
'gimpframe.c',
|
||||||
'gimphelpui.c',
|
'gimphelpui.c',
|
||||||
'gimphintbox.c',
|
'gimphintbox.c',
|
||||||
|
@ -134,6 +135,7 @@ libgimpwidgets_headers_introspectable = files(
|
||||||
'gimpenumlabel.h',
|
'gimpenumlabel.h',
|
||||||
'gimpenumstore.h',
|
'gimpenumstore.h',
|
||||||
'gimpenumwidgets.h',
|
'gimpenumwidgets.h',
|
||||||
|
'gimpfilechooser.h',
|
||||||
'gimpframe.h',
|
'gimpframe.h',
|
||||||
'gimphelpui.h',
|
'gimphelpui.h',
|
||||||
'gimphintbox.h',
|
'gimphintbox.h',
|
||||||
|
|
|
@ -56,6 +56,7 @@ libgimpwidgets/gimpcolorselect.c
|
||||||
libgimpwidgets/gimpcolorselection.c
|
libgimpwidgets/gimpcolorselection.c
|
||||||
libgimpwidgets/gimpcontroller.c
|
libgimpwidgets/gimpcontroller.c
|
||||||
libgimpwidgets/gimpdialog.c
|
libgimpwidgets/gimpdialog.c
|
||||||
|
libgimpwidgets/gimpfilechooser.c
|
||||||
libgimpwidgets/gimpfileentry.c
|
libgimpwidgets/gimpfileentry.c
|
||||||
libgimpwidgets/gimphelpui.c
|
libgimpwidgets/gimphelpui.c
|
||||||
libgimpwidgets/gimpicons.c
|
libgimpwidgets/gimpicons.c
|
||||||
|
|
Loading…
Reference in New Issue