~ubuntu-branches/ubuntu/maverick/telepathy-salut/maverick

« back to all changes in this revision

Viewing changes to src/salut-olpc-activity-manager.c

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2008-09-17 19:03:47 UTC
  • mfrom: (7.1.8 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080917190347-fhkvbcpf8jp8wxkw
Tags: 0.3.3-2
* Use my debian.org address in Uploaders
* debian/patches/fix-activity-announce.patch:
  - Only announce OLPC activity we actually joined (dev.laptop.org #8441)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * salut-olpc-activity-manager.c - Source for SalutOlpcActivityManager
 
3
 * Copyright (C) 2008 Collabora Ltd.
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Lesser General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2.1 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Lesser General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#include <dbus/dbus-glib.h>
 
21
#include <stdio.h>
 
22
#include <stdlib.h>
 
23
#include <string.h>
 
24
 
 
25
#include "salut-olpc-activity-manager.h"
 
26
 
 
27
#include "salut-connection.h"
 
28
#include "signals-marshal.h"
 
29
 
 
30
#define DEBUG_FLAG DEBUG_OLPC_ACTIVITY
 
31
#include "debug.h"
 
32
 
 
33
G_DEFINE_TYPE (SalutOlpcActivityManager, salut_olpc_activity_manager,
 
34
    G_TYPE_OBJECT);
 
35
 
 
36
/* properties */
 
37
enum {
 
38
  PROP_CONNECTION = 1,
 
39
  LAST_PROP
 
40
};
 
41
 
 
42
/* signal enum */
 
43
enum
 
44
{
 
45
  ACTIVITY_MODIFIED,
 
46
  LAST_SIGNAL
 
47
};
 
48
 
 
49
static guint signals[LAST_SIGNAL] = {0};
 
50
 
 
51
/* private structure */
 
52
typedef struct _SalutOlpcActivityManagerPrivate SalutOlpcActivityManagerPrivate;
 
53
 
 
54
struct _SalutOlpcActivityManagerPrivate
 
55
{
 
56
  /* TpHandle (owned by the activity) => SalutOlpcActivity */
 
57
  GHashTable *activities_by_room;
 
58
 
 
59
  gboolean dispose_has_run;
 
60
};
 
61
 
 
62
#define SALUT_OLPC_ACTIVITY_MANAGER_GET_PRIVATE(o)     (G_TYPE_INSTANCE_GET_PRIVATE ((o), SALUT_TYPE_OLPC_ACTIVITY_MANAGER, SalutOlpcActivityManagerPrivate))
 
63
 
 
64
static void
 
65
salut_olpc_activity_manager_init (SalutOlpcActivityManager *self)
 
66
{
 
67
  SalutOlpcActivityManagerPrivate *priv =
 
68
    SALUT_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
 
69
   /* We just keep a weak reference on the activity object so we'll remove
 
70
    * it from the hash when no one is using anymore */
 
71
  priv->activities_by_room = g_hash_table_new_full (g_direct_hash,
 
72
      g_direct_equal, NULL, NULL);
 
73
}
 
74
 
 
75
static void
 
76
salut_olpc_activity_manager_get_property (GObject *object,
 
77
                                          guint property_id,
 
78
                                          GValue *value,
 
79
                                          GParamSpec *pspec)
 
80
{
 
81
  SalutOlpcActivityManager *self = SALUT_OLPC_ACTIVITY_MANAGER (object);
 
82
 
 
83
  switch (property_id)
 
84
    {
 
85
      case PROP_CONNECTION:
 
86
        g_value_set_object (value, self->connection);
 
87
        break;
 
88
      default:
 
89
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
90
        break;
 
91
    }
 
92
}
 
93
 
 
94
static void
 
95
salut_olpc_activity_manager_set_property (GObject *object,
 
96
                                          guint property_id,
 
97
                                          const GValue *value,
 
98
                                          GParamSpec *pspec)
 
99
{
 
100
  SalutOlpcActivityManager *self = SALUT_OLPC_ACTIVITY_MANAGER (object);
 
101
 
 
102
  switch (property_id)
 
103
    {
 
104
      case PROP_CONNECTION:
 
105
        self->connection = g_value_get_object (value);
 
106
        break;
 
107
      default:
 
108
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
109
        break;
 
110
    }
 
111
}
 
112
 
 
113
static void salut_olpc_activity_manager_dispose (GObject *object);
 
114
static void salut_olpc_activity_manager_finalize (GObject *object);
 
115
 
 
116
static void
 
117
salut_olpc_activity_manager_class_init (SalutOlpcActivityManagerClass *salut_olpc_activity_manager_class)
 
118
{
 
119
  GObjectClass *object_class = G_OBJECT_CLASS (salut_olpc_activity_manager_class);
 
120
  GParamSpec *param_spec;
 
121
 
 
122
  g_type_class_add_private (salut_olpc_activity_manager_class,
 
123
                              sizeof (SalutOlpcActivityManagerPrivate));
 
124
 
 
125
  object_class->get_property = salut_olpc_activity_manager_get_property;
 
126
  object_class->set_property = salut_olpc_activity_manager_set_property;
 
127
 
 
128
  object_class->dispose = salut_olpc_activity_manager_dispose;
 
129
  object_class->finalize = salut_olpc_activity_manager_finalize;
 
130
 
 
131
  param_spec = g_param_spec_object (
 
132
      "connection",
 
133
      "SalutConnection object",
 
134
      "The Salut Connection associated with this muc manager",
 
135
      SALUT_TYPE_CONNECTION,
 
136
      G_PARAM_CONSTRUCT_ONLY |
 
137
      G_PARAM_READWRITE |
 
138
      G_PARAM_STATIC_NAME |
 
139
      G_PARAM_STATIC_NICK |
 
140
      G_PARAM_STATIC_BLURB);
 
141
  g_object_class_install_property (object_class, PROP_CONNECTION,
 
142
      param_spec);
 
143
 
 
144
  signals[ACTIVITY_MODIFIED] = g_signal_new ("activity-modified",
 
145
      G_OBJECT_CLASS_TYPE (salut_olpc_activity_manager_class),
 
146
      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
 
147
      salut_signals_marshal_VOID__OBJECT,
 
148
      G_TYPE_NONE, 1, SALUT_TYPE_OLPC_ACTIVITY);
 
149
}
 
150
 
 
151
static gboolean
 
152
remove_activity_foreach (gpointer room,
 
153
                         gpointer act,
 
154
                         gpointer activity)
 
155
{
 
156
  return act == activity;
 
157
}
 
158
 
 
159
static void
 
160
activity_finalized_cb (gpointer data,
 
161
                       GObject *activity)
 
162
{
 
163
  SalutOlpcActivityManager *self = SALUT_OLPC_ACTIVITY_MANAGER (data);
 
164
  SalutOlpcActivityManagerPrivate *priv =
 
165
    SALUT_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
 
166
 
 
167
  g_hash_table_foreach_remove (priv->activities_by_room,
 
168
      remove_activity_foreach, activity);
 
169
}
 
170
 
 
171
static gboolean
 
172
dispose_activity_foreach (gpointer room,
 
173
                          gpointer activity,
 
174
                          gpointer user_data)
 
175
{
 
176
  SalutOlpcActivityManager *self = SALUT_OLPC_ACTIVITY_MANAGER (user_data);
 
177
 
 
178
  g_object_weak_unref (G_OBJECT (activity), activity_finalized_cb, self);
 
179
  g_signal_handlers_disconnect_matched (activity, G_SIGNAL_MATCH_DATA,
 
180
      0, 0, NULL, NULL, self);
 
181
 
 
182
  return TRUE;
 
183
}
 
184
 
 
185
static void
 
186
salut_olpc_activity_manager_dispose (GObject *object)
 
187
{
 
188
  SalutOlpcActivityManager *self = SALUT_OLPC_ACTIVITY_MANAGER (object);
 
189
  SalutOlpcActivityManagerPrivate *priv = SALUT_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
 
190
 
 
191
  if (priv->dispose_has_run)
 
192
    return;
 
193
 
 
194
  priv->dispose_has_run = TRUE;
 
195
 
 
196
  if (priv->activities_by_room != NULL)
 
197
    {
 
198
      g_hash_table_foreach_remove (priv->activities_by_room,
 
199
          dispose_activity_foreach, self);
 
200
      g_hash_table_destroy (priv->activities_by_room);
 
201
      priv->activities_by_room = NULL;
 
202
    }
 
203
 
 
204
  if (G_OBJECT_CLASS (salut_olpc_activity_manager_parent_class)->dispose)
 
205
    G_OBJECT_CLASS (salut_olpc_activity_manager_parent_class)->dispose (object);
 
206
}
 
207
 
 
208
static void
 
209
salut_olpc_activity_manager_finalize (GObject *object)
 
210
{
 
211
  //SalutOlpcActivityManager *self = SALUT_OLPC_ACTIVITY_MANAGER (object);
 
212
 
 
213
  G_OBJECT_CLASS (salut_olpc_activity_manager_parent_class)->finalize (object);
 
214
}
 
215
 
 
216
gboolean
 
217
salut_olpc_activity_manager_start (SalutOlpcActivityManager *self,
 
218
                                   GError **error)
 
219
{
 
220
  return SALUT_OLPC_ACTIVITY_MANAGER_GET_CLASS (self)->start (self, error);
 
221
}
 
222
 
 
223
SalutOlpcActivity *
 
224
salut_olpc_activity_manager_get_activity_by_room (SalutOlpcActivityManager *self,
 
225
                                                  TpHandle room)
 
226
{
 
227
  SalutOlpcActivityManagerPrivate *priv =
 
228
    SALUT_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
 
229
  return g_hash_table_lookup (priv->activities_by_room,
 
230
      GUINT_TO_POINTER (room));
 
231
}
 
232
 
 
233
SalutOlpcActivity *
 
234
salut_olpc_activity_manager_ensure_activity_by_room (
 
235
    SalutOlpcActivityManager *self,
 
236
    TpHandle room)
 
237
{
 
238
  SalutOlpcActivity *activity;
 
239
  SalutOlpcActivityManagerPrivate *priv =
 
240
    SALUT_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
 
241
 
 
242
  activity = g_hash_table_lookup (priv->activities_by_room,
 
243
      GUINT_TO_POINTER (room));
 
244
 
 
245
  if (activity != NULL)
 
246
    {
 
247
      return g_object_ref (activity);
 
248
    }
 
249
  else
 
250
    {
 
251
      activity = salut_olpc_activity_manager_create_activity (self, room);
 
252
      return activity;
 
253
    }
 
254
}
 
255
 
 
256
static void
 
257
activity_modified_cb (SalutOlpcActivity *activity,
 
258
                      SalutOlpcActivityManager *self)
 
259
{
 
260
  g_signal_emit (self, signals[ACTIVITY_MODIFIED], 0, activity);
 
261
}
 
262
 
 
263
SalutOlpcActivity *
 
264
salut_olpc_activity_manager_create_activity (SalutOlpcActivityManager *self,
 
265
                                             TpHandle room)
 
266
{
 
267
  SalutOlpcActivity *activity;
 
268
  SalutOlpcActivityManagerPrivate *priv =
 
269
    SALUT_OLPC_ACTIVITY_MANAGER_GET_PRIVATE (self);
 
270
 
 
271
  g_assert (room != 0);
 
272
  g_assert (g_hash_table_lookup (priv->activities_by_room, GUINT_TO_POINTER (
 
273
        room)) == NULL);
 
274
 
 
275
  activity = SALUT_OLPC_ACTIVITY_MANAGER_GET_CLASS (self)->create_activity (
 
276
      self);
 
277
  salut_olpc_activity_update (activity, room, NULL, NULL, NULL, NULL, NULL,
 
278
      TRUE);
 
279
 
 
280
  g_hash_table_insert (priv->activities_by_room, GUINT_TO_POINTER (room),
 
281
      activity);
 
282
 
 
283
  g_signal_connect (activity, "modified", G_CALLBACK (activity_modified_cb),
 
284
      self);
 
285
  g_object_weak_ref (G_OBJECT (activity), activity_finalized_cb , self);
 
286
 
 
287
  return activity;
 
288
}
 
289
 
 
290
SalutOlpcActivity *
 
291
salut_olpc_activity_manager_got_invitation (SalutOlpcActivityManager *self,
 
292
                                            TpHandle room,
 
293
                                            SalutContact *inviter,
 
294
                                            const gchar *id,
 
295
                                            const gchar *name,
 
296
                                            const gchar *type,
 
297
                                            const gchar *color,
 
298
                                            const gchar *tags)
 
299
{
 
300
  SalutOlpcActivity *activity;
 
301
 
 
302
  activity = salut_olpc_activity_manager_ensure_activity_by_room (self, room);
 
303
 
 
304
  salut_olpc_activity_update (activity, room, id, name, type, color, tags,
 
305
      activity->is_private);
 
306
 
 
307
  /* FIXME: we shouldn't add it if the local user is already in the activity
 
308
   * as, for now, we don't manage private activity membership (it's PS job) */
 
309
 
 
310
  /* add the inviter to the activity */
 
311
  salut_contact_joined_activity (inviter, activity);
 
312
 
 
313
  /* contact reffed the activity if it didn't hold a ref on it yet */
 
314
  g_object_unref (activity);
 
315
 
 
316
  return activity;
 
317
}
 
318
 
 
319
void
 
320
salut_olpc_activity_manager_contact_joined (SalutOlpcActivityManager *self,
 
321
                                            SalutContact *contact,
 
322
                                            SalutOlpcActivity *activity)
 
323
{
 
324
  salut_contact_joined_activity (contact, activity);
 
325
}
 
326
 
 
327
void
 
328
salut_olpc_activity_manager_contact_left (SalutOlpcActivityManager *mgr,
 
329
                                          SalutContact *contact,
 
330
                                          SalutOlpcActivity *activity)
 
331
{
 
332
  salut_contact_left_activity (contact, activity);
 
333
}