[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Initial work on the context menu for the new shortcuts view.
Jannis Pohlmann
noreply at xfce.org
Fri Jul 15 21:10:36 CEST 2011
Updating branch refs/heads/jannis/new-shortcuts-pane
to 5baf592a668c489f991c3d2164f4e68990ad0654 (commit)
from a78349f2fc3924202ab8b69661dedc1e5c4f018b (commit)
commit 5baf592a668c489f991c3d2164f4e68990ad0654
Author: Jannis Pohlmann <jannis at xfce.org>
Date: Thu Jun 9 21:54:06 2011 +0200
Initial work on the context menu for the new shortcuts view.
thunar/thunar-shortcut-row.c | 56 ++++++++--
thunar/thunar-shortcuts-view.c | 229 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 272 insertions(+), 13 deletions(-)
diff --git a/thunar/thunar-shortcut-row.c b/thunar/thunar-shortcut-row.c
index 932df87..be91cf2 100644
--- a/thunar/thunar-shortcut-row.c
+++ b/thunar/thunar-shortcut-row.c
@@ -65,6 +65,7 @@ enum
enum
{
SIGNAL_ACTIVATED,
+ SIGNAL_CONTEXT_MENU,
LAST_SIGNAL,
};
@@ -94,6 +95,8 @@ static void thunar_shortcut_row_set_property (GObject
GParamSpec *pspec);
static gboolean thunar_shortcut_row_button_press_event (GtkWidget *widget,
GdkEventButton *event);
+static gboolean thunar_shortcut_row_button_release_event (GtkWidget *widget,
+ GdkEventButton *event);
static gboolean thunar_shortcut_row_key_press_event (GtkWidget *widget,
GdkEventKey *event);
static gboolean thunar_shortcut_row_enter_notify_event (GtkWidget *widget,
@@ -210,6 +213,7 @@ thunar_shortcut_row_class_init (ThunarShortcutRowClass *klass)
gtkwidget_class = GTK_WIDGET_CLASS (klass);
gtkwidget_class->button_press_event = thunar_shortcut_row_button_press_event;
+ gtkwidget_class->button_release_event = thunar_shortcut_row_button_release_event;
gtkwidget_class->key_press_event = thunar_shortcut_row_key_press_event;
gtkwidget_class->enter_notify_event = thunar_shortcut_row_enter_notify_event;
gtkwidget_class->leave_notify_event = thunar_shortcut_row_leave_notify_event;
@@ -292,12 +296,21 @@ thunar_shortcut_row_class_init (ThunarShortcutRowClass *klass)
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);
+ 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);
+
+ row_signals[SIGNAL_CONTEXT_MENU] =
+ g_signal_new (I_("context-menu"),
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
@@ -582,14 +595,14 @@ thunar_shortcut_row_button_press_event (GtkWidget *widget,
}
else if (event->button == 3)
{
- /* TODO emit a popup-menu signal or something similar here */
- g_debug ("right click");
+ /* TODO emit a context-menu signal or something similar here */
+ g_debug ("right button press");
return FALSE;
}
else if (event->button == 2)
{
/* TODO we don't handle middle-click events yet */
- g_debug ("middle click");
+ g_debug ("middle button press");
return FALSE;
}
@@ -599,6 +612,31 @@ thunar_shortcut_row_button_press_event (GtkWidget *widget,
static gboolean
+thunar_shortcut_row_button_release_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT_ROW (widget), FALSE);
+
+ /* distinguish between left, right and middle-click */
+ if (event->button == 3)
+ {
+ /* TODO abort the menu popup timeout created in reaction to
+ * the right button press event */
+
+ /* emit the popup-menu signal */
+ g_signal_emit_by_name (widget, "context-menu");
+
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+
+
+static gboolean
thunar_shortcut_row_key_press_event (GtkWidget *widget,
GdkEventKey *event)
{
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
index 553a9d1..3afe01c 100644
--- a/thunar/thunar-shortcuts-view.c
+++ b/thunar/thunar-shortcuts-view.c
@@ -103,6 +103,8 @@ static void thunar_shortcuts_view_row_activated (ThunarShortcut
static void thunar_shortcuts_view_row_state_changed (ThunarShortcutsView *view,
GtkStateType previous_state,
ThunarShortcutRow *row);
+static gboolean thunar_shortcuts_view_row_context_menu (ThunarShortcutsView *view,
+ GtkWidget *widget);
static void thunar_shortcuts_view_open (ThunarShortcutsView *view,
ThunarFile *file,
gboolean new_window);
@@ -128,15 +130,21 @@ struct _ThunarShortcutsViewClass
struct _ThunarShortcutsView
{
- GtkEventBox __parent__;
+ GtkEventBox __parent__;
- GtkTreeModel *model;
- GtkWidget *expander_box;
+ ThunarxProviderFactory *provider_factory;
+
+ GtkTreeModel *model;
+ GtkWidget *expander_box;
};
-static guint view_signals[LAST_SIGNAL] G_GNUC_UNUSED;
+static guint view_signals[LAST_SIGNAL];
+
+
+
+static GQuark thunar_shortcuts_view_row_quark;
@@ -150,6 +158,9 @@ thunar_shortcuts_view_class_init (ThunarShortcutsViewClass *klass)
{
GObjectClass *gobject_class;
+ /* initialize the row quark */
+ thunar_shortcuts_view_row_quark = g_quark_from_static_string ("thunar-shortcuts-view-row");
+
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->constructed = thunar_shortcuts_view_constructed;
gobject_class->finalize = thunar_shortcuts_view_finalize;
@@ -222,6 +233,9 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view)
view->model = NULL;
+ /* grab a reference on the provider factory */
+ view->provider_factory = thunarx_provider_factory_get_default ();
+
alignment = gtk_alignment_new (0.0f, 0.0f, 1.0f, 1.0f);
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 4, 4, 0, 0);
gtk_container_add (GTK_CONTAINER (view), alignment);
@@ -319,6 +333,9 @@ thunar_shortcuts_view_finalize (GObject *object)
{
ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (object);
+ /* release the provider factory */
+ g_object_unref (G_OBJECT (view->provider_factory));
+
/* release the shortcuts model */
if (view->model != NULL)
g_object_unref (view->model);
@@ -455,9 +472,17 @@ thunar_shortcuts_view_row_inserted (ThunarShortcutsView *view,
/* 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);
+
+ /* be notified when the state of the row changes (e.g. when it is
+ * being hovered or selected by the user) */
g_signal_connect_swapped (shortcut_row, "state-changed",
G_CALLBACK (thunar_shortcuts_view_row_state_changed),
view);
+
+ /* be notified when a context menu should be displayed for the row */
+ g_signal_connect_swapped (shortcut_row, "context-menu",
+ G_CALLBACK (thunar_shortcuts_view_row_context_menu),
+ view);
}
}
@@ -636,6 +661,202 @@ thunar_shortcuts_view_row_state_changed (ThunarShortcutsView *view,
+static gboolean
+thunar_shortcuts_view_row_context_menu (ThunarShortcutsView *view,
+ GtkWidget *widget)
+{
+ ThunarShortcutType shortcut_type;
+ ThunarShortcutRow *row = THUNAR_SHORTCUT_ROW (widget);
+ ThunarFile *file;
+ GtkWidget *image;
+ GtkWidget *item;
+ GtkWidget *menu;
+ GtkWidget *window;
+ GVolume *volume;
+ GList *lp;
+ GList *providers;
+ GList *actions = NULL;
+ GList *tmp;
+
+ _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), FALSE);
+ _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT_ROW (row), FALSE);
+
+ /* prepare the popup menu */
+ menu = gtk_menu_new ();
+
+ /* append the "Open" menu action */
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Open"));
+ g_object_set_qdata (G_OBJECT (item), thunar_shortcuts_view_row_quark, row);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* set the stock icon */
+ image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+ gtk_widget_show (image);
+
+ /* append the "Open in New Window" menu action */
+ item = gtk_image_menu_item_new_with_mnemonic (_("Open in New Window"));
+ g_object_set_qdata (G_OBJECT (item), thunar_shortcuts_view_row_quark, row);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* append a menu separator */
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* determine the type of the row */
+ shortcut_type = thunar_shortcut_row_get_shortcut_type (row);
+
+ /* check if we are dealing with a mount */
+ if (shortcut_type == THUNAR_SHORTCUT_STANDALONE_MOUNT)
+ {
+ /* append the "Disconnect" item */
+ item = gtk_image_menu_item_new_with_mnemonic (_("Disconn_ect"));
+ g_object_set_qdata (G_OBJECT (item), thunar_shortcuts_view_row_quark, row);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* append a menu separator */
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+
+ /* check if we're dealing with a volume */
+ if (shortcut_type == THUNAR_SHORTCUT_REGULAR_VOLUME
+ || shortcut_type == THUNAR_SHORTCUT_EJECTABLE_VOLUME)
+ {
+ /* get the volume from the shortcut row */
+ volume = thunar_shortcut_row_get_volume (row);
+
+ /* check if we have a mounted volume */
+ /* append the "Mount" item */
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Mount"));
+ g_object_set_qdata (G_OBJECT (item), thunar_shortcuts_view_row_quark, row);
+ gtk_widget_set_sensitive (item, !thunar_g_volume_is_mounted (volume));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ if (shortcut_type == THUNAR_SHORTCUT_REGULAR_VOLUME)
+ {
+ /* append the "Unmount" item */
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Unmount"));
+ g_object_set_qdata (G_OBJECT (item), thunar_shortcuts_view_row_quark, row);
+ gtk_widget_set_sensitive (item, thunar_g_volume_is_mounted (volume));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+
+ /* append the "Disconnect" (eject + safely remove drive) item */
+ item = gtk_image_menu_item_new_with_mnemonic (_("Disconn_ect"));
+ g_object_set_qdata (G_OBJECT (item), thunar_shortcuts_view_row_quark, row);
+ gtk_widget_set_sensitive (item, thunar_g_volume_is_mounted (volume));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+
+ /* get the ThunarFile from the row */
+ file = thunar_shortcut_row_get_file (row);
+
+ /* check if we're dealing with the trash */
+ if (shortcut_type == THUNAR_SHORTCUT_REGULAR_FILE
+ && file != NULL
+ && thunar_file_is_trashed (file)
+ && thunar_file_is_root (file))
+ {
+ /* append the "Empty Trash" menu action */
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Empty Trash"));
+ g_object_set_qdata (G_OBJECT (item), thunar_shortcuts_view_row_quark, row);
+ gtk_widget_set_sensitive (item, (thunar_file_get_item_count (file) > 0));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* append a menu separator */
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+
+ /* create provider menu items if there is a non-trashed file */
+ if (G_LIKELY (file != NULL && !thunar_file_is_trashed (file)))
+ {
+ /* load the menu providers from the provider factory */
+ providers = thunarx_provider_factory_list_providers (view->provider_factory,
+ THUNARX_TYPE_MENU_PROVIDER);
+ if (G_LIKELY (providers != NULL))
+ {
+ /* determine the toplevel window we belong to */
+ window = gtk_widget_get_toplevel (GTK_WIDGET (view));
+
+ /* load the actions offered by the menu providers */
+ for (lp = providers; lp != NULL; lp = lp->next)
+ {
+ tmp = thunarx_menu_provider_get_folder_actions (lp->data, window,
+ THUNARX_FILE_INFO (file));
+ actions = g_list_concat (actions, tmp);
+ g_object_unref (G_OBJECT (lp->data));
+ }
+ g_list_free (providers);
+
+ /* add the actions to the menu */
+ for (lp = actions; lp != NULL; lp = lp->next)
+ {
+ item = gtk_action_create_menu_item (GTK_ACTION (lp->data));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* release the reference on the action */
+ g_object_unref (G_OBJECT (lp->data));
+ }
+
+ /* add a separator to the end of the menu */
+ if (G_LIKELY (lp != actions))
+ {
+ /* append a menu separator */
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+
+ /* cleanup */
+ g_list_free (actions);
+ }
+ }
+
+#if 0
+ if (thunar_shortcut_row_get_mutable (row))
+#endif
+ {
+ /* append the remove menu item */
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Remove Shortcut"));
+ gtk_widget_set_sensitive (item, FALSE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* set the remove stock icon */
+ image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+ gtk_widget_show (image);
+
+ /* append the rename menu item */
+ item = gtk_image_menu_item_new_with_mnemonic (_("Re_name Shortcut"));
+ gtk_widget_set_sensitive (item, FALSE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+
+ /* run the menu on the view's screen (taking over the floating
+ * reference on the menu) */
+ thunar_gtk_menu_run (GTK_MENU (menu), GTK_WIDGET (view), NULL, NULL,
+ 0, gtk_get_current_event_time ());
+
+ return TRUE;
+}
+
+
+
static void
thunar_shortcuts_view_foreach_row (ThunarShortcutsView *view,
ThunarShortcutsViewForeachRowFunc func,
More information about the Xfce4-commits
mailing list