]> git.0d.be Git - empathy.git/blob - libempathy/empathy-irc-network.c
Import tools from telepathy-glib 0.7.3 and build a static libemp-extensions.la.
[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., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Authors: Guillaume Desmottes <gdesmott@gnome.org>
20  */
21
22 #include <config.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <glib.h>
26 #include <glib/gi18n.h>
27
28 #include <telepathy-glib/util.h>
29
30 #include "empathy-marshal.h"
31 #include "empathy-irc-network.h"
32
33 G_DEFINE_TYPE (EmpathyIrcNetwork, empathy_irc_network, G_TYPE_OBJECT);
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 typedef struct _EmpathyIrcNetworkPrivate EmpathyIrcNetworkPrivate;
53
54 struct _EmpathyIrcNetworkPrivate
55 {
56   gchar *name;
57   gchar *charset;
58   GSList *servers;
59 };
60
61 #define EMPATHY_IRC_NETWORK_GET_PRIVATE(obj)\
62     ((EmpathyIrcNetworkPrivate *) obj->priv)
63
64 static void
65 server_modified_cb (EmpathyIrcServer *server,
66                     EmpathyIrcNetwork *self)
67 {
68   g_signal_emit (self, signals[MODIFIED], 0);
69 }
70
71 static void
72 empathy_irc_network_get_property (GObject *object,
73                                   guint property_id,
74                                   GValue *value,
75                                   GParamSpec *pspec)
76 {
77   EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
78   EmpathyIrcNetworkPrivate *priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
79
80   switch (property_id)
81     {
82       case PROP_NAME:
83         g_value_set_string (value, priv->name);
84         break;
85       case PROP_CHARSET:
86         g_value_set_string (value, priv->charset);
87         break;
88       default:
89         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
90         break;
91     }
92 }
93
94 static void
95 empathy_irc_network_set_property (GObject *object,
96                                   guint property_id,
97                                   const GValue *value,
98                                   GParamSpec *pspec)
99 {
100   EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
101   EmpathyIrcNetworkPrivate *priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
102
103   switch (property_id)
104     {
105       case PROP_NAME:
106         if (tp_strdiff (priv->name, g_value_get_string (value)))
107           {
108             g_free (priv->name);
109             priv->name = g_value_dup_string (value);
110             g_signal_emit (object, signals[MODIFIED], 0);
111           }
112         break;
113       case PROP_CHARSET:
114         if (tp_strdiff (priv->charset, g_value_get_string (value)))
115           {
116             g_free (priv->charset);
117             priv->charset = g_value_dup_string (value);
118             g_signal_emit (object, signals[MODIFIED], 0);
119           }
120         break;
121       default:
122         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
123         break;
124     }
125 }
126
127 static void
128 empathy_irc_network_dispose (GObject *object)
129 {
130   EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
131   EmpathyIrcNetworkPrivate *priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
132   GSList *l;
133
134   for (l = priv->servers; l != NULL; l = g_slist_next (l))
135     {
136       g_signal_handlers_disconnect_by_func (l->data,
137           G_CALLBACK (server_modified_cb), self);
138       g_object_unref (l->data);
139     }
140
141   G_OBJECT_CLASS (empathy_irc_network_parent_class)->dispose (object);
142 }
143
144 static void
145 empathy_irc_network_finalize (GObject *object)
146 {
147   EmpathyIrcNetwork *self = EMPATHY_IRC_NETWORK (object);
148   EmpathyIrcNetworkPrivate *priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
149
150   g_slist_free (priv->servers);
151   g_free (priv->name);
152   g_free (priv->charset);
153
154   G_OBJECT_CLASS (empathy_irc_network_parent_class)->finalize (object);
155 }
156
157 static void
158 empathy_irc_network_init (EmpathyIrcNetwork *self)
159 {
160   EmpathyIrcNetworkPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
161       EMPATHY_TYPE_IRC_NETWORK, EmpathyIrcNetworkPrivate);
162
163   self->priv = priv;
164
165   priv->servers = NULL;
166
167   self->user_defined = TRUE;
168   self->dropped = FALSE;
169 }
170
171 static void
172 empathy_irc_network_class_init (EmpathyIrcNetworkClass *klass)
173 {
174   GObjectClass *object_class = G_OBJECT_CLASS (klass);
175   GParamSpec *param_spec;
176
177   object_class->get_property = empathy_irc_network_get_property;
178   object_class->set_property = empathy_irc_network_set_property;
179
180   g_type_class_add_private (object_class,
181           sizeof (EmpathyIrcNetworkPrivate));
182
183   object_class->dispose = empathy_irc_network_dispose;
184   object_class->finalize = empathy_irc_network_finalize;
185
186   param_spec = g_param_spec_string (
187       "name",
188       "Network name",
189       "The displayed name of this network",
190       NULL,
191       G_PARAM_READWRITE |
192       G_PARAM_STATIC_NAME |
193       G_PARAM_STATIC_NICK |
194       G_PARAM_STATIC_BLURB);
195   g_object_class_install_property (object_class, PROP_NAME, param_spec);
196
197   param_spec = g_param_spec_string (
198       "charset",
199       "Charset",
200       "The charset to use on this network",
201       "UTF-8",
202       G_PARAM_CONSTRUCT |
203       G_PARAM_READWRITE |
204       G_PARAM_STATIC_NAME |
205       G_PARAM_STATIC_NICK |
206       G_PARAM_STATIC_BLURB);
207   g_object_class_install_property (object_class, PROP_CHARSET, param_spec);
208
209   /**
210    * EmpathyIrcNetwork::modified:
211    * @network: the object that received the signal
212    *
213    * Emitted when either a property or a server of the network is modified.
214    *
215    */
216   signals[MODIFIED] = g_signal_new (
217       "modified",
218       G_OBJECT_CLASS_TYPE (object_class),
219       G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
220       0,
221       NULL, NULL,
222       g_cclosure_marshal_VOID__VOID,
223       G_TYPE_NONE, 0);
224 }
225
226 /**
227  * empathy_irc_network_new:
228  * @name: the name of the network
229  *
230  * Creates a new #EmpathyIrcNetwork.
231  *
232  * Returns: a new #EmpathyIrcNetwork
233  */
234 EmpathyIrcNetwork *
235 empathy_irc_network_new (const gchar *name)
236 {
237   return g_object_new (EMPATHY_TYPE_IRC_NETWORK,
238       "name", name,
239       NULL);
240 }
241
242 /**
243  * empathy_irc_network_get_servers:
244  * @network: an #EmpathyIrcNetwork
245  *
246  * Get the list of #EmpathyIrcServer that belongs to this network.
247  * These servers are sorted according their priority.
248  * So the first one will be the first used when trying to connect to
249  * the network.
250  *
251  * Returns: a new #GSList of refed #EmpathyIrcServer.
252  */
253 GSList *
254 empathy_irc_network_get_servers (EmpathyIrcNetwork *self)
255 {
256   EmpathyIrcNetworkPrivate *priv;
257   GSList *servers = NULL, *l;
258
259   g_return_val_if_fail (EMPATHY_IS_IRC_NETWORK (self), NULL);
260   priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
261
262   for (l = priv->servers; l != NULL; l = g_slist_next (l))
263     {
264       servers = g_slist_prepend (servers, g_object_ref (l->data));
265     }
266
267   return g_slist_reverse (servers);
268 }
269
270 /**
271  * empathy_irc_network_append_server:
272  * @network: an #EmpathyIrcNetwork
273  * @server: the #EmpathyIrcServer to add
274  *
275  * Add an #EmpathyIrcServer to the given #EmpathyIrcNetwork. The server
276  * is added at the last position in network's servers list.
277  *
278  */
279 void
280 empathy_irc_network_append_server (EmpathyIrcNetwork *self,
281                                    EmpathyIrcServer *server)
282 {
283   EmpathyIrcNetworkPrivate *priv;
284
285   g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
286   g_return_if_fail (server != NULL && EMPATHY_IS_IRC_SERVER (server));
287
288   priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
289
290   g_return_if_fail (g_slist_find (priv->servers, server) == NULL);
291
292   priv->servers = g_slist_append (priv->servers, g_object_ref (server));
293
294   g_signal_connect (server, "modified", G_CALLBACK (server_modified_cb), self);
295
296   g_signal_emit (self, signals[MODIFIED], 0);
297 }
298
299 /**
300  * empathy_irc_network_remove_server:
301  * @network: an #EmpathyIrcNetwork
302  * @server: the #EmpathyIrcServer to remove
303  *
304  * Remove an #EmpathyIrcServer from the servers list of the
305  * given #EmpathyIrcNetwork.
306  *
307  */
308 void
309 empathy_irc_network_remove_server (EmpathyIrcNetwork *self,
310                                    EmpathyIrcServer *server)
311 {
312   EmpathyIrcNetworkPrivate *priv;
313   GSList *l;
314
315   g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
316   g_return_if_fail (server != NULL && EMPATHY_IS_IRC_SERVER (server));
317
318   priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
319
320   l = g_slist_find (priv->servers, server);
321   if (l == NULL)
322     return;
323
324   g_object_unref (l->data);
325   priv->servers = g_slist_delete_link (priv->servers, l);
326   g_signal_handlers_disconnect_by_func (server, G_CALLBACK (server_modified_cb),
327       self);
328
329   g_signal_emit (self, signals[MODIFIED], 0);
330 }
331
332 /**
333  * empathy_irc_network_set_server_position:
334  * @network: an #EmpathyIrcNetwork
335  * @server: the #EmpathyIrcServer to move
336  * @pos: the position to move the server. If this is negative, or is larger than
337  * the number of servers in the list, the server is moved to the end of the
338  * list.
339  *
340  * Move an #EmpathyIrcServer in the servers list of the given
341  * #EmpathyIrcNetwork.
342  *
343  */
344 void
345 empathy_irc_network_set_server_position (EmpathyIrcNetwork *self,
346                                          EmpathyIrcServer *server,
347                                          gint pos)
348 {
349   EmpathyIrcNetworkPrivate *priv;
350   GSList *l;
351
352   g_return_if_fail (EMPATHY_IS_IRC_NETWORK (self));
353   g_return_if_fail (server != NULL && EMPATHY_IS_IRC_SERVER (server));
354
355   priv = EMPATHY_IRC_NETWORK_GET_PRIVATE (self);
356
357   l = g_slist_find (priv->servers, server);
358   if (l == NULL)
359     return;
360
361   priv->servers = g_slist_delete_link (priv->servers, l);
362   priv->servers = g_slist_insert (priv->servers, server, pos);
363
364   g_signal_emit (self, signals[MODIFIED], 0);
365 }