Merge branch 'file-chooser-selectability2' into 'main'

file system model: Store selectability

See merge request GNOME/gtk!5582
This commit is contained in:
Matthias Clasen 2023-03-10 16:37:41 +00:00
commit 5f24218123
6 changed files with 99 additions and 4 deletions

View File

@ -103,6 +103,8 @@ gtk_column_list_item_factory_update (GtkListItemFactory *factory,
{
GtkListItem *list_item = GTK_LIST_ITEM (item);
GtkWidget *child;
gboolean selectable = TRUE;
gboolean activatable = TRUE;
GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->update (factory, item, unbind, bind, func, data);
@ -114,7 +116,18 @@ gtk_column_list_item_factory_update (GtkListItemFactory *factory,
gtk_list_item_get_position (list_item),
gtk_list_item_get_item (list_item),
gtk_list_item_get_selected (list_item));
selectable &= gtk_list_item_get_selectable (gtk_list_item_widget_get_list_item (GTK_LIST_ITEM_WIDGET (child)));
activatable &= gtk_list_item_get_activatable (gtk_list_item_widget_get_list_item (GTK_LIST_ITEM_WIDGET (child)));
}
/* This really does not belong here, but doing better
* requires considerable plumbing that we don't have now,
* and something like this is needed to fix the filechooser
* in select_folder mode.
*/
gtk_list_item_set_selectable (list_item, selectable);
gtk_list_item_set_activatable (list_item, activatable);
}
static void

View File

@ -31,6 +31,7 @@
#include "gtkselectionmodel.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtklistitem.h"
struct _GtkFileChooserCell
{
@ -39,6 +40,7 @@ struct _GtkFileChooserCell
GFileInfo *item;
gboolean selected;
guint position;
GtkListItem *list_item;
gboolean show_time;
};
@ -56,6 +58,7 @@ enum
PROP_SELECTED,
PROP_ITEM,
PROP_SHOW_TIME,
PROP_LIST_ITEM,
};
#define ICON_SIZE 16
@ -197,6 +200,22 @@ gtk_file_chooser_cell_dispose (GObject *object)
G_OBJECT_CLASS (gtk_file_chooser_cell_parent_class)->dispose (object);
}
static gboolean
get_selectable (GtkFileChooserCell *self)
{
if (self->item)
return g_file_info_get_attribute_boolean (self->item, "filechooser::selectable");
return TRUE;
}
static void
update_list_item (GtkFileChooserCell *self)
{
if (self->list_item)
gtk_list_item_set_selectable (self->list_item, get_selectable (self));
}
static void
gtk_file_chooser_cell_set_property (GObject *object,
guint prop_id,
@ -217,12 +236,25 @@ gtk_file_chooser_cell_set_property (GObject *object,
case PROP_ITEM:
self->item = g_value_get_object (value);
if (get_selectable (self))
gtk_widget_remove_css_class (GTK_WIDGET (self), "dim-label");
else
gtk_widget_add_css_class (GTK_WIDGET (self), "dim-label");
update_list_item (self);
break;
case PROP_SHOW_TIME:
self->show_time = g_value_get_boolean (value);
break;
case PROP_LIST_ITEM:
self->list_item = g_value_get_object (value);
update_list_item (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -292,6 +324,11 @@ gtk_file_chooser_cell_class_init (GtkFileChooserCellClass *klass)
FALSE,
GTK_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_LIST_ITEM,
g_param_spec_object ("list-item", NULL, NULL,
GTK_TYPE_LIST_ITEM,
GTK_PARAM_WRITABLE));
gtk_widget_class_set_css_name (widget_class, I_("filelistcell"));
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
}

View File

@ -3981,10 +3981,10 @@ set_list_model (GtkFileChooserWidget *impl,
set_busy_cursor (impl, TRUE);
impl->browse_files_model =
_gtk_file_system_model_new_for_directory (impl->current_folder,
MODEL_ATTRIBUTES);
_gtk_file_system_model_new_for_directory (impl->current_folder, MODEL_ATTRIBUTES);
_gtk_file_system_model_set_show_hidden (impl->browse_files_model, impl->show_hidden);
_gtk_file_system_model_set_can_select_files (impl->browse_files_model, impl->action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
load_setup_timer (impl); /* This changes the state to LOAD_PRELOAD */
@ -5820,6 +5820,8 @@ search_setup_model (GtkFileChooserWidget *impl)
impl->search_model = _gtk_file_system_model_new ();
_gtk_file_system_model_set_can_select_files (impl->search_model, impl->action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
set_current_model (impl, G_LIST_MODEL (impl->search_model));
update_columns (impl, TRUE, _("Modified"));
}
@ -5986,6 +5988,7 @@ recent_start_loading (GtkFileChooserWidget *impl)
impl->recent_model = _gtk_file_system_model_new ();
_gtk_file_system_model_set_filter (impl->recent_model, impl->current_filter);
_gtk_file_system_model_set_can_select_files (impl->recent_model, impl->action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
if (!impl->recent_manager)
return;

View File

@ -81,6 +81,7 @@ struct _GtkFileSystemModel
guint show_folders :1;/* whether to show folders */
guint show_files :1; /* whether to show files */
guint filter_folders :1;/* whether filter applies to folders */
guint can_select_files : 1;
};
static void freeze_updates (GtkFileSystemModel *model);
@ -151,7 +152,8 @@ static void
node_set_visible_and_filtered_out (GtkFileSystemModel *model,
guint id,
gboolean visible,
gboolean filtered_out)
gboolean filtered_out,
gboolean selectable)
{
FileModelNode *node = get_node (model, id);
@ -164,6 +166,10 @@ node_set_visible_and_filtered_out (GtkFileSystemModel *model,
node->filtered_out = filtered_out;
}
/* Selectability */
g_file_info_set_attribute_boolean (node->info, "filechooser::selectable", selectable);
/* Visibility */
g_file_info_set_attribute_boolean (node->info, "filechooser::visible", visible);
@ -242,17 +248,34 @@ node_should_be_visible (GtkFileSystemModel *model,
return result;
}
static gboolean
node_should_be_selectable (GtkFileSystemModel *model,
guint id)
{
FileModelNode *node = get_node (model, id);
if (node->info == NULL)
return TRUE;
if (_gtk_file_info_consider_as_directory (node->info))
return TRUE;
else
return model->can_select_files;
}
static void
node_compute_visibility_and_filters (GtkFileSystemModel *model,
guint id)
{
gboolean filtered_out;
gboolean visible;
gboolean selectable;
filtered_out = node_should_be_filtered_out (model, id);
visible = node_should_be_visible (model, id, filtered_out);
selectable = node_should_be_selectable (model, id);
node_set_visible_and_filtered_out (model, id, visible, filtered_out);
node_set_visible_and_filtered_out (model, id, visible, filtered_out, selectable);
}
static guint
@ -545,6 +568,7 @@ gtk_file_system_model_init (GtkFileSystemModel *model)
model->show_folders = TRUE;
model->show_hidden = FALSE;
model->filter_folders = FALSE;
model->can_select_files = TRUE;
model->file_lookup = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
model->cancellable = g_cancellable_new ();
@ -1096,3 +1120,11 @@ _gtk_file_system_model_get_directory (GtkFileSystemModel *model)
return model->dir;
}
void
_gtk_file_system_model_set_can_select_files (GtkFileSystemModel *model,
gboolean can_select)
{
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
model->can_select_files = can_select;
}

View File

@ -21,6 +21,7 @@
#include <gio/gio.h>
#include <gtk/gtkfilefilter.h>
#include <gtk/deprecated/gtkfilechooser.h>
G_BEGIN_DECLS
@ -57,6 +58,9 @@ void _gtk_file_system_model_set_filter_folders (GtkFileSystemMode
void _gtk_file_system_model_set_filter (GtkFileSystemModel *model,
GtkFileFilter *filter);
void _gtk_file_system_model_set_can_select_files (GtkFileSystemModel *model,
gboolean can_select);
G_END_DECLS
#endif /* __GTK_FILE_SYSTEM_MODEL_PRIVATE_H__ */

View File

@ -193,6 +193,7 @@
<binding name="selected">
<lookup name="selected">GtkListItem</lookup>
</binding>
<property name="list-item">GtkListItem</property>
<child>
<object class="GtkBox">
<binding name="tooltip-text">
@ -256,6 +257,7 @@
<binding name="selected">
<lookup name="selected">GtkListItem</lookup>
</binding>
<property name="list-item">GtkListItem</property>
<child>
<object class="GtkInscription">
<property name="hexpand">1</property>
@ -305,6 +307,7 @@
<binding name="selected">
<lookup name="selected">GtkListItem</lookup>
</binding>
<property name="list-item">GtkListItem</property>
<child>
<object class="GtkLabel">
<property name="hexpand">1</property>
@ -352,6 +355,7 @@
<binding name="selected">
<lookup name="selected">GtkListItem</lookup>
</binding>
<property name="list-item">GtkListItem</property>
<child>
<object class="GtkLabel">
<property name="hexpand">1</property>
@ -398,6 +402,7 @@
<binding name="selected">
<lookup name="selected">GtkListItem</lookup>
</binding>
<property name="list-item">GtkListItem</property>
<child>
<object class="GtkBox">
<property name="spacing">6</property>
@ -712,6 +717,7 @@
<binding name="selected">
<lookup name="selected">GtkListItem</lookup>
</binding>
<property name="list-item">GtkListItem</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>