Merge lp:~dbarth/indicator-me/entry-hint into lp:indicator-me

Proposed by David Barth
Status: Merged
Merged at revision: 104
Proposed branch: lp:~dbarth/indicator-me/entry-hint
Merge into: lp:indicator-me
Diff against target: 368 lines (+189/-27)
5 files modified
src/dbus-shared-names.h (+1/-0)
src/indicator-me.c (+122/-25)
src/me-service-gwibber.c (+62/-2)
src/me-service-gwibber.h (+1/-0)
src/me-service.c (+3/-0)
To merge this branch: bzr merge lp:~dbarth/indicator-me/entry-hint
Reviewer Review Type Date Requested Status
Ted Gould (community) Needs Information
Cody Russell (community) Approve
Review via email: mp+35595@code.launchpad.net

Description of the change

Add a hint field to the broadcast field. The hint is computed from the list of protocols associated with accounts configured for broadcasting.

To post a comment you must log in.
lp:~dbarth/indicator-me/entry-hint updated
108. By David Barth

Fix the entry hint to be shown at the right time

Revision history for this message
Cody Russell (bratsche) :
review: Approve
Revision history for this message
Ted Gould (ted) wrote :

A few concerns.

 * This patch adds several translatable strings. So I don't think it can land for Maverick.
 * And this comment:
179 + /* this is dangerous: it leaves the signal connected even if the dbusmenu
180 + object is disposed, for example if the service quits
181 + */
   We should just remove the signal handler on distruction instead of not having it, or delete the code entirely if it's not needed.
 *

review: Needs Information

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/dbus-shared-names.h'
2--- src/dbus-shared-names.h 2010-03-11 12:20:48 +0000
3+++ src/dbus-shared-names.h 2010-09-16 14:51:54 +0000
4@@ -32,6 +32,7 @@
5
6 #define DBUSMENU_ENTRY_MENUITEM_TYPE "x-canonical-entry-item"
7 #define DBUSMENU_ENTRY_MENUITEM_PROP_TEXT "text"
8+#define DBUSMENU_ENTRY_MENUITEM_PROP_HINT "hint"
9
10 #define DBUSMENU_ABOUT_ME_MENUITEM_TYPE "x-canonical-about-me-item"
11 #define DBUSMENU_ABOUT_ME_MENUITEM_PROP_NAME "name"
12
13=== modified file 'src/indicator-me.c'
14--- src/indicator-me.c 2010-03-31 22:07:27 +0000
15+++ src/indicator-me.c 2010-09-16 14:51:54 +0000
16@@ -254,11 +254,112 @@
17 }
18
19 static void
20+entry_hint_set_shown (GtkWidget *widget, gboolean flag)
21+{
22+ g_object_set_data (G_OBJECT (widget),
23+ DBUSMENU_ENTRY_MENUITEM_PROP_HINT "_shown",
24+ GUINT_TO_POINTER (flag));
25+}
26+
27+
28+static void
29+entry_set_style (GtkEntry *entry, GtkStateType state)
30+{
31+ GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (entry));
32+ GdkColor *color = &style->text[state];
33+ gtk_widget_modify_text (GTK_WIDGET (entry), GTK_STATE_NORMAL, color);
34+}
35+
36+static void
37+entry_maybe_show_hint (GtkEntry *entry)
38+{
39+ g_return_if_fail (GTK_IS_ENTRY (entry));
40+
41+ const gchar *hint = g_object_get_data (G_OBJECT (entry),
42+ DBUSMENU_ENTRY_MENUITEM_PROP_HINT);
43+ if (gtk_entry_get_text_length (entry) > 0 ||
44+ GTK_WIDGET_HAS_FOCUS (entry)) {
45+ g_debug ("%s, the hint shouldn't be shown atm", __func__);
46+
47+ entry_set_style (entry, GTK_STATE_NORMAL);
48+ entry_hint_set_shown (GTK_WIDGET (entry), FALSE);
49+
50+ } else {
51+ g_debug ("%s, nothing in the entry or not focused, so setting the hint to: %s", __func__, hint);
52+
53+ gtk_entry_set_text (entry, hint);
54+ entry_set_style (entry, GTK_STATE_INSENSITIVE);
55+
56+ entry_hint_set_shown (GTK_WIDGET (entry), TRUE);
57+ }
58+}
59+
60+
61+static void
62+entry_set_hint (GtkEntry *entry, const char *hint)
63+{
64+ g_debug ("entry hint: %s", hint);
65+ g_object_set_data_full (G_OBJECT (entry), DBUSMENU_ENTRY_MENUITEM_PROP_HINT,
66+ g_strdup (hint), (GDestroyNotify) g_free);
67+ entry_maybe_show_hint (entry);
68+}
69+
70+static gboolean
71+entry_hint_is_shown (GtkWidget *widget)
72+{
73+ gboolean shown = GPOINTER_TO_UINT
74+ (g_object_get_data (G_OBJECT (widget),
75+ DBUSMENU_ENTRY_MENUITEM_PROP_HINT "_shown"));
76+
77+ return shown;
78+}
79+
80+static gboolean
81+entry_focus_grab_cb (GtkWidget *widget, GdkEventFocus *event)
82+{
83+ GtkEntry *entry = GTK_ENTRY (widget);
84+ GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry));
85+ gboolean select_on_focus;
86+
87+ g_debug ("%s", __func__);
88+
89+ if (entry_hint_is_shown (GTK_WIDGET (entry))) {
90+ /* override select-on-focus */
91+ g_object_get (settings, "gtk-entry-select-on-focus", &select_on_focus, NULL);
92+ g_object_set (settings, "gtk-entry-select-on-focus", FALSE, NULL);
93+ gtk_entry_set_text (entry, "");
94+ g_object_set (settings, "gtk-entry-select-on-focus", select_on_focus, NULL);
95+ }
96+
97+ entry_set_style (entry, GTK_STATE_NORMAL);
98+ entry_hint_set_shown (GTK_WIDGET (entry), FALSE);
99+
100+ return FALSE;
101+}
102+
103+static gboolean
104+entry_focus_ungrab_cb (GtkWidget *widget, GdkEventFocus *event)
105+{
106+ GtkEntry *entry = GTK_ENTRY (widget);
107+
108+ g_debug ("%s", __func__);
109+
110+ entry_maybe_show_hint (entry);
111+
112+ return FALSE;
113+}
114+
115+static void
116 entry_prop_change_cb (DbusmenuMenuitem *mi, gchar *prop, GValue *value, GtkEntry *entry)
117 {
118+ g_return_if_fail (GTK_IS_ENTRY (entry));
119+
120 if (g_strcmp0 (prop, DBUSMENU_ENTRY_MENUITEM_PROP_TEXT) == 0) {
121 gtk_entry_set_text (entry, g_value_get_string (value));
122 }
123+ if (g_strcmp0 (prop, DBUSMENU_ENTRY_MENUITEM_PROP_HINT) == 0) {
124+ entry_set_hint (entry, g_value_get_string (value));
125+ }
126 }
127
128 static void
129@@ -277,31 +378,6 @@
130 }
131
132 static gboolean
133-menu_visibility_changed (GtkWidget *widget,
134- IdoEntryMenuItem *menuitem)
135-{
136- if (GTK_IS_WIDGET (widget)
137- && IDO_IS_ENTRY_MENU_ITEM (menuitem))
138- gtk_menu_shell_select_item (GTK_MENU_SHELL (widget), GTK_WIDGET (menuitem));
139-
140- return FALSE;
141-}
142-
143-static void
144-entry_parent_changed (GtkWidget *widget,
145- gpointer user_data)
146-{
147- GtkWidget *parent = gtk_widget_get_parent (widget);
148-
149- if (parent && GTK_IS_MENU_SHELL (parent))
150- {
151- g_signal_connect (parent,
152- "map", G_CALLBACK (menu_visibility_changed),
153- widget);
154- }
155-}
156-
157-static gboolean
158 new_entry_item (DbusmenuMenuitem * newitem,
159 DbusmenuMenuitem * parent,
160 DbusmenuClient * client)
161@@ -314,14 +390,27 @@
162 GtkEntry *entry = GTK_ENTRY(ido_entry_menu_item_get_entry (ido));
163 if (dbusmenu_menuitem_property_get (newitem, DBUSMENU_ENTRY_MENUITEM_PROP_TEXT) != NULL)
164 gtk_entry_set_text(entry, dbusmenu_menuitem_property_get(newitem, DBUSMENU_ENTRY_MENUITEM_PROP_TEXT));
165+ if (dbusmenu_menuitem_property_get (newitem, DBUSMENU_ENTRY_MENUITEM_PROP_HINT) != NULL) {
166+ entry_set_hint (entry, dbusmenu_menuitem_property_get (newitem, DBUSMENU_ENTRY_MENUITEM_PROP_HINT));
167+ }
168+
169 gtk_entry_set_width_chars (entry, 23); /* set some nice aspect ratio for the menu */
170 gtk_entry_set_max_length (entry, 140); /* enforce current gwibber limit */
171
172+ /* override select-on-focus */
173+ GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry));
174+ g_object_set (settings, "gtk-entry-select-on-focus", FALSE, NULL);
175+
176 ido_entry = ido;
177
178+#if 0
179+ /* this is dangerous: it leaves the signal connected even if the dbusmenu
180+ object is disposed, for example if the service quits
181+ */
182 g_signal_connect (ido,
183 "notify::parent", G_CALLBACK (entry_parent_changed),
184 NULL);
185+#endif
186
187 dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(ido), parent);
188 /* disconnect the activate signal that newitem_base connected with the wrong
189@@ -333,6 +422,14 @@
190 g_signal_connect (DBUSMENU_MENUITEM (newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK (entry_prop_change_cb), entry);
191 g_signal_connect (GTK_ENTRY (entry), "activate", G_CALLBACK (entry_activate_cb), newitem);
192
193+ g_signal_connect (entry,
194+ "grab-focus", G_CALLBACK (entry_focus_grab_cb),
195+ entry);
196+
197+ g_signal_connect (entry,
198+ "grab-broken-event", G_CALLBACK (entry_focus_ungrab_cb),
199+ entry);
200+
201 return TRUE;
202 }
203
204
205=== modified file 'src/me-service-gwibber.c'
206--- src/me-service-gwibber.c 2010-08-17 14:43:36 +0000
207+++ src/me-service-gwibber.c 2010-09-16 14:51:54 +0000
208@@ -22,7 +22,10 @@
209
210 #include "me-service-gwibber.h"
211
212+#include <glib/gi18n.h>
213+
214 #include <glib.h>
215+#include <glib/gprintf.h>
216
217 #include <gwibber.h>
218
219@@ -34,6 +37,7 @@
220 GwibberAccounts * me_gwibber_accounts;
221 int status;
222 gboolean has_configured_accounts;
223+ gchar * accounts_string;
224 };
225
226 /* Signals */
227@@ -89,6 +93,7 @@
228 priv->me_gwibber_accounts = NULL;
229 priv->status = ME_GWIBBER_SERVICE_STATUS_NOT_RUNNING;
230 priv->has_configured_accounts = FALSE;
231+ priv->accounts_string = NULL;
232
233 setup_service_proxies(self);
234 return;
235@@ -109,6 +114,11 @@
236 priv->me_gwibber_accounts = NULL;
237 }
238
239+ if (priv->accounts_string != NULL) {
240+ g_free(priv->accounts_string);
241+ priv->accounts_string = NULL;
242+ }
243+
244 G_OBJECT_CLASS (me_gwibber_service_parent_class)->dispose (object);
245 return;
246 }
247@@ -140,32 +150,72 @@
248
249 if (priv->me_gwibber_accounts == NULL) {
250 g_warning ("no accounts, can't query for accounts");
251- return;
252+ goto reset_accounts_string;
253 }
254
255 accounts_table = gwibber_accounts_list (priv->me_gwibber_accounts);
256 if (accounts_table == NULL) {
257 g_warning ("failed to get accounts list");
258- return;
259+ goto reset_accounts_string;
260 }
261
262 g_hash_table_iter_init (&accounts_iter, accounts_table);
263
264 priv->has_configured_accounts = FALSE;
265+ GList *list = NULL;
266
267 while (g_hash_table_iter_next (&accounts_iter, &account, &account_table)) {
268 send_enabled = check_account_send_enabled (account_table);
269 if (send_enabled) {
270 priv->has_configured_accounts = TRUE;
271+ GValue *value = g_hash_table_lookup (account_table, "service");
272+ if (value != NULL)
273+ list = g_list_append (list,
274+ g_strdup (g_value_get_string (value)));
275 }
276 }
277
278+ if (priv->accounts_string != NULL) {
279+ g_free(priv->accounts_string);
280+ priv->accounts_string = NULL;
281+ }
282+
283+ guint len = g_list_length (list);
284+ if (len > 0) {
285+ GList *item0 = g_list_nth (list, 0);
286+ GList *item1 = g_list_nth (list, 1);
287+ if (len == 1)
288+ priv->accounts_string = g_strconcat (_("Post to: "),
289+ item0->data,
290+ "...", NULL);
291+ else if (len < 3)
292+ priv->accounts_string = g_strconcat (_("Post to: "),
293+ item0->data,
294+ ", ",
295+ item1->data,
296+ "...", NULL);
297+ else
298+ priv->accounts_string = g_strdup (_("Post to: multiple networks..."));
299+ g_debug ("accounts_string: %s", priv->accounts_string);
300+ }
301+
302+ g_list_foreach (list, (GFunc) g_free, NULL);
303+ g_list_free (list);
304+
305 g_signal_emit (G_OBJECT (self),
306 ME_GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED_ID,
307 0, priv->status, TRUE);
308
309 g_hash_table_destroy(accounts_table);
310+
311 return;
312+
313+reset_accounts_string:
314+
315+ if (priv->accounts_string != NULL) {
316+ g_free(priv->accounts_string);
317+ priv->accounts_string = NULL;
318+ }
319 }
320
321 static void
322@@ -300,3 +350,13 @@
323
324 return priv->has_configured_accounts;
325 }
326+
327+const gchar *
328+me_gwibber_service_get_accounts_string (MeGwibberService *self)
329+{
330+ g_return_val_if_fail (IS_ME_GWIBBER_SERVICE (self), FALSE);
331+
332+ MeGwibberServicePrivate * priv = ME_GWIBBER_SERVICE_GET_PRIVATE(self);
333+
334+ return priv->accounts_string;
335+}
336
337=== modified file 'src/me-service-gwibber.h'
338--- src/me-service-gwibber.h 2010-08-16 15:11:05 +0000
339+++ src/me-service-gwibber.h 2010-09-16 14:51:54 +0000
340@@ -68,6 +68,7 @@
341 MeGwibberService * me_gwibber_service_get (void);
342 void me_gwibber_service_send (MeGwibberService *self, const gchar *msg);
343 gboolean me_gwibber_service_has_configured_accounts (MeGwibberService *self);
344+const gchar * me_gwibber_service_get_accounts_string (MeGwibberService *self);
345
346 G_END_DECLS
347
348
349=== modified file 'src/me-service.c'
350--- src/me-service.c 2010-09-09 13:26:05 +0000
351+++ src/me-service.c 2010-09-16 14:51:54 +0000
352@@ -189,6 +189,8 @@
353 if (! dbusmenu_menuitem_property_get_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE))
354 dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
355
356+ dbusmenu_menuitem_property_set (broadcast_field, DBUSMENU_ENTRY_MENUITEM_PROP_HINT, me_gwibber_service_get_accounts_string (instance));
357+
358 return;
359 }
360
361@@ -409,6 +411,7 @@
362 #endif
363
364 broadcast_field = DBUSMENU_MENUITEM (entry_menu_item_new());
365+ dbusmenu_menuitem_property_set (broadcast_field, DBUSMENU_ENTRY_MENUITEM_PROP_HINT, _("Post message..."));
366 dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
367 dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
368 dbusmenu_menuitem_child_append(root, broadcast_field);

Subscribers

People subscribed via source and target branches