2 * Copyright (C) 2007-2008 Guillaume Desmottes
3 * Copyright (C) 2010 Collabora Ltd.
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.
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.
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
19 * Authors: Guillaume Desmottes <gdesmott@gnome.org>
23 #include "empathy-irc-network-chooser.h"
25 #include "empathy-irc-network-chooser-dialog.h"
26 #include "empathy-irc-network-manager.h"
27 #include "empathy-ui-utils.h"
28 #include "empathy-utils.h"
30 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
31 #include "empathy-debug.h"
33 #define DEFAULT_IRC_NETWORK "irc.gimp.org"
34 #define DEFAULT_IRC_PORT 6667
35 #define DEFAULT_IRC_SSL FALSE
37 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetworkChooser)
48 static guint signals[LAST_SIGNAL] = { 0 };
51 EmpathyAccountSettings *settings;
53 EmpathyIrcNetworkManager *network_manager;
55 /* Displayed network */
56 EmpathyIrcNetwork *network;
57 } EmpathyIrcNetworkChooserPriv;
59 G_DEFINE_TYPE (EmpathyIrcNetworkChooser, empathy_irc_network_chooser,
63 empathy_irc_network_chooser_set_property (GObject *object,
68 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (object);
73 priv->settings = g_value_dup_object (value);
76 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
82 empathy_irc_network_chooser_get_property (GObject *object,
87 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (object);
92 g_value_set_object (value, priv->settings);
95 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
101 unset_server_params (EmpathyIrcNetworkChooser *self)
103 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
105 DEBUG ("Unset server, port and use-ssl");
106 empathy_account_settings_unset (priv->settings, "server");
107 empathy_account_settings_unset (priv->settings, "port");
108 empathy_account_settings_unset (priv->settings, "use-ssl");
112 dup_network_service (EmpathyIrcNetwork *network)
114 /* Account.Service has to be a lower case alphanumeric string which may
115 * also contain '-' but not start with it. */
116 #define VALID G_CSET_a_2_z G_CSET_DIGITS "-"
117 gchar *service, *tmp;
119 service = g_strdup (empathy_irc_network_get_name (network));
120 service = g_strstrip (service);
122 if (tp_str_empty (service))
129 service = g_ascii_strdown (service, -1);
132 service = g_strcanon (service, VALID, '-');
134 if (service[0] == '-')
137 service = g_strdup (service + 1);
146 update_server_params (EmpathyIrcNetworkChooser *self)
148 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
150 const gchar *charset;
152 g_assert (priv->network != NULL);
154 charset = empathy_irc_network_get_charset (priv->network);
155 DEBUG ("Setting charset to %s", charset);
156 empathy_account_settings_set (priv->settings, "charset",
157 g_variant_new_string (charset));
159 servers = empathy_irc_network_get_servers (priv->network);
160 if (g_slist_length (servers) > 0)
162 /* set the first server as CM server */
163 EmpathyIrcServer *server = servers->data;
169 g_object_get (server,
175 DEBUG ("Setting server to %s", address);
176 empathy_account_settings_set (priv->settings, "server",
177 g_variant_new_string (address));
178 DEBUG ("Setting port to %u", port);
179 empathy_account_settings_set (priv->settings, "port",
180 g_variant_new_uint32 (port));
181 DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" );
182 empathy_account_settings_set (priv->settings, "use-ssl",
183 g_variant_new_boolean (ssl));
185 /* Set Account.Service */
186 service = dup_network_service (priv->network);
187 DEBUG ("Setting Service to %s", service);
188 empathy_account_settings_set_service (priv->settings, service);
195 /* No server. Unset values */
196 unset_server_params (self);
199 g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
200 g_slist_free (servers);
204 set_label (EmpathyIrcNetworkChooser *self)
206 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
208 g_assert (priv->network != NULL);
210 gtk_button_set_label (GTK_BUTTON (self),
211 empathy_irc_network_get_name (priv->network));
215 set_label_from_settings (EmpathyIrcNetworkChooser *self)
217 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
220 tp_clear_object (&priv->network);
222 server = empathy_account_settings_dup_string (priv->settings, "server");
226 EmpathyIrcServer *srv;
230 priv->network = empathy_irc_network_manager_find_network_by_address (
231 priv->network_manager, server);
233 if (priv->network != NULL)
235 /* The network is known */
236 g_object_ref (priv->network);
241 /* We don't have this network. Let's create it */
242 port = empathy_account_settings_get_uint32 (priv->settings, "port");
243 ssl = empathy_account_settings_get_boolean (priv->settings,
246 DEBUG ("Create a network %s", server);
247 priv->network = empathy_irc_network_new (server);
248 srv = empathy_irc_server_new (server, port, ssl);
250 empathy_irc_network_append_server (priv->network, srv);
251 empathy_irc_network_manager_add (priv->network_manager, priv->network);
255 g_object_unref (srv);
260 /* Set default network */
261 priv->network = empathy_irc_network_manager_find_network_by_address (
262 priv->network_manager, DEFAULT_IRC_NETWORK);
264 if (priv->network == NULL)
266 /* Default network is not known, recreate it */
267 EmpathyIrcServer *srv;
269 priv->network = empathy_irc_network_new (DEFAULT_IRC_NETWORK);
271 srv = empathy_irc_server_new (DEFAULT_IRC_NETWORK, DEFAULT_IRC_PORT,
274 empathy_irc_network_append_server (priv->network, srv);
275 empathy_irc_network_manager_add (priv->network_manager, priv->network);
277 g_object_unref (srv);
281 update_server_params (self);
282 g_object_ref (priv->network);
286 dialog_response_cb (GtkDialog *dialog,
288 EmpathyIrcNetworkChooser *self)
290 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
291 EmpathyIrcNetworkChooserDialog *chooser =
292 EMPATHY_IRC_NETWORK_CHOOSER_DIALOG (priv->dialog);
294 if (response != GTK_RESPONSE_CLOSE &&
295 response != GTK_RESPONSE_DELETE_EVENT)
298 if (empathy_irc_network_chooser_dialog_get_changed (chooser))
300 tp_clear_object (&priv->network);
302 priv->network = g_object_ref (
303 empathy_irc_network_chooser_dialog_get_network (chooser));
305 update_server_params (self);
308 g_signal_emit (self, signals[SIG_CHANGED], 0);
311 gtk_widget_destroy (priv->dialog);
316 clicked_cb (GtkButton *button,
319 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (button);
322 if (priv->dialog != NULL)
325 window = empathy_get_toplevel_window (GTK_WIDGET (button));
327 priv->dialog = empathy_irc_network_chooser_dialog_new (priv->settings,
328 priv->network, window);
329 gtk_widget_show_all (priv->dialog);
331 tp_g_signal_connect_object (priv->dialog, "response",
332 G_CALLBACK (dialog_response_cb), button, 0);
335 empathy_window_present (GTK_WINDOW (priv->dialog));
339 empathy_irc_network_chooser_constructed (GObject *object)
341 EmpathyIrcNetworkChooser *self = (EmpathyIrcNetworkChooser *) object;
342 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
344 g_assert (priv->settings != NULL);
346 set_label_from_settings (self);
348 g_signal_connect (self, "clicked", G_CALLBACK (clicked_cb), self);
352 empathy_irc_network_chooser_dispose (GObject *object)
354 EmpathyIrcNetworkManager *self = (EmpathyIrcNetworkManager *) object;
355 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
357 tp_clear_object (&priv->settings);
358 tp_clear_object (&priv->network_manager);
359 tp_clear_object (&priv->network);
361 if (G_OBJECT_CLASS (empathy_irc_network_chooser_parent_class)->dispose)
362 G_OBJECT_CLASS (empathy_irc_network_chooser_parent_class)->dispose (object);
366 empathy_irc_network_chooser_class_init (EmpathyIrcNetworkChooserClass *klass)
368 GObjectClass *object_class = G_OBJECT_CLASS (klass);
370 object_class->get_property = empathy_irc_network_chooser_get_property;
371 object_class->set_property = empathy_irc_network_chooser_set_property;
372 object_class->constructed = empathy_irc_network_chooser_constructed;
373 object_class->dispose = empathy_irc_network_chooser_dispose;
375 g_object_class_install_property (object_class, PROP_SETTINGS,
376 g_param_spec_object ("settings",
378 "The EmpathyAccountSettings to show and edit",
379 EMPATHY_TYPE_ACCOUNT_SETTINGS,
380 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
382 signals[SIG_CHANGED] = g_signal_new ("changed",
383 G_OBJECT_CLASS_TYPE (object_class),
387 g_cclosure_marshal_generic,
391 g_type_class_add_private (object_class,
392 sizeof (EmpathyIrcNetworkChooserPriv));
396 empathy_irc_network_chooser_init (EmpathyIrcNetworkChooser *self)
398 EmpathyIrcNetworkChooserPriv *priv;
400 priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
401 EMPATHY_TYPE_IRC_NETWORK_CHOOSER, EmpathyIrcNetworkChooserPriv);
404 priv->network_manager = empathy_irc_network_manager_dup_default ();
408 empathy_irc_network_chooser_new (EmpathyAccountSettings *settings)
410 return g_object_new (EMPATHY_TYPE_IRC_NETWORK_CHOOSER,
411 "settings", settings,
416 empathy_irc_network_chooser_get_network (EmpathyIrcNetworkChooser *self)
418 EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
420 return priv->network;