[gnome-panel] menu: add volumes to places menu
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-panel] menu: add volumes to places menu
- Date: Mon, 5 Feb 2018 21:38:16 +0000 (UTC)
commit 70356e75c9a7094311144a798ef8025971295e28
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Mon Feb 5 22:47:44 2018 +0200
menu: add volumes to places menu
modules/menu/gp-places-menu.c | 317 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 317 insertions(+), 0 deletions(-)
---
diff --git a/modules/menu/gp-places-menu.c b/modules/menu/gp-places-menu.c
index b450bcd..d343722 100644
--- a/modules/menu/gp-places-menu.c
+++ b/modules/menu/gp-places-menu.c
@@ -23,6 +23,7 @@
#include "gp-bookmarks.h"
#include "gp-menu-utils.h"
#include "gp-places-menu.h"
+#include "gp-volumes.h"
#define MAX_ITEMS_OR_SUBMENU 8
@@ -37,6 +38,10 @@ struct _GpPlacesMenu
GpBookmarks *bookmarks;
GtkWidget *bookmarks_menu;
+ GpVolumes *volumes;
+ GtkWidget *volumes_local_menu;
+ GtkWidget *volumes_remote_menu;
+
gulong locked_down_id;
gulong menu_icon_size_id;
};
@@ -55,6 +60,99 @@ static GParamSpec *menu_properties[LAST_PROP] = { NULL };
G_DEFINE_TYPE (GpPlacesMenu, gp_places_menu, GTK_TYPE_MENU)
static void
+poll_for_media_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error;
+
+ error = NULL;
+ if (!g_drive_poll_for_media_finish (G_DRIVE (object), res, &error))
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED))
+ {
+ gchar *name;
+ gchar *message;
+
+ name = g_drive_get_name (G_DRIVE (object));
+ message = g_strdup_printf (_("Unable to scan %s for media changes"), name);
+ g_free (name);
+
+ gp_menu_utils_show_error_dialog (message, error);
+ g_free (message);
+ }
+ }
+
+ g_clear_error (&error);
+}
+
+static void
+drive_activate_cb (GtkWidget *item,
+ GDrive *drive)
+{
+ g_drive_poll_for_media (drive, NULL, poll_for_media_cb, NULL);
+}
+
+static void
+mount_cb (GObject *object,
+ GAsyncResult *res,
+ GMountOperation *operation)
+{
+ GError *error;
+
+ error = NULL;
+ if (g_volume_mount_finish (G_VOLUME (object), res, &error))
+ {
+ GMount *mount;
+ GFile *root;
+ gchar *uri;
+
+ mount = g_volume_get_mount (G_VOLUME (object));
+ root = g_mount_get_root (mount);
+ g_object_unref (mount);
+
+ uri = g_file_get_uri (root);
+ g_object_unref (root);
+
+ gp_menu_utils_launch_uri (uri);
+ g_free (uri);
+ }
+ else
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED))
+ {
+ gchar *name;
+ gchar *message;
+
+ name = g_volume_get_name (G_VOLUME (object));
+ message = g_strdup_printf (_("Unable to mount %s"), name);
+ g_free (name);
+
+ gp_menu_utils_show_error_dialog (message, error);
+ g_free (message);
+ }
+ }
+
+ g_object_unref (operation);
+ g_clear_error (&error);
+}
+
+static void
+volume_activate_cb (GtkWidget *item,
+ GVolume *volume)
+{
+ GMountMountFlags flags;
+ GMountOperation *operation;
+
+ flags = G_MOUNT_MOUNT_NONE;
+ operation = gtk_mount_operation_new (NULL);
+
+ g_volume_mount (volume, flags, operation, NULL,
+ (GAsyncReadyCallback) mount_cb,
+ operation);
+}
+
+static void
uri_activate_cb (GtkWidget *item,
const gchar *uri)
{
@@ -164,6 +262,144 @@ append_bookmark (GpBookmarks *bookmarks,
}
static void
+append_local_drive (GpVolumes *volumes,
+ GDrive *drive,
+ GpPlacesMenu *menu)
+{
+ GIcon *icon;
+ gchar *label;
+ gchar *tooltip;
+ guint icon_size;
+ GtkWidget *image;
+ GtkWidget *item;
+ GtkWidget *add_menu;
+
+ icon = g_drive_get_icon (drive);
+ label = g_drive_get_name (drive);
+ tooltip = g_strdup_printf (_("Rescan %s"), label);
+
+ icon_size = gp_applet_get_menu_icon_size (menu->applet);
+ image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU);
+ gtk_image_set_pixel_size (GTK_IMAGE (image), icon_size);
+
+ item = gp_image_menu_item_new_with_label (label);
+ gp_image_menu_item_set_image (GP_IMAGE_MENU_ITEM (item), image);
+
+ gtk_widget_set_tooltip_text (item, tooltip);
+ g_object_bind_property (menu->applet, "enable-tooltips", item, "has-tooltip",
+ G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+ g_object_unref (icon);
+ g_free (tooltip);
+ g_free (label);
+
+ add_menu = menu->volumes_local_menu ? menu->volumes_local_menu : GTK_WIDGET (menu);
+ gtk_menu_shell_append (GTK_MENU_SHELL (add_menu), item);
+ gtk_widget_show (item);
+
+ g_signal_connect_data (item, "activate",
+ G_CALLBACK (drive_activate_cb),
+ g_object_ref (drive),
+ (GClosureNotify) g_object_unref,
+ 0);
+}
+
+static void
+append_local_volume (GpVolumes *volumes,
+ GVolume *volume,
+ GpPlacesMenu *menu)
+{
+ GIcon *icon;
+ gchar *label;
+ gchar *tooltip;
+ guint icon_size;
+ GtkWidget *image;
+ GtkWidget *item;
+ GtkWidget *add_menu;
+
+ icon = g_volume_get_icon (volume);
+ label = g_volume_get_name (volume);
+ tooltip = g_strdup_printf (_("Mount %s"), label);
+
+ icon_size = gp_applet_get_menu_icon_size (menu->applet);
+ image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU);
+ gtk_image_set_pixel_size (GTK_IMAGE (image), icon_size);
+
+ item = gp_image_menu_item_new_with_label (label);
+ gp_image_menu_item_set_image (GP_IMAGE_MENU_ITEM (item), image);
+
+ gtk_widget_set_tooltip_text (item, tooltip);
+ g_object_bind_property (menu->applet, "enable-tooltips", item, "has-tooltip",
+ G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+ g_object_unref (icon);
+ g_free (tooltip);
+ g_free (label);
+
+ add_menu = menu->volumes_local_menu ? menu->volumes_local_menu : GTK_WIDGET (menu);
+ gtk_menu_shell_append (GTK_MENU_SHELL (add_menu), item);
+ gtk_widget_show (item);
+
+ g_signal_connect_data (item, "activate",
+ G_CALLBACK (volume_activate_cb),
+ g_object_ref (volume),
+ (GClosureNotify) g_object_unref,
+ 0);
+}
+
+static void
+append_local_mount (GpVolumes *volumes,
+ GMount *mount,
+ GpPlacesMenu *menu)
+{
+ GFile *file;
+ GIcon *icon;
+ gchar *label;
+ GtkWidget *item;
+ GtkWidget *add_menu;
+
+ file = g_mount_get_root (mount);
+ icon = g_mount_get_icon (mount);
+ label = g_mount_get_name (mount);
+
+ item = create_menu_item (menu, file, icon, NULL, label, NULL);
+
+ add_menu = menu->volumes_local_menu ? menu->volumes_local_menu : GTK_WIDGET (menu);
+ gtk_menu_shell_append (GTK_MENU_SHELL (add_menu), item);
+ gtk_widget_show (item);
+
+ g_object_unref (file);
+ g_object_unref (icon);
+ g_free (label);
+}
+
+static void
+append_remote_mount (GpVolumes *volumes,
+ GMount *mount,
+ GpPlacesMenu *menu)
+{
+ GFile *file;
+ GIcon *icon;
+ gchar *label;
+ GtkWidget *item;
+ GtkWidget *add_menu;
+
+ file = g_mount_get_root (mount);
+ icon = g_mount_get_icon (mount);
+ label = g_mount_get_name (mount);
+
+ item = create_menu_item (menu, file, icon, NULL, label, NULL);
+
+ add_menu = menu->volumes_remote_menu ? menu->volumes_remote_menu : GTK_WIDGET (menu);
+ gtk_menu_shell_append (GTK_MENU_SHELL (add_menu), item);
+ gtk_widget_show (item);
+
+ g_object_unref (file);
+ g_object_unref (icon);
+ g_free (label);
+}
+
+static void
append_home_dir (GpPlacesMenu *menu)
{
GFile *file;
@@ -268,6 +504,42 @@ append_computer (GpPlacesMenu *menu)
}
static void
+append_local_volumes (GpPlacesMenu *menu)
+{
+ if (gp_volumes_get_local_count (menu->volumes) > MAX_ITEMS_OR_SUBMENU)
+ {
+ guint icon_size;
+ GtkWidget *icon;
+ GtkWidget *item;
+
+ icon_size = gp_applet_get_menu_icon_size (menu->applet);
+ icon = gtk_image_new_from_icon_name ("drive-removable-media", GTK_ICON_SIZE_MENU);
+ gtk_image_set_pixel_size (GTK_IMAGE (icon), icon_size);
+
+ item = gp_image_menu_item_new_with_label (_("Removable Media"));
+ gp_image_menu_item_set_image (GP_IMAGE_MENU_ITEM (item), icon);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ menu->volumes_local_menu = gtk_menu_new ();
+ g_object_add_weak_pointer (G_OBJECT (item), (gpointer *) &menu->volumes_local_menu);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu->volumes_local_menu);
+ }
+
+ gp_volumes_foreach_local_drives (menu->volumes,
+ (GpVolumesForeachDrivesFunc) append_local_drive,
+ menu);
+
+ gp_volumes_foreach_local_volumes (menu->volumes,
+ (GpVolumesForeachVolumesFunc) append_local_volume,
+ menu);
+
+ gp_volumes_foreach_local_mounts (menu->volumes,
+ (GpVolumesForeachMountsFunc) append_local_mount,
+ menu);
+}
+
+static void
append_network (GpPlacesMenu *menu)
{
GFile *file;
@@ -288,6 +560,34 @@ append_network (GpPlacesMenu *menu)
}
static void
+append_remote_volumes (GpPlacesMenu *menu)
+{
+ if (gp_volumes_get_remote_count (menu->volumes) > MAX_ITEMS_OR_SUBMENU)
+ {
+ guint icon_size;
+ GtkWidget *icon;
+ GtkWidget *item;
+
+ icon_size = gp_applet_get_menu_icon_size (menu->applet);
+ icon = gtk_image_new_from_icon_name ("network-server", GTK_ICON_SIZE_MENU);
+ gtk_image_set_pixel_size (GTK_IMAGE (icon), icon_size);
+
+ item = gp_image_menu_item_new_with_label (_("Network Places"));
+ gp_image_menu_item_set_image (GP_IMAGE_MENU_ITEM (item), icon);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ menu->volumes_remote_menu = gtk_menu_new ();
+ g_object_add_weak_pointer (G_OBJECT (item), (gpointer *) &menu->volumes_remote_menu);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu->volumes_remote_menu);
+ }
+
+ gp_volumes_foreach_remote_mounts (menu->volumes,
+ (GpVolumesForeachMountsFunc) append_remote_mount,
+ menu);
+}
+
+static void
remove_item (GtkWidget *widget,
gpointer user_data)
{
@@ -298,7 +598,10 @@ static void
menu_reload (GpPlacesMenu *menu)
{
gtk_container_foreach (GTK_CONTAINER (menu), remove_item, NULL);
+
g_assert (menu->bookmarks_menu == NULL);
+ g_assert (menu->volumes_local_menu == NULL);
+ g_assert (menu->volumes_remote_menu == NULL);
append_home_dir (menu);
append_desktop_dir (menu);
@@ -306,9 +609,11 @@ menu_reload (GpPlacesMenu *menu)
append_separator (menu);
append_computer (menu);
+ append_local_volumes (menu);
append_separator (menu);
append_network (menu);
+ append_remote_volumes (menu);
}
static gboolean
@@ -345,6 +650,13 @@ bookmarks_changed_cb (GpBookmarks *bookmarks,
}
static void
+volumes_changed_cb (GpVolumes *volumes,
+ GpPlacesMenu *menu)
+{
+ queue_reload (menu);
+}
+
+static void
locked_down_cb (GpApplet *applet,
GParamSpec *pspec,
GpPlacesMenu *menu)
@@ -373,6 +685,10 @@ gp_places_menu_constructed (GObject *object)
g_signal_connect (menu->bookmarks, "changed",
G_CALLBACK (bookmarks_changed_cb), menu);
+ menu->volumes = gp_volumes_new ();
+ g_signal_connect (menu->volumes, "changed",
+ G_CALLBACK (volumes_changed_cb), menu);
+
menu->locked_down_id = g_signal_connect (menu->applet, "notify::locked-down",
G_CALLBACK (locked_down_cb), menu);
@@ -410,6 +726,7 @@ gp_places_menu_dispose (GObject *object)
}
g_clear_object (&menu->bookmarks);
+ g_clear_object (&menu->volumes);
menu->applet = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]