[gtk+/gtk-2-24] Desensitize filtered folders when in folder selection mode



commit 5c03d6a9437d92acf89d43109e82e628ef822251
Author: William Jon McCann <jmccann redhat com>
Date:   Sun Jul 8 03:25:02 2012 -0400

    Desensitize filtered folders when in folder selection mode
    
    https://bugzilla.gnome.org/show_bug.cgi?id=679333

 gtk/gtkfilechooserdefault.c |   65 ++++++++++++++++++--------
 gtk/gtkfilesystemmodel.c    |  109 +++++++++++++++++++++++++++++++++---------
 gtk/gtkfilesystemmodel.h    |    2 +
 3 files changed, 132 insertions(+), 44 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index f89a672..0f668a0 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -205,6 +205,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,
@@ -221,6 +222,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 */    \
@@ -6710,6 +6712,33 @@ 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;
+            }
+          else if (!_gtk_file_info_consider_as_directory (info))
+            {
+              sensitive = FALSE;
+            }
+          else
+            {
+              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 (model, &iter);
+            }
+
+          g_value_set_boolean (value, sensitive);
+        }
+      else
+        g_value_set_boolean (value, TRUE);
+      break;
     case MODEL_COL_PIXBUF:
       if (info)
         {
@@ -7399,16 +7428,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);
@@ -9917,14 +9949,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;
     }
     
@@ -9974,6 +10008,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);
 
@@ -9983,9 +10018,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);
       return;
@@ -10026,10 +10062,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() */
 
@@ -10052,10 +10084,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);
 
@@ -10066,10 +10096,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 */
@@ -10079,10 +10107,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);
 }
 
diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c
index ac27cac..c023aa4 100644
--- a/gtk/gtkfilesystemmodel.c
+++ b/gtk/gtkfilesystemmodel.c
@@ -123,6 +123,7 @@ struct _FileModelNode
                                         */
 
   guint                 visible :1;     /* if the file is currently visible */
+  guint                 filtered :1;    /* if the file is currently filtered */
   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 */
@@ -309,6 +310,18 @@ emit_row_deleted_for_row (GtkFileSystemModel *model, guint row)
 }
 
 static void
+node_set_filtered (GtkFileSystemModel *model, guint id, gboolean filtered)
+{
+  FileModelNode *node = get_node (model, id);
+
+  if (node->filtered == filtered ||
+      node->frozen_add)
+    return;
+
+  node->filtered = filtered;
+}
+
+static void
 node_set_visible (GtkFileSystemModel *model, guint id, gboolean visible)
 {
   FileModelNode *node = get_node (model, id);
@@ -337,7 +350,7 @@ node_set_visible (GtkFileSystemModel *model, guint id, gboolean visible)
 }
 
 static gboolean
-node_should_be_visible (GtkFileSystemModel *model, guint id)
+node_should_be_filtered (GtkFileSystemModel *model, guint id)
 {
   FileModelNode *node = get_node (model, id);
   GtkFileFilterInfo filter_info = { 0, };
@@ -348,28 +361,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);
@@ -411,7 +406,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);
@@ -420,6 +415,38 @@ node_should_be_visible (GtkFileSystemModel *model, guint id)
   return result;
 }
 
+static gboolean
+node_should_be_visible (GtkFileSystemModel *model, guint id)
+{
+  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 = !node_should_be_filtered (model, id);
+
+  return result;
+}
+
 /*** GtkTreeModel ***/
 
 static GtkTreeModelFlags
@@ -1403,6 +1430,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_filtered (model, i, node_should_be_filtered (model, i));
       node_set_visible (model, i, node_should_be_visible (model, i));
     }
 
@@ -1550,6 +1578,31 @@ _gtk_file_system_model_iter_is_visible (GtkFileSystemModel *model,
 }
 
 /**
+ * _gtk_file_system_model_iter_is_filtered:
+ * @model: the model
+ * @iter: a valid iterator
+ *
+ * Checks if the iterator is filtered. A filtered iterator references
+ * a row that is currently exposed using the #GtkTreeModel API. If
+ * the iterator is filtered, it references a file that filtered by
+ * the current filter.
+ *
+ * Returns: %TRUE if the iterator is filtered
+ **/
+gboolean
+_gtk_file_system_model_iter_is_filtered (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;
+}
+
+/**
  * _gtk_file_system_model_get_info:
  * @model: a #GtkFileSystemModel
  * @iter: a #GtkTreeIter pointing to a row of @model
@@ -1746,8 +1799,12 @@ 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_set_filtered (model, model->files->len -1,
+                         node_should_be_filtered (model, model->files->len - 1));
+      node_set_visible (model, model->files->len -1,
+                        node_should_be_visible (model, model->files->len - 1));
+    }
   gtk_file_system_model_sort_node (model, model->files->len -1);
 }
 
@@ -1776,6 +1833,7 @@ remove_file (GtkFileSystemModel *model,
 
   node = get_node (model, id);
   node_set_visible (model, id, FALSE);
+  node_set_filtered (model, id, FALSE);
 
   g_hash_table_remove (model->file_lookup, file);
   g_object_unref (node->file);
@@ -1887,6 +1945,7 @@ _gtk_file_system_model_add_editable (GtkFileSystemModel *model, GtkTreeIter *ite
   g_return_if_fail (!get_node (model, 0)->visible);
 
   node_set_visible (model, 0, TRUE);
+  node_set_filtered (model, 0, FALSE);
   ITER_INIT_FROM_INDEX (model, iter, 0);
 }
 
@@ -1905,6 +1964,7 @@ _gtk_file_system_model_remove_editable (GtkFileSystemModel *model)
   g_return_if_fail (get_node (model, 0)->visible);
 
   node_set_visible (model, 0, FALSE);
+  node_set_filtered (model, 0, FALSE);
 }
 
 /**
@@ -1962,6 +2022,7 @@ _gtk_file_system_model_thaw_updates (GtkFileSystemModel *model)
             continue;
           node->frozen_add = FALSE;
           node_set_visible (model, i, node_should_be_visible (model, i));
+          node_set_filtered (model, i, node_should_be_filtered (model, i));
         }
     }
 }
diff --git a/gtk/gtkfilesystemmodel.h b/gtk/gtkfilesystemmodel.h
index 4a533da..83da3e4 100644
--- a/gtk/gtkfilesystemmodel.h
+++ b/gtk/gtkfilesystemmodel.h
@@ -55,6 +55,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 (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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]