]> jfr.im git - irc/xchat.git/commitdiff
* "Add to Friends List" in nick menu.
authorzed <redacted>
Sun, 8 Jun 2008 07:58:58 +0000 (07:58 +0000)
committerzed <redacted>
Sun, 8 Jun 2008 07:58:58 +0000 (07:58 +0000)
* Automated /WHOIS in nick menu when information is missing.
* Default to "IRC (Latin/Unicode Hybrid)" when adding a new network.
* Implement add/remove from Favorites.
* Zero out passwords upon exit.

git-svn-id: svn://svn.code.sf.net/p/xchat/svn@1299 893a96be-7f27-4fdf-9d1e-6aeec9d3cce1

src/common/notify.c
src/common/servlist.c
src/common/servlist.h
src/common/userlist.c
src/common/xchat.c
src/fe-gtk/about.c
src/fe-gtk/fe-gtk.h
src/fe-gtk/maingui.c
src/fe-gtk/menu.c
src/fe-gtk/servlistgui.c
src/fe-text/fe-text.c

index a52c615954659b571b8941c17e2d6cee0e33a357..04795849640ccbf25bbb72c4184b7405891215ba 100644 (file)
@@ -545,6 +545,23 @@ notify_adduser (char *name, char *networks)
        }
 }
 
+gboolean
+notify_is_in_list (server *serv, char *name)
+{
+       struct notify *notify;
+       GSList *list = notify_list;
+
+       while (list)
+       {
+               notify = (struct notify *) list->data;
+               if (!serv->p_cmp (notify->name, name))
+                       return TRUE;
+               list = list->next;
+       }
+
+       return FALSE;
+}
+
 int
 notify_isnotify (struct session *sess, char *name)
 {
index 96c76c16d57bf5ff8e14223f1e0698024127335e..05ed263ef2f66232563b75f8cb5334e38d27a2d6 100644 (file)
@@ -793,6 +793,34 @@ servlist_server_remove_all (ircnet *net)
        }
 }
 
+static void
+free_and_clear (char *str)
+{
+       if (str)
+       {
+               char *orig = str;
+               while (*str)
+                       *str++ = 0;
+               free (orig);
+       }
+}
+
+/* executed on exit: Clear any password strings */
+
+void
+servlist_cleanup (void)
+{
+       GSList *list;
+       ircnet *net;
+
+       for (list = network_list; list; list = list->next)
+       {
+               net = list->data;
+               free_and_clear (net->pass);
+               free_and_clear (net->nickserv);
+       }
+}
+
 void
 servlist_net_remove (ircnet *net)
 {
@@ -810,14 +838,12 @@ servlist_net_remove (ircnet *net)
                free (net->user);
        if (net->real)
                free (net->real);
-       if (net->pass)
-               free (net->pass);
+       free_and_clear (net->pass);
        if (net->autojoin)
                free (net->autojoin);
        if (net->command)
                free (net->command);
-       if (net->nickserv)
-               free (net->nickserv);
+       free_and_clear (net->nickserv);
        if (net->comment)
                free (net->comment);
        if (net->encoding)
index b919491e66671da15dd36e784967e6b528bc6e6a..cc4e6c4a28203c4809bc644bceb3e8ed92bcf360 100644 (file)
@@ -43,6 +43,7 @@ int servlist_connect_by_netname (session *sess, char *network, gboolean join);
 int servlist_auto_connect (session *sess);
 int servlist_have_auto (void);
 int servlist_check_encoding (char *charset);
+void servlist_cleanup (void);
 
 ircnet *servlist_net_add (char *name, char *comment, int prepend);
 void servlist_net_remove (ircnet *net);
index 1362298e069a0b14552877e4dbe438222044d5c4..18ac4bed415b3b522ea33cc20141d19aa133785e 100644 (file)
@@ -107,6 +107,8 @@ userlist_set_away (struct session *sess, char *nick, unsigned int away)
                        user->away = away;
                        /* rehash GUI */
                        fe_userlist_rehash (sess, user);
+                       if (away)
+                               fe_userlist_update (sess, user);
                }
        }
 }
@@ -127,12 +129,18 @@ userlist_add_hostname (struct session *sess, char *nick, char *hostname,
                if (!user->servername && servername)
                        user->servername = strdup (servername);
 
-               if (prefs.showhostname_in_userlist || user->away != away)
+               if (away != 0xff)
                {
+                       if (prefs.showhostname_in_userlist || user->away != away)
+                       {
+                               user->away = away;
+                               fe_userlist_rehash (sess, user);
+                       }
                        user->away = away;
-                       fe_userlist_rehash (sess, user);
                }
-               user->away = away;
+
+               fe_userlist_update (sess, user);
+
                return 1;
        }
        return 0;
index 67657123e70135f3147812010b12f8a157428c4d..eddc80214e2f681e4826ced6001909319531bbdd 100644 (file)
@@ -846,6 +846,7 @@ xchat_exit (void)
        ignore_save ();
        free_sessions ();
        chanopt_save_all ();
+       servlist_cleanup ();
        fe_exit ();
 }
 
index 9852de79c3c60d8b912f41db086da7987efaa729..674d9bbe2b6b67e80af330b1275ce9de10298456 100644 (file)
@@ -99,7 +99,7 @@ menu_about (GtkWidget * wid, gpointer sess)
        about = gtk_dialog_new ();
        gtk_window_set_position (GTK_WINDOW (about), GTK_WIN_POS_CENTER);
        gtk_window_set_resizable (GTK_WINDOW (about), FALSE);
-       gtk_window_set_title (GTK_WINDOW (about), _("About XChat"));
+       gtk_window_set_title (GTK_WINDOW (about), _("About "DISPLAY_NAME));
        if (parent_window)
                gtk_window_set_transient_for (GTK_WINDOW (about), parent_window);
        g_signal_connect (G_OBJECT (about), "destroy",
@@ -115,7 +115,7 @@ menu_about (GtkWidget * wid, gpointer sess)
        gtk_container_add (GTK_CONTAINER (vbox), label);
        g_get_charset (&locale);
        (snprintf) (buf, sizeof (buf),
-                               "<span size=\"x-large\"><b>XChat "PACKAGE_VERSION"</b></span>\n\n"
+                               "<span size=\"x-large\"><b>"DISPLAY_NAME" "PACKAGE_VERSION"</b></span>\n\n"
                                "%s\n\n"
 #ifdef WIN32
                                /* leave this message to avoid time wasting bug reports! */
@@ -129,7 +129,7 @@ menu_about (GtkWidget * wid, gpointer sess)
                                "<b>Renderer</b>: %s\n"
 #endif
                                "<b>Compiled</b>: "__DATE__"\n\n"
-                               "<small>\302\251 1998-2007 Peter \305\275elezn\303\275 &lt;zed@xchat.org></small>",
+                               "<small>\302\251 1998-2008 Peter \305\275elezn\303\275 &lt;zed@xchat.org></small>",
                                        _("A multiplatform IRC Client"),
                                        get_cpu_str(),
                                        locale,
index ba6ee939ccf327fd6ff3ad1ba44be2a839b3d165..495e2bf6ee7faea0f7992de8c564e28663bd48b6 100644 (file)
@@ -1,5 +1,14 @@
 #include "../../config.h"
 
+#ifdef WIN32
+/* If you're compiling this for Windows, your release is un-official
+ * and not condoned. Please don't use the XChat name. Call it YChat
+ * or make up your own name! */
+#define DISPLAY_NAME "YChat"
+#else
+#define DISPLAY_NAME "XChat"
+#endif
+
 #ifndef WIN32
 #include <sys/types.h>
 #include <regex.h>
index f24aeac7f031794eb42c518f8a6d0aede785576a..7501261914b9a3308cc575e99cf533fe2c425df3 100644 (file)
@@ -502,23 +502,23 @@ fe_set_title (session *sess)
        switch (type)
        {
        case SESS_DIALOG:
-               snprintf (tbuf, sizeof (tbuf), "XChat: %s %s @ %s",
+               snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s %s @ %s",
                                         _("Dialog with"), sess->channel, server_get_network (sess->server, TRUE));
                break;
        case SESS_SERVER:
-               snprintf (tbuf, sizeof (tbuf), "XChat: %s @ %s",
+               snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s",
                                         sess->server->nick, server_get_network (sess->server, TRUE));
                break;
        case SESS_CHANNEL:
                /* don't display keys in the titlebar */
                if ((!(prefs.gui_tweaks & 16)) && has_key (sess->current_modes))
                        snprintf (tbuf, sizeof (tbuf),
-                                                "XChat: %s @ %s / %s",
+                                                DISPLAY_NAME": %s @ %s / %s",
                                                 sess->server->nick, server_get_network (sess->server, TRUE),
                                                 sess->channel);
                else
                        snprintf (tbuf, sizeof (tbuf),
-                                                "XChat: %s @ %s / %s (%s)",
+                                                DISPLAY_NAME": %s @ %s / %s (%s)",
                                                 sess->server->nick, server_get_network (sess->server, TRUE),
                                                 sess->channel, sess->current_modes ? sess->current_modes : "");
                if (prefs.gui_tweaks & 1)
@@ -526,12 +526,12 @@ fe_set_title (session *sess)
                break;
        case SESS_NOTICES:
        case SESS_SNOTICES:
-               snprintf (tbuf, sizeof (tbuf), "XChat: %s @ %s (notices)",
+               snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s (notices)",
                                         sess->server->nick, server_get_network (sess->server, TRUE));
                break;
        default:
        def:
-               gtk_window_set_title (GTK_WINDOW (sess->gui->window), "XChat");
+               gtk_window_set_title (GTK_WINDOW (sess->gui->window), DISPLAY_NAME);
                return;
        }
 
index 1eb4a86fe5a01d6ceec8b7ad5ccebf177e6b92a8..3d235f8ca048b77ccf40a26de843f83dfa0dadea 100644 (file)
@@ -515,6 +515,17 @@ menu_create (GtkWidget *menu, GSList *list, char *target, int check_path)
                {
                        char *icon, *label;
 
+                       /* default command in xchat.c */
+                       if (pop->cmd[0] == 'n' && !strcmp (pop->cmd, "notify -n ASK %s"))
+                       {
+                               /* don't create this item if already in notify list */
+                               if (notify_is_in_list (current_sess->server, target))
+                               {
+                                       list = list->next;
+                                       continue;
+                               }
+                       }
+
                        menu_extract_icon (pop->name, &label, &icon);
 
                        if (!check_path || pop->cmd[0] != '!')
@@ -539,6 +550,9 @@ menu_create (GtkWidget *menu, GSList *list, char *target, int check_path)
                submenu_list = g_slist_remove (submenu_list, submenu_list->data);
 }
 
+static char *str_copy = NULL;          /* for all pop-up menus */
+static GtkWidget *nick_submenu = NULL; /* user info submenu */
+
 static void
 menu_destroy (GtkWidget *menu, gpointer objtounref)
 {
@@ -546,6 +560,7 @@ menu_destroy (GtkWidget *menu, gpointer objtounref)
        g_object_unref (menu);
        if (objtounref)
                g_object_unref (G_OBJECT (objtounref));
+       nick_submenu = NULL;
 }
 
 static void
@@ -565,15 +580,122 @@ menu_popup (GtkWidget *menu, GdkEventButton *event, gpointer objtounref)
                                                 0, event ? event->time : 0);
 }
 
-static char *str_copy = 0;             /* for all pop-up menus */
+static void
+menu_nickinfo_cb (GtkWidget *menu, session *sess)
+{
+       char buf[512];
+
+       if (!is_session (sess))
+               return;
+
+       /* issue a /WHOIS */
+       snprintf (buf, sizeof (buf), "WHOIS %s %s", str_copy, str_copy);
+       handle_command (sess, buf, FALSE);
+       /* and hide the output */
+       sess->server->skip_next_whois = 1;
+}
+
+/* returns boolean: Some data is missing */
+
+static gboolean
+menu_create_nickinfo_menu (struct User *user, GtkWidget *submenu)
+{
+       char buf[512];
+       char unknown[96];
+       char *real, *fmt;
+       struct away_msg *away;
+       gboolean missing = FALSE;
+
+       /* let the translators tweak this if need be */
+       fmt = _("<tt><b>%-11s</b></tt> %s");
+       snprintf (unknown, sizeof (unknown), "<i>%s</i>", _("Unknown"));
+
+       if (user->realname)
+       {
+               real = strip_color (user->realname, -1, STRIP_ALL|STRIP_ESCMARKUP);
+               snprintf (buf, sizeof (buf), fmt, _("Real Name:"), real);
+               g_free (real);
+       } else
+       {
+               snprintf (buf, sizeof (buf), fmt, _("Real Name:"), unknown);
+       }
+       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
+
+       snprintf (buf, sizeof (buf), fmt, _("User:"),
+                                user->hostname ? user->hostname : unknown);
+       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
+
+       snprintf (buf, sizeof (buf), fmt, _("Country:"),
+                                user->hostname ? country(user->hostname) : unknown);
+       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
+
+       snprintf (buf, sizeof (buf), fmt, _("Server:"),
+                                user->servername ? user->servername : unknown);
+       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
+
+       if (user->lasttalk)
+       {
+               char min[96];
+
+               snprintf (min, sizeof (min), _("%u minutes ago"),
+                                       (unsigned int) ((time (0) - user->lasttalk) / 60));
+               snprintf (buf, sizeof (buf), fmt, _("Last Msg:"), min);
+       } else
+       {
+               snprintf (buf, sizeof (buf), fmt, _("Last Msg:"), unknown);
+       }
+       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
+
+       if (user->away)
+       {
+               away = server_away_find_message (current_sess->server, user->nick);
+               if (away)
+               {
+                       char *msg = strip_color (away->message ? away->message : unknown, -1, STRIP_ALL|STRIP_ESCMARKUP);
+                       snprintf (buf, sizeof (buf), fmt, _("Away Msg:"), msg);
+                       g_free (msg);
+                       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
+               }
+               else
+                       missing = TRUE;
+       }
+
+       return missing;
+}
+
+void
+fe_userlist_update (session *sess, struct User *user)
+{
+       GList *items, *next;
+
+       if (!nick_submenu || !str_copy)
+               return;
+
+       /* not the same nick as the menu? */
+       if (sess->server->p_cmp (user->nick, str_copy))
+               return;
+
+       /* get rid of the "show" signal */
+       g_signal_handlers_disconnect_by_func (nick_submenu, menu_nickinfo_cb, sess);
+
+       /* destroy all the old items */
+       items = ((GtkMenuShell *) nick_submenu)->children;
+       while (items)
+       {
+               next = items->next;
+               gtk_widget_destroy (items->data);
+               items = next;
+       }
+
+       /* and re-create them with new info */
+       menu_create_nickinfo_menu (user, nick_submenu);
+}
 
 void
 menu_nickmenu (session *sess, GdkEventButton *event, char *nick, int num_sel)
 {
        char buf[512];
-       char *real, *fmt;
        struct User *user;
-       struct away_msg *away;
        GtkWidget *submenu, *menu = gtk_menu_new ();
 
        if (str_copy)
@@ -585,7 +707,7 @@ menu_nickmenu (session *sess, GdkEventButton *event, char *nick, int num_sel)
        /* more than 1 nick selected? */
        if (num_sel > 1)
        {
-               snprintf (buf, sizeof (buf), "%d nicks selected.", num_sel);
+               snprintf (buf, sizeof (buf), _("%d nicks selected."), num_sel);
                menu_quick_item (0, buf, menu, 0, 0, 0);
                menu_quick_item (0, 0, menu, XCMENU_SHADED, 0, 0);
        } else
@@ -595,61 +717,13 @@ menu_nickmenu (session *sess, GdkEventButton *event, char *nick, int num_sel)
                        user = userlist_find_global (current_sess->server, nick);
                if (user)
                {
-                       submenu = menu_quick_sub (nick, menu, NULL, XCMENU_DOLIST, -1);
+                       nick_submenu = submenu = menu_quick_sub (nick, menu, NULL, XCMENU_DOLIST, -1);
 
-                       /* let the translators tweak this if need be */
-                       fmt = _("<tt><b>%-11s</b></tt> %s");
-
-                       if (user->realname)
+                       if (menu_create_nickinfo_menu (user, submenu) ||
+                                !user->hostname || !user->realname || !user->servername)
                        {
-                               real = g_markup_escape_text (user->realname, -1);
-                               snprintf (buf, sizeof (buf), fmt, _("Real Name:"), real);
-                               g_free (real);
-                       } else
-                       {
-                               snprintf (buf, sizeof (buf), fmt, _("Real Name:"), _("Unknown"));
+                               g_signal_connect (G_OBJECT (submenu), "show", G_CALLBACK (menu_nickinfo_cb), sess);
                        }
-                       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
-
-                       snprintf (buf, sizeof (buf), fmt, _("User:"),
-                                               user->hostname ? user->hostname : _("Unknown"));
-                       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
-
-                       snprintf (buf, sizeof (buf), fmt, _("Country:"),
-                                               user->hostname ? country(user->hostname) : _("Unknown"));
-                       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
-
-                       snprintf (buf, sizeof (buf), fmt, _("Server:"),
-                                               user->servername ? user->servername : _("Unknown"));
-                       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
-
-                       if (user->away)
-                       {
-                               away = server_away_find_message (current_sess->server, nick);
-                               if (away)
-                               {
-                                       char *msg = strip_color (away->message ? away->message : _("Unknown"), -1, STRIP_ALL);
-                                       real = g_markup_escape_text (msg, -1);
-                                       g_free (msg);
-                                       snprintf (buf, sizeof (buf), fmt, _("Away Msg:"), real);
-                                       g_free (real);
-                                       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
-                               }
-                       }
-
-                       if (user->lasttalk)
-                       {
-                               char min[96];
-
-                               snprintf (min, sizeof (min), _("%u minutes ago"),
-                                                       (unsigned int) ((time (0) - user->lasttalk) / 60));
-                               snprintf (buf, sizeof (buf), fmt, _("Last Msg:"), min);
-                       } else
-                       {
-                               snprintf (buf, sizeof (buf), fmt, _("Last Msg:"), _("Unknown"));
-                       }
-
-                       menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0);
 
                        menu_quick_endsub ();
                        menu_quick_item (0, 0, menu, XCMENU_SHADED, 0, 0);
@@ -935,11 +1009,13 @@ menu_chanmenu (struct session *sess, GdkEventButton * event, char *chan)
 static void
 menu_delfav_cb (GtkWidget *item, server *serv)
 {
+       servlist_autojoinedit (serv->network, str_copy, FALSE);
 }
 
 static void
 menu_addfav_cb (GtkWidget *item, server *serv)
 {
+       servlist_autojoinedit (serv->network, str_copy, TRUE);
 }
 
 void
index 788357eb34221725dce97286167298de3aa67ed4..ba887bdb565ee0d6048774af20ae7391219d38aa 100644 (file)
@@ -81,6 +81,7 @@ static GtkWidget *edit_tree;
 
 static ircnet *selected_net = NULL;
 static ircserver *selected_serv = NULL;
+static ircnet *fav_add_net = NULL; /* used in Add/Remove fav context menus */
 static session *servlist_sess;
 
 static void servlist_network_row_cb (GtkTreeSelection *sel, gpointer user_data);
@@ -265,15 +266,11 @@ servlist_addnet_cb (GtkWidget *item, GtkTreeView *treeview)
        GtkListStore *store;
        ircnet *net;
 
-       store = (GtkListStore *)gtk_tree_view_get_model (treeview);
        net = servlist_net_add (_("New Network"), "", TRUE);
-#ifdef WIN32
-       /* Windows gets UTF-8 for new users. Unix gets "System Default",
-               which is often UTF-8 anyway! */
-       net->encoding = strdup ("UTF-8 (Unicode)");
-#endif
+       net->encoding = strdup ("IRC (Latin/Unicode Hybrid)");
        servlist_server_add (net, "newserver/6667");
 
+       store = (GtkListStore *)gtk_tree_view_get_model (treeview);
        gtk_list_store_prepend (store, &iter);
        gtk_list_store_set (store, &iter, 0, net->name, 1, 1, -1);
 
@@ -486,10 +483,8 @@ servlist_update_from_entry (char **str, GtkWidget *entry)
 }
 
 static void
-servlist_edit_close_cb (GtkWidget *button, gpointer userdata)
+servlist_edit_update (ircnet *net)
 {
-       ircnet *net = selected_net;
-
        servlist_update_from_entry (&net->nick, edit_entry_nick);
        servlist_update_from_entry (&net->nick2, edit_entry_nick2);
        servlist_update_from_entry (&net->user, edit_entry_user);
@@ -499,6 +494,12 @@ servlist_edit_close_cb (GtkWidget *button, gpointer userdata)
        servlist_update_from_entry (&net->command, edit_entry_cmd);
        servlist_update_from_entry (&net->nickserv, edit_entry_nickserv);
        servlist_update_from_entry (&net->pass, edit_entry_pass);
+}
+
+static void
+servlist_edit_close_cb (GtkWidget *button, gpointer userdata)
+{
+       servlist_edit_update (selected_net);
 
        gtk_widget_destroy (edit_win);
        edit_win = NULL;
@@ -667,8 +668,143 @@ servlist_savegui (void)
        return 0;
 }
 
+static gboolean
+servlist_get_iter_from_name (GtkTreeModel *model, gchar *name, GtkTreeIter *iter)
+{
+       GtkTreePath *path = gtk_tree_path_new_from_string (name);
+
+       if (!gtk_tree_model_get_iter (model, iter, path))
+       {
+               gtk_tree_path_free (path);
+               return FALSE;
+       }
+
+       gtk_tree_path_free (path);
+       return TRUE;
+}
+
 static void
-servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
+servlist_editchannel_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, GtkTreeModel *model)
+{
+       GtkTreeIter iter;
+
+       if (!servlist_get_iter_from_name (model, name, &iter))
+               return;
+
+       /* delete empty item */
+       if (newval[0] == 0)
+               gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+       else
+               gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, newval, -1);
+}
+
+static void
+servlist_editkey_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, GtkTreeModel *model)
+{
+       GtkTreeIter iter;
+
+       if (!servlist_get_iter_from_name (model, name, &iter))
+               return;
+
+       gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, newval, -1);
+}
+
+static void
+servlist_addchannel (GtkWidget *tree, char *channel)
+{
+       GtkTreeIter iter;
+       GtkListStore *store;
+
+       store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
+
+       gtk_list_store_append (store, &iter);
+       gtk_list_store_set (store, &iter, 0, channel, 1, "", 2, TRUE, -1);
+
+       /* select this server */
+       servlist_select_and_show (GTK_TREE_VIEW (tree), &iter, store);
+       servlist_start_editing (GTK_TREE_VIEW (tree));
+}
+
+static void
+servlist_addchannel_cb (GtkWidget *item, GtkWidget *tree)
+{
+       servlist_addchannel (tree, _("#channel"));
+}
+
+static void
+servlist_deletechannel_cb (GtkWidget *item, GtkWidget *tree)
+{
+       GtkTreeSelection *sel;
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+
+       /* find the selected item in the GUI */
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
+       sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
+
+       if (gtk_tree_selection_get_selected (sel, &model, &iter))
+               gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+}
+
+static void
+servlist_editchannelbutton_cb (GtkWidget *item, GtkWidget *tree)
+{
+       servlist_start_editing (GTK_TREE_VIEW (tree));
+}
+
+/* save everything from the GUI to the GtkEntry */
+
+static void
+servlist_autojoineditok_cb (GtkWidget *button, GtkWidget *tree)
+{
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+       char *channel, *key;
+       char *autojoin;
+       GSList *channels = NULL, *keys = NULL;
+
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
+
+       if (gtk_tree_model_get_iter_first (model, &iter))
+       {
+               do
+               {
+                       gtk_tree_model_get (model, &iter, 0, &channel, 1, &key, -1);
+                       channels = g_slist_append (channels, channel);
+                       if (key && key[0] == 0)
+                       {
+                               /* NULL out empty keys */
+                               g_free (key);
+                               keys = g_slist_append (keys, NULL);                             
+                       }
+                       else
+                               keys = g_slist_append (keys, key);
+               }
+               while (gtk_tree_model_iter_next (model, &iter));
+       }
+
+       gtk_widget_destroy (gtk_widget_get_toplevel (button));
+
+       autojoin = joinlist_merge (channels, keys);
+       if (autojoin)
+       {
+               if (selected_net)
+                       gtk_entry_set_text (GTK_ENTRY (edit_entry_join), autojoin);
+               else
+               {
+                       if (fav_add_net->autojoin)
+                               free (fav_add_net->autojoin);
+                       fav_add_net->autojoin = strdup (autojoin);
+               }
+               g_free (autojoin);
+       }
+
+       /* this does g_free too */
+       joinlist_free (channels, keys);
+}
+
+void
+servlist_autojoinedit (ircnet *net, char *channel, gboolean add)
 {
        GtkWidget *win;
        GtkWidget *scrolledwindow;
@@ -678,6 +814,7 @@ servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
        GtkWidget *tree;
        GtkWidget *table;
        GtkWidget *label;
+       GtkWidget *label2;
        GtkWidget *bbox;
        GtkWidget *wid;
 
@@ -687,14 +824,18 @@ servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
        GtkWidget *buttonedit;
 
        char buf[128];
+       char lab[128];
        GSList *channels, *keys;
        GSList *clist, *klist;
        GtkTreeIter iter;
 
+       if (selected_net)
+               /* update net->autojoin */
+               servlist_edit_update (selected_net);
+
        win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        gtk_container_set_border_width (GTK_CONTAINER (win), 4);
-       snprintf (buf, sizeof (buf), _("XChat: Favorite Channels (Auto-Join List)"));//, net->name);
-       gtk_window_set_title (GTK_WINDOW (win), buf);
+       gtk_window_set_title (GTK_WINDOW (win), _("XChat: Favorite Channels (Auto-Join List)"));
        gtk_window_set_default_size (GTK_WINDOW (win), 354, 256);
        gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_MOUSE);
        gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (edit_win));
@@ -706,51 +847,19 @@ servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
        gtk_container_add (GTK_CONTAINER (win), table);
        gtk_widget_show (table);
 
-       snprintf (buf, sizeof (buf), _("These channels will be joined\nwhenever you connect to %s"), net->name);
+       snprintf (buf, sizeof (buf), _("These channels will be joined whenever you connect to %s."), net->name);
        label = gtk_label_new (buf);
        gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
        gtk_table_attach (GTK_TABLE (table), label, 0, 2, 0, 1, GTK_FILL|GTK_EXPAND, GTK_FILL, 3, 3);
        gtk_widget_show (label);
 
-       bbox = gtk_hbutton_box_new ();
-       gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
-       gtk_box_set_spacing (GTK_BOX (bbox), 4);
-       gtk_table_attach (GTK_TABLE (table), bbox, 0, 1, 2, 3, GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 4);
-       gtk_widget_show (bbox);
-
-       wid = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
-       gtk_container_add (GTK_CONTAINER (bbox), wid);
-       gtk_widget_show (wid);
-
-       wid = gtk_button_new_from_stock (GTK_STOCK_OK);
-       gtk_container_add (GTK_CONTAINER (bbox), wid);
-       gtk_widget_show (wid);
-
-       /* ===== */
-       vbuttonbox1 = gtk_vbutton_box_new ();
-       gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 3);
-       gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_START);
-       gtk_widget_show (vbuttonbox1);
-       gtk_table_attach (GTK_TABLE (table), vbuttonbox1, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 3, 0);
-
-       buttonadd = gtk_button_new_from_stock ("gtk-add");
-       gtk_widget_show (buttonadd);
-       gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonadd);
-       GTK_WIDGET_SET_FLAGS (buttonadd, GTK_CAN_DEFAULT);
-
-       buttonremove = gtk_button_new_from_stock ("gtk-remove");
-       gtk_widget_show (buttonremove);
-       gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonremove);
-       GTK_WIDGET_SET_FLAGS (buttonremove, GTK_CAN_DEFAULT);
-
-       buttonedit = gtk_button_new_with_mnemonic (_("_Edit"));
-       gtk_widget_show (buttonedit);
-       gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonedit);
-       GTK_WIDGET_SET_FLAGS (buttonedit, GTK_CAN_DEFAULT);
-       /* ===== */
+       label2 = gtk_label_new ("");
+       gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER);
+       gtk_table_attach (GTK_TABLE (table), label2, 0, 2, 1, 2, GTK_FILL, 0, 3, 3);
+       gtk_widget_show (label2);
 
        scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
-       gtk_table_attach (GTK_TABLE (table), scrolledwindow, 0, 1, 1, 2, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+       gtk_table_attach (GTK_TABLE (table), scrolledwindow, 0, 1, 2, 3, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
                                                                                          GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
@@ -767,8 +876,8 @@ servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
        gtk_widget_show (tree);
 
        renderer = gtk_cell_renderer_text_new ();
-/*     g_signal_connect (G_OBJECT (renderer), "edited",
-                                                       G_CALLBACK (servlist_editserver_cb), model);*/
+       g_signal_connect (G_OBJECT (renderer), "edited",
+                                                       G_CALLBACK (servlist_editchannel_cb), model);
        gtk_tree_view_insert_column_with_attributes (
                                                                GTK_TREE_VIEW (tree), -1,
                                                                _("Channel"), renderer,
@@ -777,8 +886,8 @@ servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
                                                                NULL);
 
        renderer = gtk_cell_renderer_text_new ();
-/*     g_signal_connect (G_OBJECT (renderer), "edited",
-                                                       G_CALLBACK (servlist_editserver_cb), model);*/
+       g_signal_connect (G_OBJECT (renderer), "edited",
+                                                       G_CALLBACK (servlist_editkey_cb), model);
        gtk_tree_view_insert_column_with_attributes (
                                                                GTK_TREE_VIEW (tree), -1,
                                                                _("Key (Password)"), renderer,
@@ -789,6 +898,54 @@ servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
        gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (tree), 0), TRUE);
        gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (tree), 1), TRUE);
 
+       gtk_tree_sortable_set_sort_column_id ((GtkTreeSortable *)model, 0, GTK_SORT_ASCENDING);
+
+       /* ===BUTTONS=== */
+       vbuttonbox1 = gtk_vbutton_box_new ();
+       gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 3);
+       gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_START);
+       gtk_widget_show (vbuttonbox1);
+       gtk_table_attach (GTK_TABLE (table), vbuttonbox1, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 3, 0);
+
+       buttonadd = gtk_button_new_from_stock ("gtk-add");
+       g_signal_connect (G_OBJECT (buttonadd), "clicked",
+                                                       G_CALLBACK (servlist_addchannel_cb), tree);
+       gtk_widget_show (buttonadd);
+       gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonadd);
+       GTK_WIDGET_SET_FLAGS (buttonadd, GTK_CAN_DEFAULT);
+
+       buttonremove = gtk_button_new_from_stock ("gtk-remove");
+       g_signal_connect (G_OBJECT (buttonremove), "clicked",
+                                                       G_CALLBACK (servlist_deletechannel_cb), tree);
+       gtk_widget_show (buttonremove);
+       gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonremove);
+       GTK_WIDGET_SET_FLAGS (buttonremove, GTK_CAN_DEFAULT);
+
+       buttonedit = gtk_button_new_with_mnemonic (_("_Edit"));
+       g_signal_connect (G_OBJECT (buttonedit), "clicked",
+                                                       G_CALLBACK (servlist_editchannelbutton_cb), tree);
+       gtk_widget_show (buttonedit);
+       gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonedit);
+       GTK_WIDGET_SET_FLAGS (buttonedit, GTK_CAN_DEFAULT);
+
+       bbox = gtk_hbutton_box_new ();
+       gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+       gtk_box_set_spacing (GTK_BOX (bbox), 4);
+       gtk_table_attach (GTK_TABLE (table), bbox, 0, 1, 3, 4, GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 4);
+       gtk_widget_show (bbox);
+
+       wid = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+       g_signal_connect (G_OBJECT (wid), "clicked", G_CALLBACK (gtkutil_destroy), win);
+       gtk_container_add (GTK_CONTAINER (bbox), wid);
+       gtk_widget_show (wid);
+
+       wid = gtk_button_new_from_stock (GTK_STOCK_OK);
+       g_signal_connect (G_OBJECT (wid), "clicked", G_CALLBACK (servlist_autojoineditok_cb), tree);
+       gtk_container_add (GTK_CONTAINER (bbox), wid);
+       gtk_widget_show (wid);
+       gtk_widget_grab_focus (wid);
+       /* =========== */
+
        if (net->autojoin)
        {
                joinlist_split (net->autojoin, &channels, &keys);
@@ -798,8 +955,17 @@ servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
 
                while (clist)
                {
-                       gtk_list_store_append (store, &iter);
-                       gtk_list_store_set (store, &iter, 0, clist->data, 1, klist->data, -1);
+                       if (channel && !add && !rfc_casecmp (channel, clist->data))
+                       {
+                               snprintf (buf, sizeof (buf), _("%s has been removed."), channel);
+                               snprintf (lab, sizeof (lab), "<span foreground=\"#2222DD\">%s</span>", buf);
+                               gtk_label_set_markup (GTK_LABEL (label2), lab);
+                       }
+                       else
+                       {
+                               gtk_list_store_append (store, &iter);
+                               gtk_list_store_set (store, &iter, 0, clist->data, 1, klist->data, 2, TRUE, -1);
+                       }
 
                        klist = klist->next;
                        clist = clist->next;
@@ -808,9 +974,25 @@ servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
                joinlist_free (channels, keys);
        }
 
+       if (channel && add)
+       {
+               servlist_addchannel (tree, channel);
+               snprintf (buf, sizeof (buf), _("%s has been added."), channel);
+               snprintf (lab, sizeof (lab), "<span foreground=\"#2222DD\">%s</span>", buf);
+               gtk_label_set_markup (GTK_LABEL (label2), lab);
+       }
+
+       fav_add_net = net;
+
        gtk_widget_show (win);
 }
 
+static void
+servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
+{
+       servlist_autojoinedit (net, NULL, FALSE);
+}
+
 static void
 servlist_connect_cb (GtkWidget *button, gpointer userdata)
 {
@@ -832,6 +1014,7 @@ servlist_connect_cb (GtkWidget *button, gpointer userdata)
 
        gtk_widget_destroy (serverlist_win);
        serverlist_win = NULL;
+       selected_net = NULL;
 }
 
 static void
@@ -989,6 +1172,7 @@ servlist_delete_cb (GtkWidget *win, GdkEventAny *event, gpointer userdata)
 {
        servlist_savegui ();
        serverlist_win = NULL;
+       selected_net = NULL;
 
        if (sess_list == NULL)
                xchat_exit ();
@@ -1002,6 +1186,7 @@ servlist_close_cb (GtkWidget *button, gpointer userdata)
        servlist_savegui ();
        gtk_widget_destroy (serverlist_win);
        serverlist_win = NULL;
+       selected_net = NULL;
 
        if (sess_list == NULL)
                xchat_exit ();
@@ -1236,7 +1421,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
 #endif
 
        edit_entry_join =
-               servlist_create_entry (table3, _("C_hannels to join:"), 15,
+               servlist_create_entry (table3, _("_Favorite channels:"), 15,
                                                                          net->autojoin, 0,
                                  _("Channels to join, separated by commas, but not spaces!"));
 
index 6848ddb820a9b36a4fdaf684e1e09c619b776f4a..98f6af5969cf9754b59cdf65718b990ea113e1fe 100644 (file)
@@ -572,7 +572,7 @@ fe_add_rawlog (struct server *serv, char *text, int len, int outbound)
 {
 }
 void
-fe_set_topic (struct session *sess, char *topic)
+fe_set_topic (struct session *sess, char *topic, char *stripped_topic)
 {
 }
 void
@@ -631,7 +631,11 @@ fe_notify_update (char *name)
 {
 }
 void
-fe_text_clear (struct session *sess)
+fe_notify_ask (char *name, char *networks)
+{
+}
+void
+fe_text_clear (struct session *sess, int lines)
 {
 }
 void
@@ -775,10 +779,6 @@ fe_set_away (server *serv)
 {
 }
 void
-fe_set_color_paste (session *sess, int status)
-{
-}
-void
 fe_serverlist_open (session *sess)
 {
 }