Merge branch 'file-chooser-api-cleanups' into 'master'

File chooser api cleanups

See merge request GNOME/gtk!2195
This commit is contained in:
Matthias Clasen 2020-07-06 15:41:56 +00:00
commit 2a2a6879c5
14 changed files with 308 additions and 201 deletions

View File

@ -1310,7 +1310,7 @@ gtk_file_chooser_get_current_folder
<SUBSECTION>
gtk_file_chooser_add_filter
gtk_file_chooser_remove_filter
gtk_file_chooser_list_filters
gtk_file_chooser_get_filters
gtk_file_chooser_set_filter
gtk_file_chooser_get_filter
<SUBSECTION>

View File

@ -168,6 +168,38 @@ gtk_file_chooser_default_init (GtkFileChooserInterface *iface)
FALSE,
GTK_PARAM_READWRITE));
/**
* GtkFileChooser:filters:
*
* A #GListModel containing the filters that have been
* added with gtk_file_chooser_add_filter().
*
* The returned object should not be modified. It may
* or may not be updated for later changes.
*/
g_object_interface_install_property (iface,
g_param_spec_object ("filters",
P_("Filters"),
P_("List model of filters"),
G_TYPE_LIST_MODEL,
GTK_PARAM_READABLE));
/**
* GtkFileChooser:shortcut-folders:
*
* A #GListModel containing the shortcut folders that have been
* added with gtk_file_chooser_add_shortcut().
*
* The returned object should not be modified. It may
* or may not be updated for later changes.
*/
g_object_interface_install_property (iface,
g_param_spec_object ("shortcut-folders",
P_("Shortcut Folders"),
P_("List model of shortcut folders"),
G_TYPE_LIST_MODEL,
GTK_PARAM_READABLE));
/**
* GtkFileChooser:create-folders:
*
@ -682,23 +714,24 @@ gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
}
/**
* gtk_file_chooser_list_filters:
* gtk_file_chooser_get_filters:
* @chooser: a #GtkFileChooser
*
* Lists the current set of user-selectable filters; see
* Gets the current set of user-selectable filters, as a list model; see
* gtk_file_chooser_add_filter(), gtk_file_chooser_remove_filter().
*
* Returns: (element-type GtkFileFilter) (transfer container): a
* #GSList containing the current set of user selectable filters. The
* contents of the list are owned by GTK+, but you must free the list
* itself with g_slist_free() when you are done with it.
* You should not modify the returned list model. Future changes to
* @chooser may or may not affect the returned model.
*
* Returns: (transfer full): a #GListModel containing the current set
* of user-selectable filters.
**/
GSList *
gtk_file_chooser_list_filters (GtkFileChooser *chooser)
GListModel *
gtk_file_chooser_get_filters (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_filters (chooser);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_filters (chooser);
}
/**
@ -750,21 +783,23 @@ gtk_file_chooser_get_filter (GtkFileChooser *chooser)
}
/**
* gtk_file_chooser_list_shortcut_folders:
* gtk_file_chooser_get_shortcut_folders:
* @chooser: a #GtkFileChooser
*
* Queries the list of shortcut folders in the file chooser, as set by
* gtk_file_chooser_add_shortcut_folder().
*
* Returns: (nullable) (element-type Gio.File) (transfer full): A list
* of folder filenames, or %NULL if there are no shortcut folders.
* You should not modify the returned list model. Future changes to
* @chooser may or may not affect the returned model.
*
* Returns: (transfer full): A list model of #GFiles
*/
GSList *
gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser)
GListModel *
gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_shortcut_folders (chooser);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_shortcut_folders (chooser);
}
/**

View File

@ -145,18 +145,18 @@ GFile * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser);
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GSList *gtk_file_chooser_list_filters (GtkFileChooser *chooser);
GListModel *gtk_file_chooser_get_filters (GtkFileChooser *chooser);
/* Current filter
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
@ -164,14 +164,14 @@ GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
GFile *folder,
GError **error);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
GFile *folder,
GError **error);
GDK_AVAILABLE_IN_ALL
GSList *gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser);
GListModel *gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,

View File

@ -1035,6 +1035,8 @@ gtk_file_chooser_button_get_property (GObject *object,
case GTK_FILE_CHOOSER_PROP_FILTER:
case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS:
case GTK_FILE_CHOOSER_PROP_FILTERS:
case GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS:
g_object_get_property (G_OBJECT (button->chooser), pspec->name, value);
break;

View File

@ -126,7 +126,7 @@ response_cb (GDBusConnection *connection,
if (current_filter)
{
GtkFileFilter *filter = gtk_file_filter_new_from_gvariant (current_filter);
const gchar *current_filter_name = gtk_file_filter_get_name (filter);
const char *current_filter_name = gtk_file_filter_get_name (filter);
/* Try to find the given filter in the list of filters.
* Since filters are compared by pointer value, using the passed
@ -137,18 +137,24 @@ response_cb (GDBusConnection *connection,
* If there is no match, just set the filter as it was retrieved.
*/
GtkFileFilter *filter_to_select = filter;
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
for (GSList *l = filters; l; l = l->next)
GListModel *filters;
guint j, n;
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
n = g_list_model_get_n_items (filters);
for (j = 0; j < n; j++)
{
GtkFileFilter *f = l->data;
GtkFileFilter *f = g_list_model_get_item (filters, j);
if (g_strcmp0 (gtk_file_filter_get_name (f), current_filter_name) == 0)
{
filter_to_select = f;
break;
}
g_object_unref (f);
}
g_slist_free (filters);
g_object_unref (filters);
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (self), filter_to_select);
g_object_unref (filter_to_select);
}
g_slist_free_full (self->custom_files, g_object_unref);
@ -264,17 +270,20 @@ open_file_msg_cb (GObject *source_object,
static GVariant *
get_filters (GtkFileChooser *self)
{
GSList *list, *l;
GListModel *filters;
guint n, i;
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sa(us))"));
list = gtk_file_chooser_list_filters (self);
for (l = list; l; l = l->next)
filters = gtk_file_chooser_get_filters (self);
n = g_list_model_get_n_items (filters);
for (i = 0; i < n; i++)
{
GtkFileFilter *filter = l->data;
GtkFileFilter *filter = g_list_model_get_item (filters, i);
g_variant_builder_add (&builder, "@(sa(us))", gtk_file_filter_to_gvariant (filter));
g_object_unref (filter);
}
g_slist_free (list);
g_object_unref (filters);
return g_variant_builder_end (&builder);
}

View File

@ -99,9 +99,10 @@ typedef struct {
else
[data->panel setAllowedFileTypes:filter];
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
data->self->current_filter = g_slist_nth_data (filters, selected_index);
g_slist_free (filters);
GListModel *filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
data->self->current_filter = g_list_model_get_item (filters, selected_index);
g_object_unref (data->self->current_filter);
g_object_unref (filters);
g_object_notify (G_OBJECT (data->self), "filter");
}
@end
@ -307,13 +308,28 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
if (data->self->current_filter)
{
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
gint current_filter_index = g_slist_index (filters, data->self->current_filter);
g_slist_free (filters);
GListModel *filters;
guint i, n;
guint current_filter_index = GTK_INVALID_LIST_POSITION;
if (current_filter_index >= 0)
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
n = g_list_model_get_n_items (filters);
for (i = 0; i < n; i++)
{
gpointer item = g_list_model_get_item (filters, i);
if (item == data->self->current_filter)
{
g_object_unref (item);
current_filter_index = i;
break;
}
g_object_unref (item);
}
g_object_unref (filters);
if (current_filter_index != GTK_INVALID_LIST_POSITION)
[data->filter_combo_box selectItemAtIndex:current_filter_index];
else
else
[data->filter_combo_box selectItemAtIndex:0];
}
else
@ -437,15 +453,15 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
GtkWindow *transient_for;
GtkFileChooserAction action;
GSList *filters, *l;
int n_filters, i;
GListModel *filters;
guint n_filters, i;
char *message = NULL;
data = g_new0 (FileChooserQuartzData, 1);
// examine filters!
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
n_filters = g_slist_length (filters);
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
n_filters = g_list_model_get_n_items (filters);
if (n_filters > 0)
{
data->filters = [NSMutableArray arrayWithCapacity:n_filters];
@ -453,13 +469,17 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
data->filter_names = [NSMutableArray arrayWithCapacity:n_filters];
[data->filter_names retain];
for (l = filters, i = 0; l != NULL; l = l->next, i++)
for (i = 0; i < n; i++)
{
if (!file_filter_to_quartz (l->data, data->filters, data->filter_names))
GtkFileFilter *filter = g_list_model_get_item (filters, i);
if (!file_filter_to_quartz (filter, data->filters, data->filter_names))
{
filechooser_quartz_data_free (data);
g_object_unref (filter);
g_object_unref (filters);
return FALSE;
}
g_object_unref (filter);
}
self->current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
}
@ -467,6 +487,8 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
{
self->current_filter = NULL;
}
g_object_unref (filters);
self->mode_data = data;
data->self = g_object_ref (self);

View File

@ -66,7 +66,7 @@ typedef struct {
char *cancel_label;
char *title;
GSList *shortcut_files;
GListModel *shortcut_files;
GArray *choices_selections;
GFile *current_folder;
@ -244,9 +244,11 @@ ifiledialogevents_OnTypeChange (IFileDialogEvents * self,
return S_OK;
}
fileType--; // fileTypeIndex starts at 1
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (events->data->self));
events->data->self->current_filter = g_slist_nth_data (filters, fileType);
g_slist_free (filters);
GListModel *filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (events->data->self));
GtkFileFilter *filter = g_list_model_get_item (filters, fileType);
events->data->self->current_filter = filter;
g_object_unref (filter);
g_object_unref (filters);
g_object_notify (G_OBJECT (events->data->self), "filter");
return S_OK;
}
@ -328,7 +330,7 @@ filechooser_win32_thread_data_free (FilechooserWin32ThreadData *data)
g_array_free (data->choices_selections, TRUE);
data->choices_selections = NULL;
}
g_slist_free_full (data->shortcut_files, g_object_unref);
g_object_unref (data->shortcut_files);
g_slist_free_full (data->files, g_object_unref);
if (data->self)
g_object_unref (data->self);
@ -463,7 +465,7 @@ filechooser_win32_thread (gpointer _data)
IFileDialog2 *pfd2 = NULL;
DWORD flags;
DWORD cookie;
GSList *l;
guint j, n_items;
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
@ -529,9 +531,11 @@ filechooser_win32_thread (gpointer _data)
g_free (label);
}
for (l = data->shortcut_files; l != NULL; l = l->next)
n_items = g_list_model_get_n_items (data->shortcut_files);
for (j = 0; j < n_items; j++)
{
IShellItem *item = get_shell_item_for_file (l->data);
GFile *file = g_list_model_get_item (data->shortcut_files, j);
IShellItem *item = get_shell_item_for_file (file);
if (item)
{
hr = IFileDialog_AddPlace (pfd, item, FDAP_BOTTOM);
@ -539,6 +543,7 @@ filechooser_win32_thread (gpointer _data)
g_warning_hr ("Can't add dialog shortcut", hr);
IShellItem_Release (item);
}
g_object_unref (file);
}
if (data->current_file)
@ -591,9 +596,23 @@ filechooser_win32_thread (gpointer _data)
if (data->self->current_filter)
{
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
gint current_filter_index = g_slist_index (filters, data->self->current_filter);
g_slist_free (filters);
GListModel *filters;
guint current_filter_index = GTK_INVALID_LIST_POSITION;
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
n_items = g_list_model_get_n_items (filters);
for (j = 0; j < n_items; j++)
{
gpointer item = g_list_model_get_item (filters, j);
if (item == data->self->current_filter)
{
current_filter_index = j;
g_object_unref (item);
break;
}
g_object_unref (item);
}
g_object_unref (filters);
if (current_filter_index >= 0)
hr = IFileDialog_SetFileTypeIndex (pfd, current_filter_index + 1);
@ -617,6 +636,8 @@ filechooser_win32_thread (gpointer _data)
hr = IFileDialog_QueryInterface (pfd, &IID_IFileDialogCustomize, (LPVOID *) &pfdc);
if (SUCCEEDED (hr))
{
GSList *l;
for (l = data->self->choices; l; l = l->next, dialog_control_id++)
{
GtkFileChooserNativeChoice *choice = (GtkFileChooserNativeChoice*) l->data;
@ -742,6 +763,8 @@ filechooser_win32_thread (gpointer _data)
hr = IFileDialog_QueryInterface (pfd, &IID_IFileDialogCustomize, (LPVOID *) &pfdc);
if (SUCCEEDED (hr))
{
GSList *l;
for (l = data->self->choices; l; l = l->next)
{
GtkFileChooserNativeChoice *choice = (GtkFileChooserNativeChoice*) l->data;
@ -864,21 +887,24 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
FilechooserWin32ThreadData *data;
GtkWindow *transient_for;
GtkFileChooserAction action;
GSList *filters, *l;
int n_filters, i;
GListModel *filters;
guint n_filters, i;
data = g_new0 (FilechooserWin32ThreadData, 1);
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
n_filters = g_slist_length (filters);
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
n_filters = g_list_model_get_n_items (filters);
if (n_filters > 0)
{
data->filters = g_new0 (COMDLG_FILTERSPEC, n_filters + 1);
for (l = filters, i = 0; l != NULL; l = l->next, i++)
for (i = 0; i < n_filters; i++)
{
if (!file_filter_to_win32 (l->data, &data->filters[i]))
GtkFileFilter *filter = g_list_model_get_item (filters, i);
if (!file_filter_to_win32 (filter, &data->filters[i]))
{
g_object_unref (filter);
g_object_unref (filters);
filechooser_win32_thread_data_free (data);
return FALSE;
}
@ -889,12 +915,13 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
{
self->current_filter = NULL;
}
g_object_unref (filters);
self->mode_data = data;
data->self = g_object_ref (self);
data->shortcut_files =
gtk_file_chooser_list_shortcut_folders (GTK_FILE_CHOOSER (self->dialog));
gtk_file_chooser_get_shortcut_folders (GTK_FILE_CHOOSER (self->dialog));
data->accept_label = translate_mnemonics (self->accept_label);
data->cancel_label = translate_mnemonics (self->cancel_label);

View File

@ -58,34 +58,34 @@ struct _GtkFileChooserIface
/* Methods
*/
gboolean (*set_current_folder) (GtkFileChooser *chooser,
GFile *file,
GError **error);
GFile * (*get_current_folder) (GtkFileChooser *chooser);
void (*set_current_name) (GtkFileChooser *chooser,
const gchar *name);
gboolean (*set_current_folder) (GtkFileChooser *chooser,
GFile *file,
GError **error);
GFile * (*get_current_folder) (GtkFileChooser *chooser);
void (*set_current_name) (GtkFileChooser *chooser,
const gchar *name);
gchar * (*get_current_name) (GtkFileChooser *chooser);
gboolean (*select_file) (GtkFileChooser *chooser,
GFile *file,
GError **error);
void (*unselect_file) (GtkFileChooser *chooser,
GFile *file);
void (*select_all) (GtkFileChooser *chooser);
void (*unselect_all) (GtkFileChooser *chooser);
GSList * (*get_files) (GtkFileChooser *chooser);
GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
void (*add_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
void (*remove_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
GSList * (*list_filters) (GtkFileChooser *chooser);
gboolean (*select_file) (GtkFileChooser *chooser,
GFile *file,
GError **error);
void (*unselect_file) (GtkFileChooser *chooser,
GFile *file);
void (*select_all) (GtkFileChooser *chooser);
void (*unselect_all) (GtkFileChooser *chooser);
GSList * (*get_files) (GtkFileChooser *chooser);
GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
void (*add_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
void (*remove_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
GListModel * (*get_filters) (GtkFileChooser *chooser);
gboolean (*add_shortcut_folder) (GtkFileChooser *chooser,
GFile *file,
GError **error);
GFile *file,
GError **error);
gboolean (*remove_shortcut_folder) (GtkFileChooser *chooser,
GFile *file,
GError **error);
GSList * (*list_shortcut_folders) (GtkFileChooser *chooser);
GFile *file,
GError **error);
GListModel * (*get_shortcut_folders) (GtkFileChooser *chooser);
/* Signals
*/

View File

@ -45,14 +45,14 @@ static void delegate_add_filter (GtkFileChooser *choose
GtkFileFilter *filter);
static void delegate_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
static GSList * delegate_list_filters (GtkFileChooser *chooser);
static GListModel * delegate_get_filters (GtkFileChooser *chooser);
static gboolean delegate_add_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
static gboolean delegate_remove_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
static GSList * delegate_list_shortcut_folders (GtkFileChooser *chooser);
static GListModel * delegate_get_shortcut_folders (GtkFileChooser *chooser);
static void delegate_notify (GObject *object,
GParamSpec *pspec,
gpointer data);
@ -92,17 +92,23 @@ void
_gtk_file_chooser_install_properties (GObjectClass *klass)
{
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_ACTION,
"action");
GTK_FILE_CHOOSER_PROP_ACTION,
"action");
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_FILTER,
"filter");
GTK_FILE_CHOOSER_PROP_FILTER,
"filter");
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
"select-multiple");
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
"select-multiple");
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
"create-folders");
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
"create-folders");
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_FILTERS,
"filters");
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS,
"shortcut-folders");
}
/**
@ -131,10 +137,10 @@ _gtk_file_chooser_delegate_iface_init (GtkFileChooserIface *iface)
iface->get_file_system = delegate_get_file_system;
iface->add_filter = delegate_add_filter;
iface->remove_filter = delegate_remove_filter;
iface->list_filters = delegate_list_filters;
iface->get_filters = delegate_get_filters;
iface->add_shortcut_folder = delegate_add_shortcut_folder;
iface->remove_shortcut_folder = delegate_remove_shortcut_folder;
iface->list_shortcut_folders = delegate_list_shortcut_folders;
iface->get_shortcut_folders = delegate_get_shortcut_folders;
iface->add_choice = delegate_add_choice;
iface->remove_choice = delegate_remove_choice;
iface->set_choice = delegate_set_choice;
@ -241,10 +247,10 @@ delegate_remove_filter (GtkFileChooser *chooser,
gtk_file_chooser_remove_filter (get_delegate (chooser), filter);
}
static GSList *
delegate_list_filters (GtkFileChooser *chooser)
static GListModel *
delegate_get_filters (GtkFileChooser *chooser)
{
return gtk_file_chooser_list_filters (get_delegate (chooser));
return gtk_file_chooser_get_filters (get_delegate (chooser));
}
static gboolean
@ -263,10 +269,10 @@ delegate_remove_shortcut_folder (GtkFileChooser *chooser,
return gtk_file_chooser_remove_shortcut_folder (get_delegate (chooser), file, error);
}
static GSList *
delegate_list_shortcut_folders (GtkFileChooser *chooser)
static GListModel *
delegate_get_shortcut_folders (GtkFileChooser *chooser)
{
return gtk_file_chooser_list_shortcut_folders (get_delegate (chooser));
return gtk_file_chooser_get_shortcut_folders (get_delegate (chooser));
}
static gboolean

View File

@ -32,7 +32,9 @@ typedef enum {
GTK_FILE_CHOOSER_PROP_FILTER,
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS
GTK_FILE_CHOOSER_PROP_FILTERS,
GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS,
GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS
} GtkFileChooserProp;
void _gtk_file_chooser_install_properties (GObjectClass *klass);

View File

@ -485,14 +485,14 @@ static void gtk_file_chooser_widget_add_filter (GtkF
GtkFileFilter *filter);
static void gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
static GSList * gtk_file_chooser_widget_list_filters (GtkFileChooser *chooser);
static GListModel * gtk_file_chooser_widget_get_filters (GtkFileChooser *chooser);
static gboolean gtk_file_chooser_widget_add_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
static gboolean gtk_file_chooser_widget_remove_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
static GSList * gtk_file_chooser_widget_list_shortcut_folders (GtkFileChooser *chooser);
static GListModel * gtk_file_chooser_widget_get_shortcut_folders (GtkFileChooser *chooser);
static gboolean gtk_file_chooser_widget_should_respond (GtkFileChooserEmbed *chooser_embed);
static void gtk_file_chooser_widget_initial_focus (GtkFileChooserEmbed *chooser_embed);
@ -619,10 +619,10 @@ gtk_file_chooser_widget_iface_init (GtkFileChooserIface *iface)
iface->get_current_name = gtk_file_chooser_widget_get_current_name;
iface->add_filter = gtk_file_chooser_widget_add_filter;
iface->remove_filter = gtk_file_chooser_widget_remove_filter;
iface->list_filters = gtk_file_chooser_widget_list_filters;
iface->get_filters = gtk_file_chooser_widget_get_filters;
iface->add_shortcut_folder = gtk_file_chooser_widget_add_shortcut_folder;
iface->remove_shortcut_folder = gtk_file_chooser_widget_remove_shortcut_folder;
iface->list_shortcut_folders = gtk_file_chooser_widget_list_shortcut_folders;
iface->get_shortcut_folders = gtk_file_chooser_widget_get_shortcut_folders;
iface->add_choice = gtk_file_chooser_widget_add_choice;
iface->remove_choice = gtk_file_chooser_widget_remove_choice;
iface->set_choice = gtk_file_chooser_widget_set_choice;
@ -3072,6 +3072,14 @@ gtk_file_chooser_widget_get_property (GObject *object,
g_value_set_boolean (value, impl->create_folders);
break;
case GTK_FILE_CHOOSER_PROP_FILTERS:
g_value_set_object (value, impl->filters);
break;
case GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS:
g_value_take_object (value, gtk_file_chooser_get_shortcut_folders (GTK_FILE_CHOOSER (impl)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -3429,25 +3437,27 @@ set_startup_mode (GtkFileChooserWidget *impl)
static gboolean
shortcut_exists (GtkFileChooserWidget *impl, GFile *needle)
{
GSList *haystack;
GSList *l;
GListModel *haystack;
guint n, i;
gboolean exists;
exists = FALSE;
haystack = gtk_places_sidebar_list_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
for (l = haystack; l; l = l->next)
haystack = gtk_places_sidebar_get_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
n = g_list_model_get_n_items (haystack);
for (i = 0; i < n; i++)
{
GFile *hay;
GFile *hay = g_list_model_get_item (haystack, i);
hay = G_FILE (l->data);
if (g_file_equal (hay, needle))
{
g_object_unref (hay);
exists = TRUE;
break;
}
g_object_unref (hay);
}
g_slist_free_full (haystack, g_object_unref);
g_object_unref (haystack);
return exists;
}
@ -5564,6 +5574,8 @@ gtk_file_chooser_widget_add_filter (GtkFileChooser *chooser,
set_current_filter (impl, filter);
show_filters (impl, TRUE);
g_object_notify (G_OBJECT (chooser), "filters");
}
static void
@ -5597,25 +5609,16 @@ gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser,
if (!impl->filters)
show_filters (impl, FALSE);
g_object_notify (G_OBJECT (chooser), "filters");
}
static GSList *
gtk_file_chooser_widget_list_filters (GtkFileChooser *chooser)
static GListModel *
gtk_file_chooser_widget_get_filters (GtkFileChooser *chooser)
{
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
GSList *filters;
guint i;
filters = NULL;
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (impl->filters)); i++)
{
GtkFileFilter *filter = g_list_model_get_item (G_LIST_MODEL (impl->filters), i);
filters = g_slist_append (filters, filter);
g_object_unref (filter);
}
return filters;
return G_LIST_MODEL (g_object_ref (impl->filters));
}
static gboolean
@ -5626,6 +5629,9 @@ gtk_file_chooser_widget_add_shortcut_folder (GtkFileChooser *chooser,
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
gtk_places_sidebar_add_shortcut (GTK_PLACES_SIDEBAR (impl->places_sidebar), file);
g_object_notify (G_OBJECT (chooser), "shortcut-folders");
return TRUE;
}
@ -5637,15 +5643,18 @@ gtk_file_chooser_widget_remove_shortcut_folder (GtkFileChooser *chooser,
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
gtk_places_sidebar_remove_shortcut (GTK_PLACES_SIDEBAR (impl->places_sidebar), file);
g_object_notify (G_OBJECT (chooser), "shortcut-folders");
return TRUE;
}
static GSList *
gtk_file_chooser_widget_list_shortcut_folders (GtkFileChooser *chooser)
static GListModel *
gtk_file_chooser_widget_get_shortcut_folders (GtkFileChooser *chooser)
{
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
return gtk_places_sidebar_list_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
return gtk_places_sidebar_get_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
}
struct switch_folder_closure {

View File

@ -162,7 +162,7 @@ struct _GtkPlacesSidebar {
GtkWidget *popover;
GtkSidebarRow *context_row;
GSList *shortcuts;
GListStore *shortcuts;
GDBusProxy *hostnamed_proxy;
GCancellable *hostnamed_cancellable;
@ -709,15 +709,25 @@ file_is_shown (GtkPlacesSidebar *sidebar,
return found;
}
typedef struct
{
GtkPlacesSidebar *sidebar;
guint position;
} ShortcutData;
static void
on_app_shortcuts_query_complete (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkPlacesSidebar *sidebar = data;
ShortcutData *sdata = data;
GtkPlacesSidebar *sidebar = sdata->sidebar;
guint pos = sdata->position;
GFile *file = G_FILE (source);
GFileInfo *info;
g_free (sdata);
info = g_file_query_info_finish (file, result, NULL);
if (info)
@ -726,20 +736,12 @@ on_app_shortcuts_query_complete (GObject *source,
gchar *tooltip;
const gchar *name;
GIcon *start_icon;
int pos = 0;
name = g_file_info_get_display_name (info);
start_icon = g_file_info_get_symbolic_icon (info);
uri = g_file_get_uri (file);
tooltip = g_file_get_parse_name (file);
/* XXX: we could avoid this by using an ancillary closure
* with the index coming from add_application_shortcuts(),
* but in terms of algorithmic overhead, the application
* shortcuts is not going to be really big
*/
pos = g_slist_index (sidebar->shortcuts, file);
add_place (sidebar, PLACES_BUILT_IN,
SECTION_COMPUTER,
name, start_icon, NULL, uri,
@ -757,11 +759,13 @@ on_app_shortcuts_query_complete (GObject *source,
static void
add_application_shortcuts (GtkPlacesSidebar *sidebar)
{
GSList *l;
guint i, n;
for (l = sidebar->shortcuts; l; l = l->next)
n = g_list_model_get_n_items (G_LIST_MODEL (sidebar->shortcuts));
for (i = 0; i < n; i++)
{
GFile *file = l->data;
GFile *file = g_list_model_get_item (G_LIST_MODEL (sidebar->shortcuts), i);
ShortcutData *data;
if (!should_show_file (sidebar, file))
continue;
@ -769,13 +773,16 @@ add_application_shortcuts (GtkPlacesSidebar *sidebar)
if (file_is_shown (sidebar, file))
continue;
data = g_new (ShortcutData, 1);
data->sidebar = sidebar;
data->position = i;
g_file_query_info_async (file,
"standard::display-name,standard::symbolic-icon",
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT,
sidebar->cancellable,
on_app_shortcuts_query_complete,
sidebar);
data);
}
}
@ -3748,6 +3755,8 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
sidebar->show_recent = TRUE;
sidebar->show_desktop = TRUE;
sidebar->shortcuts = g_list_store_new (G_TYPE_FILE);
create_volume_monitor (sidebar);
sidebar->open_flags = GTK_PLACES_OPEN_NORMAL;
@ -4018,9 +4027,7 @@ gtk_places_sidebar_dispose (GObject *object)
g_clear_object (&sidebar->current_location);
g_clear_pointer (&sidebar->rename_uri, g_free);
g_slist_free_full (sidebar->shortcuts, g_object_unref);
sidebar->shortcuts = NULL;
g_clear_object (&sidebar->shortcuts);
#ifdef HAVE_CLOUDPROVIDERS
for (l = cloud_providers_collector_get_providers (sidebar->cloud_manager);
@ -4782,24 +4789,6 @@ gtk_places_sidebar_get_show_trash (GtkPlacesSidebar *sidebar)
return sidebar->show_trash;
}
static GSList *
find_shortcut_link (GtkPlacesSidebar *sidebar,
GFile *location)
{
GSList *l;
for (l = sidebar->shortcuts; l; l = l->next)
{
GFile *shortcut;
shortcut = G_FILE (l->data);
if (g_file_equal (shortcut, location))
return l;
}
return NULL;
}
/*
* gtk_places_sidebar_add_shortcut:
* @sidebar: a places sidebar
@ -4823,8 +4812,7 @@ gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar,
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
g_return_if_fail (G_IS_FILE (location));
g_object_ref (location);
sidebar->shortcuts = g_slist_append (sidebar->shortcuts, location);
g_list_store_append (sidebar->shortcuts, location);
update_places (sidebar);
}
@ -4842,43 +4830,46 @@ void
gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
GFile *location)
{
GSList *link;
GFile *shortcut;
guint i, n;
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
g_return_if_fail (G_IS_FILE (location));
link = find_shortcut_link (sidebar, location);
if (!link)
return;
n = g_list_model_get_n_items (G_LIST_MODEL (sidebar->shortcuts));
for (i = 0; i < n; i++)
{
GFile *shortcut = g_list_model_get_item (G_LIST_MODEL (sidebar->shortcuts), i);
shortcut = G_FILE (link->data);
g_object_unref (shortcut);
if (shortcut == location)
{
g_list_store_remove (sidebar->shortcuts, i);
g_object_unref (shortcut);
update_places (sidebar);
return;
}
sidebar->shortcuts = g_slist_delete_link (sidebar->shortcuts, link);
update_places (sidebar);
g_object_unref (shortcut);
}
}
/*
* gtk_places_sidebar_list_shortcuts:
* @sidebar: a places sidebar
*
* Gets the list of shortcuts.
* Gets the list of shortcuts, as a list model containing #GFile objects.
*
* Returns: (element-type GFile) (transfer full):
* A #GSList of #GFile of the locations that have been added as
* You should not modify the returned list model. Future changes to
* @sidebar may or may not affect the returned model.
*
* Returns: (transfer full): a list model of #GFiles that have been added as
* application-specific shortcuts with gtk_places_sidebar_add_shortcut().
* To free this list, you can use
* |[<!-- language="C" -->
* g_slist_free_full (list, (GDestroyNotify) g_object_unref);
* ]|
*/
GSList *
gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar)
GListModel *
gtk_places_sidebar_get_shortcuts (GtkPlacesSidebar *sidebar)
{
g_return_val_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar), NULL);
return g_slist_copy_deep (sidebar->shortcuts, (GCopyFunc) g_object_ref, NULL);
return G_LIST_MODEL (g_object_ref (sidebar->shortcuts));
}
/*

View File

@ -92,7 +92,7 @@ void gtk_places_sidebar_add_shortcut (GtkPlacesSideb
GFile *location);
void gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
GFile *location);
GSList * gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar);
GListModel * gtk_places_sidebar_get_shortcuts (GtkPlacesSidebar *sidebar);
GFile * gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar,
gint n);

View File

@ -5672,15 +5672,19 @@ native_filter_changed (GtkWidget *combo,
GtkFileChooserNative *native)
{
int i;
GSList *filters, *l;
GListModel *filters;
GtkFileFilter *filter;
i = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (native));
for (l = filters; l != NULL; l = l->next)
gtk_file_chooser_remove_filter (GTK_FILE_CHOOSER (native), l->data);
g_slist_free (filters);
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (native));
while (g_list_model_get_n_items (filters) > 0)
{
GtkFileFilter *f = g_list_model_get_item (filters, 0);
gtk_file_chooser_remove_filter (GTK_FILE_CHOOSER (native), f);
g_object_unref (f);
}
g_object_unref (filters);
switch (i)
{