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