Compare commits
8 Commits
wip/matthi
...
filechoose
Author | SHA1 | Date | |
---|---|---|---|
|
48872232f7 | ||
|
523d897550 | ||
|
aff313788a | ||
|
fdb5a5bda1 | ||
|
dcf780cef7 | ||
|
4a7b80cf4b | ||
|
8dce83c464 | ||
|
b13f1528a5 |
@@ -206,6 +206,7 @@ enum {
|
||||
MODEL_COL_FILE,
|
||||
MODEL_COL_NAME_COLLATED,
|
||||
MODEL_COL_IS_FOLDER,
|
||||
MODEL_COL_IS_SENSITIVE,
|
||||
MODEL_COL_PIXBUF,
|
||||
MODEL_COL_SIZE_TEXT,
|
||||
MODEL_COL_MTIME_TEXT,
|
||||
@@ -222,6 +223,7 @@ enum {
|
||||
G_TYPE_FILE, /* MODEL_COL_FILE */ \
|
||||
G_TYPE_STRING, /* MODEL_COL_NAME_COLLATED */ \
|
||||
G_TYPE_BOOLEAN, /* MODEL_COL_IS_FOLDER */ \
|
||||
G_TYPE_BOOLEAN, /* MODEL_COL_IS_SENSITIVE */ \
|
||||
GDK_TYPE_PIXBUF, /* MODEL_COL_PIXBUF */ \
|
||||
G_TYPE_STRING, /* MODEL_COL_SIZE_TEXT */ \
|
||||
G_TYPE_STRING, /* MODEL_COL_MTIME_TEXT */ \
|
||||
@@ -6202,13 +6204,6 @@ gtk_file_chooser_default_unmap (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->unmap (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
install_list_model_filter (GtkFileChooserDefault *impl)
|
||||
{
|
||||
_gtk_file_system_model_set_filter (impl->browse_files_model,
|
||||
impl->current_filter);
|
||||
}
|
||||
|
||||
#define COMPARE_DIRECTORIES \
|
||||
GtkFileChooserDefault *impl = user_data; \
|
||||
GtkFileSystemModel *fs_model = GTK_FILE_SYSTEM_MODEL (model); \
|
||||
@@ -6838,6 +6833,34 @@ file_system_model_set (GtkFileSystemModel *model,
|
||||
case MODEL_COL_IS_FOLDER:
|
||||
g_value_set_boolean (value, info == NULL || _gtk_file_info_consider_as_directory (info));
|
||||
break;
|
||||
case MODEL_COL_IS_SENSITIVE:
|
||||
if (info)
|
||||
{
|
||||
gboolean sensitive = TRUE;
|
||||
|
||||
if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
|
||||
|| impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
|
||||
{
|
||||
sensitive = TRUE; /* for file modes... */
|
||||
}
|
||||
else if (!_gtk_file_info_consider_as_directory (info))
|
||||
{
|
||||
sensitive = FALSE; /* for folder modes, files are not sensitive... */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ... and for folder modes, folders are sensitive only if the filter says so */
|
||||
GtkTreeIter iter;
|
||||
if (!_gtk_file_system_model_get_iter_for_file (model, &iter, file))
|
||||
g_assert_not_reached ();
|
||||
sensitive = !_gtk_file_system_model_iter_is_filtered_out (model, &iter);
|
||||
}
|
||||
|
||||
g_value_set_boolean (value, sensitive);
|
||||
}
|
||||
else
|
||||
g_value_set_boolean (value, TRUE);
|
||||
break;
|
||||
case MODEL_COL_PIXBUF:
|
||||
if (info)
|
||||
{
|
||||
@@ -6961,7 +6984,7 @@ set_list_model (GtkFileChooserDefault *impl,
|
||||
g_signal_connect (impl->browse_files_model, "finished-loading",
|
||||
G_CALLBACK (browse_files_model_finished_loading_cb), impl);
|
||||
|
||||
install_list_model_filter (impl);
|
||||
_gtk_file_system_model_set_filter (impl->browse_files_model, impl->current_filter);
|
||||
|
||||
profile_end ("end", NULL);
|
||||
|
||||
@@ -7532,16 +7555,19 @@ maybe_select (GtkTreeModel *model,
|
||||
{
|
||||
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
|
||||
GtkTreeSelection *selection;
|
||||
gboolean is_sensitive;
|
||||
gboolean is_folder;
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
MODEL_COL_IS_FOLDER, &is_folder,
|
||||
MODEL_COL_IS_SENSITIVE, &is_sensitive,
|
||||
-1);
|
||||
|
||||
if ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ||
|
||||
(!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN))
|
||||
if (is_sensitive &&
|
||||
((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ||
|
||||
(!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)))
|
||||
gtk_tree_selection_select_iter (selection, iter);
|
||||
else
|
||||
gtk_tree_selection_unselect_iter (selection, iter);
|
||||
@@ -9655,13 +9681,22 @@ set_current_filter (GtkFileChooserDefault *impl,
|
||||
filter_index);
|
||||
|
||||
if (impl->browse_files_model)
|
||||
install_list_model_filter (impl);
|
||||
{
|
||||
_gtk_file_system_model_set_filter (impl->browse_files_model, impl->current_filter);
|
||||
_gtk_file_system_model_clear_cache (impl->browse_files_model, MODEL_COL_IS_SENSITIVE);
|
||||
}
|
||||
|
||||
if (impl->search_model)
|
||||
_gtk_file_system_model_set_filter (impl->search_model, filter);
|
||||
{
|
||||
_gtk_file_system_model_set_filter (impl->search_model, filter);
|
||||
_gtk_file_system_model_clear_cache (impl->search_model, MODEL_COL_IS_SENSITIVE);
|
||||
}
|
||||
|
||||
if (impl->recent_model)
|
||||
_gtk_file_system_model_set_filter (impl->recent_model, filter);
|
||||
{
|
||||
_gtk_file_system_model_set_filter (impl->recent_model, filter);
|
||||
_gtk_file_system_model_clear_cache (impl->recent_model, MODEL_COL_IS_SENSITIVE);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (impl), "filter");
|
||||
}
|
||||
@@ -10052,14 +10087,16 @@ list_select_func (GtkTreeSelection *selection,
|
||||
impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gboolean is_sensitive;
|
||||
gboolean is_folder;
|
||||
|
||||
if (!gtk_tree_model_get_iter (model, &iter, path))
|
||||
return FALSE;
|
||||
gtk_tree_model_get (model, &iter,
|
||||
MODEL_COL_IS_SENSITIVE, &is_sensitive,
|
||||
MODEL_COL_IS_FOLDER, &is_folder,
|
||||
-1);
|
||||
if (!is_folder)
|
||||
if (!is_sensitive || !is_folder)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -10110,6 +10147,7 @@ list_row_activated (GtkTreeView *tree_view,
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
gboolean is_folder;
|
||||
gboolean is_sensitive;
|
||||
|
||||
model = gtk_tree_view_get_model (tree_view);
|
||||
|
||||
@@ -10119,9 +10157,10 @@ list_row_activated (GtkTreeView *tree_view,
|
||||
gtk_tree_model_get (model, &iter,
|
||||
MODEL_COL_FILE, &file,
|
||||
MODEL_COL_IS_FOLDER, &is_folder,
|
||||
MODEL_COL_IS_SENSITIVE, &is_sensitive,
|
||||
-1);
|
||||
|
||||
if (is_folder && file)
|
||||
if (is_sensitive && is_folder && file)
|
||||
{
|
||||
change_folder_and_display_error (impl, file, FALSE);
|
||||
goto out;
|
||||
@@ -10164,10 +10203,6 @@ update_cell_renderer_attributes (GtkFileChooserDefault *impl)
|
||||
GtkTreeViewColumn *column;
|
||||
GtkCellRenderer *renderer;
|
||||
GList *walk, *list;
|
||||
gboolean always_sensitive;
|
||||
|
||||
always_sensitive = impl->action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
|
||||
impl->action != GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
|
||||
|
||||
/* Keep the following column numbers in sync with create_file_list() */
|
||||
|
||||
@@ -10190,10 +10225,8 @@ update_cell_renderer_attributes (GtkFileChooserDefault *impl)
|
||||
"ellipsize", MODEL_COL_ELLIPSIZE,
|
||||
NULL);
|
||||
}
|
||||
if (always_sensitive)
|
||||
g_object_set (renderer, "sensitive", TRUE, NULL);
|
||||
else
|
||||
gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_FOLDER);
|
||||
|
||||
gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_SENSITIVE);
|
||||
}
|
||||
g_list_free (list);
|
||||
|
||||
@@ -10204,10 +10237,8 @@ update_cell_renderer_attributes (GtkFileChooserDefault *impl)
|
||||
gtk_tree_view_column_set_attributes (column, renderer,
|
||||
"text", MODEL_COL_SIZE_TEXT,
|
||||
NULL);
|
||||
if (always_sensitive)
|
||||
g_object_set (renderer, "sensitive", TRUE, NULL);
|
||||
else
|
||||
gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_FOLDER);
|
||||
|
||||
gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_SENSITIVE);
|
||||
g_list_free (list);
|
||||
|
||||
/* mtime */
|
||||
@@ -10217,10 +10248,7 @@ update_cell_renderer_attributes (GtkFileChooserDefault *impl)
|
||||
gtk_tree_view_column_set_attributes (column, renderer,
|
||||
"text", MODEL_COL_MTIME_TEXT,
|
||||
NULL);
|
||||
if (always_sensitive)
|
||||
g_object_set (renderer, "sensitive", TRUE, NULL);
|
||||
else
|
||||
gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_FOLDER);
|
||||
gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_SENSITIVE);
|
||||
g_list_free (list);
|
||||
}
|
||||
|
||||
|
@@ -120,6 +120,7 @@ struct _FileModelNode
|
||||
*/
|
||||
|
||||
guint visible :1; /* if the file is currently visible */
|
||||
guint filtered_out :1;/* if the file is currently filtered out (i.e. it didn't pass the filters) */
|
||||
guint frozen_add :1; /* true if the model was frozen and the entry has not been added yet */
|
||||
|
||||
GValue values[1]; /* actually n_columns values */
|
||||
@@ -306,10 +307,21 @@ emit_row_deleted_for_row (GtkFileSystemModel *model, guint row)
|
||||
}
|
||||
|
||||
static void
|
||||
node_set_visible (GtkFileSystemModel *model, guint id, gboolean visible)
|
||||
node_set_visible_and_filtered_out (GtkFileSystemModel *model, guint id, gboolean visible, gboolean filtered_out)
|
||||
{
|
||||
FileModelNode *node = get_node (model, id);
|
||||
|
||||
/* Filteredness */
|
||||
|
||||
if (node->filtered_out != filtered_out)
|
||||
{
|
||||
node->filtered_out = filtered_out;
|
||||
if (node->visible && visible)
|
||||
emit_row_changed_for_node (model, id);
|
||||
}
|
||||
|
||||
/* Visibility */
|
||||
|
||||
if (node->visible == visible ||
|
||||
node->frozen_add)
|
||||
return;
|
||||
@@ -334,7 +346,7 @@ node_set_visible (GtkFileSystemModel *model, guint id, gboolean visible)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
node_should_be_visible (GtkFileSystemModel *model, guint id)
|
||||
node_should_be_filtered_out (GtkFileSystemModel *model, guint id)
|
||||
{
|
||||
FileModelNode *node = get_node (model, id);
|
||||
GtkFileFilterInfo filter_info = { 0, };
|
||||
@@ -345,28 +357,10 @@ node_should_be_visible (GtkFileSystemModel *model, guint id)
|
||||
char *uri = NULL;
|
||||
|
||||
if (node->info == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!model->show_hidden &&
|
||||
(g_file_info_get_is_hidden (node->info) || g_file_info_get_is_backup (node->info)))
|
||||
return FALSE;
|
||||
|
||||
if (_gtk_file_info_consider_as_directory (node->info))
|
||||
{
|
||||
if (!model->show_folders)
|
||||
return FALSE;
|
||||
|
||||
if (!model->filter_folders)
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!model->show_files)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
if (model->filter == NULL)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
|
||||
/* fill info */
|
||||
required = gtk_file_filter_get_needed (model->filter);
|
||||
@@ -408,7 +402,7 @@ node_should_be_visible (GtkFileSystemModel *model, guint id)
|
||||
}
|
||||
}
|
||||
|
||||
result = gtk_file_filter_filter (model->filter, &filter_info);
|
||||
result = !gtk_file_filter_filter (model->filter, &filter_info);
|
||||
|
||||
g_free (mime_type);
|
||||
g_free (filename);
|
||||
@@ -417,6 +411,50 @@ node_should_be_visible (GtkFileSystemModel *model, guint id)
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
node_should_be_visible (GtkFileSystemModel *model, guint id, gboolean filtered_out)
|
||||
{
|
||||
FileModelNode *node = get_node (model, id);
|
||||
gboolean result;
|
||||
|
||||
if (node->info == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!model->show_hidden &&
|
||||
(g_file_info_get_is_hidden (node->info) || g_file_info_get_is_backup (node->info)))
|
||||
return FALSE;
|
||||
|
||||
if (_gtk_file_info_consider_as_directory (node->info))
|
||||
{
|
||||
if (!model->show_folders)
|
||||
return FALSE;
|
||||
|
||||
if (!model->filter_folders)
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!model->show_files)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
result = !filtered_out;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
node_compute_visibility_and_filters (GtkFileSystemModel *model, guint id)
|
||||
{
|
||||
gboolean filtered_out;
|
||||
gboolean visible;
|
||||
|
||||
filtered_out = node_should_be_filtered_out (model, id);
|
||||
visible = node_should_be_visible (model, id, filtered_out);
|
||||
|
||||
node_set_visible_and_filtered_out (model, id, visible, filtered_out);
|
||||
}
|
||||
|
||||
/*** GtkTreeModel ***/
|
||||
|
||||
static GtkTreeModelFlags
|
||||
@@ -1399,9 +1437,7 @@ gtk_file_system_model_refilter_all (GtkFileSystemModel *model)
|
||||
|
||||
/* start at index 1, don't change the editable */
|
||||
for (i = 1; i < model->files->len; i++)
|
||||
{
|
||||
node_set_visible (model, i, node_should_be_visible (model, i));
|
||||
}
|
||||
node_compute_visibility_and_filters (model, i);
|
||||
|
||||
model->filter_on_thaw = FALSE;
|
||||
_gtk_file_system_model_thaw_updates (model);
|
||||
@@ -1528,7 +1564,7 @@ _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model)
|
||||
* Checks if the iterator is visible. A visible iterator references
|
||||
* a row that is currently exposed using the #GtkTreeModel API. If
|
||||
* the iterator is invisible, it references a file that is not shown
|
||||
* for some reason, such as being filtered by the current filter or
|
||||
* for some reason, such as being filtered out by the current filter or
|
||||
* being a hidden file.
|
||||
*
|
||||
* Returns: %TRUE if the iterator is visible
|
||||
@@ -1546,6 +1582,32 @@ _gtk_file_system_model_iter_is_visible (GtkFileSystemModel *model,
|
||||
return node->visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_system_model_iter_is_filtered_out:
|
||||
* @model: the model
|
||||
* @iter: a valid iterator
|
||||
*
|
||||
* Checks if the iterator is filtered out. This is only useful for rows
|
||||
* that refer to folders, as those are always visible regardless
|
||||
* of what the current filter says. This function lets you see
|
||||
* the results of the filter.
|
||||
*
|
||||
* Returns: %TRUE if the iterator passed the current filter; %FALSE if the
|
||||
* filter would not have let the row pass.
|
||||
**/
|
||||
gboolean
|
||||
_gtk_file_system_model_iter_is_filtered_out (GtkFileSystemModel *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
FileModelNode *node;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model), FALSE);
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
|
||||
node = get_node (model, ITER_INDEX (iter));
|
||||
return node->filtered_out;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_system_model_get_info:
|
||||
* @model: a #GtkFileSystemModel
|
||||
@@ -1743,8 +1805,8 @@ add_file (GtkFileSystemModel *model,
|
||||
g_slice_free1 (model->node_size, node);
|
||||
|
||||
if (!model->frozen)
|
||||
node_set_visible (model, model->files->len -1,
|
||||
node_should_be_visible (model, model->files->len - 1));
|
||||
node_compute_visibility_and_filters (model, model->files->len -1);
|
||||
|
||||
gtk_file_system_model_sort_node (model, model->files->len -1);
|
||||
}
|
||||
|
||||
@@ -1772,7 +1834,7 @@ remove_file (GtkFileSystemModel *model,
|
||||
return;
|
||||
|
||||
node = get_node (model, id);
|
||||
node_set_visible (model, id, FALSE);
|
||||
node_set_visible_and_filtered_out (model, id, FALSE, FALSE);
|
||||
|
||||
g_hash_table_remove (model->file_lookup, file);
|
||||
g_object_unref (node->file);
|
||||
@@ -1883,7 +1945,7 @@ _gtk_file_system_model_add_editable (GtkFileSystemModel *model, GtkTreeIter *ite
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (!get_node (model, 0)->visible);
|
||||
|
||||
node_set_visible (model, 0, TRUE);
|
||||
node_set_visible_and_filtered_out (model, 0, TRUE, FALSE);
|
||||
ITER_INIT_FROM_INDEX (model, iter, 0);
|
||||
}
|
||||
|
||||
@@ -1901,7 +1963,7 @@ _gtk_file_system_model_remove_editable (GtkFileSystemModel *model)
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (get_node (model, 0)->visible);
|
||||
|
||||
node_set_visible (model, 0, FALSE);
|
||||
node_set_visible_and_filtered_out (model, 0, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1958,7 +2020,7 @@ _gtk_file_system_model_thaw_updates (GtkFileSystemModel *model)
|
||||
if (!node->frozen_add)
|
||||
continue;
|
||||
node->frozen_add = FALSE;
|
||||
node_set_visible (model, i, node_should_be_visible (model, i));
|
||||
node_compute_visibility_and_filters (model, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -53,6 +53,8 @@ GtkFileSystemModel *_gtk_file_system_model_new_for_directory(GFile *
|
||||
GCancellable * _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model);
|
||||
gboolean _gtk_file_system_model_iter_is_visible (GtkFileSystemModel *model,
|
||||
GtkTreeIter *iter);
|
||||
gboolean _gtk_file_system_model_iter_is_filtered_out (GtkFileSystemModel *model,
|
||||
GtkTreeIter *iter);
|
||||
GFileInfo * _gtk_file_system_model_get_info (GtkFileSystemModel *model,
|
||||
GtkTreeIter *iter);
|
||||
gboolean _gtk_file_system_model_get_iter_for_file(GtkFileSystemModel *model,
|
||||
|
@@ -577,6 +577,11 @@ main (int argc, char **argv)
|
||||
gtk_file_filter_add_mime_type (filter, "image/png");
|
||||
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
|
||||
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_set_name (filter, "Starts with D");
|
||||
gtk_file_filter_add_pattern (filter, "D*");
|
||||
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
|
||||
|
||||
g_signal_connect (dialog, "notify::filter",
|
||||
G_CALLBACK (filter_changed), NULL);
|
||||
|
||||
|
Reference in New Issue
Block a user