[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Add a ThunarShortcut::changed signal for lazy loading shortcuts.

Jannis Pohlmann noreply at xfce.org
Fri Jul 15 21:10:26 CEST 2011


Updating branch refs/heads/jannis/new-shortcuts-pane
         to 4ab0b79b26290bd7eeb04ee3116429604cd459da (commit)
       from 235f9f191d08b8742c14edc6b6e587c042adac44 (commit)

commit 4ab0b79b26290bd7eeb04ee3116429604cd459da
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Wed Jun 8 01:09:16 2011 +0200

    Add a ThunarShortcut::changed signal for lazy loading shortcuts.
    
    This doesn't do anything yet but we can use it to watch volumes, mounts
    and regular files for changes and forward those to the model, then to
    the view and then to the individual rows. Another use is to resolve URIs
    into GFiles into ThunarFiles asynchronously step-by-step and emit a
    "changed" signal after each transition.
    
    Maybe this will help fixing the startup delay issues due to all the slow
    GVfs D-Bus services (e.g. network).

 thunar/thunar-shortcut.c        |   11 +++
 thunar/thunar-shortcuts-model.c |  149 +++++++++++++++++++++++++++++++++++----
 thunar/thunar-shortcuts-view.c  |   77 ++++++++++++++++++++-
 3 files changed, 220 insertions(+), 17 deletions(-)

diff --git a/thunar/thunar-shortcut.c b/thunar/thunar-shortcut.c
index 216618c..6b3178c 100644
--- a/thunar/thunar-shortcut.c
+++ b/thunar/thunar-shortcut.c
@@ -54,6 +54,7 @@ enum
 /* signal identifiers */
 enum
 {
+  SIGNAL_CHANGED,
   LAST_SIGNAL,
 };
 
@@ -106,6 +107,10 @@ G_DEFINE_TYPE (ThunarShortcut, thunar_shortcut, G_TYPE_OBJECT)
 
 
 
+static guint shortcut_signals[LAST_SIGNAL];
+
+
+
 static void
 thunar_shortcut_class_init (ThunarShortcutClass *klass)
 {
@@ -208,6 +213,12 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                          "persistent",
                                                          FALSE,
                                                          EXO_PARAM_READWRITE));
+
+  shortcut_signals[SIGNAL_CHANGED] = g_signal_new ("changed",
+                                                   G_TYPE_FROM_CLASS (klass),
+                                                   G_SIGNAL_RUN_LAST,
+                                                   0, NULL, NULL, NULL,
+                                                   G_TYPE_NONE, 0);
 }
 
 
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index 49cf505..0c5706e 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -111,6 +111,10 @@ static gboolean                thunar_shortcuts_model_find_category         (Thu
                                                                              ThunarShortcut            *shortcut,
                                                                              ThunarShortcutCategory   **category,
                                                                              gint                      *category_index);
+static gboolean                thunar_shortcuts_model_find_shortcut         (ThunarShortcutsModel      *model,
+                                                                             ThunarShortcut            *shortcut,
+                                                                             gint                      *category_index,
+                                                                             gint                      *shortcut_index);
 static gboolean                thunar_shortcuts_model_find_volume           (ThunarShortcutsModel      *model,
                                                                              GVolume                   *volume,
                                                                              gint                      *category_index,
@@ -121,6 +125,8 @@ static gboolean                thunar_shortcuts_model_find_mount            (Thu
                                                                              gint                      *shortcut_index);
 static void                    thunar_shortcuts_model_add_shortcut          (ThunarShortcutsModel      *model,
                                                                              ThunarShortcut            *shortcut);
+static void                    thunar_shortcuts_model_shortcut_changed      (ThunarShortcutsModel      *model,
+                                                                             ThunarShortcut            *shortcut);
 static gboolean                thunar_shortcuts_model_load_system_shortcuts (gpointer                   user_data);
 static gboolean                thunar_shortcuts_model_load_user_dirs        (gpointer                   user_data);
 static gboolean                thunar_shortcuts_model_load_bookmarks        (gpointer                   user_data);
@@ -940,6 +946,47 @@ thunar_shortcuts_model_find_category (ThunarShortcutsModel    *model,
 
 
 static gboolean
+thunar_shortcuts_model_find_shortcut (ThunarShortcutsModel *model,
+                                      ThunarShortcut       *shortcut,
+                                      gint                 *category_index,
+                                      gint                 *shortcut_index)
+{
+  ThunarShortcutCategory *category;
+  ThunarShortcut         *current_shortcut;
+  gboolean                shortcut_found = FALSE;
+  gint                    c;
+  gint                    s;
+
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), FALSE);
+
+  for (c = 0; !shortcut_found && (guint) c < model->categories->len; ++c)
+    {
+      category = g_ptr_array_index (model->categories, c);
+
+      for (s = 0; !shortcut_found && (guint) s < category->shortcuts->len; ++s)
+        {
+          current_shortcut = g_ptr_array_index (category->shortcuts, s);
+
+          if (current_shortcut == shortcut)
+            {
+              if (category_index != NULL)
+                *category_index = c;
+
+              if (shortcut_index != NULL)
+                *shortcut_index = s;
+
+              shortcut_found = TRUE;
+            }
+        }
+    }
+
+  return shortcut_found;
+}
+
+
+
+static gboolean
 thunar_shortcuts_model_find_volume (ThunarShortcutsModel *model,
                                     GVolume              *volume,
                                     gint                 *category_index,
@@ -1047,25 +1094,59 @@ thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
     }
 
   /* insert the shortcut into the category if we have one for it */
-  if (category != NULL)
-    {
-      /* add the shortcut to the category */
-      g_ptr_array_add (category->shortcuts, shortcut);
+  /* add the shortcut to the category */
+  g_ptr_array_add (category->shortcuts, shortcut);
 
-      /* create a tree path for the new row */
-      path = gtk_tree_path_new_from_indices (category_index, 
-                                             category->shortcuts->len - 1,
-                                             -1);
+  /* create a tree path for the new row */
+  path = gtk_tree_path_new_from_indices (category_index, 
+                                         category->shortcuts->len - 1,
+                                         -1);
 
-      /* create a tree iter for the new row */
+  /* create a tree iter for the new row */
 #ifndef NDEBUG
-      iter.stamp = model->stamp;
+  iter.stamp = model->stamp;
 #endif
-      iter.user_data = GINT_TO_POINTER (category_index);
-      iter.user_data2 = GINT_TO_POINTER (category->shortcuts->len - 1);
+  iter.user_data = GINT_TO_POINTER (category_index);
+  iter.user_data2 = GINT_TO_POINTER (category->shortcuts->len - 1);
 
-      /* create a tree path for the new row */
-      g_signal_emit_by_name (model, "row-inserted", path, &iter, NULL);
+  /* create a tree path for the new row */
+  g_signal_emit_by_name (model, "row-inserted", path, &iter, NULL);
+
+  /* release the tree path */
+  gtk_tree_path_free (path);
+
+  /* be notified whenever the shortcut changes */
+  g_signal_connect_swapped (shortcut, "changed", 
+                            G_CALLBACK (thunar_shortcuts_model_shortcut_changed),
+                            model);
+}
+
+
+
+static void
+thunar_shortcuts_model_shortcut_changed (ThunarShortcutsModel *model,
+                                         ThunarShortcut       *shortcut)
+{
+  GtkTreePath *path;
+  GtkTreeIter  iter;
+  gint         category_index;
+  gint         shortcut_index;
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+
+  /* try find the shortcut in the model */
+  if (thunar_shortcuts_model_find_shortcut (model, shortcut, 
+                                            &category_index, &shortcut_index))
+    {
+      /* create a tree path for the row */
+      path = gtk_tree_path_new_from_indices (category_index, shortcut_index, -1);
+
+      /* create a tree iter for the row */
+      gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+
+      /* notify others that the row has changed */
+      g_signal_emit_by_name (model, "row-changed", path, &iter, NULL);
 
       /* release the tree path */
       gtk_tree_path_free (path);
@@ -1174,6 +1255,34 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
   g_object_unref (icon);
   g_object_unref (location);
 
+  /* create network information */
+  /* TODO we need a new "uri" property for ThunarShortcut that is 
+   * resolved into a real GFile and then into a ThunarFile 
+   * asynchronously */
+  location = g_file_new_for_uri ("network://");
+  icon = g_themed_icon_new (GTK_STOCK_NETWORK);
+  name = g_strdup (_("Browse Network"));
+
+  /* create the network shortcut */
+  shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
+                           "shortcut-type", THUNAR_SHORTCUT_NETWORK_FILE,
+                           "location", location,
+                           "icon", icon,
+                           "eject-icon", NULL,
+                           "name", name,
+                           "hidden", FALSE,
+                           "mutable", FALSE,
+                           "persistent", TRUE,
+                           NULL);
+
+  /* add the network shortcut */
+  thunar_shortcuts_model_add_shortcut (model, shortcut);
+
+  /* release network information */
+  g_free (name);
+  g_object_unref (icon);
+  g_object_unref (location);
+
   /* load rest of the user dirs next */
   model->load_idle_id = g_idle_add (thunar_shortcuts_model_load_user_dirs, model);
 
@@ -1383,6 +1492,7 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
                                      GVolumeMonitor       *monitor)
 {
   ThunarShortcut *shortcut;
+  gboolean        hidden = TRUE;
   GIcon          *eject_icon;
   GIcon          *icon;
   gchar          *name;
@@ -1396,6 +1506,15 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
   eject_icon = g_themed_icon_new ("media-eject");
   name = g_volume_get_name (volume);
 
+  /* hide the volume if there is no media */
+  if (!thunar_g_volume_is_present (volume))
+    hidden = TRUE;
+
+  /* hide the volume if it is not removable (this can be 
+   * overridden by the user in the shortcuts editor) */
+  if (!thunar_g_volume_is_removable (volume))
+    hidden = TRUE;
+
   /* create a shortcut for the volume */
   shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
                            "shortcut-type", THUNAR_SHORTCUT_REGULAR_VOLUME,
@@ -1403,7 +1522,7 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
                            "icon", icon,
                            "eject-icon", eject_icon,
                            "name", name,
-                           "hidden", FALSE,
+                           "hidden", hidden,
                            "mutable", FALSE,
                            "persistent", FALSE,
                            NULL);
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
index 2f635e5..6048998 100644
--- a/thunar/thunar-shortcuts-view.c
+++ b/thunar/thunar-shortcuts-view.c
@@ -91,6 +91,10 @@ static void       thunar_shortcuts_view_row_inserted             (ThunarShortcut
 static void       thunar_shortcuts_view_row_deleted              (ThunarShortcutsView              *view,
                                                                   GtkTreePath                      *path,
                                                                   GtkTreeModel                     *model);
+static void       thunar_shortcuts_view_row_changed              (ThunarShortcutsView              *view,
+                                                                  GtkTreePath                      *path,
+                                                                  GtkTreeIter                      *iter,
+                                                                  GtkTreeModel                     *model);
 static GtkWidget *thunar_shortcuts_view_get_expander_at          (ThunarShortcutsView              *view,
                                                                   gint                              index);
 static void       thunar_shortcuts_view_row_activated            (ThunarShortcutsView              *view,
@@ -302,6 +306,10 @@ thunar_shortcuts_view_constructed (GObject *object)
   /* be notified when a shortcut is removed from the model */
   g_signal_connect_swapped (view->model, "row-deleted",
                             G_CALLBACK (thunar_shortcuts_view_row_deleted), view);
+
+  /* be notified when a shortcut changes */
+  g_signal_connect_swapped (view->model, "row-changed",
+                            G_CALLBACK (thunar_shortcuts_view_row_changed), view);
 }
 
 
@@ -432,8 +440,7 @@ thunar_shortcuts_view_row_inserted (ThunarShortcutsView *view,
       gtk_box_reorder_child (GTK_BOX (box), shortcut_row, shortcut_index);
 
       /* show the row now (unless it was hidden by the user) */
-      if (visible)
-        gtk_widget_show (shortcut_row);
+      gtk_widget_set_visible (shortcut_row, visible);
 
       /* be notified when the user wishes to open the shortcut */
       g_signal_connect_swapped (shortcut_row, "activated",
@@ -490,6 +497,72 @@ thunar_shortcuts_view_row_deleted (ThunarShortcutsView *view,
 
 
 
+static void
+thunar_shortcuts_view_row_changed (ThunarShortcutsView *view,
+                                   GtkTreePath         *path,
+                                   GtkTreeIter         *iter,
+                                   GtkTreeModel        *model)
+{
+  ThunarShortcutRow *row;
+  GtkWidget         *expander;
+  GtkWidget         *box;
+  GIcon             *icon;
+  GList             *rows;
+  GList             *row_element;
+  gchar             *name;
+  gint               category_index;
+  gint               shortcut_index;
+
+  _thunar_return_if_fail (THUNAR_SHORTCUTS_VIEW (view));
+  _thunar_return_if_fail (GTK_IS_TREE_MODEL (model));
+
+  /* get the category and shortcut index */
+  category_index = gtk_tree_path_get_indices (path)[0];
+  shortcut_index = gtk_tree_path_get_indices (path)[1];
+
+  /* find the expander for the row widget */
+  expander = thunar_shortcuts_view_get_expander_at (view, category_index);
+
+  /* if this fails then we are out of sync with the model */
+  g_assert (expander != NULL);
+
+  /* get the box widget that holds the shortcut row */
+  box = gtk_bin_get_child (GTK_BIN (expander));
+
+  /* get a list of all shortcut rows */
+  rows = gtk_container_get_children (GTK_CONTAINER (box));
+
+  /* get the shortcut row we want to update */
+  row_element = g_list_nth (rows, shortcut_index);
+  if (row_element != NULL)
+    {
+      /* cast so that we have a proper row object to work with */
+      row = THUNAR_SHORTCUT_ROW (row_element->data);
+
+      /* read updated information from the tree row */
+      /* TODO also read the ThunarFile if we have one etc. */
+      gtk_tree_model_get (model, iter,
+                          THUNAR_SHORTCUTS_MODEL_COLUMN_NAME, &name,
+                          THUNAR_SHORTCUTS_MODEL_COLUMN_ICON, &icon,
+                          -1);
+
+      /* update the row */
+      g_object_set (row,
+                    "name", name,
+                    "icon", icon,
+                    NULL);
+
+      /* release the values */
+      g_free (name);
+      g_object_unref (icon);
+    }
+
+  /* free the row list */
+  g_list_free (rows);
+}
+
+
+
 static GtkWidget *
 thunar_shortcuts_view_get_expander_at (ThunarShortcutsView *view,
                                        gint                 expander_index)



More information about the Xfce4-commits mailing list