[gnome-flashback] bluetooth-applet: add status icon



commit 05801ced20258d92ab3c4d821510870f22037cd3
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Sep 10 02:59:31 2015 +0300

    bluetooth-applet: add status icon
    
    Thanks György Balló for initial version in javascript.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=753424

 configure.ac                                       |    2 +-
 .../libbluetooth-applet/gf-bluetooth-applet.c      |  399 +++++++++++++++++++-
 po/POTFILES.in                                     |    1 +
 3 files changed, 400 insertions(+), 2 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 92cff57..92ce712 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,7 +47,7 @@ PKG_CHECK_MODULES(AUTOMOUNT_MANAGER, gtk+-3.0 >= $GTK_REQUIRED gsettings-desktop
 AC_SUBST(AUTOMOUNT_MANAGER_CFLAGS)
 AC_SUBST(AUTOMOUNT_MANAGER_LIBS)
 
-PKG_CHECK_MODULES(BLUETOOTH_APPLET, gtk+-3.0 >= $GTK_REQUIRED)
+PKG_CHECK_MODULES(BLUETOOTH_APPLET, gtk+-3.0 >= $GTK_REQUIRED gnome-bluetooth-1.0)
 AC_SUBST(BLUETOOTH_APPLET_CFLAGS)
 AC_SUBST(BLUETOOTH_APPLET_LIBS)
 
diff --git a/gnome-flashback/libbluetooth-applet/gf-bluetooth-applet.c 
b/gnome-flashback/libbluetooth-applet/gf-bluetooth-applet.c
index fe46eea..7845158 100644
--- a/gnome-flashback/libbluetooth-applet/gf-bluetooth-applet.c
+++ b/gnome-flashback/libbluetooth-applet/gf-bluetooth-applet.c
@@ -17,23 +17,420 @@
 
 #include "config.h"
 
+#include <bluetooth-client.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
 #include "gf-bluetooth-applet.h"
+#include "gf-sd-rfkill.h"
+
+#define GSM_DBUS_NAME "org.gnome.SettingsDaemon.Rfkill"
+#define GSM_DBUS_PATH "/org/gnome/SettingsDaemon/Rfkill"
 
 struct _GfBluetoothApplet
 {
-  GObject parent;
+  GObject          parent;
+
+  GtkStatusIcon   *status_icon;
+  GfSdRfkill      *rfkill;
+  BluetoothClient *client;
+  GtkTreeModel    *model;
 };
 
 G_DEFINE_TYPE (GfBluetoothApplet, gf_bluetooth_applet, G_TYPE_OBJECT)
 
 static void
+turn_off_cb (GtkMenuItem *item,
+             gpointer     user_data)
+{
+  GfBluetoothApplet *applet;
+
+  applet = GF_BLUETOOTH_APPLET (user_data);
+
+  if (applet->rfkill == NULL)
+    return;
+
+  gf_sd_rfkill_set_bluetooth_airplane_mode (applet->rfkill, FALSE);
+}
+
+static void
+send_files_cb (GtkMenuItem *item,
+               gpointer     user_data)
+{
+  GAppInfo *app_info;
+  GError *error;
+
+  error = NULL;
+  app_info = g_app_info_create_from_commandline ("bluetooth-sendto",
+                                                 "Bluetooth Transfer",
+                                                 G_APP_INFO_CREATE_NONE,
+                                                 &error);
+
+  if (error != NULL)
+    {
+      g_warning ("Failed to crete GAppInfo from commandline - %s",
+                 error->message);
+      g_error_free (error);
+    }
+  else
+    {
+      g_app_info_launch (app_info, NULL, NULL, &error);
+
+      if (error != NULL)
+        {
+          g_warning ("Failed to start Bluetooth Transfer - %s", error->message);
+          g_error_free (error);
+        }
+    }
+
+  g_clear_object (&app_info);
+}
+
+static void
+turn_on_cb (GtkMenuItem *item,
+            gpointer     user_data)
+{
+  GfBluetoothApplet *applet;
+
+  applet = GF_BLUETOOTH_APPLET (user_data);
+
+  if (applet->rfkill == NULL)
+    return;
+
+  gf_sd_rfkill_set_bluetooth_airplane_mode (applet->rfkill, TRUE);
+}
+
+static void
+settings_cb (GtkMenuItem *item,
+             gpointer     user_data)
+{
+  GAppInfo *app_info;
+  GError *error;
+
+  error = NULL;
+  app_info = g_app_info_create_from_commandline ("gnome-control-center bluetooth",
+                                                 "Bluetooth Settings",
+                                                 G_APP_INFO_CREATE_NONE,
+                                                 &error);
+
+  if (error != NULL)
+    {
+      g_warning ("Failed to crete GAppInfo from commandline - %s",
+                 error->message);
+      g_error_free (error);
+    }
+  else
+    {
+      g_app_info_launch (app_info, NULL, NULL, &error);
+
+      if (error != NULL)
+        {
+          g_warning ("Failed to start Bluetooth Settings - %s", error->message);
+          g_error_free (error);
+        }
+    }
+
+  g_clear_object (&app_info);
+}
+
+static void
+popup_menu_cb (GtkStatusIcon *status_icon,
+               guint          button,
+               guint          activate_time,
+               gpointer       user_data)
+{
+  GfBluetoothApplet *applet;
+  GtkWidget *menu;
+  gboolean airplane_mode;
+  GtkWidget *item;
+
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+
+  applet = GF_BLUETOOTH_APPLET (user_data);
+  menu = gtk_menu_new ();
+
+  airplane_mode = FALSE;
+  if (applet->rfkill != NULL)
+    airplane_mode = gf_sd_rfkill_get_bluetooth_airplane_mode (applet->rfkill);
+
+  if (!airplane_mode)
+    {
+      item = gtk_menu_item_new_with_label (_("Turn Off"));
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+      g_signal_connect (item, "activate", G_CALLBACK (turn_off_cb), NULL);
+
+      item = gtk_menu_item_new_with_label (_("Send Files"));
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+      g_signal_connect (item, "activate", G_CALLBACK (send_files_cb), NULL);
+    }
+  else
+    {
+      item = gtk_menu_item_new_with_label (_("Turn On"));
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+      g_signal_connect (item, "activate", G_CALLBACK (turn_on_cb), NULL);
+    }
+
+  item = gtk_menu_item_new_with_label (_("Bluetooth Settings"));
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+  g_signal_connect (item, "activate", G_CALLBACK (settings_cb), NULL);
+
+  gtk_widget_show_all (menu);
+  gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
+                  gtk_status_icon_position_menu, status_icon,
+                  button, activate_time);
+
+  G_GNUC_END_IGNORE_DEPRECATIONS
+}
+
+static GtkTreeIter *
+get_default_adapter (GfBluetoothApplet *applet)
+{
+  gboolean valid;
+  GtkTreeIter iter;
+
+  valid = gtk_tree_model_get_iter_first (applet->model, &iter);
+
+  while (valid)
+    {
+      gboolean is_default;
+
+      gtk_tree_model_get (applet->model, &iter,
+                          BLUETOOTH_COLUMN_DEFAULT, &is_default,
+                          -1);
+
+      if (is_default)
+        return gtk_tree_iter_copy (&iter);
+
+      valid = gtk_tree_model_iter_next (applet->model , &iter);
+    }
+
+  return NULL;
+}
+
+static guint
+get_n_connected_devices (GfBluetoothApplet *applet)
+{
+  GtkTreeIter *adapter;
+  guint devices;
+  gboolean valid;
+  GtkTreeIter iter;
+
+  adapter = get_default_adapter (applet);
+  devices = 0;
+
+  if (adapter == NULL)
+    return 0;
+
+  valid = gtk_tree_model_iter_children (applet->model, &iter, adapter);
+
+  while (valid)
+    {
+      gboolean is_connected;
+
+      gtk_tree_model_get (applet->model, &iter,
+                          BLUETOOTH_COLUMN_CONNECTED, &is_connected,
+                          -1);
+
+      if (is_connected)
+        devices++;
+
+      valid = gtk_tree_model_iter_next (applet->model , &iter);
+    }
+
+  gtk_tree_iter_free (adapter);
+
+  return devices;
+}
+
+static void
+gf_bluetooth_applet_sync (GfBluetoothApplet *applet)
+{
+  guint devices;
+  gboolean airplane_mode;
+  const gchar *title;
+  const gchar *icon_name;
+  gchar *tooltip_text;
+
+  devices = get_n_connected_devices (applet);
+
+  if (devices == 0)
+    {
+      G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+      gtk_status_icon_set_visible (applet->status_icon, FALSE);
+      G_GNUC_END_IGNORE_DEPRECATIONS
+
+      return;
+    }
+
+  airplane_mode = FALSE;
+  if (applet->rfkill != NULL)
+    airplane_mode = gf_sd_rfkill_get_bluetooth_airplane_mode (applet->rfkill);
+
+  if (!airplane_mode)
+    {
+      title = _("Bluetooth active");
+      icon_name = "bluetooth-active";
+    }
+  else
+    {
+      title = _("Bluetooth disabled");
+      icon_name = "bluetooth-disabled";
+    }
+
+  tooltip_text = g_strdup_printf (ngettext ("%d Connected Device",
+                                                             "%d Connected Devices",
+                                                             devices), devices);
+
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+
+  gtk_status_icon_set_title (applet->status_icon, title);
+  gtk_status_icon_set_from_icon_name (applet->status_icon, icon_name);
+  gtk_status_icon_set_tooltip_text (applet->status_icon, tooltip_text);
+  gtk_status_icon_set_visible (applet->status_icon, TRUE);
+
+  G_GNUC_END_IGNORE_DEPRECATIONS
+
+  g_free (tooltip_text);
+}
+
+static void
+properties_changed_cb (GDBusProxy *proxy,
+                       GVariant   *changed_properties,
+                       GStrv       invalidated_properties,
+                       gpointer    user_data)
+{
+  GfBluetoothApplet *applet;
+
+  applet = GF_BLUETOOTH_APPLET (user_data);
+
+  gf_bluetooth_applet_sync (applet);
+}
+
+static void
+rfkill_proxy_ready_cb (GObject      *source_object,
+                       GAsyncResult *res,
+                       gpointer      user_data)
+{
+  GfBluetoothApplet *applet;
+  GError *error;
+
+  applet = GF_BLUETOOTH_APPLET (user_data);
+
+  error = NULL;
+  applet->rfkill = gf_sd_rfkill_proxy_new_for_bus_finish (res, &error);
+
+  if (error != NULL)
+    {
+      g_warning ("Failed to get Rfkill proxy - %s", error->message);
+      g_error_free (error);
+
+      return;
+    }
+
+  g_signal_connect (applet->rfkill, "g-properties-changed",
+                    G_CALLBACK (properties_changed_cb), applet);
+
+  gf_bluetooth_applet_sync (applet);
+}
+
+static void
+row_changed_cb (GtkTreeModel *tree_model,
+                GtkTreePath  *path,
+                GtkTreeIter  *iter,
+                gpointer      user_data)
+{
+  GfBluetoothApplet *applet;
+
+  applet = GF_BLUETOOTH_APPLET (user_data);
+
+  gf_bluetooth_applet_sync (applet);
+}
+
+static void
+row_deleted_cb (GtkTreeModel *tree_model,
+                GtkTreePath  *path,
+                gpointer      user_data)
+{
+  GfBluetoothApplet *applet;
+
+  applet = GF_BLUETOOTH_APPLET (user_data);
+
+  gf_bluetooth_applet_sync (applet);
+}
+
+static void
+row_inserted_cb (GtkTreeModel *tree_model,
+                 GtkTreePath  *path,
+                 GtkTreeIter  *iter,
+                 gpointer      user_data)
+{
+  GfBluetoothApplet *applet;
+
+  applet = GF_BLUETOOTH_APPLET (user_data);
+
+  gf_bluetooth_applet_sync (applet);
+}
+
+static void
+gf_bluetooth_applet_dispose (GObject *object)
+{
+  GfBluetoothApplet *applet;
+
+  applet = GF_BLUETOOTH_APPLET (object);
+
+  g_clear_object (&applet->status_icon);
+  g_clear_object (&applet->rfkill);
+  g_clear_object (&applet->client);
+  g_clear_object (&applet->model);
+
+  G_OBJECT_CLASS (gf_bluetooth_applet_parent_class)->dispose (object);
+}
+
+static void
 gf_bluetooth_applet_class_init (GfBluetoothAppletClass *applet_class)
 {
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (applet_class);
+
+  object_class->dispose = gf_bluetooth_applet_dispose;
 }
 
 static void
 gf_bluetooth_applet_init (GfBluetoothApplet *applet)
 {
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+
+  applet->status_icon = gtk_status_icon_new_from_icon_name ("bluetooth-active");
+
+  gtk_status_icon_set_visible (applet->status_icon, FALSE);
+  gtk_status_icon_set_title (applet->status_icon, _("Bluetooth"));
+  gtk_status_icon_set_tooltip_text (applet->status_icon, _("Bluetooth"));
+
+  G_GNUC_END_IGNORE_DEPRECATIONS
+
+  g_signal_connect (applet->status_icon, "popup-menu",
+                    G_CALLBACK (popup_menu_cb), applet);
+
+  gf_sd_rfkill_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+                                  G_DBUS_PROXY_FLAGS_NONE,
+                                  GSM_DBUS_NAME,
+                                  GSM_DBUS_PATH,
+                                  NULL,
+                                  rfkill_proxy_ready_cb,
+                                  applet);
+
+  applet->client = bluetooth_client_new ();
+  applet->model = bluetooth_client_get_model (applet->client);
+
+  g_signal_connect (applet->model, "row-changed",
+                    G_CALLBACK (row_changed_cb), applet);
+  g_signal_connect (applet->model, "row-deleted",
+                    G_CALLBACK (row_deleted_cb), applet);
+  g_signal_connect (applet->model, "row-inserted",
+                    G_CALLBACK (row_inserted_cb), applet);
+
+  gf_bluetooth_applet_sync (applet);
 }
 
 GfBluetoothApplet *
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0be07fd..bd13592 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -13,6 +13,7 @@ data/org.gnome.gnome-flashback.gschema.xml.in.in
 gnome-flashback/gf-main.c
 gnome-flashback/libautomount-manager/gsd-automount-manager.c
 gnome-flashback/libautomount-manager/gsd-autorun.c
+gnome-flashback/libbluetooth-applet/gf-bluetooth-applet.c
 [type: gettext/glade]gnome-flashback/libdisplay-config/flashback-confirm-dialog.ui
 gnome-flashback/libdisplay-config/flashback-display-config.c
 gnome-flashback/libend-session-dialog/flashback-inhibit-dialog.c


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