[empathy: 3/26] add empathy-irc-network-chooser-dialog



commit 8f678a31a63eccb4fc086a8caddb37b1a0e7de91
Author: Guillaume Desmottes <guillaume desmottes collabora co uk>
Date:   Tue Aug 24 16:09:24 2010 +0200

    add empathy-irc-network-chooser-dialog
    
    Some of the code has been copied from empathy-account-widget-irc.c.

 libempathy-gtk/Makefile.am                         |    2 +
 .../empathy-irc-network-chooser-dialog.c           |  487 ++++++++++++++++++++
 .../empathy-irc-network-chooser-dialog.h           |   70 +++
 3 files changed, 559 insertions(+), 0 deletions(-)
---
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index 15e187c..d81b972 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -64,6 +64,7 @@ libempathy_gtk_handwritten_source =            	\
 	empathy-individual-view.c		\
 	empathy-individual-widget.c		\
 	empathy-irc-network-chooser.c \
+	empathy-irc-network-chooser-dialog.c \
 	empathy-irc-network-dialog.c		\
 	empathy-kludge-label.c			\
 	empathy-log-window.c			\
@@ -125,6 +126,7 @@ libempathy_gtk_headers =			\
 	empathy-individual-view.h		\
 	empathy-individual-widget.h		\
 	empathy-irc-network-chooser.h \
+	empathy-irc-network-chooser-dialog.h \
 	empathy-irc-network-dialog.h		\
 	empathy-kludge-label.h			\
 	empathy-log-window.h			\
diff --git a/libempathy-gtk/empathy-irc-network-chooser-dialog.c b/libempathy-gtk/empathy-irc-network-chooser-dialog.c
new file mode 100644
index 0000000..e4f6146
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser-dialog.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott gnome org>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-irc-network-manager.h>
+
+#include "empathy-irc-network-dialog.h"
+#include "empathy-ui-utils.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
+#include <libempathy/empathy-debug.h>
+
+#include "empathy-irc-network-chooser-dialog.h"
+
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetworkChooserDialog)
+
+enum {
+    PROP_SETTINGS = 1,
+    PROP_NETWORK
+};
+
+typedef struct {
+    EmpathyAccountSettings *settings;
+    EmpathyIrcNetwork *network;
+
+    EmpathyIrcNetworkManager *network_manager;
+    gboolean changed;
+
+    GtkWidget *treeview;
+    GtkListStore *store;
+} EmpathyIrcNetworkChooserDialogPriv;
+
+enum {
+  COL_NETWORK_OBJ,
+  COL_NETWORK_NAME,
+};
+
+G_DEFINE_TYPE (EmpathyIrcNetworkChooserDialog, empathy_irc_network_chooser_dialog,
+    GTK_TYPE_DIALOG);
+
+static void
+empathy_irc_network_chooser_dialog_set_property (GObject *object,
+    guint prop_id,
+    const GValue *value,
+    GParamSpec *pspec)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (object);
+
+  switch (prop_id)
+    {
+      case PROP_SETTINGS:
+        priv->settings = g_value_dup_object (value);
+        break;
+      case PROP_NETWORK:
+        priv->network = g_value_dup_object (value);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+empathy_irc_network_chooser_dialog_get_property (GObject *object,
+    guint prop_id,
+    GValue *value,
+    GParamSpec *pspec)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (object);
+
+  switch (prop_id)
+    {
+      case PROP_SETTINGS:
+        g_value_set_object (value, priv->settings);
+        break;
+      case PROP_NETWORK:
+        g_value_set_object (value, priv->network);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static EmpathyIrcNetwork *
+dup_selected_network (EmpathyIrcNetworkChooserDialog *self,
+    GtkTreeIter *it)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+  GtkTreeSelection *selection;
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
+  gtk_tree_selection_get_selected (selection, &model, &iter);
+
+  gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
+  g_assert (network != NULL);
+
+  if (it != NULL)
+    *it = iter;
+
+  return network;
+}
+
+static void
+treeview_changed_cb (GtkTreeView *treeview,
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+
+  network = dup_selected_network (self, NULL);
+  if (network == priv->network)
+    {
+      g_object_unref (network);
+      return;
+    }
+
+  tp_clear_object (&priv->network);
+  /* Transfer the reference */
+  priv->network = network;
+
+  priv->changed = TRUE;
+}
+
+static void
+scroll_to_iter (EmpathyIrcNetworkChooserDialog *self,
+    GtkTreeIter *iter)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  GtkTreePath *path;
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), iter);
+
+  if (path != NULL)
+    {
+      gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->treeview),
+          path, NULL, FALSE, 0, 0);
+
+      gtk_tree_path_free (path);
+    }
+}
+
+static void
+select_iter (EmpathyIrcNetworkChooserDialog *self,
+    GtkTreeIter *iter,
+    gboolean emulate_changed)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  GtkTreeSelection *selection;
+
+  /* Select the network */
+  selection = gtk_tree_view_get_selection (
+      GTK_TREE_VIEW (priv->treeview));
+
+  gtk_tree_selection_select_iter (selection, iter);
+
+  /* Scroll to the selected network */
+  scroll_to_iter (self, iter);
+
+  if (emulate_changed)
+    {
+      /* gtk_tree_selection_select_iter doesn't fire the 'cursor-changed' signal
+       * so we call the callback manually. */
+      treeview_changed_cb (GTK_TREE_VIEW (priv->treeview), self);
+    }
+}
+
+static void
+fill_store (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  GSList *networks, *l;
+
+  networks = empathy_irc_network_manager_get_networks (
+      priv->network_manager);
+
+  for (l = networks; l != NULL; l = g_slist_next (l))
+    {
+      gchar *name;
+      EmpathyIrcNetwork *network = l->data;
+      GtkTreeIter iter;
+
+      g_object_get (network, "name", &name, NULL);
+
+      gtk_list_store_insert_with_values (priv->store, &iter, -1,
+          COL_NETWORK_OBJ, network,
+          COL_NETWORK_NAME, name,
+          -1);
+
+      if (network == priv->network)
+        select_iter (self, &iter, FALSE);
+
+      g_free (name);
+      g_object_unref (network);
+    }
+
+  g_slist_free (networks);
+}
+
+static void
+irc_network_dialog_destroy_cb (GtkWidget *widget,
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+  gchar *name;
+  GtkTreeIter iter;
+
+  network = dup_selected_network (self, &iter);
+
+  /* name could be changed */
+  g_object_get (network, "name", &name, NULL);
+  gtk_list_store_set (GTK_LIST_STORE (priv->store), &iter,
+      COL_NETWORK_NAME, name, -1);
+
+  scroll_to_iter (self, &iter);
+
+  priv->changed = TRUE;
+
+  g_object_unref (network);
+  g_free (name);
+}
+
+static void
+display_irc_network_dialog (EmpathyIrcNetworkChooserDialog *self,
+    EmpathyIrcNetwork *network)
+{
+  GtkWidget *dialog;
+
+  dialog = empathy_irc_network_dialog_show (network, NULL);
+
+  g_signal_connect (dialog, "destroy",
+      G_CALLBACK (irc_network_dialog_destroy_cb), self);
+}
+
+static void
+edit_network (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetwork *network;
+
+  network = dup_selected_network (self, NULL);
+  display_irc_network_dialog (self, network);
+
+  g_object_unref (network);
+}
+
+static void
+add_network (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+  gchar *name;
+  GtkTreeIter iter;
+
+  network = empathy_irc_network_new (_("New Network"));
+  empathy_irc_network_manager_add (priv->network_manager, network);
+
+  g_object_get (network, "name", &name, NULL);
+
+  gtk_list_store_insert_with_values (priv->store, &iter, -1,
+      COL_NETWORK_OBJ, network,
+      COL_NETWORK_NAME, name,
+      -1);
+
+  select_iter (self, &iter, TRUE);
+
+  display_irc_network_dialog (self, network);
+
+  g_free (name);
+  g_object_unref (network);
+}
+
+static void
+remove_network (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+  GtkTreeIter iter;
+  gchar *name;
+
+  network = dup_selected_network (self, &iter);
+
+  g_object_get (network, "name", &name, NULL);
+  DEBUG ("Remove network %s", name);
+
+  gtk_list_store_remove (priv->store, &iter);
+  empathy_irc_network_manager_remove (priv->network_manager, network);
+
+  /* Select next network */
+  if (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->store), &iter))
+    select_iter (self, &iter, TRUE);
+
+  g_free (name);
+  g_object_unref (network);
+}
+
+static void
+dialog_response_cb (GtkDialog *dialog,
+    gint response,
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  if (response == GTK_RESPONSE_OK)
+    add_network (self);
+  else if (response == GTK_RESPONSE_APPLY)
+    edit_network (self);
+  else if (response == GTK_RESPONSE_REJECT)
+    remove_network (self);
+}
+
+static void
+empathy_irc_network_chooser_dialog_constructed (GObject *object)
+{
+  EmpathyIrcNetworkChooserDialog *self = (EmpathyIrcNetworkChooserDialog *) object;
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  GtkDialog *dialog = GTK_DIALOG (self);
+  GtkCellRenderer *renderer;
+  GtkWidget *vbox;
+  GtkTreeViewColumn *column;
+  GtkWidget *scroll;
+
+  g_assert (priv->settings != NULL);
+
+  gtk_window_set_title (GTK_WINDOW (self), _("IRC Networks"));
+
+  /* Create store and treeview */
+  priv->store = gtk_list_store_new (2, G_TYPE_OBJECT, G_TYPE_STRING);
+
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->store),
+      COL_NETWORK_NAME,
+      GTK_SORT_ASCENDING);
+
+  priv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->store));
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
+  gtk_tree_view_set_enable_search (GTK_TREE_VIEW (priv->treeview), FALSE);
+
+  column = gtk_tree_view_column_new ();
+  gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, TRUE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column),
+      renderer,
+      "text", COL_NETWORK_NAME,
+      NULL);
+
+  /* add the treeview in a GtkScrolledWindow */
+  vbox = gtk_dialog_get_content_area (dialog);
+
+  scroll = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+      GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+
+  gtk_container_add (GTK_CONTAINER (scroll), priv->treeview);
+  gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 6);
+
+  /* Add buttons */
+  gtk_dialog_add_buttons (dialog,
+      GTK_STOCK_ADD, GTK_RESPONSE_OK,
+      GTK_STOCK_EDIT, GTK_RESPONSE_APPLY,
+      GTK_STOCK_REMOVE, GTK_RESPONSE_REJECT,
+      GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+      NULL);
+
+  fill_store (self);
+
+  g_signal_connect (priv->treeview, "cursor-changed",
+      G_CALLBACK (treeview_changed_cb), self);
+
+  g_signal_connect (self, "response",
+      G_CALLBACK (dialog_response_cb), self);
+
+  /* Request a side ensuring to display at least some networks */
+  gtk_widget_set_size_request (GTK_WIDGET (self), -1, 300);
+}
+
+static void
+empathy_irc_network_chooser_dialog_dispose (GObject *object)
+{
+  EmpathyIrcNetworkManager *self = (EmpathyIrcNetworkManager *) object;
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+  tp_clear_object (&priv->settings);
+  tp_clear_object (&priv->network);
+  tp_clear_object (&priv->network_manager);
+  tp_clear_object (&priv->store);
+
+  if (G_OBJECT_CLASS (empathy_irc_network_chooser_dialog_parent_class)->dispose)
+    G_OBJECT_CLASS (empathy_irc_network_chooser_dialog_parent_class)->dispose (object);
+}
+
+static void
+empathy_irc_network_chooser_dialog_class_init (EmpathyIrcNetworkChooserDialogClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->get_property = empathy_irc_network_chooser_dialog_get_property;
+  object_class->set_property = empathy_irc_network_chooser_dialog_set_property;
+  object_class->constructed = empathy_irc_network_chooser_dialog_constructed;
+  object_class->dispose = empathy_irc_network_chooser_dialog_dispose;
+
+  g_object_class_install_property (object_class, PROP_SETTINGS,
+    g_param_spec_object ("settings",
+      "Settings",
+      "The EmpathyAccountSettings to show and edit",
+      EMPATHY_TYPE_ACCOUNT_SETTINGS,
+      G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (object_class, PROP_NETWORK,
+    g_param_spec_object ("network",
+      "Network",
+      "The EmpathyIrcNetwork selected in the treeview",
+      EMPATHY_TYPE_IRC_NETWORK,
+      G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_type_class_add_private (object_class,
+      sizeof (EmpathyIrcNetworkChooserDialogPriv));
+}
+
+static void
+empathy_irc_network_chooser_dialog_init (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv;
+
+  priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+      EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, EmpathyIrcNetworkChooserDialogPriv);
+  self->priv = priv;
+
+  priv->network_manager = empathy_irc_network_manager_dup_default ();
+}
+
+GtkWidget *
+empathy_irc_network_chooser_dialog_new (EmpathyAccountSettings *settings,
+    EmpathyIrcNetwork *network)
+{
+  return g_object_new (EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG,
+      "settings", settings,
+      "network", network,
+      NULL);
+}
+
+EmpathyIrcNetwork *
+empathy_irc_network_chooser_dialog_get_network (
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+  return priv->network;
+}
+
+gboolean
+empathy_irc_network_chooser_dialog_get_changed (
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+  return priv->changed;
+}
diff --git a/libempathy-gtk/empathy-irc-network-chooser-dialog.h b/libempathy-gtk/empathy-irc-network-chooser-dialog.h
new file mode 100644
index 0000000..1c9d3fa
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser-dialog.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott gnome org>
+ */
+
+#ifndef __EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_H__
+#define __EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-account-settings.h>
+#include <libempathy/empathy-irc-network.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG (empathy_irc_network_chooser_dialog_get_type ())
+#define EMPATHY_IRC_NETWORK_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, EmpathyIrcNetworkChooserDialog))
+#define EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, EmpathyIrcNetworkChooserDialogClass))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG))
+#define EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_GET_CLASS(o) ( \
+    G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, \
+        EmpathyIrcNetworkChooserDialogClass))
+
+typedef struct {
+  GtkDialog parent;
+
+  /*<private>*/
+  gpointer priv;
+} EmpathyIrcNetworkChooserDialog;
+
+typedef struct {
+  GtkDialogClass parent_class;
+} EmpathyIrcNetworkChooserDialogClass;
+
+GType empathy_irc_network_chooser_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget * empathy_irc_network_chooser_dialog_new (
+    EmpathyAccountSettings *settings,
+    EmpathyIrcNetwork *network);
+
+EmpathyIrcNetwork * empathy_irc_network_chooser_dialog_get_network (
+    EmpathyIrcNetworkChooserDialog *self);
+
+gboolean empathy_irc_network_chooser_dialog_get_changed (
+    EmpathyIrcNetworkChooserDialog *self);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]