← Back to team overview

ayatana-commits team mailing list archive

[Branch ~indicator-applet-developers/indicator-me/trunk] Rev 104: add a hint in the broadcast field

 

Merge authors:
  David Barth (dbarth)
Related merge proposals:
  https://code.launchpad.net/~dbarth/indicator-me/entry-hint/+merge/35595
  proposed by: David Barth (dbarth)
  review: Needs Information - Ted Gould (ted)
  review: Approve - Cody Russell (bratsche)
------------------------------------------------------------
revno: 104 [merge]
committer: David Barth <david.barth@xxxxxxxxxxxxx>
branch nick: indicator-me
timestamp: Thu 2010-09-16 17:49:12 +0200
message:
  add a hint in the broadcast field
modified:
  src/dbus-shared-names.h
  src/indicator-me.c
  src/me-service-gwibber.c
  src/me-service-gwibber.h
  src/me-service.c


--
lp:indicator-me
https://code.launchpad.net/~indicator-applet-developers/indicator-me/trunk

Your team ayatana-commits is subscribed to branch lp:indicator-me.
To unsubscribe from this branch go to https://code.launchpad.net/~indicator-applet-developers/indicator-me/trunk/+edit-subscription
=== modified file 'src/dbus-shared-names.h'
--- src/dbus-shared-names.h	2010-03-11 12:20:48 +0000
+++ src/dbus-shared-names.h	2010-09-10 07:29:03 +0000
@@ -32,6 +32,7 @@
 
 #define DBUSMENU_ENTRY_MENUITEM_TYPE           "x-canonical-entry-item"
 #define DBUSMENU_ENTRY_MENUITEM_PROP_TEXT      "text"
+#define DBUSMENU_ENTRY_MENUITEM_PROP_HINT      "hint"
 
 #define DBUSMENU_ABOUT_ME_MENUITEM_TYPE           "x-canonical-about-me-item"
 #define DBUSMENU_ABOUT_ME_MENUITEM_PROP_NAME      "name"

=== modified file 'src/indicator-me.c'
--- src/indicator-me.c	2010-03-31 22:07:27 +0000
+++ src/indicator-me.c	2010-09-16 14:49:20 +0000
@@ -254,11 +254,112 @@
 }
 
 static void
+entry_hint_set_shown (GtkWidget *widget, gboolean flag)
+{
+  g_object_set_data (G_OBJECT (widget),
+                     DBUSMENU_ENTRY_MENUITEM_PROP_HINT "_shown",
+                     GUINT_TO_POINTER (flag));
+}
+
+
+static void
+entry_set_style (GtkEntry *entry, GtkStateType state)
+{
+    GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (entry));
+    GdkColor *color = &style->text[state];
+    gtk_widget_modify_text (GTK_WIDGET (entry), GTK_STATE_NORMAL, color);
+}
+
+static void
+entry_maybe_show_hint (GtkEntry *entry)
+{
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  const gchar *hint = g_object_get_data (G_OBJECT (entry),
+                                         DBUSMENU_ENTRY_MENUITEM_PROP_HINT);
+  if (gtk_entry_get_text_length (entry) > 0 ||
+      GTK_WIDGET_HAS_FOCUS (entry)) {
+    g_debug ("%s, the hint shouldn't be shown atm", __func__);
+
+    entry_set_style (entry, GTK_STATE_NORMAL);
+    entry_hint_set_shown (GTK_WIDGET (entry), FALSE);
+
+  } else {
+    g_debug ("%s, nothing in the entry or not focused, so setting the hint to: %s", __func__, hint);
+
+    gtk_entry_set_text (entry, hint);
+    entry_set_style (entry, GTK_STATE_INSENSITIVE);
+
+    entry_hint_set_shown (GTK_WIDGET (entry), TRUE);
+  }
+}
+
+
+static void
+entry_set_hint (GtkEntry *entry, const char *hint)
+{
+    g_debug ("entry hint: %s", hint);
+		g_object_set_data_full (G_OBJECT (entry), DBUSMENU_ENTRY_MENUITEM_PROP_HINT,
+                            g_strdup (hint), (GDestroyNotify) g_free);
+    entry_maybe_show_hint (entry);
+}
+
+static gboolean
+entry_hint_is_shown (GtkWidget *widget)
+{
+  gboolean shown = GPOINTER_TO_UINT
+    (g_object_get_data (G_OBJECT (widget),
+                        DBUSMENU_ENTRY_MENUITEM_PROP_HINT "_shown"));
+
+  return shown;
+}
+
+static gboolean
+entry_focus_grab_cb (GtkWidget *widget, GdkEventFocus *event)
+{
+  GtkEntry *entry = GTK_ENTRY (widget);
+  GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry));
+  gboolean select_on_focus;
+
+  g_debug ("%s", __func__);
+
+  if (entry_hint_is_shown (GTK_WIDGET (entry))) {
+    /* override select-on-focus */
+    g_object_get (settings, "gtk-entry-select-on-focus", &select_on_focus, NULL);
+    g_object_set (settings, "gtk-entry-select-on-focus", FALSE, NULL);
+    gtk_entry_set_text (entry, "");
+    g_object_set (settings, "gtk-entry-select-on-focus", select_on_focus, NULL);
+  }
+
+  entry_set_style (entry, GTK_STATE_NORMAL);
+  entry_hint_set_shown (GTK_WIDGET (entry), FALSE);
+
+  return FALSE;
+}
+
+static gboolean
+entry_focus_ungrab_cb (GtkWidget *widget, GdkEventFocus *event)
+{
+  GtkEntry *entry = GTK_ENTRY (widget);
+
+  g_debug ("%s", __func__);
+
+  entry_maybe_show_hint (entry);
+
+  return FALSE;
+}
+
+static void
 entry_prop_change_cb (DbusmenuMenuitem *mi, gchar *prop, GValue *value, GtkEntry *entry)
 {
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
 	if (g_strcmp0 (prop, DBUSMENU_ENTRY_MENUITEM_PROP_TEXT) == 0) {
 		gtk_entry_set_text (entry, g_value_get_string (value));
 	}
+	if (g_strcmp0 (prop, DBUSMENU_ENTRY_MENUITEM_PROP_HINT) == 0) {
+    entry_set_hint (entry, g_value_get_string (value));
+	}
 }
 
 static void
@@ -277,31 +378,6 @@
 }
 
 static gboolean
-menu_visibility_changed (GtkWidget          *widget,
-                         IdoEntryMenuItem   *menuitem)
-{
-  if (GTK_IS_WIDGET (widget)
-      && IDO_IS_ENTRY_MENU_ITEM (menuitem))
-    gtk_menu_shell_select_item (GTK_MENU_SHELL (widget), GTK_WIDGET (menuitem));
-
-  return FALSE;
-}
-
-static void
-entry_parent_changed (GtkWidget *widget,
-                      gpointer   user_data)
-{
-  GtkWidget *parent = gtk_widget_get_parent (widget);
-
-  if (parent && GTK_IS_MENU_SHELL (parent))
-    {
-      g_signal_connect (parent,
-                        "map", G_CALLBACK (menu_visibility_changed),
-                        widget);
-    }
-}
-
-static gboolean
 new_entry_item (DbusmenuMenuitem * newitem,
                 DbusmenuMenuitem * parent,
                 DbusmenuClient   * client)
@@ -314,14 +390,27 @@
 	GtkEntry *entry = GTK_ENTRY(ido_entry_menu_item_get_entry (ido));
 	if (dbusmenu_menuitem_property_get (newitem, DBUSMENU_ENTRY_MENUITEM_PROP_TEXT) != NULL)
 		gtk_entry_set_text(entry, dbusmenu_menuitem_property_get(newitem, DBUSMENU_ENTRY_MENUITEM_PROP_TEXT));
+	if (dbusmenu_menuitem_property_get (newitem, DBUSMENU_ENTRY_MENUITEM_PROP_HINT) != NULL) {
+    entry_set_hint (entry, dbusmenu_menuitem_property_get (newitem, DBUSMENU_ENTRY_MENUITEM_PROP_HINT));
+	}
+
 	gtk_entry_set_width_chars (entry, 23); /* set some nice aspect ratio for the menu */
   gtk_entry_set_max_length (entry, 140); /* enforce current gwibber limit */
 
+  /* override select-on-focus */
+  GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry));
+  g_object_set (settings, "gtk-entry-select-on-focus", FALSE, NULL);
+
   ido_entry = ido;
 
+#if 0
+  /* this is dangerous: it leaves the signal connected even if the dbusmenu
+     object is disposed, for example if the service quits
+  */
   g_signal_connect (ido,
                     "notify::parent", G_CALLBACK (entry_parent_changed),
                     NULL);
+#endif
 
 	dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(ido), parent);
 	/* disconnect the activate signal that newitem_base connected with the wrong
@@ -333,6 +422,14 @@
 	g_signal_connect (DBUSMENU_MENUITEM (newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK (entry_prop_change_cb), entry);
 	g_signal_connect (GTK_ENTRY (entry), "activate", G_CALLBACK (entry_activate_cb), newitem);
 
+  g_signal_connect (entry,
+                    "grab-focus", G_CALLBACK (entry_focus_grab_cb),
+                    entry);
+
+  g_signal_connect (entry,
+                    "grab-broken-event", G_CALLBACK (entry_focus_ungrab_cb),
+                    entry);
+
 	return TRUE;
 }
 

=== modified file 'src/me-service-gwibber.c'
--- src/me-service-gwibber.c	2010-08-17 14:43:36 +0000
+++ src/me-service-gwibber.c	2010-09-15 21:07:40 +0000
@@ -22,7 +22,10 @@
 
 #include "me-service-gwibber.h"
 
+#include <glib/gi18n.h>
+
 #include <glib.h>
+#include <glib/gprintf.h>
 
 #include <gwibber.h>
 
@@ -34,6 +37,7 @@
 	GwibberAccounts * me_gwibber_accounts;
 	int status;
 	gboolean has_configured_accounts;
+	gchar * accounts_string;
 };
 
 /* Signals */
@@ -89,6 +93,7 @@
 	priv->me_gwibber_accounts = NULL;
 	priv->status = ME_GWIBBER_SERVICE_STATUS_NOT_RUNNING;
 	priv->has_configured_accounts = FALSE;
+	priv->accounts_string = NULL;
 
 	setup_service_proxies(self);
 	return;
@@ -109,6 +114,11 @@
 		priv->me_gwibber_accounts = NULL;
 	}
 
+	if (priv->accounts_string != NULL) {
+		g_free(priv->accounts_string);
+		priv->accounts_string = NULL;
+	}
+
 	G_OBJECT_CLASS (me_gwibber_service_parent_class)->dispose (object);
 	return;
 }
@@ -140,32 +150,72 @@
 
 	if (priv->me_gwibber_accounts == NULL) {
 		g_warning ("no accounts, can't query for accounts");
-		return;
+		goto reset_accounts_string;
 	}
 	
         accounts_table = gwibber_accounts_list (priv->me_gwibber_accounts);
         if (accounts_table == NULL) {
                 g_warning ("failed to get accounts list");
-                return;
+				goto reset_accounts_string;
         }
 
 	g_hash_table_iter_init (&accounts_iter, accounts_table);
 
 	priv->has_configured_accounts = FALSE;
+	GList *list = NULL;
 
 	while (g_hash_table_iter_next (&accounts_iter, &account, &account_table)) {
 		send_enabled = check_account_send_enabled (account_table);
 		if (send_enabled) {
 			priv->has_configured_accounts = TRUE;
+			GValue *value = g_hash_table_lookup (account_table, "service");
+			if (value != NULL)
+				list = g_list_append (list,
+									  g_strdup (g_value_get_string (value)));
 		}
 	}
 
+	if (priv->accounts_string != NULL) {
+		g_free(priv->accounts_string);
+		priv->accounts_string = NULL;
+	}	
+
+	guint len = g_list_length (list);
+	if (len > 0) {
+		GList *item0 = g_list_nth (list, 0);
+		GList *item1 = g_list_nth (list, 1);
+		if (len == 1)
+			priv->accounts_string = g_strconcat (_("Post to: "),
+												 item0->data,
+												 "...", NULL);
+		else if (len < 3)
+			priv->accounts_string = g_strconcat (_("Post to: "),
+												 item0->data,
+												 ", ",
+												 item1->data,
+												 "...", NULL);
+		else
+			priv->accounts_string = g_strdup (_("Post to: multiple networks..."));
+		g_debug ("accounts_string: %s", priv->accounts_string);
+	}
+
+	g_list_foreach (list, (GFunc) g_free, NULL);
+	g_list_free (list);
+
 	g_signal_emit (G_OBJECT (self),
 				   ME_GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED_ID,
 				   0, priv->status, TRUE);
 
 	g_hash_table_destroy(accounts_table);
+
 	return;
+
+reset_accounts_string:
+
+	if (priv->accounts_string != NULL) {
+		g_free(priv->accounts_string);
+		priv->accounts_string = NULL;
+	}	
 }
 
 static void
@@ -300,3 +350,13 @@
 
 	return priv->has_configured_accounts;
 }
+
+const gchar *
+me_gwibber_service_get_accounts_string (MeGwibberService *self)
+{
+	g_return_val_if_fail (IS_ME_GWIBBER_SERVICE (self), FALSE);
+
+	MeGwibberServicePrivate * priv = ME_GWIBBER_SERVICE_GET_PRIVATE(self);
+
+	return priv->accounts_string;
+}

=== modified file 'src/me-service-gwibber.h'
--- src/me-service-gwibber.h	2010-08-16 15:11:05 +0000
+++ src/me-service-gwibber.h	2010-09-15 21:07:40 +0000
@@ -68,6 +68,7 @@
 MeGwibberService * me_gwibber_service_get (void);
 void me_gwibber_service_send (MeGwibberService *self, const gchar *msg);
 gboolean me_gwibber_service_has_configured_accounts (MeGwibberService *self);
+const gchar * me_gwibber_service_get_accounts_string (MeGwibberService *self);
 
 G_END_DECLS
 

=== modified file 'src/me-service.c'
--- src/me-service.c	2010-09-09 13:26:05 +0000
+++ src/me-service.c	2010-09-15 21:07:40 +0000
@@ -189,6 +189,8 @@
   if (! dbusmenu_menuitem_property_get_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE))
     dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
 
+  dbusmenu_menuitem_property_set (broadcast_field, DBUSMENU_ENTRY_MENUITEM_PROP_HINT, me_gwibber_service_get_accounts_string (instance));
+
   return;
 }
 
@@ -409,6 +411,7 @@
 #endif
 
   broadcast_field = DBUSMENU_MENUITEM (entry_menu_item_new());
+  dbusmenu_menuitem_property_set (broadcast_field, DBUSMENU_ENTRY_MENUITEM_PROP_HINT, _("Post message..."));
   dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
   dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
   dbusmenu_menuitem_child_append(root, broadcast_field);