]> git.0d.be Git - empathy.git/blob - libempathy/empathy-irc-network.c
Merge remote-tracking branch 'origin/gnome-3-8'
[empathy.git] / libempathy / empathy-irc-network.c
1 /*
2  * Copyright (C) 2007 Guillaume Desmottes
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA  02110-1301  USA
18  *
19  * Authors: Guillaume Desmottes <gdesmott@gnome.org>
20  */
21
22 #include "config.h"
23 #include "empathy-irc-network.h"
24
25 #include "empathy-utils.h"
26
27 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetwork)
28 typedef struct
29 {
30   gchar *name;
31   gchar *charset;
32   GSList *servers;
33 } EmpathyIrcNetworkPriv;
34
35 /* properties */
36 enum
37 {
38   PROP_NAME = 1,
39   PROP_CHARSET,
40   LAST_PROPERTY
41 };
42
43 /* signals */
44 enum
45 {
46   MODIFIED,
47   LAST_SIGNAL
48 };
49
50 static guint signals[LAST_SIGNAL] = {0};
51
52 G_DEFINE_TYPE (EmpathyIrcNetwork, empathy_irc_network, G_TYPE_OBJECT);
53
54 static void
55 server_modified_cb (EmpathyIrcServer *server,
56                     EmpathyIrcNetwork *self)
57 {
58   g_signal_emit (self, signals[MODIFIED], 0);
59 }
60
61 static void
62 empathy_irc_network_get_property (GObject *object,
63                                   guint property_id,
64                                   GValue *value,
65                                   GParamSpec *pspec)
66 {
67   EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
68   EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
69
70   switch (property_id)
71     {
72       case PROP_NAME:
73         g_value_set_string (value, priv->name);
74         break;
75       case PROP_CHARSET:
76         g_value_set_string (value, priv->charset);
77         break;
78       default:
79         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
80         break;
81     }
82 }
83
84 static void
85 empathy_irc_network_set_property (GObject *object,
86                                   guint property_id,
87                                   const GValue *value,
88                                   GParamSpec *pspec)
89 {
90   EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
91   EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
92
93   switch (property_id)
94     {
95       case PROP_NAME:
96         if (tp_strdiff (priv->name, g_value_get_string (value)))
97           {
98             g_free (priv->name);
99             priv->name = g_value_dup_string (value);
100             g_signal_emit (object, signals[MODIFIED], 0);
101           }
102         break;
103       case PROP_CHARSET:
104         if (tp_strdiff (priv->charset, g_value_get_string (value)))
105           {
106             g_free (priv->charset);
107             priv->charset = g_value_dup_string (value);
108             g_signal_emit (object, signals[MODIFIED], 0);
109           }
110         break;
111       default:
112         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
113         break;
114     }
115 }
116
117 static void
118 empathy_irc_network_dispose (GObject *object)
119 {
120   EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
121   EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
122   GSList *l;
123
124   for (l = priv->servers; l != NULL; l = g_slist_next (l))
125     {
126       g_signal_handlers_disconnect_by_func (l->data,
127           G_CALLBACK (server_modified_cb), self);
128       g_object_unref (l->data);
129     }
130
131   G_OBJECT_CLASS (empathy_irc_network_parent_class)->dispose (object);
132 }
133
134 static void
135 empathy_irc_network_finalize (GObject *object)
136 {
137   EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
138   EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
139
140   g_slist_free (priv->servers);
141   g_free (priv->name);
142   g_free (priv->charset);
143
144   G_OBJECT_CLASS (empathy_irc_network_parent_class)->finalize (object);
145 }
146
147 static void
148 empathy_irc_network_init (EmpathyIrcNetwork *self)
149 {
150   EmpathyIrcNetworkPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
151       EMPATHY_TYPE_IRC_NETWORK, EmpathyIrcNetworkPriv);
152
153   self->priv = priv;
154
155   priv->servers = NULL;
156
157   self->user_defined = TRUE;
158   self->dropped = FALSE;
159 }
160
161 static void
162 empathy_irc_network_class_init (EmpathyIrcNetworkClass *klass)
163 {
164   GObjectClass *object_class = G_OBJECT_CLASS (klass);
165   GParamSpec *param_spec;
166
167   object_class->get_property = empathy_irc_network_get_property;
168   object_class->set_property = empathy_irc_network_set_property;
169
170   g_type_class_add_private (object_class, sizeof (EmpathyIrcNetworkPriv));
171
172   object_class->dispose = empathy_irc_network_dispose;
173   object_class->finalize = empathy_irc_network_finalize;
174
175   param_spec = g_param_spec_string (
176       "name",
177       "Network name",
178       "The displayed name of this network",
179       NULL,
180       G_PARAM_READWRITE |
181       G_PARAM_STATIC_NAME |
182       G_PARAM_STATIC_NICK |
183       G_PARAM_STATIC_BLURB);
184   g_object_class_install_property (object_class, PROP_NAME, param_spec);
185
186   param_spec = g_param_spec_string (
187       "charset",
188       "Charset",
189       "The charset to use on this network",
190       "UTF-8",
191       G_PARAM_CONSTRUCT |
192       G_PARAM_READWRITE |
193       G_PARAM_STATIC_NAME |
194       G_PARAM_STATIC_NICK |
195       G_PARAM_STATIC_BLURB);
196   g_object_class_install_property (object_class, PROP_CHARSET, param_spec);
197
198   /**
199    * EmpathyIrcNetwork::modified:
200    * @network: the object that received the signal
201    *
202    * Emitted when either a property or a server of the network is modified or
203    * when a network is activated.
204    *
205    */
206   signals[MODIFIED] = g_signal_new (
207       "modified",
208       G_OBJECT_CLASS_TYPE (object_class),
209       G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
210       0,
211       NULL, NULL,
212       g_cclosure_marshal_generic,
213       G_TYPE_NONE, 0);
214 }
215
216 /**
217  * empathy_irc_network_activate:
218  * @self: the name of the network
219  *
220  * Activates a #EmpathyIrcNetwork.
221  *
222  */
223 void
224 empathy_irc_network_activate (EmpathyIrcNetwork *self)
225 {
226   g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
227   g_return_if_fail (self->dropped);
228
229   self->dropped = FALSE;
230
231   g_signal_emit (self, signals[MODIFIED], 0);
232 }
233
234 /**
235  * empathy_irc_network_new:
236  * @name: the name of the network
237  *
238  * Creates a new #EmpathyIrcNetwork.
239  *
240  * Returns: a new #EmpathyIrcNetwork
241  */
242 EmpathyIrcNetwork *
243 empathy_irc_network_new (const gchar *name)
244 {
245   return g_object_new (EMPATHY_TYPE_IRC_NETWORK,
246       "name", name,
247       NULL);
248 }
249
250 /**
251  * empathy_irc_network_get_servers:
252  * @network: an #EmpathyIrcNetwork
253  *
254  * Get the list of #EmpathyIrcServer that belongs to this network.
255  * These servers are sorted according their priority.
256  * So the first one will be the first used when trying to connect to
257  * the network.
258  *
259  * Returns: a new #GSList of refed #EmpathyIrcServer.
260  */
261 GSList *
262 empathy_irc_network_get_servers (EmpathyIrcNetwork *self)
263 {
264   EmpathyIrcNetworkPriv *priv;
265   GSList *servers = NULL, *l;
266
267   g_return_val_if_fail (EMPATHY_IS_IRC_NETWORK (self), NULL);
268   priv = GET_PRIV (self);
269
270   for (l = priv->servers; l != NULL; l = g_slist_next (l))
271     {
272       servers = g_slist_prepend (servers, g_object_ref (l->data));
273     }
274
275   return g_slist_reverse (servers);
276 }
277
278 /**
279  * empathy_irc_network_append_server:
280  * @network: an #EmpathyIrcNetwork
281  * @server: the #EmpathyIrcServer to add
282  *
283  * Add an #EmpathyIrcServer to the given #EmpathyIrcNetwork. The server
284  * is added at the last position in network's servers list.
285  *
286  */
287 void
288 empathy_irc_network_append_server (EmpathyIrcNetwork *self,
289                                    EmpathyIrcServer *server)
290 {
291   EmpathyIrcNetworkPriv *priv;
292
293   g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
294   g_return_if_fail (server != NULL && EMPATHY_IS_IRC_SERVER (server));
295
296   priv = GET_PRIV (self);
297
298   g_return_if_fail (g_slist_find (priv->servers, server) == NULL);
299
300   priv->servers = g_slist_append (priv->servers, g_object_ref (server));
301
302   g_signal_connect (server, "modified", G_CALLBACK (server_modified_cb), self);
303
304   g_signal_emit (self, signals[MODIFIED], 0);
305 }
306
307 /**
308  * empathy_irc_network_remove_server:
309  * @network: an #EmpathyIrcNetwork
310  * @server: the #EmpathyIrcServer to remove
311  *
312  * Remove an #EmpathyIrcServer from the servers list of the
313  * given #EmpathyIrcNetwork.
314  *
315  */
316 void
317 empathy_irc_network_remove_server (EmpathyIrcNetwork *self,
318                                    EmpathyIrcServer *server)
319 {
320   EmpathyIrcNetworkPriv *priv;
321   GSList *l;
322
323   g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
324   g_return_if_fail (server != NULL && EMPATHY_IS_IRC_SERVER (server));
325
326   priv = GET_PRIV (self);
327
328   l = g_slist_find (priv->servers, server);
329   if (l == NULL)
330     return;
331
332   g_object_unref (l->data);
333   priv->servers = g_slist_delete_link (priv->servers, l);
334   g_signal_handlers_disconnect_by_func (server, G_CALLBACK (server_modified_cb),
335       self);
336
337   g_signal_emit (self, signals[MODIFIED], 0);
338 }
339
340 /**
341  * empathy_irc_network_set_server_position:
342  * @network: an #EmpathyIrcNetwork
343  * @server: the #EmpathyIrcServer to move
344  * @pos: the position to move the server. If this is negative, or is larger than
345  * the number of servers in the list, the server is moved to the end of the
346  * list.
347  *
348  * Move an #EmpathyIrcServer in the servers list of the given
349  * #EmpathyIrcNetwork.
350  *
351  */
352 void
353 empathy_irc_network_set_server_position (EmpathyIrcNetwork *self,
354                                          EmpathyIrcServer *server,
355                                          gint pos)
356 {
357   EmpathyIrcNetworkPriv *priv;
358   GSList *l;
359
360   g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
361   g_return_if_fail (server != NULL && EMPATHY_IS_IRC_SERVER (server));
362
363   priv = GET_PRIV (self);
364
365   l = g_slist_find (priv->servers, server);
366   if (l == NULL)
367     return;
368
369   priv->servers = g_slist_delete_link (priv->servers, l);
370   priv->servers = g_slist_insert (priv->servers, server, pos);
371
372   g_signal_emit (self, signals[MODIFIED], 0);
373 }
374
375 const gchar *
376 empathy_irc_network_get_name (EmpathyIrcNetwork *self)
377 {
378   EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
379
380   return priv->name;
381 }
382
383 const gchar *
384 empathy_irc_network_get_charset (EmpathyIrcNetwork *self)
385 {
386   EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
387
388   return priv->charset;
389 }