[gtk+/multiroot-filechooser: 6/15] Filter the path bar and auto-completion results.



commit 20eedbd0b46496f985962514d66dcf0ef6ccad15
Author: Christian Hammond <chipx86 chipx86 com>
Date:   Mon Mar 22 18:04:11 2010 -0700

    Filter the path bar and auto-completion results.
    
    This changes the path bar to only show those folders accessible within
    the root URI. If a particular folder has been set as the root URI, it will
    appear as the top-most button in the path bar, much like the File System
    does.
    
    This also hides the scroll buttons in the Path Bar when no buttons are set
    (in the case of an invalid root URI) and hides the left scroll button if the
    first shown folder is the very first folder in the path bar.

 gtk/gtkfilechooserdefault.c |   16 ++++++++++-
 gtk/gtkfilechooserentry.c   |    5 +++
 gtk/gtkpathbar.c            |   63 ++++++++++++++++++++++++++++++++++++++-----
 gtk/gtkpathbar.h            |    4 +++
 4 files changed, 80 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 70b00e8..2643ed1 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -359,6 +359,8 @@ static gboolean shortcuts_select_func   (GtkTreeSelection      *selection,
 					 GtkTreePath           *path,
 					 gboolean               path_currently_selected,
 					 gpointer               data);
+static void shortcuts_find_folder (GtkFileChooserDefault *impl,
+                                   GFile                 *folder);
 static gboolean shortcuts_get_selected  (GtkFileChooserDefault *impl,
 					 GtkTreeIter           *iter);
 static void shortcuts_activate_iter (GtkFileChooserDefault *impl,
@@ -4942,7 +4944,10 @@ save_widgets_create (GtkFileChooserDefault *impl)
   _gtk_file_chooser_entry_set_local_only (
      GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
      gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (impl)));
-  _gtk_file_chooser_entry_set_root_uri (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->root_uri);
+  _gtk_file_chooser_entry_set_root_uri (
+     GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
+     impl->root_uri);
+  _gtk_path_bar_set_root_uri (GTK_PATH_BAR (impl->browse_path_bar), impl->root_uri);
   gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45);
   gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
   gtk_table_attach (GTK_TABLE (table), impl->location_entry,
@@ -5097,6 +5102,12 @@ location_switch_to_filename_entry (GtkFileChooserDefault *impl)
   /* Configure the entry */
 
   _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->current_folder);
+  _gtk_file_chooser_entry_set_local_only (
+     GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
+     gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (impl)));
+  _gtk_file_chooser_entry_set_root_uri (
+     GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
+     impl->root_uri);
 
   /* Done */
 
@@ -5409,6 +5420,9 @@ set_root_uri (GtkFileChooserDefault *impl,
             local_only);
         }
 
+      _gtk_path_bar_set_root_uri (GTK_PATH_BAR (impl->browse_path_bar),
+                                  impl->root_uri);
+
       /* Attempt to preserve the sidebar selection if possible. */
       if (shortcuts_get_selected (impl, &iter))
         {
diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c
index bf39236..d077e47 100644
--- a/gtk/gtkfilechooserentry.c
+++ b/gtk/gtkfilechooserentry.c
@@ -1343,6 +1343,9 @@ populate_completion_store (GtkFileChooserEntry *chooser_entry)
 
       file = tmp_list->data;
 
+      if (!is_file_in_root (chooser_entry, file))
+        continue;
+
       info = _gtk_folder_get_info (chooser_entry->current_folder, file);
 
       if (info)
@@ -2039,3 +2042,5 @@ _gtk_file_chooser_entry_get_root_uri (GtkFileChooserEntry *chooser_entry)
 {
   return chooser_entry->root_uri;
 }
+
+// vim: et sw=2 cinoptions=(0,t0,f1s,n-1s,{1s,>2s,^-1s
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index a9d2da3..3e124c9 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -25,6 +25,7 @@
 #include "gtkalignment.h"
 #include "gtkarrow.h"
 #include "gtkdnd.h"
+#include "gtkfilechooserprivate.h"
 #include "gtkimage.h"
 #include "gtkintl.h"
 #include "gtkicontheme.h"
@@ -259,6 +260,8 @@ gtk_path_bar_finalize (GObject *object)
   g_list_free (path_bar->button_list);
   if (path_bar->root_file)
     g_object_unref (path_bar->root_file);
+  if (path_bar->root_uri)
+    g_free (path_bar->root_uri);
   if (path_bar->home_file)
     g_object_unref (path_bar->home_file);
   if (path_bar->desktop_file)
@@ -455,7 +458,7 @@ gtk_path_bar_size_allocate (GtkWidget     *widget,
   GtkPathBar *path_bar = GTK_PATH_BAR (widget);
   GtkTextDirection direction;
   GtkAllocation child_allocation;
-  GList *list, *first_button;
+  GList *list, *first_button, *root_button;
   gint width;
   gint allocation_width;
   gint border_width;
@@ -471,7 +474,11 @@ gtk_path_bar_size_allocate (GtkWidget     *widget,
 
   /* No path is set; we don't have to allocate anything. */
   if (path_bar->button_list == NULL)
-    return;
+    {
+      gtk_widget_set_child_visible (path_bar->up_slider_button, FALSE);
+      gtk_widget_set_child_visible (path_bar->down_slider_button, FALSE);
+      return;
+    }
 
   direction = gtk_widget_get_direction (widget);
   border_width = (gint) GTK_CONTAINER (path_bar)->border_width;
@@ -489,15 +496,17 @@ gtk_path_bar_size_allocate (GtkWidget     *widget,
 
       width += child->requisition.width + path_bar->spacing;
       if (list == path_bar->fake_root)
-	break;
+        break;
     }
 
+  root_button = g_list_last (path_bar->button_list);
+
   if (width <= allocation_width)
     {
       if (path_bar->fake_root)
 	first_button = path_bar->fake_root;
       else
-	first_button = g_list_last (path_bar->button_list);
+	first_button = root_button;
     }
   else
     {
@@ -559,7 +568,8 @@ gtk_path_bar_size_allocate (GtkWidget     *widget,
   if (direction == GTK_TEXT_DIR_RTL)
     {
       child_allocation.x = allocation->x + allocation->width - border_width;
-      if (need_sliders || path_bar->fake_root)
+      if (need_sliders ||
+          (path_bar->fake_root && path_bar->fake_root != root_button))
 	{
 	  child_allocation.x -= (path_bar->spacing + path_bar->slider_width);
 	  up_slider_offset = allocation->width - border_width - path_bar->slider_width;
@@ -568,7 +578,8 @@ gtk_path_bar_size_allocate (GtkWidget     *widget,
   else
     {
       child_allocation.x = allocation->x + border_width;
-      if (need_sliders || path_bar->fake_root)
+      if (need_sliders ||
+          (path_bar->fake_root && path_bar->fake_root != root_button))
 	{
 	  up_slider_offset = border_width;
 	  child_allocation.x += (path_bar->spacing + path_bar->slider_width);
@@ -628,7 +639,8 @@ gtk_path_bar_size_allocate (GtkWidget     *widget,
       gtk_widget_set_child_visible (BUTTON_DATA (list->data)->button, FALSE);
     }
 
-  if (need_sliders || path_bar->fake_root)
+  if (need_sliders ||
+      (path_bar->fake_root && path_bar->fake_root != root_button))
     {
       child_allocation.width = path_bar->slider_width;
       child_allocation.x = up_slider_offset + allocation->x;
@@ -1592,6 +1604,18 @@ struct SetFileInfo
   gboolean first_directory;
 };
 
+static gboolean
+is_file_in_root (GtkPathBar *path_bar,
+                 GFile      *file)
+{
+  char *uri = g_file_get_uri (file);
+  gboolean result = path_bar->root_uri == NULL ||
+                    _gtk_file_chooser_uri_has_prefix (uri, path_bar->root_uri);
+  g_free(uri);
+
+  return result;
+}
+
 static void
 gtk_path_bar_set_file_finish (struct SetFileInfo *info,
                               gboolean            result)
@@ -1663,6 +1687,12 @@ gtk_path_bar_get_info_callback (GCancellable *cancellable,
   display_name = g_file_info_get_display_name (info);
   is_hidden = g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info);
 
+  if (!is_file_in_root (file_info->path_bar, file_info->file))
+    {
+      gtk_path_bar_set_file_finish (file_info, TRUE);
+      return;
+    }
+
   gtk_widget_push_composite_child ();
   button_data = make_directory_button (file_info->path_bar, display_name,
                                        file_info->file,
@@ -1770,6 +1800,23 @@ _gtk_path_bar_set_file_system (GtkPathBar    *path_bar,
   path_bar->root_file = g_file_new_for_path ("/");
 }
 
+void
+_gtk_path_bar_set_root_uri    (GtkPathBar         *path_bar,
+                               const char         *root_uri)
+{
+  g_return_if_fail (GTK_IS_PATH_BAR (path_bar));
+
+  g_free (path_bar->root_uri);
+  path_bar->root_uri = (root_uri == NULL ? NULL : g_strdup (root_uri));
+
+  /*
+   * We don't know if we can even query this URI, so clear the buttons as
+   * a precaution. Otherwise the user could jump to folders outside the root
+   * URI and break things.
+   */
+  gtk_path_bar_clear_buttons (path_bar);
+}
+
 /**
  * _gtk_path_bar_up:
  * @path_bar: a #GtkPathBar
@@ -1826,3 +1873,5 @@ _gtk_path_bar_down (GtkPathBar *path_bar)
 
 #define __GTK_PATH_BAR_C__
 #include "gtkaliasdef.c"
+
+// vim: et sw=2 cinoptions=(0,t0,f1s,n-1s,{1s,>2s,^-1s
diff --git a/gtk/gtkpathbar.h b/gtk/gtkpathbar.h
index 2006411..5aad390 100644
--- a/gtk/gtkpathbar.h
+++ b/gtk/gtkpathbar.h
@@ -45,6 +45,8 @@ struct _GtkPathBar
   GFile *home_file;
   GFile *desktop_file;
 
+  char *root_uri;
+
   GCancellable *get_info_cancellable;
 
   GdkPixbuf *root_icon;
@@ -88,6 +90,8 @@ gboolean _gtk_path_bar_set_file        (GtkPathBar         *path_bar,
 					GFile              *file,
 					gboolean            keep_trail,
 					GError            **error);
+void     _gtk_path_bar_set_root_uri    (GtkPathBar         *path_bar,
+										const char         *root_uri);
 void     _gtk_path_bar_up              (GtkPathBar *path_bar);
 void     _gtk_path_bar_down            (GtkPathBar *path_bar);
 



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