~ubuntu-branches/ubuntu/lucid/indicator-me/lucid

« back to all changes in this revision

Viewing changes to src/me-service.c

  • Committer: Sebastien Bacher
  • Date: 2010-03-24 12:59:43 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: seb128@ubuntu.com-20100324125943-e54i1nihe8h3wb2i
Tags: 0.2.6-0ubuntu1
releasing version 0.2.6-0ubuntu1

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
#include "status-provider-pidgin.h"
52
52
#include "status-provider-telepathy.h"
53
53
 
 
54
#include "me-service-gwibber.h"
54
55
#include "entry-menu-item.h"
55
56
 
56
57
typedef StatusProvider * (*newfunc) (void);
80
81
  /* STATUS_PROVIDER_STATUS_DISCONNECTED */"user-offline"
81
82
};
82
83
 
 
84
static GwibberService * gwibber = NULL;
83
85
 
84
86
static DbusmenuMenuitem * root_menuitem = NULL;
85
87
static DbusmenuMenuitem * status_menuitems[STATUS_PROVIDER_STATUS_LAST] = {0};
87
89
static StatusServiceDbus * dbus_interface = NULL;
88
90
static StatusProviderStatus global_status = STATUS_PROVIDER_STATUS_DISCONNECTED;
89
91
static GFileMonitor *avatar_monitor = NULL;
 
92
static DbusmenuMenuitem *broadcast_field = NULL;
 
93
static DbusmenuMenuitem * useritem = NULL;
90
94
 
91
95
static void
92
96
status_update (void) {
93
97
        StatusProviderStatus oldglobal = global_status;
94
98
        global_status = STATUS_PROVIDER_STATUS_DISCONNECTED;
 
99
  gboolean indeterminate = FALSE;
95
100
 
96
101
        /* Ask everyone what they think the status should be, if
97
102
           they're more connected, up the global level */
98
 
        int i;
 
103
  StatusProviderStatus i;
99
104
        for (i = 0; i < STATUS_PROVIDER_CNT; i++) {
 
105
    if (status_providers[i] == NULL) continue;
100
106
                StatusProviderStatus localstatus = status_provider_get_status(status_providers[i]);
101
 
                if (localstatus < global_status) {
 
107
    g_debug ("provider[%d]: %s", i, status_strings[localstatus]);
 
108
 
 
109
    if (localstatus >= STATUS_PROVIDER_STATUS_OFFLINE)
 
110
      /* offline and disconnected is similar for some providers
 
111
         so it's not meaningful to determine the 'indeterminate' status
 
112
      */
 
113
      continue;
 
114
 
 
115
                if (localstatus != global_status) {
 
116
      if (global_status < STATUS_PROVIDER_STATUS_OFFLINE)
 
117
        /* at least one provider was maintaining a status better than 'offline'
 
118
           and there's now another one with something different */
 
119
        indeterminate = TRUE;
102
120
                        global_status = localstatus;
103
121
                }
104
122
        }
105
123
 
106
 
        /* If changed */
107
 
        if (global_status != oldglobal) {
108
 
                g_debug("Global status changed to: %s", _(status_strings[global_status]));
109
 
 
110
 
                /* Configure the icon on the panel */
111
 
                status_service_dbus_set_status(dbus_interface, status_icons[global_status]);
112
 
 
113
 
                /* If we're now disconnected, make setting the statuses
114
 
                   insensitive. */
115
 
                if (global_status == STATUS_PROVIDER_STATUS_DISCONNECTED) {
116
 
                        StatusProviderStatus i;
117
 
                        for (i = STATUS_PROVIDER_STATUS_ONLINE; i < STATUS_PROVIDER_STATUS_LAST; i++) {
118
 
                                if (status_menuitems[i] == NULL) continue;
119
 
                                dbusmenu_menuitem_property_set_bool(status_menuitems[i], DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
120
 
                        }
121
 
                }
122
 
 
123
 
                /* If we're now back to a state where we have an IM client
124
 
                   connected then we need to resensitize the items. */
125
 
                if (oldglobal == STATUS_PROVIDER_STATUS_DISCONNECTED) {
126
 
                        StatusProviderStatus i;
127
 
                        for (i = STATUS_PROVIDER_STATUS_ONLINE; i < STATUS_PROVIDER_STATUS_LAST; i++) {
128
 
                                if (status_menuitems[i] == NULL) continue;
129
 
                                dbusmenu_menuitem_property_set_bool(status_menuitems[i], DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
130
 
                        }
131
 
                }
132
 
        }
 
124
  /* Configure the icon on the panel */
 
125
  status_service_dbus_set_status(dbus_interface, indeterminate ? "user-indeterminate" : status_icons[global_status]);
 
126
 
 
127
  g_debug("Global status changed to: %s", indeterminate ? "indeterminate" : status_strings[global_status]);
 
128
 
 
129
  /* If we're now disconnected, make setting the statuses
 
130
     insensitive. */
 
131
  if (global_status == STATUS_PROVIDER_STATUS_DISCONNECTED) {
 
132
    StatusProviderStatus i;
 
133
    for (i = STATUS_PROVIDER_STATUS_ONLINE;
 
134
         i < STATUS_PROVIDER_STATUS_LAST; i++) {
 
135
      if (status_menuitems[i] == NULL) continue;
 
136
      dbusmenu_menuitem_property_set_bool(status_menuitems[i],
 
137
                                          DBUSMENU_MENUITEM_PROP_ENABLED,
 
138
                                          FALSE);
 
139
    }
 
140
    return;
 
141
  }
 
142
 
 
143
  /* Ensure items are sensititive if they were previoulsy disabled */
 
144
  if (oldglobal == STATUS_PROVIDER_STATUS_DISCONNECTED) {
 
145
    StatusProviderStatus i;
 
146
    for (i = STATUS_PROVIDER_STATUS_ONLINE;
 
147
         i < STATUS_PROVIDER_STATUS_LAST; i++) {
 
148
      if (status_menuitems[i] == NULL) continue;
 
149
      dbusmenu_menuitem_property_set_bool(status_menuitems[i], DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
 
150
    }
 
151
  }
 
152
 
 
153
  /* add a radio mark to the user status entry */
 
154
  for (i = STATUS_PROVIDER_STATUS_ONLINE;
 
155
       i < STATUS_PROVIDER_STATUS_LAST; i++) {
 
156
    if (status_menuitems[i] == NULL) continue;
 
157
    if (indeterminate
 
158
        || (i != global_status)) {
 
159
      dbusmenu_menuitem_property_set_int (status_menuitems[i],
 
160
                                          DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
 
161
                                          DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
 
162
    } else {
 
163
      dbusmenu_menuitem_property_set_int (status_menuitems[i],
 
164
                                          DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
 
165
                                          DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED);
 
166
    }
 
167
  }
133
168
 
134
169
        return;
135
170
}
136
171
 
137
172
static void
 
173
gwibber_status_update (GwibberService *instance, GwibberServiceStatus status, gpointer data) {
 
174
  g_return_if_fail (instance != NULL);
 
175
 
 
176
  g_debug ("gwibber service status changed to: %d", status);
 
177
 
 
178
  if (broadcast_field == NULL) {
 
179
    g_warning ("no broadcast field to update");
 
180
    return;
 
181
  }
 
182
 
 
183
  if (! gwibber_service_has_configured_accounts (instance)) {
 
184
    g_debug ("no configured accounts detected, so hiding the broadcast field");
 
185
    dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
 
186
    return;
 
187
  }
 
188
 
 
189
  if (! dbusmenu_menuitem_property_get_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE))
 
190
    dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
 
191
 
 
192
#if 0
 
193
  if (status == GWIBBER_SERVICE_STATUS_RUNNING) {
 
194
    g_debug ("enabling the broadcast field");
 
195
    dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
 
196
  } else {
 
197
    g_debug ("disabling the broadcast field");
 
198
    dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
 
199
  }
 
200
#endif
 
201
 
 
202
  return;
 
203
}
 
204
 
 
205
 
 
206
static void
138
207
status_menu_click (DbusmenuMenuitem * mi, guint timestamp, gpointer data)
139
208
{
140
209
        StatusProviderStatus status = (StatusProviderStatus)GPOINTER_TO_INT(data);
218
287
 
219
288
        status_update();
220
289
 
221
 
        return FALSE;
 
290
  gwibber = gwibber_service_new ();
 
291
  if (gwibber != NULL) {
 
292
    g_signal_connect (G_OBJECT (gwibber), GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED, G_CALLBACK (gwibber_status_update), NULL);
 
293
  }
 
294
 
 
295
  return FALSE;
222
296
}
223
297
 
224
 
#define GCONF_ANONYMOUS "/system/indicator/me/anonymous"
 
298
#define GCONF_NAMESPACE "/system/indicator/me"
 
299
#define GCONF_DISPLAY   "/system/indicator/me/display"
225
300
 
226
 
static gboolean
227
 
anonymous_mode (void)
 
301
static void
 
302
display_mode_changed ()
228
303
{
229
 
  GConfClient *context = NULL;
230
 
  GConfValue *option = NULL;
231
 
  gboolean value = FALSE; /* not anonymous, by default */
232
 
 
233
 
  context = gconf_client_get_default ();
234
 
  if (! context) {
235
 
                g_warning ("Couldn't get a gconf context");
236
 
                return FALSE;
237
 
        }
238
 
 
239
 
  option = gconf_client_get (context, GCONF_ANONYMOUS, NULL);
 
304
  GConfClient *context = gconf_client_get_default ();
 
305
  g_return_if_fail (context != NULL);
 
306
 
 
307
  GConfValue *option = gconf_client_get (context, GCONF_DISPLAY, NULL);
 
308
  gint value = 1; /* username, by default */
 
309
 
 
310
  g_debug ("display_mode_changed");
 
311
 
240
312
  if (option != NULL &&
241
 
      option->type == GCONF_VALUE_BOOL)
242
 
    value = gconf_value_get_bool (option);
 
313
      option->type == GCONF_VALUE_INT)
 
314
    value = gconf_value_get_int (option);
 
315
 
 
316
  switch (value) {
 
317
  case 0: /* anonymous */
 
318
    status_service_dbus_set_username (dbus_interface, "");
 
319
    break;
 
320
  default:
 
321
  case 1:
 
322
    status_service_dbus_set_username (dbus_interface, g_get_user_name ());
 
323
    break;
 
324
  case 2:
 
325
    status_service_dbus_set_username (dbus_interface, g_get_real_name ());
 
326
    break;
 
327
  }
 
328
 
 
329
  dbusmenu_menuitem_property_set_bool (useritem,
 
330
                                       DBUSMENU_MENUITEM_PROP_VISIBLE,
 
331
                                       (value == 0) ? FALSE : TRUE);
243
332
 
244
333
  g_object_unref (context);
245
334
 
246
 
  return value;
 
335
  return;
247
336
}
248
337
 
 
338
 
249
339
static void
250
340
avatar_changed_cb (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data)
251
341
{
264
354
static void
265
355
build_user_item (DbusmenuMenuitem * root)
266
356
{
267
 
        struct passwd * pwd = NULL;
268
 
 
269
 
  if (anonymous_mode ())
270
 
    return;
271
 
 
272
 
        pwd = getpwuid(getuid());
273
 
 
274
 
  if (pwd != NULL && pwd->pw_name != NULL && pwd->pw_name[0] != '\0') {
275
 
    status_service_dbus_set_username(dbus_interface, pwd->pw_name);
276
 
  } else {
277
 
    g_warning ("PWD: %s", (pwd == NULL ? "(pwd null)" : (pwd->pw_name == NULL ? "(pw_name null)" : pwd->pw_name)));
278
 
 
279
 
    /* that's kind of an anonymous mode too if ever that can happen */
280
 
    return;
281
 
  }
282
 
 
283
 
  DbusmenuMenuitem * useritem = dbusmenu_menuitem_new();
 
357
  useritem = dbusmenu_menuitem_new();
 
358
  dbusmenu_menuitem_property_set(useritem, DBUSMENU_ABOUT_ME_MENUITEM_PROP_NAME, g_get_real_name ());
284
359
  dbusmenu_menuitem_property_set_bool(useritem, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
 
360
  dbusmenu_menuitem_property_set_bool(useritem, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
285
361
  dbusmenu_menuitem_property_set(useritem, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_ABOUT_ME_MENUITEM_TYPE);
286
362
  dbusmenu_menuitem_child_append(root, useritem);
287
363
 
304
380
    g_free(gam);
305
381
  }
306
382
 
307
 
        if (pwd != NULL && pwd->pw_gecos != NULL) {
308
 
                gchar * name = g_strdup(pwd->pw_gecos);
309
 
                gchar * walker = name;
310
 
                while (*walker != '\0' && *walker != ',') { walker++; }
311
 
                *walker = '\0';
312
 
 
313
 
                if (name[0] != '\0') {
314
 
      dbusmenu_menuitem_property_set(useritem, DBUSMENU_ABOUT_ME_MENUITEM_PROP_NAME, name);
315
 
                } else {
316
 
      /* fallback on the username, at least we know it's not null from above */
317
 
      dbusmenu_menuitem_property_set(useritem, DBUSMENU_ABOUT_ME_MENUITEM_PROP_NAME, pwd->pw_name);
318
 
    }
319
 
 
320
 
                g_free(name);
321
 
        }
 
383
  /* set the menu name */
 
384
  display_mode_changed ();
 
385
 
 
386
  /* and receive display mode notifications to update it later */
 
387
  GConfClient *context = gconf_client_get_default ();
 
388
  if (context != NULL) {
 
389
    gconf_client_add_dir (context, GCONF_NAMESPACE,
 
390
                          GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
 
391
    gconf_client_notify_add (context, GCONF_DISPLAY,
 
392
                             display_mode_changed, NULL, NULL, NULL);
 
393
    g_object_unref (context);
 
394
  }
322
395
 
323
396
        return;
324
397
}
331
404
 
332
405
  build_user_item(root);
333
406
 
334
 
        DbusmenuMenuitem *entry = DBUSMENU_MENUITEM (entry_menu_item_new());
335
 
        dbusmenu_menuitem_child_append(root, entry);
 
407
  broadcast_field = DBUSMENU_MENUITEM (entry_menu_item_new());
 
408
  dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
 
409
  dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
 
410
  dbusmenu_menuitem_child_append(root, broadcast_field);
336
411
 
337
412
        StatusProviderStatus i;
338
413
        for (i = STATUS_PROVIDER_STATUS_ONLINE; i < STATUS_PROVIDER_STATUS_LAST; i++) {
346
421
 
347
422
                dbusmenu_menuitem_property_set(status_menuitems[i], DBUSMENU_MENUITEM_PROP_LABEL, _(status_strings[i]));
348
423
                dbusmenu_menuitem_property_set(status_menuitems[i], DBUSMENU_MENUITEM_PROP_ICON_NAME, status_icons[i]);
 
424
    dbusmenu_menuitem_property_set (status_menuitems[i],
 
425
                                    DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE,
 
426
                                    DBUSMENU_MENUITEM_TOGGLE_RADIO);
 
427
    dbusmenu_menuitem_property_set_int (status_menuitems[i],
 
428
                                        DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
 
429
                                        DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
349
430
                if (global_status == STATUS_PROVIDER_STATUS_DISCONNECTED) {
350
431
                        dbusmenu_menuitem_property_set_bool(status_menuitems[i], DBUSMENU_MENUITEM_PROP_ENABLED, FALSE);
351
432
                }