[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Partially implement shortcut row activation.

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


Updating branch refs/heads/jannis/new-shortcuts-pane
         to 6fe61d4de447f103919202148c5d12d321800e09 (commit)
       from 87577206e8d6b8e1e185485a7c2d7efb7c62c0a2 (commit)

commit 6fe61d4de447f103919202148c5d12d321800e09
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Mon Jun 6 21:58:27 2011 +0200

    Partially implement shortcut row activation.
    
    Files and volumes can now be resolved/mounted and are opened properly in
    the folder view. However, canceling does not work yet and, since we use
    GFiles in ThunarShortcutRow, we still have to load synchronously the
    ThunarFile for it before we can resolve the file with ThunarBrowser.
    This needs to be improved.
    
    Also, the selection is lost as soon as an item is clicked and a file in
    the folder view is selected. This may not be as easy to solve as with a
    tree view but we'll see.

 thunar/thunar-shortcut-row.c    |  172 +++++++++++++++++++++++++++++++++++++--
 thunar/thunar-shortcuts-model.c |   86 +++++++++++++++++++-
 thunar/thunar-shortcuts-pane.c  |    2 -
 thunar/thunar-shortcuts-view.c  |   57 +++++++++++++-
 4 files changed, 300 insertions(+), 17 deletions(-)

diff --git a/thunar/thunar-shortcut-row.c b/thunar/thunar-shortcut-row.c
index 86f9676..4395cc2 100644
--- a/thunar/thunar-shortcut-row.c
+++ b/thunar/thunar-shortcut-row.c
@@ -27,7 +27,11 @@
 
 #include <exo/exo.h>
 
+#include <thunar/thunar-browser.h>
+#include <thunar/thunar-dialogs.h>
 #include <thunar/thunar-enum-types.h>
+#include <thunar/thunar-file.h>
+#include <thunar/thunar-gio-extensions.h>
 #include <thunar/thunar-preferences.h>
 #include <thunar/thunar-private.h>
 #include <thunar/thunar-shortcut-row.h>
@@ -48,6 +52,15 @@ enum
 
 
 
+/* signal identifiers */
+enum
+{
+  SIGNAL_ACTIVATED,
+  LAST_SIGNAL,
+};
+
+
+
 static void     thunar_shortcut_row_constructed          (GObject           *object);
 static void     thunar_shortcut_row_dispose              (GObject           *object);
 static void     thunar_shortcut_row_finalize             (GObject           *object);
@@ -76,6 +89,19 @@ static gboolean thunar_shortcut_row_focus_out_event      (GtkWidget         *wid
 static void     thunar_shortcut_row_button_state_changed (ThunarShortcutRow *row,
                                                           GtkStateType       previous_state,
                                                           GtkWidget         *button);
+static void     thunar_shortcut_row_button_clicked       (ThunarShortcutRow *row,
+                                                          GtkButton         *button);
+static void     thunar_shortcut_row_poke_volume_finish   (ThunarBrowser     *browser,
+                                                          GVolume           *volume,
+                                                          ThunarFile        *file,
+                                                          GError            *error,
+                                                          gpointer           unused);
+static void     thunar_shortcut_row_poke_file_finish     (ThunarBrowser     *browser,
+                                                          ThunarFile        *file,
+                                                          ThunarFile        *target_file,
+                                                          GError            *error,
+                                                          gpointer           unused);
+static void     thunar_shortcut_row_resolve_and_activate (ThunarShortcutRow *row);
 static void     thunar_shortcut_row_icon_changed         (ThunarShortcutRow *row);
 static void     thunar_shortcut_row_label_changed        (ThunarShortcutRow *row);
 static void     thunar_shortcut_row_file_changed         (ThunarShortcutRow *row);
@@ -114,7 +140,12 @@ struct _ThunarShortcutRow
 
 
 
-G_DEFINE_TYPE (ThunarShortcutRow, thunar_shortcut_row, GTK_TYPE_EVENT_BOX)
+G_DEFINE_TYPE_WITH_CODE (ThunarShortcutRow, thunar_shortcut_row, GTK_TYPE_EVENT_BOX,
+                         G_IMPLEMENT_INTERFACE (THUNAR_TYPE_BROWSER, NULL))
+
+
+
+static guint row_signals[LAST_SIGNAL];
 
 
 
@@ -185,6 +216,14 @@ thunar_shortcut_row_class_init (ThunarShortcutRowClass *klass)
                                                       THUNAR_TYPE_ICON_SIZE,
                                                       THUNAR_ICON_SIZE_SMALLER,
                                                       EXO_PARAM_READWRITE));
+
+  row_signals[SIGNAL_ACTIVATED] = g_signal_new (I_("activated"),
+                                                G_TYPE_FROM_CLASS (klass),
+                                                G_SIGNAL_RUN_LAST,
+                                                0, NULL, NULL,
+                                                g_cclosure_marshal_VOID__OBJECT,
+                                                G_TYPE_NONE, 1, THUNAR_TYPE_FILE);
+
 }
 
 
@@ -233,6 +272,10 @@ thunar_shortcut_row_init (ThunarShortcutRow *row)
   g_signal_connect_swapped (row->action_button, "state-changed",
                             G_CALLBACK (thunar_shortcut_row_button_state_changed), row);
 
+  /* react on button click events */
+  g_signal_connect_swapped (row->action_button, "clicked",
+                            G_CALLBACK (thunar_shortcut_row_button_clicked), row);
+
   /* create the action button image */
   row->action_image = gtk_image_new ();
   gtk_button_set_image (GTK_BUTTON (row->action_button), row->action_image);
@@ -345,7 +388,6 @@ thunar_shortcut_row_set_property (GObject      *object,
       break;
 
     case PROP_EJECT_ICON:
-      g_debug ("set eject icon");
       thunar_shortcut_row_set_eject_icon (row, g_value_get_object (value));
       break;
 
@@ -397,6 +439,10 @@ thunar_shortcut_row_button_press_event (GtkWidget      *widget,
           gtk_widget_set_state (widget, GTK_STATE_SELECTED);
           gtk_widget_grab_focus (widget);
         }
+
+      /* resolve (e.g. mount) the shortcut and activate it */
+      if (gtk_widget_get_state (widget) == GTK_STATE_SELECTED)
+        thunar_shortcut_row_resolve_and_activate (THUNAR_SHORTCUT_ROW (widget));
     }
   else if (event->button == 3)
     {
@@ -612,6 +658,110 @@ thunar_shortcut_row_button_state_changed (ThunarShortcutRow *row,
 
 
 static void
+thunar_shortcut_row_button_clicked (ThunarShortcutRow *row,
+                                    GtkButton         *button)
+{
+  g_debug ("left click on the action button");
+}
+
+
+
+static void
+thunar_shortcut_row_poke_volume_finish (ThunarBrowser *browser,
+                                        GVolume       *volume,
+                                        ThunarFile    *file,
+                                        GError        *error,
+                                        gpointer       unused)
+{
+  ThunarShortcutRow *row = THUNAR_SHORTCUT_ROW (browser);
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (browser));
+  _thunar_return_if_fail (G_IS_VOLUME (volume));
+  _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
+  
+  if (error == NULL)
+    {
+      g_signal_emit (row, row_signals[SIGNAL_ACTIVATED], 0, file);
+    }
+  else
+    {
+      thunar_dialogs_show_error (GTK_WIDGET (row), error,
+                                 _("Failed to open \"%s\""),
+                                 row->label);
+    }
+}
+
+
+
+static void
+thunar_shortcut_row_poke_file_finish (ThunarBrowser *browser,
+                                        ThunarFile    *file,
+                                        ThunarFile    *target_file,
+                                        GError        *error,
+                                        gpointer       unused)
+{
+  ThunarShortcutRow *row = THUNAR_SHORTCUT_ROW (browser);
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (browser));
+  _thunar_return_if_fail (THUNAR_IS_FILE (file));
+  _thunar_return_if_fail (target_file == NULL || THUNAR_IS_FILE (target_file));
+  
+  if (error == NULL)
+    {
+      g_signal_emit (row, row_signals[SIGNAL_ACTIVATED], 0, target_file);
+    }
+  else
+    {
+      thunar_dialogs_show_error (GTK_WIDGET (row), error,
+                                 _("Failed to open \"%s\""),
+                                 row->label);
+    }
+}
+
+
+
+static void
+thunar_shortcut_row_resolve_and_activate (ThunarShortcutRow *row)
+{
+  ThunarFile *file;
+  GError     *error = NULL;
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+
+  if (row->volume != NULL)
+    {
+      thunar_browser_poke_volume (THUNAR_BROWSER (row), row->volume, row,
+                                  thunar_shortcut_row_poke_volume_finish,
+                                  NULL);
+    }
+  else
+    {
+      file = thunar_file_get (row->file, NULL);
+      if (file != NULL)
+        {
+          thunar_browser_poke_file (THUNAR_BROWSER (row), file, row,
+                                    thunar_shortcut_row_poke_file_finish,
+                                    NULL);
+
+          g_object_unref (file);
+        }
+      else
+        {
+          g_set_error (&error, G_IO_ERROR, G_IO_ERROR_UNKNOWN,
+                       _("Folder could not be loaded"));
+
+          thunar_dialogs_show_error (GTK_WIDGET (row), error,
+                                     _("Failed to open \"%s\""),
+                                     row->label);
+
+          g_error_free (error);
+        }
+    }
+}
+
+
+
+static void
 thunar_shortcut_row_icon_changed (ThunarShortcutRow *row)
 {
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
@@ -672,9 +822,8 @@ thunar_shortcut_row_file_changed (ThunarShortcutRow *row)
 static void
 thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
 {
-  GMount *mount;
-  GIcon  *icon;
-  gchar  *name;
+  GIcon *icon;
+  gchar *name;
 
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
 
@@ -698,10 +847,15 @@ thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
       g_object_unref (icon);
 
       /* update the action button */
-      mount = g_volume_get_mount (row->volume);
-      gtk_widget_set_visible (row->action_button, mount != NULL);
-      if (mount != NULL)
-        g_object_unref (mount);
+      if (thunar_g_volume_is_removable (row->volume)
+          && thunar_g_volume_is_mounted (row->volume))
+        {
+          gtk_widget_set_visible (row->action_button, TRUE);
+        }
+      else
+        {
+          gtk_widget_set_visible (row->action_button, FALSE);
+        }
     }
 }
 
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index b9594db..1021d8d 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -122,12 +122,14 @@ static gboolean                thunar_shortcuts_model_parse_iter            (Thu
                                                                              gint                      *shortcut_index);
 static gboolean                thunar_shortcuts_model_find_category         (ThunarShortcutsModel      *model,
                                                                              GFile                     *file,
+                                                                             GVolume                   *volume,
                                                                              ThunarShortcutType         type,
                                                                              ThunarShortcutCategory   **category,
                                                                              gint                      *category_index);
 static void                    thunar_shortcuts_model_add_shortcut          (ThunarShortcutsModel      *model,
                                                                              ThunarShortcut            *shortcut);
 static gboolean                thunar_shortcuts_model_load_system_shortcuts (gpointer                   user_data);
+static gboolean                thunar_shortcuts_model_load_volumes          (gpointer                   user_data);
 static ThunarShortcutCategory *thunar_shortcut_category_new                 (ThunarShortcutCategoryType type);
 static void                    thunar_shortcut_category_free                (ThunarShortcutCategory    *category);
 static void                    thunar_shortcut_free                         (ThunarShortcut            *shortcut);
@@ -151,6 +153,10 @@ struct _ThunarShortcutsModel
 #endif
 
   GPtrArray      *categories;
+
+  guint           load_idle_id;
+
+  GVolumeMonitor *volume_monitor;
 };
 
 struct _ThunarShortcutCategory
@@ -240,7 +246,7 @@ thunar_shortcuts_model_init (ThunarShortcutsModel *model)
   g_ptr_array_add (model->categories, category);
 
   /* start the load chain */
-  g_idle_add (thunar_shortcuts_model_load_system_shortcuts, model);
+  model->load_idle_id = g_idle_add (thunar_shortcuts_model_load_system_shortcuts, model);
 }
 
 
@@ -252,6 +258,16 @@ thunar_shortcuts_model_finalize (GObject *object)
 
   _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
 
+  if (model->load_idle_id != 0)
+    g_source_remove (model->load_idle_id);
+  
+  /* release the volume monitor */
+  if (model->volume_monitor != NULL)
+    {
+      /* TODO disconnect from the monitor signals */
+      g_object_unref (model->volume_monitor);
+    }
+
   /* free shortcut categories and their shortcuts */
   g_ptr_array_free (model->categories, TRUE);
 
@@ -824,6 +840,7 @@ thunar_shortcuts_model_parse_iter (ThunarShortcutsModel *model,
 static gboolean
 thunar_shortcuts_model_find_category (ThunarShortcutsModel    *model,
                                       GFile                   *file,
+                                      GVolume                 *volume,
                                       ThunarShortcutType       type,
                                       ThunarShortcutCategory **category,
                                       gint                    *category_index)
@@ -855,6 +872,14 @@ thunar_shortcuts_model_find_category (ThunarShortcutsModel    *model,
           if (type == THUNAR_SHORTCUT_SYSTEM_VOLUME)
             item_belongs_here = TRUE;
 
+          /* regular volumes belong into devices as well */
+          if (type == THUNAR_SHORTCUT_VOLUME)
+            item_belongs_here = TRUE;
+
+          /* items with volumes belong here too */
+          if (volume != NULL)
+            item_belongs_here = TRUE;
+
           /* check whether we have an archive mountable */
           if (file != NULL && g_file_has_uri_scheme (file, "archive"))
             item_belongs_here = TRUE;
@@ -920,10 +945,11 @@ thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
   _thunar_return_if_fail (shortcut != NULL);
 
   /* find the destination category for the shortcut */
-  if (!thunar_shortcuts_model_find_category (model, 
-                                             shortcut->file, shortcut->type,
-                                             &category, &category_index))
+  if (!thunar_shortcuts_model_find_category (model, shortcut->file, shortcut->volume,
+                                             shortcut->type, &category, &category_index))
     {
+      g_debug ("failed to add shortcut \"%s\": no category found",
+               shortcut->name);
       return;
     }
 
@@ -1021,11 +1047,63 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
   /* add the shortcut */
   thunar_shortcuts_model_add_shortcut (model, shortcut);
 
+  /* load volumes next */
+  model->load_idle_id = g_idle_add (thunar_shortcuts_model_load_volumes, model);
+
   return FALSE;
 }
 
 
 
+static gboolean
+thunar_shortcuts_model_load_volumes (gpointer user_data)
+{
+  ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data);
+  ThunarShortcut       *shortcut;
+  GList                *volumes;
+  GList                *lp;
+
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
+
+  /* get the default volume monitor */
+  model->volume_monitor = g_volume_monitor_get ();
+
+  /* get a list of all volumes available */
+  volumes = g_volume_monitor_get_volumes (model->volume_monitor);
+
+  /* create shortcuts for the volumes */
+  for (lp = volumes; lp != NULL; lp = lp->next)
+    {
+      g_debug ("volume: %s", g_volume_get_name (lp->data));
+
+      /* create the shortcut */
+      shortcut = g_slice_new0 (ThunarShortcut);
+      shortcut->volume = lp->data;
+      shortcut->icon = g_volume_get_icon (shortcut->volume);
+      shortcut->eject_icon = g_themed_icon_new ("media-eject");
+      shortcut->name = g_volume_get_name (shortcut->volume);
+      shortcut->type = THUNAR_SHORTCUT_VOLUME;
+      shortcut->visible = TRUE;
+      shortcut->mutable = TRUE;
+      shortcut->persistent = FALSE;
+
+      /* add the shortcut */
+      thunar_shortcuts_model_add_shortcut (model, shortcut);
+    }
+
+  /* release the volume list */
+  g_list_free (volumes);
+
+  /* TODO be notified of new and removed volumes on the system */
+
+  /* reset the load idle ID */
+  model->load_idle_id = 0;
+
+  return FALSE;
+};
+
+
+
 static ThunarShortcutCategory *
 thunar_shortcut_category_new (ThunarShortcutCategoryType type)
 {
diff --git a/thunar/thunar-shortcuts-pane.c b/thunar/thunar-shortcuts-pane.c
index 8d8514d..6326f8b 100644
--- a/thunar/thunar-shortcuts-pane.c
+++ b/thunar/thunar-shortcuts-pane.c
@@ -200,12 +200,10 @@ thunar_shortcuts_pane_init (ThunarShortcutsPane *shortcuts_pane)
   gtk_container_add (GTK_CONTAINER (viewport), shortcuts_pane->view);
   gtk_widget_show (shortcuts_pane->view);
 
-#if 0
   /* connect the "shortcut-activated" signal */
   g_signal_connect_swapped (G_OBJECT (shortcuts_pane->view), "shortcut-activated",
                             G_CALLBACK (thunar_navigator_change_directory),
                             shortcuts_pane);
-#endif
 }
 
 
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
index 98b9358..9d79822 100644
--- a/thunar/thunar-shortcuts-view.c
+++ b/thunar/thunar-shortcuts-view.c
@@ -37,6 +37,7 @@
 #include <thunar/thunar-browser.h>
 #include <thunar/thunar-dialogs.h>
 #include <thunar/thunar-dnd.h>
+#include <thunar/thunar-file.h>
 #include <thunar/thunar-gio-extensions.h>
 #include <thunar/thunar-gtk-extensions.h>
 #include <thunar/thunar-preferences.h>
@@ -83,6 +84,12 @@ static void       thunar_shortcuts_view_row_inserted    (ThunarShortcutsView *vi
                                                          GtkTreeModel        *model);
 static GtkWidget *thunar_shortcuts_view_get_expander_at (ThunarShortcutsView *view, 
                                                          gint                 index);
+static void       thunar_shortcuts_view_row_activated   (ThunarShortcutsView *view,
+                                                         ThunarFile          *file,
+                                                         ThunarShortcutRow   *row);
+static void       thunar_shortcuts_view_open            (ThunarShortcutsView *view,
+                                                         ThunarFile          *file,
+                                                         gboolean             new_window);
 
 
 
@@ -135,7 +142,6 @@ thunar_shortcuts_view_class_init (ThunarShortcutsViewClass *klass)
                                                         EXO_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT));
 
-#if 0
   /**
    * ThunarShortcutsView:row-activated:
    *
@@ -147,8 +153,9 @@ thunar_shortcuts_view_class_init (ThunarShortcutsViewClass *klass)
                   G_SIGNAL_RUN_LAST,
                   0, NULL, NULL,
                   g_cclosure_marshal_VOID__OBJECT,
-                  G_TYPE_NONE, 1, THUNAR_TYPE_SHORTCUT);
+                  G_TYPE_NONE, 1, THUNAR_TYPE_FILE);
 
+#if 0
   /**
    * ThunarShortcutsView:shortcut-disconnect:
    *
@@ -399,6 +406,10 @@ thunar_shortcuts_view_row_inserted (ThunarShortcutsView *view,
       /* show the row now (unless it was hidden by the user) */
       if (visible)
         gtk_widget_show (shortcut_row);
+
+      /* be notified when the user wishes to open the shortcut */
+      g_signal_connect_swapped (shortcut_row, "activated",
+                                G_CALLBACK (thunar_shortcuts_view_row_activated), view);
     }
 }
 
@@ -428,6 +439,48 @@ thunar_shortcuts_view_get_expander_at (ThunarShortcutsView *view,
 
 
 
+static void
+thunar_shortcuts_view_row_activated (ThunarShortcutsView *view,
+                                     ThunarFile          *file,
+                                     ThunarShortcutRow   *row)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
+  _thunar_return_if_fail (THUNAR_IS_FILE (file));
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+
+  thunar_shortcuts_view_open (view, file, FALSE);
+}
+
+
+
+static void
+thunar_shortcuts_view_open (ThunarShortcutsView *view,
+                            ThunarFile          *file,
+                            gboolean             new_window)
+{
+  ThunarApplication *application;
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
+  _thunar_return_if_fail (THUNAR_IS_FILE (file));
+
+  if (new_window)
+    {
+      /* open the file in a new window */
+      application = thunar_application_get ();
+      thunar_application_open_window (application, file,
+                                      gtk_widget_get_screen (GTK_WIDGET (view)),
+                                      NULL);
+      g_object_unref (application);
+    }
+  else
+    {
+      /* invoke the signal to change to the folder */
+      g_signal_emit (view, view_signals[SHORTCUT_ACTIVATED], 0, file);
+    }
+}
+
+
+
 /**
  * thunar_shortcuts_view_new:
  *



More information about the Xfce4-commits mailing list