Merge branch 'file-chooser-api-cleanup-2' into 'master'

File chooser api cleanup 2

See merge request GNOME/gtk!2213
This commit is contained in:
Matthias Clasen 2020-07-09 14:31:14 +00:00
commit be12131d74
18 changed files with 255 additions and 445 deletions

View File

@ -1300,10 +1300,6 @@ gtk_file_chooser_get_current_name
<SUBSECTION>
gtk_file_chooser_get_file
gtk_file_chooser_set_file
gtk_file_chooser_select_file
gtk_file_chooser_unselect_file
gtk_file_chooser_select_all
gtk_file_chooser_unselect_all
gtk_file_chooser_get_files
gtk_file_chooser_set_current_folder
gtk_file_chooser_get_current_folder
@ -1316,7 +1312,7 @@ gtk_file_chooser_get_filter
<SUBSECTION>
gtk_file_chooser_add_shortcut_folder
gtk_file_chooser_remove_shortcut_folder
gtk_file_chooser_list_shortcut_folders
gtk_file_chooser_get_shortcut_folders
<SUBSECTION>
gtk_file_chooser_add_choice
gtk_file_chooser_remove_choice

View File

@ -79,75 +79,6 @@ G_DEFINE_INTERFACE (GtkFileChooser, gtk_file_chooser, G_TYPE_OBJECT);
static void
gtk_file_chooser_default_init (GtkFileChooserInterface *iface)
{
GType iface_type = G_TYPE_FROM_INTERFACE (iface);
/**
* GtkFileChooser::current-folder-changed:
* @chooser: the object which received the signal.
*
* This signal is emitted when the current folder in a #GtkFileChooser
* changes. This can happen due to the user performing some action that
* changes folders, such as selecting a bookmark or visiting a folder on the
* file list. It can also happen as a result of calling a function to
* explicitly change the current folder in a file chooser.
*
* Normally you do not need to connect to this signal, unless you need to keep
* track of which folder a file chooser is showing.
*
* See also: gtk_file_chooser_set_current_folder(),
* gtk_file_chooser_get_current_folder(),
*/
g_signal_new (I_("current-folder-changed"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileChooserIface, current_folder_changed),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
/**
* GtkFileChooser::selection-changed:
* @chooser: the object which received the signal.
*
* This signal is emitted when there is a change in the set of selected files
* in a #GtkFileChooser. This can happen when the user modifies the selection
* with the mouse or the keyboard, or when explicitly calling functions to
* change the selection.
*
* Normally you do not need to connect to this signal, as it is easier to wait
* for the file chooser to finish running, and then to get the list of
* selected files using the functions mentioned below.
*/
g_signal_new (I_("selection-changed"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileChooserIface, selection_changed),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
/**
* GtkFileChooser::file-activated:
* @chooser: the object which received the signal.
*
* This signal is emitted when the user "activates" a file in the file
* chooser. This can happen by double-clicking on a file in the file list, or
* by pressing `Enter`.
*
* Normally you do not need to connect to this signal. It is used internally
* by #GtkFileChooserDialog to know when to activate the default button in the
* dialog.
*
* See also: gtk_file_chooser_get_file(), gtk_file_chooser_get_files()
*/
g_signal_new (I_("file-activated"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileChooserIface, file_activated),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
g_object_interface_install_property (iface,
g_param_spec_enum ("action",
P_("Action"),
@ -508,16 +439,15 @@ gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
/**
* gtk_file_chooser_get_files:
* @chooser: a #GtkFileChooser
*
* Lists all the selected files and subfolders in the current folder of @chooser
* as #GFile.
*
* Returns: (element-type GFile) (transfer full): a list
* containing a #GFile for each selected file and subfolder in the
* current folder. Free the returned list with g_slist_free(), and
* the files with g_object_unref().
**/
GSList *
* Lists all the selected files and subfolders in the current folder
* of @chooser as #GFile.
*
* Returns: (transfer full): a list model containing a #GFile for each
* selected file and subfolder in the current folder. Free the returned
* list with g_object_unref().
*/
GListModel *
gtk_file_chooser_get_files (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
@ -597,19 +527,15 @@ gtk_file_chooser_set_file (GtkFileChooser *chooser,
GFile *
gtk_file_chooser_get_file (GtkFileChooser *chooser)
{
GSList *list;
GListModel *list;
GFile *result = NULL;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
list = gtk_file_chooser_get_files (chooser);
if (list)
{
result = list->data;
list = g_slist_delete_link (list, list);
g_slist_free_full (list, g_object_unref);
}
if (g_list_model_get_n_items (list) > 0)
result = g_list_model_get_item (list, 0);
g_object_unref (list);
return result;
}

View File

@ -72,7 +72,8 @@ GType gtk_file_chooser_get_type (void) G_GNUC_CONST;
* @GTK_FILE_CHOOSER_ERROR_BAD_FILENAME: Indicates a malformed filename.
* @GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS: Indicates a duplicate path (e.g. when
* adding a bookmark).
* @GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME: Indicates an incomplete hostname (e.g. "http://foo" without a slash after that).
* @GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME: Indicates an incomplete hostname
* (e.g. "http://foo" without a slash after that).
*
* These identify the various errors that can occur while calling
* #GtkFileChooser functions.
@ -87,108 +88,100 @@ typedef enum {
GDK_AVAILABLE_IN_ALL
GQuark gtk_file_chooser_error_quark (void);
/* Configuration
*/
/* Configuration */
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_action (GtkFileChooser *chooser,
GtkFileChooserAction action);
GtkFileChooserAction action);
GDK_AVAILABLE_IN_ALL
GtkFileChooserAction gtk_file_chooser_get_action (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_select_multiple (GtkFileChooser *chooser,
gboolean select_multiple);
gboolean select_multiple);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_get_select_multiple (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_create_folders (GtkFileChooser *chooser,
gboolean create_folders);
gboolean create_folders);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_get_create_folders (GtkFileChooser *chooser);
gboolean gtk_file_chooser_get_create_folders (GtkFileChooser *chooser);
/* Suggested name for the Save-type actions
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_current_name (GtkFileChooser *chooser,
const gchar *name);
GDK_AVAILABLE_IN_ALL
gchar *gtk_file_chooser_get_current_name (GtkFileChooser *chooser);
/* Suggested name for the Save-type actions */
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_select_all (GtkFileChooser *chooser);
void gtk_file_chooser_set_current_name (GtkFileChooser *chooser,
const char *name);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_unselect_all (GtkFileChooser *chooser);
char * gtk_file_chooser_get_current_name (GtkFileChooser *chooser);
/* GFile manipulation */
GDK_AVAILABLE_IN_ALL
GFile * gtk_file_chooser_get_file (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_set_file (GtkFileChooser *chooser,
GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_select_file (GtkFileChooser *chooser,
GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
GFile *file);
GDK_AVAILABLE_IN_ALL
GSList * gtk_file_chooser_get_files (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
GFile * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser);
/* List of user selectable filters
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GFile * gtk_file_chooser_get_file (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
gboolean gtk_file_chooser_set_file (GtkFileChooser *chooser,
GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
GListModel *gtk_file_chooser_get_filters (GtkFileChooser *chooser);
GListModel * gtk_file_chooser_get_files (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
GFile * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser);
/* List of user selectable filters */
/* Current filter
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_file_chooser_get_filters (GtkFileChooser *chooser);
/* Current filter */
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GtkFileFilter * gtk_file_chooser_get_filter (GtkFileChooser *chooser);
/* Per-application shortcut folders */
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
gboolean gtk_file_chooser_remove_shortcut_folder
(GtkFileChooser *chooser,
GFile *folder,
GError **error);
GDK_AVAILABLE_IN_ALL
GListModel *gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser);
GListModel * gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser);
/* Custom widgets */
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,
const char *id,
const char *label,
const char **options,
const char **option_labels);
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,
const char *id,
const char *label,
const char **options,
const char **option_labels);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_remove_choice (GtkFileChooser *chooser,
const char *id);
void gtk_file_chooser_remove_choice (GtkFileChooser *chooser,
const char *id);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_choice (GtkFileChooser *chooser,
const char *id,
const char *option);
void gtk_file_chooser_set_choice (GtkFileChooser *chooser,
const char *id,
const char *option);
GDK_AVAILABLE_IN_ALL
const char *gtk_file_chooser_get_choice (GtkFileChooser *chooser,
const char *id);
const char * gtk_file_chooser_get_choice (GtkFileChooser *chooser,
const char *id);
G_END_DECLS

View File

@ -244,7 +244,7 @@ static gboolean gtk_file_chooser_button_select_file (GtkFileChooser *chooser,
static void gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser,
GFile *file);
static void gtk_file_chooser_button_unselect_all (GtkFileChooser *chooser);
static GSList *gtk_file_chooser_button_get_files (GtkFileChooser *chooser);
static GListModel *gtk_file_chooser_button_get_files (GtkFileChooser *chooser);
static gboolean gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
@ -627,7 +627,6 @@ emit_selection_changed_if_changing_selection (GtkFileChooserButton *button)
if (button->is_changing_selection)
{
button->is_changing_selection = FALSE;
g_signal_emit_by_name (button, "selection-changed");
}
}
@ -645,8 +644,6 @@ gtk_file_chooser_button_set_current_folder (GtkFileChooser *chooser,
update_combo_box (button);
g_signal_emit_by_name (button, "current-folder-changed");
if (button->active)
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (button->chooser), file, NULL);
@ -750,17 +747,23 @@ get_selected_file (GtkFileChooserButton *button)
return NULL;
}
static GSList *
static GListModel *
gtk_file_chooser_button_get_files (GtkFileChooser *chooser)
{
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
GFile *file;
GListStore *store;
store = g_list_store_new (G_TYPE_FILE);
file = get_selected_file (button);
if (file)
return g_slist_prepend (NULL, file);
else
return NULL;
{
g_list_store_append (store, file);
g_object_unref (file);
}
return G_LIST_MODEL (store);
}
static gboolean
@ -2512,9 +2515,6 @@ common_response_cb (GtkFileChooserButton *button,
response == GTK_RESPONSE_OK)
{
save_inactive_state (button);
g_signal_emit_by_name (button, "current-folder-changed");
g_signal_emit_by_name (button, "selection-changed");
}
else
{

View File

@ -265,12 +265,8 @@ static void gtk_file_chooser_dialog_size_allocate (GtkWidget *wid
int width,
int height,
int baseline);
static void file_chooser_widget_file_activated (GtkFileChooser *chooser,
GtkFileChooserDialog *dialog);
static void file_chooser_widget_response_requested (GtkWidget *widget,
GtkFileChooserDialog *dialog);
static void file_chooser_widget_selection_changed (GtkWidget *widget,
GtkFileChooserDialog *dialog);
static void response_cb (GtkDialog *dialog,
gint response_id);
@ -310,9 +306,7 @@ gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class)
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserDialog, widget);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserDialog, buttons);
gtk_widget_class_bind_template_callback (widget_class, response_cb);
gtk_widget_class_bind_template_callback (widget_class, file_chooser_widget_file_activated);
gtk_widget_class_bind_template_callback (widget_class, file_chooser_widget_response_requested);
gtk_widget_class_bind_template_callback (widget_class, file_chooser_widget_selection_changed);
}
static void
@ -367,34 +361,6 @@ is_accept_response_id (gint response_id)
response_id == GTK_RESPONSE_APPLY);
}
/* Callback used when the user activates a file in the file chooser widget */
static void
file_chooser_widget_file_activated (GtkFileChooser *chooser,
GtkFileChooserDialog *dialog)
{
gtk_widget_activate_default (GTK_WIDGET (chooser));
}
static void
file_chooser_widget_selection_changed (GtkWidget *widget,
GtkFileChooserDialog *dialog)
{
GtkFileChooserDialogPrivate *priv = gtk_file_chooser_dialog_get_instance_private (dialog);
GtkWidget *button;
GSList *files;
gboolean sensitive;
button = get_accept_action_widget (GTK_DIALOG (dialog), FALSE);
if (button == NULL)
return;
files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (priv->widget));
sensitive = (files != NULL);
gtk_widget_set_sensitive (button, sensitive);
g_slist_free_full (files, g_object_unref);
}
static void
file_chooser_widget_response_requested (GtkWidget *widget,
GtkFileChooserDialog *dialog)

View File

@ -158,21 +158,8 @@
* possible to use with #GtkFileChooserNative, as such use would
* prohibit the use of a native dialog.
*
* There is no support for the signals that are emitted when the user
* navigates in the dialog, including:
* * #GtkFileChooser::current-folder-changed
* * #GtkFileChooser::selection-changed
* * #GtkFileChooser::file-activated
*
* You can also not use the methods that directly control user navigation:
* * gtk_file_chooser_unselect_filename()
* * gtk_file_chooser_select_all()
* * gtk_file_chooser_unselect_all()
*
* If you need any of the above you will have to use #GtkFileChooserDialog directly.
*
* No operations that change the dialog work while the dialog is visible. Set
* all the properties that are required before showing the dialog.
* No operations that change the dialog work while the dialog is visible.
* Set all the properties that are required before showing the dialog.
*
* ## Win32 details ## {#gtkfilechooserdialognative-win32}
*
@ -180,7 +167,7 @@
* used. It supports many of the features that #GtkFileChooserDialog
* does, but there are some things it does not handle:
*
* * Any #GtkFileFilter added using a mimetype or custom filter.
* * Any #GtkFileFilter added using a mimetype
*
* If any of these features are used the regular #GtkFileChooserDialog
* will be used in place of the native one.
@ -190,10 +177,7 @@
* When the org.freedesktop.portal.FileChooser portal is available on the
* session bus, it is used to bring up an out-of-process file chooser. Depending
* on the kind of session the application is running in, this may or may not
* be a GTK+ file chooser. In this situation, the following things are not
* supported and will be silently ignored:
*
* * Any #GtkFileFilter added with a custom filter.
* be a GTK file chooser.
*
* ## macOS details ## {#gtkfilechooserdialognative-macos}
*
@ -201,8 +185,6 @@
* file chooser dialogs. Some features provided by #GtkFileChooserDialog are
* not supported:
*
* * Any #GtkFileFilter added with a custom filter.
*
* * Shortcut folders.
*/
@ -683,7 +665,7 @@ gtk_file_chooser_native_set_current_name (GtkFileChooser *chooser,
g_clear_object (&self->current_file);
}
static GSList *
static GListModel *
gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
{
GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
@ -693,7 +675,16 @@ gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
case MODE_PORTAL:
case MODE_WIN32:
case MODE_QUARTZ:
return g_slist_copy_deep (self->custom_files, (GCopyFunc)g_object_ref, NULL);
{
GListStore *store;
GSList *l;
store = g_list_store_new (G_TYPE_FILE);
for (l = self->custom_files; l; l = l->next)
g_list_store_append (store, l->data);
return G_LIST_MODEL (store);
}
case MODE_FALLBACK:
default:

View File

@ -72,7 +72,7 @@ struct _GtkFileChooserIface
GFile *file);
void (*select_all) (GtkFileChooser *chooser);
void (*unselect_all) (GtkFileChooser *chooser);
GSList * (*get_files) (GtkFileChooser *chooser);
GListModel * (*get_files) (GtkFileChooser *chooser);
GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
void (*add_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
@ -111,6 +111,13 @@ struct _GtkFileChooserIface
GtkFileSystem *_gtk_file_chooser_get_file_system (GtkFileChooser *chooser);
void gtk_file_chooser_select_all (GtkFileChooser *chooser);
void gtk_file_chooser_unselect_all (GtkFileChooser *chooser);
gboolean gtk_file_chooser_select_file (GtkFileChooser *chooser,
GFile *file,
GError **error);
void gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
GFile *file);
G_END_DECLS
#endif /* __GTK_FILE_CHOOSER_PRIVATE_H__ */

View File

@ -39,7 +39,7 @@ static void delegate_unselect_file (GtkFileChooser *choose
GFile *file);
static void delegate_select_all (GtkFileChooser *chooser);
static void delegate_unselect_all (GtkFileChooser *chooser);
static GSList * delegate_get_files (GtkFileChooser *chooser);
static GListModel * delegate_get_files (GtkFileChooser *chooser);
static GtkFileSystem *delegate_get_file_system (GtkFileChooser *chooser);
static void delegate_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
@ -56,12 +56,6 @@ static GListModel * delegate_get_shortcut_folders (GtkFileChooser *choose
static void delegate_notify (GObject *object,
GParamSpec *pspec,
gpointer data);
static void delegate_current_folder_changed (GtkFileChooser *chooser,
gpointer data);
static void delegate_selection_changed (GtkFileChooser *chooser,
gpointer data);
static void delegate_file_activated (GtkFileChooser *chooser,
gpointer data);
static void delegate_add_choice (GtkFileChooser *chooser,
const char *id,
@ -168,12 +162,6 @@ _gtk_file_chooser_set_delegate (GtkFileChooser *receiver,
g_object_set_data (G_OBJECT (receiver), I_("gtk-file-chooser-delegate"), delegate);
g_signal_connect (delegate, "notify",
G_CALLBACK (delegate_notify), receiver);
g_signal_connect (delegate, "current-folder-changed",
G_CALLBACK (delegate_current_folder_changed), receiver);
g_signal_connect (delegate, "selection-changed",
G_CALLBACK (delegate_selection_changed), receiver);
g_signal_connect (delegate, "file-activated",
G_CALLBACK (delegate_file_activated), receiver);
}
GQuark
@ -221,7 +209,7 @@ delegate_unselect_all (GtkFileChooser *chooser)
gtk_file_chooser_unselect_all (get_delegate (chooser));
}
static GSList *
static GListModel *
delegate_get_files (GtkFileChooser *chooser)
{
return gtk_file_chooser_get_files (get_delegate (chooser));
@ -315,27 +303,6 @@ delegate_notify (GObject *object,
g_object_notify (data, pspec->name);
}
static void
delegate_selection_changed (GtkFileChooser *chooser,
gpointer data)
{
g_signal_emit_by_name (data, "selection-changed");
}
static void
delegate_current_folder_changed (GtkFileChooser *chooser,
gpointer data)
{
g_signal_emit_by_name (data, "current-folder-changed");
}
static void
delegate_file_activated (GtkFileChooser *chooser,
gpointer data)
{
g_signal_emit_by_name (data, "file-activated");
}
GSettings *
_gtk_file_chooser_get_settings_for_widget (GtkWidget *widget)
{

View File

@ -479,7 +479,7 @@ static void gtk_file_chooser_widget_unselect_file (GtkF
GFile *file);
static void gtk_file_chooser_widget_select_all (GtkFileChooser *chooser);
static void gtk_file_chooser_widget_unselect_all (GtkFileChooser *chooser);
static GSList * gtk_file_chooser_widget_get_files (GtkFileChooser *chooser);
static GListModel * gtk_file_chooser_widget_get_files (GtkFileChooser *chooser);
static GtkFileSystem *gtk_file_chooser_widget_get_file_system (GtkFileChooser *chooser);
static void gtk_file_chooser_widget_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
@ -2220,14 +2220,66 @@ set_icon_cell_renderer_fixed_size (GtkFileChooserWidget *impl)
ypad * 2 + ICON_SIZE);
}
static GtkWidget *
get_accept_action_widget (GtkDialog *dialog,
gboolean sensitive_only)
{
gint response[] = {
GTK_RESPONSE_ACCEPT,
GTK_RESPONSE_OK,
GTK_RESPONSE_YES,
GTK_RESPONSE_APPLY
};
gint i;
GtkWidget *widget;
for (i = 0; i < G_N_ELEMENTS (response); i++)
{
widget = gtk_dialog_get_widget_for_response (dialog, response[i]);
if (widget)
{
if (!sensitive_only)
return widget;
if (gtk_widget_is_sensitive (widget))
return widget;
}
}
return NULL;
}
static void
update_default (GtkFileChooserWidget *impl)
{
GtkWidget *dialog;
GtkWidget *button;
GListModel *files;
gboolean sensitive;
dialog = gtk_widget_get_ancestor (GTK_WIDGET (impl), GTK_TYPE_DIALOG);
if (dialog == NULL)
return;
button = get_accept_action_widget (GTK_DIALOG (dialog), FALSE);
if (button == NULL)
return;
files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (impl));
sensitive = (g_list_model_get_n_items (files) > 0);
gtk_widget_set_sensitive (button, sensitive);
g_object_unref (files);
}
static gboolean
location_changed_timeout_cb (gpointer user_data)
{
GtkFileChooserWidget *impl = user_data;
gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (impl));
g_signal_emit_by_name (impl, "selection-changed", 0);
update_default (impl);
impl->location_changed_id = 0;
return G_SOURCE_REMOVE;
@ -5084,9 +5136,7 @@ update_current_folder_get_info_cb (GCancellable *cancellable,
g_object_notify (G_OBJECT (impl), "subtitle");
g_signal_emit_by_name (impl, "current-folder-changed", 0);
g_signal_emit_by_name (impl, "selection-changed", 0);
update_default (impl);
out:
g_object_unref (data->impl);
@ -5408,7 +5458,7 @@ check_save_entry (GtkFileChooserWidget *impl,
struct get_files_closure {
GtkFileChooserWidget *impl;
GSList *result;
GListStore *result;
GFile *file_from_entry;
};
@ -5425,10 +5475,25 @@ get_files_foreach (GtkTreeModel *model,
file = _gtk_file_system_model_get_file (fs_model, iter);
if (!info->file_from_entry || !g_file_equal (info->file_from_entry, file))
info->result = g_slist_prepend (info->result, g_object_ref (file));
g_list_store_append (info->result, file);
}
static GSList *
static GListModel *
get_selected_files_as_model (GtkFileChooserWidget *impl)
{
GListStore *store;
GSList *files, *l;
store = g_list_store_new (G_TYPE_FILE);
files = get_selected_files (impl);
for (l = files; l; l = l->next)
g_list_store_append (store, l->data);
g_slist_free_full (files, g_object_unref);
return G_LIST_MODEL (store);
}
static GListModel *
gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
{
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
@ -5437,12 +5502,8 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
GtkWidget *current_focus;
gboolean file_list_seen;
info.impl = impl;
info.result = NULL;
info.file_from_entry = NULL;
if (impl->operation_mode == OPERATION_MODE_SEARCH)
return get_selected_files (impl);
return get_selected_files_as_model (impl);
if (impl->operation_mode == OPERATION_MODE_RECENT)
{
@ -5452,9 +5513,13 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
goto file_entry;
}
else
return get_selected_files (impl);
return get_selected_files_as_model (impl);
}
info.impl = impl;
info.result = g_list_store_new (G_TYPE_FILE);
info.file_from_entry = NULL;
toplevel = get_toplevel (GTK_WIDGET (impl));
if (toplevel)
current_focus = gtk_root_get_focus (GTK_ROOT (toplevel));
@ -5498,7 +5563,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
return NULL;
if (info.file_from_entry)
info.result = g_slist_prepend (info.result, info.file_from_entry);
g_list_store_append (info.result, info.file_from_entry);
else if (!file_list_seen)
goto file_list;
else
@ -5530,10 +5595,10 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
current_folder = gtk_file_chooser_get_current_folder (chooser);
if (current_folder)
info.result = g_slist_prepend (info.result, current_folder);
g_list_store_append (info.result, current_folder);
}
return g_slist_reverse (info.result);
return G_LIST_MODEL (info.result);
}
static GtkFileSystem *
@ -6143,18 +6208,18 @@ location_popup_on_paste_handler (GtkFileChooserWidget *impl)
static void
add_selection_to_recent_list (GtkFileChooserWidget *impl)
{
GSList *files;
GSList *l;
GListModel *files;
guint i, n;
files = gtk_file_chooser_widget_get_files (GTK_FILE_CHOOSER (impl));
if (!impl->recent_manager)
impl->recent_manager = gtk_recent_manager_get_default ();
for (l = files; l; l = l->next)
n = g_list_model_get_n_items (files);
for (i = 0; i < n; i++)
{
GFile *file = l->data;
GFile *file = g_list_model_get_item (files, i);
char *uri;
uri = g_file_get_uri (file);
@ -6163,9 +6228,11 @@ add_selection_to_recent_list (GtkFileChooserWidget *impl)
gtk_recent_manager_add_item (impl->recent_manager, uri);
g_free (uri);
}
g_object_unref (file);
}
g_slist_free_full (files, g_object_unref);
g_object_unref (files);
}
static gboolean
@ -6989,8 +7056,7 @@ list_selection_changed (GtkTreeSelection *selection,
update_chooser_entry (impl);
location_bar_update (impl);
g_signal_emit_by_name (impl, "selection-changed", 0);
update_default (impl);
}
static gboolean
@ -7042,7 +7108,7 @@ list_row_activated (GtkTreeView *tree_view,
if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
g_signal_emit_by_name (impl, "file-activated");
gtk_widget_activate_default (GTK_WIDGET (impl));
out:

View File

@ -28,6 +28,7 @@
#include "gtksignallistitemfactory.h"
#include "gtkentry.h"
#include "gtkfilechooserdialog.h"
#include "gtkfilechooserprivate.h"
#include "gtkimage.h"
#include "gtklabel.h"
#include "gtkliststore.h"

View File

@ -20,9 +20,7 @@
<object class="GtkFileChooserWidget" id="widget">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<signal name="file-activated" handler="file_chooser_widget_file_activated" swapped="no"/>
<signal name="response-requested" handler="file_chooser_widget_response_requested" swapped="no"/>
<signal name="selection-changed" handler="file_chooser_widget_selection_changed" swapped="no"/>
</object>
</child>
</object>

8
lsan.supp Normal file
View File

@ -0,0 +1,8 @@
leak:_cairo_pattern_create_solid
leak:_cairo_image_surface_create_for_pixman_image
leak:g_quark_init
leak:xdg_mime_init
leak:libfontconfig.so
leak:libEGL_mesa.so
leak:iris_dri.so
leak:libpixman-1.so

View File

@ -3629,6 +3629,7 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
GTK_PRINTER_CUPS (printer)->supports_collate = info->supports_collate;
GTK_PRINTER_CUPS (printer)->supports_number_up = info->supports_number_up;
GTK_PRINTER_CUPS (printer)->number_of_covers = info->number_of_covers;
g_clear_pointer (&(GTK_PRINTER_CUPS (printer)->covers), g_strfreev);
GTK_PRINTER_CUPS (printer)->covers = g_strdupv (info->covers);
status_changed = gtk_printer_set_job_count (printer, info->job_count);
status_changed |= gtk_printer_set_location (printer, info->location);

View File

@ -41,41 +41,24 @@ static GtkWidget *preview_image;
#endif
static GtkFileChooserAction action;
static void
print_current_folder (GtkFileChooser *chooser)
{
GFile *cwd;
cwd = gtk_file_chooser_get_current_folder (chooser);
if (cwd != NULL)
{
char *uri = g_file_get_uri (cwd);
g_print ("Current folder changed :\n %s\n", uri ? uri : "(null)");
g_free (uri);
g_object_unref (cwd);
}
else
{
g_print ("Current folder changed :\n none\n");
}
}
static void
print_selected (GtkFileChooser *chooser)
{
GSList *uris = gtk_file_chooser_get_files (chooser);
GSList *tmp_list;
GListModel *files = gtk_file_chooser_get_files (chooser);
guint i, n;
g_print ("Selection changed :\n");
for (tmp_list = uris; tmp_list; tmp_list = tmp_list->next)
n = g_list_model_get_n_items (files);
for (i = 0; i < n; i++)
{
GFile *file = tmp_list->data;
GFile *file = g_list_model_get_item (files, i);
char *uri = g_file_get_uri (file);
g_print (" %s\n", uri ? uri : "(null)");
g_free (uri);
g_object_unref (files);
}
g_print ("\n");
g_slist_free_full (uris, g_object_unref);
g_object_unref (files);
}
static void
@ -87,28 +70,23 @@ response_cb (GtkDialog *dialog,
if (response_id == GTK_RESPONSE_OK)
{
GSList *list;
GListModel *files;
guint i, n;
list = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (dialog));
files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (dialog));
n = g_list_model_get_n_items (files);
if (list)
{
GSList *l;
g_print ("Selected files:\n");
for (i = 0; i < n; i++)
{
GFile *file = g_list_model_get_item (files, i);
char *uri = g_file_get_uri (file);
g_print (" %s\n", uri ? uri : "(null)");
g_free (uri);
g_object_unref (file);
}
g_print ("Selected files:\n");
for (l = list; l; l = l->next)
{
GFile *file = l->data;
char *uri = g_file_get_uri (file);
g_print (" %s\n", uri ? uri : "(null)");
g_free (uri);
}
g_slist_free_full (list, g_object_unref);
}
else
g_print ("No selected files\n");
g_object_unref (files);
}
else
g_print ("Dialog was closed\n");
@ -208,33 +186,24 @@ static void
get_selection_cb (GtkButton *button,
GtkFileChooser *chooser)
{
GSList *selection;
GListModel *selection;
guint i, n;
selection = gtk_file_chooser_get_files (chooser);
n = g_list_model_get_n_items (selection);
g_print ("Selection: ");
if (selection == NULL)
g_print ("empty\n");
else
for (i = 0; i < n; i++)
{
GSList *l;
for (l = selection; l; l = l->next)
{
GFile *file = l->data;
char *uri = g_file_get_uri (file);
g_print ("%s\n", uri);
g_free (uri);
if (l->next)
g_print (" ");
}
GFile *file = g_list_model_get_item (selection, i);
char *uri = g_file_get_uri (file);
g_print ("%s\n", uri);
g_free (uri);
g_object_unref (file);
}
g_slist_free_full (selection, g_object_unref);
g_object_unref (selection);
}
static void
@ -262,18 +231,6 @@ kill_dependent (GtkWindow *win, GtkWidget *dep)
gtk_window_destroy (GTK_WINDOW (dep));
}
static void
notify_multiple_cb (GtkWidget *dialog,
GParamSpec *pspec,
GtkWidget *button)
{
gboolean multiple;
multiple = gtk_file_chooser_get_select_multiple (GTK_FILE_CHOOSER (dialog));
gtk_widget_set_sensitive (button, multiple);
}
int
main (int argc, char **argv)
{
@ -369,8 +326,6 @@ main (int argc, char **argv)
g_signal_connect (dialog, "selection-changed",
G_CALLBACK (print_selected), NULL);
g_signal_connect (dialog, "current-folder-changed",
G_CALLBACK (print_current_folder), NULL);
g_signal_connect (dialog, "response",
G_CALLBACK (response_cb), &done);
@ -443,19 +398,6 @@ main (int argc, char **argv)
vbbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (control_window), vbbox);
button = gtk_button_new_with_mnemonic ("_Select all");
gtk_widget_set_sensitive (button, multiple);
gtk_box_append (GTK_BOX (vbbox), button);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_file_chooser_select_all), dialog);
g_signal_connect (dialog, "notify::select-multiple",
G_CALLBACK (notify_multiple_cb), button);
button = gtk_button_new_with_mnemonic ("_Unselect all");
gtk_box_append (GTK_BOX (vbbox), button);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_file_chooser_unselect_all), dialog);
button = gtk_button_new_with_label ("set_current_folder (\"/nonexistent\")");
gtk_box_append (GTK_BOX (vbbox), button);
g_signal_connect (button, "clicked",

View File

@ -104,13 +104,6 @@ del_pwds_parent_as_shortcut_clicked_cb (GtkWidget *button,
g_object_unref (path);
}
static void
unselect_all_clicked_cb (GtkWidget *button,
gpointer user_data)
{
gtk_file_chooser_unselect_all (user_data);
}
static void
tests_button_clicked_cb (GtkButton *real_button,
gpointer user_data)
@ -148,38 +141,12 @@ tests_button_clicked_cb (GtkButton *real_button,
G_CALLBACK (del_pwds_parent_as_shortcut_clicked_cb), user_data);
gtk_box_append (GTK_BOX (box), button);
button = gtk_button_new_with_label ("Unselect all");
g_signal_connect (button, "clicked",
G_CALLBACK (unselect_all_clicked_cb), user_data);
gtk_box_append (GTK_BOX (box), button);
g_object_set_data (user_data, "tests-dialog", tests);
}
gtk_window_present (GTK_WINDOW (tests));
}
static void
chooser_current_folder_changed_cb (GtkFileChooser *chooser,
gpointer user_data)
{
GFile *folder, *filename;
char *folder_uri, *filename_uri;
folder = gtk_file_chooser_get_current_folder (chooser);
filename = gtk_file_chooser_get_file (chooser);
folder_uri = g_file_get_uri (folder);
filename_uri = g_file_get_uri (filename);
g_message ("%s::current-folder-changed\n\tFolder: `%s'\n\tFilename: `%s'\nDone.\n",
G_OBJECT_TYPE_NAME (chooser), folder_uri, filename_uri);
g_free (folder_uri);
g_free (filename_uri);
g_object_unref (folder);
g_object_unref (filename);
}
static void
chooser_selection_changed_cb (GtkFileChooser *chooser,
gpointer user_data)
@ -197,27 +164,6 @@ chooser_selection_changed_cb (GtkFileChooser *chooser,
g_object_unref (filename);
}
static void
chooser_file_activated_cb (GtkFileChooser *chooser,
gpointer user_data)
{
GFile *folder, *filename;
char *folder_uri, *filename_uri;
folder = gtk_file_chooser_get_current_folder (chooser);
filename = gtk_file_chooser_get_file (chooser);
folder_uri = g_file_get_uri (folder);
filename_uri = g_file_get_uri (filename);
g_message ("%s::file-activated\n\tFolder: `%s'\n\tFilename: `%s'\nDone.\n",
G_OBJECT_TYPE_NAME (chooser), folder_uri, filename_uri);
g_free (folder_uri);
g_free (filename_uri);
g_object_unref (folder);
g_object_unref (filename);
}
static void
add_new_filechooser_button (const gchar *mnemonic,
const gchar *chooser_title,
@ -247,10 +193,7 @@ add_new_filechooser_button (const gchar *mnemonic,
g_object_unref (path);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), chooser);
g_signal_connect (chooser, "current-folder-changed",
G_CALLBACK (chooser_current_folder_changed_cb), NULL);
g_signal_connect (chooser, "selection-changed", G_CALLBACK (chooser_selection_changed_cb), NULL);
g_signal_connect (chooser, "file-activated", G_CALLBACK (chooser_file_activated_cb), NULL);
gtk_box_append (GTK_BOX (hbox), chooser);
button = gtk_button_new_with_label ("Tests");

View File

@ -5507,22 +5507,26 @@ native_response (GtkNativeDialog *self,
{
static int count = 0;
char *res;
GSList *uris, *l;
GString *s;
char *response;
GtkFileFilter *filter;
GListModel *files;
guint i, n;
uris = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (self));
files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (self));
filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
s = g_string_new ("");
for (l = uris; l != NULL; l = l->next)
n = g_list_model_get_n_items (files);
for (i = 0; i < n; i++)
{
char *uri = g_file_get_uri (l->data);
GFile *file = g_list_model_get_item (files, i);
char *uri = g_file_get_uri (file);
g_string_prepend (s, uri);
g_string_prepend (s, "\n");
g_free (uri);
g_object_unref (file);
}
g_slist_free_full (uris, g_object_unref);
g_object_unref (files);
switch (response_id)
{

View File

@ -190,6 +190,7 @@ generate_focus_chain (GtkWidget *window,
}
g_free (name);
g_free (key);
g_free (first);
g_free (last);

View File

@ -360,7 +360,7 @@ add_test_for_file (GFile *file)
if (g_file_query_file_type (file, 0, NULL) != G_FILE_TYPE_DIRECTORY)
{
g_test_add_vtable (g_file_get_path (file),
g_test_add_vtable (g_file_peek_path (file),
0,
g_object_ref (file),
NULL,