From 873a3ef04725dadaf78f92c54311d8178ce28462 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Fri, 10 May 2013 23:52:47 +0200 Subject: Replace various network options with universal login method option --- src/common/hexchat.h | 3 +- src/common/proto-irc.c | 24 +++++----- src/common/servlist.c | 47 +++++-------------- src/common/servlist.h | 3 +- src/fe-gtk/servlistgui.c | 117 ++++++++++++++++++++++++++++++----------------- 5 files changed, 99 insertions(+), 95 deletions(-) diff --git a/src/common/hexchat.h b/src/common/hexchat.h index dd30dce6..f3b9ce85 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -528,13 +528,12 @@ typedef struct server char servername[128]; /* what the server says is its name */ char password[86]; char sasluser[32]; /* this is just a buffer for network->user */ - char saslpassword[86]; /* we could reuse password but then we couldn't guarantee NickServ doesn't register first */ char nick[NICKLEN]; char linebuf[2048]; /* RFC says 512 chars including \r\n */ char *last_away_reason; int pos; /* current position in linebuf */ int nickcount; - int nickservtype; /* 0=/MSG nickserv 1=/NICKSERV 2=/NS */ + int loginmethod; /* see login_types[] */ char *chantypes; /* for 005 numeric - free me */ char *chanmodes; /* for 005 numeric - free me */ diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 984f7f20..53225a95 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -49,7 +49,7 @@ irc_login (server *serv, char *user, char *realname) { tcp_sendf (serv, "CAP LS\r\n"); /* start with CAP LS as Charybdis sasl.txt suggests */ - if (serv->password[0]) + if (serv->password[0] && serv->loginmethod == 7) { tcp_sendf (serv, "PASS %s\r\n", serv->password); } @@ -64,21 +64,21 @@ static void irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3) { /* are all ircd authors idiots? */ - switch (serv->nickservtype) + switch (serv->loginmethod) { - case 0: + case 1: tcp_sendf (serv, "PRIVMSG NICKSERV :%s %s%s%s\r\n", cmd, arg1, arg2, arg3); break; - case 1: + case 2: tcp_sendf (serv, "NICKSERV %s %s%s%s\r\n", cmd, arg1, arg2, arg3); break; - case 2: + case 3: tcp_sendf (serv, "NS %s %s%s%s\r\n", cmd, arg1, arg2, arg3); break; - case 3: + case 4: tcp_sendf (serv, "PRIVMSG NS :%s %s%s%s\r\n", cmd, arg1, arg2, arg3); break; - case 4: + case 5: /* why couldn't QuakeNet implement one of the existing ones? */ tcp_sendf (serv, "AUTH %s %s\r\n", arg1, arg2); } @@ -87,7 +87,7 @@ irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3) static void irc_ns_identify (server *serv, char *pass) { - if (serv->nickservtype == 4) /* QuakeNet needs to do everything in its own ways... */ + if (serv->loginmethod == 5) /* QuakeNet needs to do everything in its own ways... */ { irc_nickserv (serv, "", serv->nick, pass, ""); } @@ -100,7 +100,7 @@ irc_ns_identify (server *serv, char *pass) static void irc_ns_ghost (server *serv, char *usname, char *pass) { - if (serv->nickservtype != 4) + if (serv->loginmethod != 5) irc_nickserv (serv, "GHOST", usname, " ", pass); } @@ -1221,7 +1221,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) EMIT_SIGNAL (XP_TE_SASLAUTH, serv->server_session, sess->server->sasluser, NULL, NULL, NULL, 0); tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20); - pass = encode_sasl_pass (sess->server->sasluser, sess->server->saslpassword); + pass = encode_sasl_pass (sess->server->sasluser, sess->server->password); tcp_sendf (sess->server, "AUTHENTICATE %s\r\n", pass); free (pass); } @@ -1259,8 +1259,8 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) strcat (buffer, "extended-join "); want_cap = 1; } - /* if the SASL password is set, request SASL auth */ - if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->saslpassword) != 0) + /* if the SASL password is set AND auth mode is set to SASL, request SASL auth */ + if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->password) != 0 && serv->loginmethod == 6) { strcat (buffer, "sasl "); want_cap = 1; diff --git a/src/common/servlist.c b/src/common/servlist.c index 4b04820b..d49b603e 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -43,7 +43,7 @@ struct defaultserver char *host; char *channel; char *charset; - int nsmode; /* default NickServ type */ + int loginmode; /* default authentication type */ }; static const struct defaultserver def[] = @@ -245,7 +245,7 @@ static const struct defaultserver def[] = {0, "irc.ggn.net"}, {0, "irc.vendetta.com"}, - {"freenode", 0, "#hexchat"}, + {"freenode", 0, "#hexchat", 0, 6}, #ifdef USE_OPENSSL {0, "irc.freenode.net/+6697"}, #endif @@ -618,18 +618,17 @@ servlist_connect (session *sess, ircnet *net, gboolean join) } } - if (net->nstype >= 1) /* once again, make sure gtk_combo_box_get_active() is not bugging us, just in case */ + if (net->logintype) { - serv->nickservtype = net->nstype - 1; /* ircnet->nstype starts at 1, server->nickservtype starts at 0! */ + serv->loginmethod = net->logintype; } else { - serv->nickservtype = 1; /* use /NickServ by default */ + serv->loginmethod = 2; /* use /NickServ by default */ } serv->password[0] = 0; serv->sasluser[0] = 0; - serv->saslpassword[0] = 0; if (net->pass) { @@ -645,11 +644,6 @@ servlist_connect (session *sess, ircnet *net, gboolean join) safe_strcpy (serv->sasluser, net->user, sizeof (serv->sasluser)); } - if (net->saslpass) - { - safe_strcpy (serv->saslpassword, net->saslpass, sizeof (serv->saslpassword)); - } - if (net->flags & FLAG_USE_GLOBAL) { strcpy (serv->nick, prefs.hex_irc_nick1); @@ -941,7 +935,6 @@ servlist_cleanup (void) { net = list->data; free_and_clear (net->pass); - free_and_clear (net->saslpass); free_and_clear (net->nickserv); } } @@ -964,7 +957,6 @@ servlist_net_remove (ircnet *net) if (net->real) free (net->real); free_and_clear (net->pass); - free_and_clear (net->saslpass); if (net->autojoin) free (net->autojoin); if (net->command) @@ -1029,9 +1021,9 @@ servlist_load_defaults (void) free (net->encoding); net->encoding = strdup (def[i].charset); } - if (def[i].nsmode) + if (def[i].loginmode) { - net->nstype = def[i].nsmode; + net->logintype = def[i].loginmode; } if (g_str_hash (def[i].network) == def_hash) { @@ -1100,9 +1092,6 @@ servlist_load (void) case 'P': net->pass = strdup (buf + 2); break; - case 'A': - net->saslpass = strdup (buf + 2); - break; case 'J': net->autojoin = strdup (buf + 2); break; @@ -1134,8 +1123,8 @@ servlist_load (void) case 'B': net->nickserv = strdup (buf + 2); break; - case 'T': - net->nstype = atoi (buf + 2); + case 'L': + net->logintype = atoi (buf + 2); break; } } @@ -1244,26 +1233,12 @@ servlist_save (void) fprintf (fp, "R=%s\n", net->real); if (net->pass) fprintf (fp, "P=%s\n", net->pass); - if (net->saslpass) - fprintf (fp, "A=%s\n", net->saslpass); if (net->autojoin) fprintf (fp, "J=%s\n", net->autojoin); if (net->nickserv) fprintf (fp, "B=%s\n", net->nickserv); - if (net->nstype) - { - if (net->nstype == -1) /* gtk_combo_box_get_active() returns -1 for invalid indices */ - { - net->nstype = 0; /* avoid further crashes for the current session */ - buf = g_strdup_printf (_("Warning: invalid NickServ type. Falling back to default type for network %s."), net->name); - fe_message (buf, FE_MSG_WARN); - g_free (buf); - } - else /* the selection was fine, save it */ - { - fprintf (fp, "T=%d\n", net->nstype); - } - } + if (net->logintype) + fprintf (fp, "L=%d\n", net->logintype); if (net->encoding && g_ascii_strcasecmp (net->encoding, "System") && g_ascii_strcasecmp (net->encoding, "System default")) { diff --git a/src/common/servlist.h b/src/common/servlist.h index b652f463..c70c3871 100644 --- a/src/common/servlist.h +++ b/src/common/servlist.h @@ -33,11 +33,10 @@ typedef struct ircnet char *user; char *real; char *pass; - char *saslpass; char *autojoin; char *command; char *nickserv; - int nstype; + int logintype; char *comment; char *encoding; GSList *servlist; diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 8d480dc4..4af648ca 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -64,7 +64,6 @@ static GtkWidget *edit_entry_user; static GtkWidget *edit_entry_real; static GtkWidget *edit_entry_join; static GtkWidget *edit_entry_pass; -static GtkWidget *edit_entry_saslpass; static GtkWidget *edit_entry_cmd; static GtkWidget *edit_entry_nickserv; static GtkWidget *edit_label_nick; @@ -103,24 +102,53 @@ static const char *pages[]= NULL }; -static const char *nstypes[]= -{ - /* This list is the same as in irc_nickserv(), except starting at 1, because - * the 1st row is not used. We can't use index 0 coz then "if (nstype)" would - * not be evaluated, it would give the same result as NULL (i.e. unset) nstype. - * For unset nstype we have a "Default" entry in place of this placeholder, so - * indices will be correct anyway. - */ - "PLACEHOLDER", /* nstype = 0 */ - "/msg NickServ", /* nstype = 1, nickservtype = 0 */ - "/NickServ", /* nstype = 2, nickservtype = 1 */ - "/NS", /* ... */ +/* This is our dictionary for authentication types. Keep these in sync with + * login_types[]! This allows us to re-order the login type dropdown in the + * network list without breaking config compatibility. + */ +static int login_types_conf[] = +{ + 0, /* default - we don't use this but it makes indexing consistent with login_types[] so it's nice */ + 6, /* SASL */ + 7, /* /pass */ + 1, /* /msg NickServ */ + 2, /* /NickServ */ + 3, /* /NS */ + 4, /* /msg NS */ + 5, /* /auth */ +}; + +static const char *login_types[]= +{ + "Default", + "SASL", + "/pass", + "/msg NickServ", + "/NickServ", + "/NS", "/msg NS", "/auth", NULL - /* This also means that we need to shift these values for irc_nickserv()! */ }; +/* poor man's IndexOf() - find the dropdown string index that belongs to the given config value */ +static int +servlist_get_login_desc_index (int conf_value) +{ + int i; + int length = sizeof (login_types_conf) / sizeof (login_types_conf[0]); /* the number of elements in the conf array */ + + for (i = 0; i < length; i++) + { + if (login_types_conf[i] == conf_value) + { + return i; + } + } + + return 0; /* make the compiler happy */ +} + static void servlist_select_and_show (GtkTreeView *treeview, GtkTreeIter *iter, GtkListStore *store) @@ -500,7 +528,6 @@ servlist_edit_update (ircnet *net) 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); - servlist_update_from_entry (&net->saslpass, edit_entry_saslpass); } static void @@ -1328,9 +1355,12 @@ servlist_combo_cb (GtkEntry *entry, gpointer userdata) } } +/* Fills up the network's authentication type so that it's guaranteed to be either NULL or a valid value. */ static void -servlist_nscombo_cb (GtkEntry *entry, gpointer userdata) +servlist_logintypecombo_cb (GtkEntry *entry, gpointer userdata) { + int index; + if (!selected_net) { return; @@ -1338,7 +1368,15 @@ servlist_nscombo_cb (GtkEntry *entry, gpointer userdata) if (!ignore_changed) { - selected_net->nstype = gtk_combo_box_get_active (GTK_COMBO_BOX (entry)); + index = gtk_combo_box_get_active (GTK_COMBO_BOX (entry)); /* starts at 0, returns -1 for invalid selections */ + + if (index != -1) + { + /* The selection is valid. It can be 0, which is the default type, but we need to allow + * that so that you can revert from other types. servlist_save() will dump 0 anyway. + */ + selected_net->logintype = login_types_conf[index]; + } } } @@ -1364,23 +1402,22 @@ servlist_create_charsetcombo (void) } static GtkWidget * -servlist_create_nstypecombo (void) +servlist_create_logintypecombo (void) { GtkWidget *cb; int i; cb = gtk_combo_box_entry_new_text (); - gtk_combo_box_append_text (GTK_COMBO_BOX (cb), "Default"); - i = 1; /* start with the 2nd row, leave the placeholder 0th element alone */ + i = 0; - while (nstypes[i]) + while (login_types[i]) { - gtk_combo_box_append_text (GTK_COMBO_BOX (cb), (char *)nstypes[i]); + gtk_combo_box_append_text (GTK_COMBO_BOX (cb), (char *)login_types[i]); i++; } - g_signal_connect (G_OBJECT (GTK_BIN (cb)), "changed", G_CALLBACK (servlist_nscombo_cb), NULL); + g_signal_connect (G_OBJECT (GTK_BIN (cb)), "changed", G_CALLBACK (servlist_logintypecombo_cb), NULL); return cb; } @@ -1430,9 +1467,9 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) GtkWidget *label16; GtkWidget *label21; GtkWidget *label34; - GtkWidget *label_nstype; + GtkWidget *label_logintype; GtkWidget *comboboxentry_charset; - GtkWidget *comboboxentry_nstypes; + GtkWidget *comboboxentry_logintypes; GtkWidget *hbox1; GtkWidget *scrolledwindow2; GtkWidget *treeview_servers; @@ -1545,37 +1582,31 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) _("If your nickname requires a password, enter it here. Not all IRC networks support this.")); gtk_entry_set_visibility (GTK_ENTRY (edit_entry_nickserv), FALSE); - label_nstype = gtk_label_new (_("NickServ type:")); - gtk_widget_show (label_nstype); - gtk_table_attach (GTK_TABLE (table3), label_nstype, 1, 2, 18, 19, + label_logintype = gtk_label_new (_("Login method:")); + gtk_widget_show (label_logintype); + gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 18, 19, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label_nstype), 0, 0.5); + gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5); - comboboxentry_nstypes = servlist_create_nstypecombo (); + comboboxentry_logintypes = servlist_create_logintypecombo (); ignore_changed = TRUE; - gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_nstypes)->child), net->nstype ? nstypes[net->nstype] : "Default"); + gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_logintypes)->child), net->logintype ? login_types[servlist_get_login_desc_index (net->logintype)] : login_types[0]); ignore_changed = FALSE; - gtk_widget_show (comboboxentry_nstypes); - gtk_table_attach (GTK_TABLE (table3), comboboxentry_nstypes, 2, 3, 18, 19, + gtk_widget_show (comboboxentry_logintypes); + gtk_table_attach (GTK_TABLE (table3), comboboxentry_logintypes, 2, 3, 18, 19, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); edit_entry_pass = - servlist_create_entry (table3, _("Server password:"), 20, + servlist_create_entry (table3, _("Password:"), 20, net->pass, 0, - _("Password for the server, if in doubt, leave blank.")); + _("Password used for login. If in doubt, leave blank.")); gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE); - edit_entry_saslpass = - servlist_create_entry (table3, _("SASL password:"), 21, - net->saslpass, 0, - _("Password for SASL authentication, if in doubt, leave blank.")); - gtk_entry_set_visibility (GTK_ENTRY (edit_entry_saslpass), FALSE); - label34 = gtk_label_new (_("Character set:")); gtk_widget_show (label34); - gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 22, 23, + gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 21, 22, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5); @@ -1585,7 +1616,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_charset)->child), net->encoding ? net->encoding : "System default"); ignore_changed = FALSE; gtk_widget_show (comboboxentry_charset); - gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 22, 23, + gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 21, 22, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); -- cgit 1.4.1 From 5db1541f9562c1568e1fb6ef0b35df42d261b97a Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 00:49:04 +0200 Subject: Reorganize the network list --- src/fe-gtk/servlistgui.c | 116 +++++++++++++++++------------------------------ 1 file changed, 42 insertions(+), 74 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 4af648ca..a2600174 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -1164,30 +1164,17 @@ servlist_check_cb (GtkWidget *but, gpointer num_p) { if (GTK_TOGGLE_BUTTON (but)->active) { - gtk_widget_hide (edit_label_nick); - gtk_widget_hide (edit_entry_nick); - - gtk_widget_hide (edit_label_nick2); - gtk_widget_hide (edit_entry_nick2); - - gtk_widget_hide (edit_label_user); - gtk_widget_hide (edit_entry_user); - - gtk_widget_hide (edit_label_real); - gtk_widget_hide (edit_entry_real); - } else + gtk_widget_set_sensitive (edit_entry_nick, FALSE); + gtk_widget_set_sensitive (edit_entry_nick2, FALSE); + gtk_widget_set_sensitive (edit_entry_user, FALSE); + gtk_widget_set_sensitive (edit_entry_real, FALSE); + } + else { - gtk_widget_show (edit_label_nick); - gtk_widget_show (edit_entry_nick); - - gtk_widget_show (edit_label_nick2); - gtk_widget_show (edit_entry_nick2); - - gtk_widget_show (edit_label_user); - gtk_widget_show (edit_entry_user); - - gtk_widget_show (edit_label_real); - gtk_widget_show (edit_entry_real); + gtk_widget_set_sensitive (edit_entry_nick, TRUE); + gtk_widget_set_sensitive (edit_entry_nick2, TRUE); + gtk_widget_set_sensitive (edit_entry_user, TRUE); + gtk_widget_set_sensitive (edit_entry_real, TRUE); } } } @@ -1228,7 +1215,7 @@ servlist_create_entry (GtkWidget *table, char *labeltext, int row, gtk_entry_set_text (GTK_ENTRY (entry), def ? def : ""); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); - if (row == 15) /* for "Channels to Join:" */ + if (row == 12) /* for "Favorite channels:" */ { GtkWidget *button, *box; @@ -1463,9 +1450,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) GtkWidget *editwindow; GtkWidget *vbox5; GtkWidget *table3; - GtkWidget *label17; GtkWidget *label16; - GtkWidget *label21; GtkWidget *label34; GtkWidget *label_logintype; GtkWidget *comboboxentry_charset; @@ -1522,69 +1507,59 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) 2, 1, _("Connect to selected server only")); add_tip (check, _("Don't cycle through all the servers when the connection fails.")); - label17 = bold_label (_("Your Details")); - gtk_table_attach (GTK_TABLE (table3), label17, 0, 3, 3, 4, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 3); + servlist_create_check (3, net->flags & FLAG_AUTO_CONNECT, table3, + 3, 1, _("Connect to this network automatically")); + servlist_create_check (4, !(net->flags & FLAG_USE_PROXY), table3, + 4, 1, _("Bypass proxy server")); + check = servlist_create_check (2, net->flags & FLAG_USE_SSL, table3, + 5, 1, _("Use SSL for all the servers on this network")); +#ifndef USE_OPENSSL + gtk_widget_set_sensitive (check, FALSE); +#endif + check = servlist_create_check (5, net->flags & FLAG_ALLOW_INVALID, table3, + 6, 1, _("Accept invalid SSL certificates")); +#ifndef USE_OPENSSL + gtk_widget_set_sensitive (check, FALSE); +#endif servlist_create_check (1, net->flags & FLAG_USE_GLOBAL, table3, - 4, 1, _("Use global user information")); + 7, 1, _("Use global user information")); edit_entry_nick = - servlist_create_entry (table3, _("_Nick name:"), 5, net->nick, + servlist_create_entry (table3, _("_Nick name:"), 8, net->nick, &edit_label_nick, 0); edit_entry_nick2 = - servlist_create_entry (table3, _("Second choice:"), 6, net->nick2, + servlist_create_entry (table3, _("Second choice:"), 9, net->nick2, &edit_label_nick2, 0); edit_entry_user = - servlist_create_entry (table3, _("_User name:"), 7, net->user, + servlist_create_entry (table3, _("_User name:"), 10, net->user, &edit_label_user, 0); edit_entry_real = - servlist_create_entry (table3, _("Rea_l name:"), 8, net->real, + servlist_create_entry (table3, _("Rea_l name:"), 11, net->real, &edit_label_real, 0); - label21 = bold_label (_("Connecting")); - gtk_table_attach (GTK_TABLE (table3), label21, 0, 3, 9, 10, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 3); - - servlist_create_check (3, net->flags & FLAG_AUTO_CONNECT, table3, - 11, 1, _("Auto connect to this network at startup")); - servlist_create_check (4, !(net->flags & FLAG_USE_PROXY), table3, - 12, 1, _("Bypass proxy server")); - check = servlist_create_check (2, net->flags & FLAG_USE_SSL, table3, - 13, 1, _("Use SSL for all the servers on this network")); -#ifndef USE_OPENSSL - gtk_widget_set_sensitive (check, FALSE); -#endif - check = servlist_create_check (5, net->flags & FLAG_ALLOW_INVALID, table3, - 14, 1, _("Accept invalid SSL certificate")); -#ifndef USE_OPENSSL - gtk_widget_set_sensitive (check, FALSE); -#endif - edit_entry_join = - servlist_create_entry (table3, _("_Favorite channels:"), 15, + servlist_create_entry (table3, _("_Favorite channels:"), 12, net->autojoin, 0, _("Channels to join, separated by commas, but not spaces!")); edit_entry_cmd = - servlist_create_entry (table3, _("Connect command:"), 16, + servlist_create_entry (table3, _("Connect command:"), 13, net->command, 0, _("Extra command to execute after connecting. If you need more than one, set this to LOAD -e , where is a text-file full of commands to execute.")); edit_entry_nickserv = - servlist_create_entry (table3, _("NickServ password:"), 17, + servlist_create_entry (table3, _("NickServ password:"), 14, net->nickserv, 0, _("If your nickname requires a password, enter it here. Not all IRC networks support this.")); gtk_entry_set_visibility (GTK_ENTRY (edit_entry_nickserv), FALSE); label_logintype = gtk_label_new (_("Login method:")); gtk_widget_show (label_logintype); - gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 18, 19, + gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 15, 16, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5); @@ -1594,19 +1569,19 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_logintypes)->child), net->logintype ? login_types[servlist_get_login_desc_index (net->logintype)] : login_types[0]); ignore_changed = FALSE; gtk_widget_show (comboboxentry_logintypes); - gtk_table_attach (GTK_TABLE (table3), comboboxentry_logintypes, 2, 3, 18, 19, + gtk_table_attach (GTK_TABLE (table3), comboboxentry_logintypes, 2, 3, 15, 16, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); edit_entry_pass = - servlist_create_entry (table3, _("Password:"), 20, + servlist_create_entry (table3, _("Password:"), 17, net->pass, 0, _("Password used for login. If in doubt, leave blank.")); gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE); label34 = gtk_label_new (_("Character set:")); gtk_widget_show (label34); - gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 21, 22, + gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 18, 19, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5); @@ -1616,7 +1591,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_charset)->child), net->encoding ? net->encoding : "System default"); ignore_changed = FALSE; gtk_widget_show (comboboxentry_charset); - gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 21, 22, + gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 18, 19, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); @@ -1700,17 +1675,10 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) if (net->flags & FLAG_USE_GLOBAL) { - gtk_widget_hide (edit_label_nick); - gtk_widget_hide (edit_entry_nick); - - gtk_widget_hide (edit_label_nick2); - gtk_widget_hide (edit_entry_nick2); - - gtk_widget_hide (edit_label_user); - gtk_widget_hide (edit_entry_user); - - gtk_widget_hide (edit_label_real); - gtk_widget_hide (edit_entry_real); + gtk_widget_set_sensitive (edit_entry_nick, FALSE); + gtk_widget_set_sensitive (edit_entry_nick2, FALSE); + gtk_widget_set_sensitive (edit_entry_user, FALSE); + gtk_widget_set_sensitive (edit_entry_real, FALSE); } gtk_widget_grab_focus (button10); -- cgit 1.4.1 From cf3d1ebb8b9177f5284c4afdeb02cbe820105175 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 01:20:53 +0200 Subject: Skeleton for tabbed ui --- src/fe-gtk/servlistgui.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index a2600174..e0e79fdd 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -1450,13 +1450,14 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) GtkWidget *editwindow; GtkWidget *vbox5; GtkWidget *table3; - GtkWidget *label16; GtkWidget *label34; GtkWidget *label_logintype; GtkWidget *comboboxentry_charset; GtkWidget *comboboxentry_logintypes; GtkWidget *hbox1; GtkWidget *scrolledwindow2; + GtkWidget *scrolledwindow4; + GtkWidget *scrolledwindow5; GtkWidget *treeview_servers; GtkWidget *vbuttonbox1; GtkWidget *buttonadd; @@ -1466,11 +1467,11 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) GtkWidget *hbuttonbox4; GtkWidget *button10; GtkWidget *check; + GtkWidget *notebook; GtkTreeModel *model; GtkListStore *store; GtkCellRenderer *renderer; char buf[128]; - char buf2[128 + 8]; editwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width (GTK_CONTAINER (editwindow), 4); @@ -1493,16 +1494,6 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_table_set_row_spacings (GTK_TABLE (table3), 2); gtk_table_set_col_spacings (GTK_TABLE (table3), 8); - snprintf (buf, sizeof (buf), _("Servers for %s"), net->name); - snprintf (buf2, sizeof (buf2), "%s", buf); - label16 = gtk_label_new (buf2); - gtk_widget_show (label16); - gtk_table_attach (GTK_TABLE (table3), label16, 0, 3, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 3); - gtk_label_set_use_markup (GTK_LABEL (label16), TRUE); - gtk_misc_set_alignment (GTK_MISC (label16), 0, 0.5); - check = servlist_create_check (0, !(net->flags & FLAG_CYCLE), table3, 2, 1, _("Connect to selected server only")); add_tip (check, _("Don't cycle through all the servers when the connection fails.")); @@ -1603,11 +1594,34 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow2); + scrolledwindow4 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow4); + scrolledwindow5 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow5); + +#if 0 /* FIXME! */ + notebook = gtk_notebook_new (); + gtk_widget_show (notebook); + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow2, gtk_label_new ("Servers")); + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow4, gtk_label_new ("Favorite channels")); + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow5, gtk_label_new ("Connect commands")); + gtk_box_pack_start (GTK_BOX (hbox1), notebook, TRUE, TRUE, 0); +#else gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow2, TRUE, TRUE, 0); +#endif + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow4), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow4), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow5), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow5), + GTK_SHADOW_IN); store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); model = GTK_TREE_MODEL (store); -- cgit 1.4.1 From a98b95923b4cfc2b05bc570036f810d127aa6e90 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 02:00:32 +0200 Subject: Get rid of this unnecessary buffer --- src/common/hexchat.h | 1 - src/common/proto-irc.c | 18 ++++++++++++++++-- src/common/servlist.c | 10 ---------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/common/hexchat.h b/src/common/hexchat.h index f3b9ce85..0a449bfa 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -527,7 +527,6 @@ typedef struct server char hostname[128]; /* real ip number */ char servername[128]; /* what the server says is its name */ char password[86]; - char sasluser[32]; /* this is just a buffer for network->user */ char nick[NICKLEN]; char linebuf[2048]; /* RFC says 512 chars including \r\n */ char *last_away_reason; diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 53225a95..5ea2c75c 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -42,6 +42,7 @@ #include "util.h" #include "hexchatc.h" #include "url.h" +#include "servlist.h" static void @@ -1218,10 +1219,23 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) if (strstr (word_eol[5], "sasl") != 0) { serv->have_sasl = TRUE; - EMIT_SIGNAL (XP_TE_SASLAUTH, serv->server_session, sess->server->sasluser, NULL, NULL, NULL, 0); + EMIT_SIGNAL + ( + XP_TE_SASLAUTH, + serv->server_session, + (((ircnet *)sess->server->network)->user) ? (((ircnet *)sess->server->network)->user) : prefs.hex_irc_user_name, + NULL, + NULL, + NULL, + 0 + ); tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20); - pass = encode_sasl_pass (sess->server->sasluser, sess->server->password); + pass = encode_sasl_pass + ( + (((ircnet *)sess->server->network)->user) ? (((ircnet *)sess->server->network)->user) : prefs.hex_irc_user_name, + sess->server->password + ); tcp_sendf (sess->server, "AUTHENTICATE %s\r\n", pass); free (pass); } diff --git a/src/common/servlist.c b/src/common/servlist.c index d49b603e..9386bf16 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -628,22 +628,12 @@ servlist_connect (session *sess, ircnet *net, gboolean join) } serv->password[0] = 0; - serv->sasluser[0] = 0; if (net->pass) { safe_strcpy (serv->password, net->pass, sizeof (serv->password)); } - if (net->flags & FLAG_USE_GLOBAL || net->user == NULL) - { - strcpy (serv->sasluser, prefs.hex_irc_user_name); - } - else - { - safe_strcpy (serv->sasluser, net->user, sizeof (serv->sasluser)); - } - if (net->flags & FLAG_USE_GLOBAL) { strcpy (serv->nick, prefs.hex_irc_nick1); -- cgit 1.4.1 From 7b0b86c9f7841217d4156503fbe004fdea54caeb Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 02:40:08 +0200 Subject: Nuke nickserv password field and some cosmetics --- src/common/inbound.c | 47 +++++++++++++++++++++++++++++++++++------------ src/common/plugin.c | 5 ----- src/common/proto-irc.c | 2 ++ src/common/servlist.c | 7 ------- src/common/servlist.h | 1 - src/fe-gtk/servlistgui.c | 12 ++++-------- 6 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index 29eaf754..2383955e 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1367,6 +1367,20 @@ inbound_exec_eom_cmd (char *str, void *sess) return 1; } +static int +inbound_nickserv_login (server *serv) +{ + /* this could grow ugly, but let's hope there won't be new NickServ types */ + if (serv->loginmethod >= 1 && serv->loginmethod <= 5) + { + return 1; + } + else + { + return 0; + } +} + void inbound_login_end (session *sess, char *text) { @@ -1385,34 +1399,43 @@ inbound_login_end (session *sess, char *text) { /* there may be more than 1, separated by \n */ if (((ircnet *)serv->network)->command) - token_foreach (((ircnet *)serv->network)->command, '\n', - inbound_exec_eom_cmd, sess); + { + token_foreach (((ircnet *)serv->network)->command, '\n', inbound_exec_eom_cmd, sess); + } /* send nickserv password */ - if (((ircnet *)serv->network)->nickserv) - serv->p_ns_identify (serv, ((ircnet *)serv->network)->nickserv); + if (((ircnet *)serv->network)->pass && inbound_nickserv_login (serv)) + { + serv->p_ns_identify (serv, ((ircnet *)serv->network)->pass); + } } /* send JOIN now or wait? */ - if (serv->network && ((ircnet *)serv->network)->nickserv && - prefs.hex_irc_join_delay) - serv->joindelay_tag = fe_timeout_add (prefs.hex_irc_join_delay * 1000, - check_autojoin_channels, serv); + if (serv->network && ((ircnet *)serv->network)->pass && prefs.hex_irc_join_delay && inbound_nickserv_login (serv)) + { + serv->joindelay_tag = fe_timeout_add (prefs.hex_irc_join_delay * 1000, check_autojoin_channels, serv); + } else + { check_autojoin_channels (serv); + } + if (serv->supports_watch || serv->supports_monitor) + { notify_send_watches (serv); + } + serv->end_of_motd = TRUE; } + if (prefs.hex_irc_skip_motd && !serv->motd_skipped) { serv->motd_skipped = TRUE; - EMIT_SIGNAL (XP_TE_MOTDSKIP, serv->server_session, NULL, NULL, - NULL, NULL, 0); + EMIT_SIGNAL (XP_TE_MOTDSKIP, serv->server_session, NULL, NULL, NULL, NULL, 0); return; } - EMIT_SIGNAL (XP_TE_MOTD, serv->server_session, text, NULL, - NULL, NULL, 0); + + EMIT_SIGNAL (XP_TE_MOTD, serv->server_session, text, NULL, NULL, NULL, 0); } void diff --git a/src/common/plugin.c b/src/common/plugin.c index 686f9749..61d5cb40 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -1111,11 +1111,6 @@ hexchat_get_info (hexchat_plugin *ph, const char *id) case 0x339763: /* nick */ return sess->server->nick; - case 0x438fdf9: /* nickserv */ - if (sess->server->network) - return ((ircnet *)sess->server->network)->nickserv; - return NULL; - case 0xca022f43: /* server */ if (!sess->server->connected) return NULL; diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 5ea2c75c..7c73b5ab 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -102,7 +102,9 @@ static void irc_ns_ghost (server *serv, char *usname, char *pass) { if (serv->loginmethod != 5) + { irc_nickserv (serv, "GHOST", usname, " ", pass); + } } static void diff --git a/src/common/servlist.c b/src/common/servlist.c index 9386bf16..f30dcf48 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -925,7 +925,6 @@ servlist_cleanup (void) { net = list->data; free_and_clear (net->pass); - free_and_clear (net->nickserv); } } @@ -951,7 +950,6 @@ servlist_net_remove (ircnet *net) free (net->autojoin); if (net->command) free (net->command); - free_and_clear (net->nickserv); if (net->comment) free (net->comment); if (net->encoding) @@ -1110,9 +1108,6 @@ servlist_load (void) case 'S': /* new server/hostname for this network */ servlist_server_add (net, buf + 2); break; - case 'B': - net->nickserv = strdup (buf + 2); - break; case 'L': net->logintype = atoi (buf + 2); break; @@ -1225,8 +1220,6 @@ servlist_save (void) fprintf (fp, "P=%s\n", net->pass); if (net->autojoin) fprintf (fp, "J=%s\n", net->autojoin); - if (net->nickserv) - fprintf (fp, "B=%s\n", net->nickserv); if (net->logintype) fprintf (fp, "L=%d\n", net->logintype); if (net->encoding && g_ascii_strcasecmp (net->encoding, "System") && diff --git a/src/common/servlist.h b/src/common/servlist.h index c70c3871..c38c5129 100644 --- a/src/common/servlist.h +++ b/src/common/servlist.h @@ -35,7 +35,6 @@ typedef struct ircnet char *pass; char *autojoin; char *command; - char *nickserv; int logintype; char *comment; char *encoding; diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index e0e79fdd..faa42772 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -65,7 +65,6 @@ static GtkWidget *edit_entry_real; static GtkWidget *edit_entry_join; static GtkWidget *edit_entry_pass; static GtkWidget *edit_entry_cmd; -static GtkWidget *edit_entry_nickserv; static GtkWidget *edit_label_nick; static GtkWidget *edit_label_nick2; static GtkWidget *edit_label_real; @@ -105,6 +104,10 @@ static const char *pages[]= /* This is our dictionary for authentication types. Keep these in sync with * login_types[]! This allows us to re-order the login type dropdown in the * network list without breaking config compatibility. + * + * Also make sure inbound_nickserv_login() won't break, i.e. if you add a new + * type that is NickServ-based, add it there as well so that HexChat knows to + * treat it as such. */ static int login_types_conf[] = { @@ -526,7 +529,6 @@ servlist_edit_update (ircnet *net) servlist_update_from_entry (&net->autojoin, edit_entry_join); 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); } @@ -1542,12 +1544,6 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) net->command, 0, _("Extra command to execute after connecting. If you need more than one, set this to LOAD -e , where is a text-file full of commands to execute.")); - edit_entry_nickserv = - servlist_create_entry (table3, _("NickServ password:"), 14, - net->nickserv, 0, - _("If your nickname requires a password, enter it here. Not all IRC networks support this.")); - gtk_entry_set_visibility (GTK_ENTRY (edit_entry_nickserv), FALSE); - label_logintype = gtk_label_new (_("Login method:")); gtk_widget_show (label_logintype); gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 15, 16, -- cgit 1.4.1 From 0e1da0d33d14e2a1b107493cbc65cb321cefadcf Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 03:02:31 +0200 Subject: Also disable labels, not just entries --- src/fe-gtk/servlistgui.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index faa42772..4ebf8c19 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -1167,16 +1167,31 @@ servlist_check_cb (GtkWidget *but, gpointer num_p) if (GTK_TOGGLE_BUTTON (but)->active) { gtk_widget_set_sensitive (edit_entry_nick, FALSE); + gtk_widget_set_sensitive (edit_label_nick, FALSE); + gtk_widget_set_sensitive (edit_entry_nick2, FALSE); + gtk_widget_set_sensitive (edit_label_nick2, FALSE); + gtk_widget_set_sensitive (edit_entry_user, FALSE); + gtk_widget_set_sensitive (edit_label_user, FALSE); + gtk_widget_set_sensitive (edit_entry_real, FALSE); + gtk_widget_set_sensitive (edit_label_real, FALSE); + } else { gtk_widget_set_sensitive (edit_entry_nick, TRUE); + gtk_widget_set_sensitive (edit_label_nick, TRUE); + gtk_widget_set_sensitive (edit_entry_nick2, TRUE); + gtk_widget_set_sensitive (edit_label_nick2, TRUE); + gtk_widget_set_sensitive (edit_entry_user, TRUE); + gtk_widget_set_sensitive (edit_label_user, TRUE); + gtk_widget_set_sensitive (edit_entry_real, TRUE); + gtk_widget_set_sensitive (edit_label_real, TRUE); } } } @@ -1686,9 +1701,16 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) if (net->flags & FLAG_USE_GLOBAL) { gtk_widget_set_sensitive (edit_entry_nick, FALSE); + gtk_widget_set_sensitive (edit_label_nick, FALSE); + gtk_widget_set_sensitive (edit_entry_nick2, FALSE); + gtk_widget_set_sensitive (edit_label_nick2, FALSE); + gtk_widget_set_sensitive (edit_entry_user, FALSE); + gtk_widget_set_sensitive (edit_label_user, FALSE); + gtk_widget_set_sensitive (edit_entry_real, FALSE); + gtk_widget_set_sensitive (edit_label_real, FALSE); } gtk_widget_grab_focus (button10); -- cgit 1.4.1 From 2e1425451dcd2515950c5ab3705b274101f14b33 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 03:13:50 +0200 Subject: Remove some redundancy --- src/fe-gtk/servlistgui.c | 58 +++++++++++++++--------------------------------- 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 4ebf8c19..53903f84 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -1037,6 +1037,22 @@ servlist_autojoinedit (ircnet *net, char *channel, gboolean add) gtk_widget_show (win); } +static void +servlist_toggle_global_user (gboolean sensitive) +{ + gtk_widget_set_sensitive (edit_entry_nick, sensitive); + gtk_widget_set_sensitive (edit_label_nick, sensitive); + + gtk_widget_set_sensitive (edit_entry_nick2, sensitive); + gtk_widget_set_sensitive (edit_label_nick2, sensitive); + + gtk_widget_set_sensitive (edit_entry_user, sensitive); + gtk_widget_set_sensitive (edit_label_user, sensitive); + + gtk_widget_set_sensitive (edit_entry_real, sensitive); + gtk_widget_set_sensitive (edit_label_real, sensitive); +} + static void servlist_autojoinedit_cb (GtkWidget *button, ircnet *net) { @@ -1164,35 +1180,7 @@ servlist_check_cb (GtkWidget *but, gpointer num_p) if ((1 << num) == FLAG_USE_GLOBAL) { - if (GTK_TOGGLE_BUTTON (but)->active) - { - gtk_widget_set_sensitive (edit_entry_nick, FALSE); - gtk_widget_set_sensitive (edit_label_nick, FALSE); - - gtk_widget_set_sensitive (edit_entry_nick2, FALSE); - gtk_widget_set_sensitive (edit_label_nick2, FALSE); - - gtk_widget_set_sensitive (edit_entry_user, FALSE); - gtk_widget_set_sensitive (edit_label_user, FALSE); - - gtk_widget_set_sensitive (edit_entry_real, FALSE); - gtk_widget_set_sensitive (edit_label_real, FALSE); - - } - else - { - gtk_widget_set_sensitive (edit_entry_nick, TRUE); - gtk_widget_set_sensitive (edit_label_nick, TRUE); - - gtk_widget_set_sensitive (edit_entry_nick2, TRUE); - gtk_widget_set_sensitive (edit_label_nick2, TRUE); - - gtk_widget_set_sensitive (edit_entry_user, TRUE); - gtk_widget_set_sensitive (edit_label_user, TRUE); - - gtk_widget_set_sensitive (edit_entry_real, TRUE); - gtk_widget_set_sensitive (edit_label_real, TRUE); - } + servlist_toggle_global_user (!GTK_TOGGLE_BUTTON (but)->active); } } @@ -1700,17 +1688,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) if (net->flags & FLAG_USE_GLOBAL) { - gtk_widget_set_sensitive (edit_entry_nick, FALSE); - gtk_widget_set_sensitive (edit_label_nick, FALSE); - - gtk_widget_set_sensitive (edit_entry_nick2, FALSE); - gtk_widget_set_sensitive (edit_label_nick2, FALSE); - - gtk_widget_set_sensitive (edit_entry_user, FALSE); - gtk_widget_set_sensitive (edit_label_user, FALSE); - - gtk_widget_set_sensitive (edit_entry_real, FALSE); - gtk_widget_set_sensitive (edit_label_real, FALSE); + servlist_toggle_global_user (FALSE); } gtk_widget_grab_focus (button10); -- cgit 1.4.1 From cdc2bb021680e674c83ea2dfab0bf1582e00697d Mon Sep 17 00:00:00 2001 From: TingPing Date: Sat, 11 May 2013 09:20:03 -0400 Subject: serverlistgui cleanup --- src/fe-gtk/servlistgui.c | 442 ++++++++++++++++++++++++++++++----------------- 1 file changed, 281 insertions(+), 161 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 53903f84..4a3f28fb 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -40,7 +40,6 @@ /* servlistgui.c globals */ static GtkWidget *serverlist_win = NULL; static GtkWidget *networks_tree; /* network TreeView */ -static int ignore_changed = FALSE; #ifdef WIN32 static int win_width = 324; static int win_height = 426; @@ -56,20 +55,25 @@ static GtkWidget *entry_nick3; static GtkWidget *entry_guser; /* static GtkWidget *entry_greal; */ +enum { + SERVER_TREE, + CHANNEL_TREE, + CMD_TREE, + N_TREES, +}; + /* edit area */ static GtkWidget *edit_win; static GtkWidget *edit_entry_nick; static GtkWidget *edit_entry_nick2; static GtkWidget *edit_entry_user; static GtkWidget *edit_entry_real; -static GtkWidget *edit_entry_join; static GtkWidget *edit_entry_pass; -static GtkWidget *edit_entry_cmd; static GtkWidget *edit_label_nick; static GtkWidget *edit_label_nick2; static GtkWidget *edit_label_real; static GtkWidget *edit_label_user; -static GtkWidget *edit_tree; +static GtkWidget *edit_trees[N_TREES]; static ircnet *selected_net = NULL; static ircserver *selected_serv = NULL; @@ -125,12 +129,12 @@ static const char *login_types[]= { "Default", "SASL", - "/pass", - "/msg NickServ", - "/NickServ", - "/NS", - "/msg NS", - "/auth", + "Server Password", + "Message NickServ", + "NickServ", + "NS", + "Message NS", + "AUTH", NULL }; @@ -173,6 +177,79 @@ servlist_select_and_show (GtkTreeView *treeview, GtkTreeIter *iter, } } +static void +servlist_channel_save (void) +{ + GtkTreeModel *model; + GtkTreeIter iter; + char *channel, *key; + char *autojoin; + GSList *channels = NULL, *keys = NULL; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CHANNEL_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)); + } + + autojoin = joinlist_merge (channels, keys); + if (autojoin) + { + if (selected_net->autojoin) + g_free(selected_net->autojoin); + strcpy (selected_net->autojoin, autojoin); + g_free (autojoin); + } + + /* this does g_free too */ + joinlist_free (channels, keys); +} + +static void +servlist_channels_populate (ircnet *net, GtkWidget *treeview) +{ + GtkTreeModel *model; + GtkListStore *store; + GSList *channels, *keys; + GSList *clist, *klist; + GtkTreeIter iter; + + if (net->autojoin) + { + joinlist_split (net->autojoin, &channels, &keys); + + clist = channels; + klist = keys; + + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview))); + + while (clist) + { + 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; + } + + joinlist_free (channels, keys); + } +} + static void servlist_servers_populate (ircnet *net, GtkWidget *treeview) { @@ -292,7 +369,7 @@ servlist_start_editing (GtkTreeView *tree) } static void -servlist_addserver_cb (GtkWidget *item, GtkWidget *treeview) +servlist_addserver (void) { GtkTreeIter iter; GtkListStore *store; @@ -300,19 +377,53 @@ servlist_addserver_cb (GtkWidget *item, GtkWidget *treeview) if (!selected_net) return; - store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[SERVER_TREE]))); servlist_server_add (selected_net, "newserver/6667"); gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, 0, "newserver/6667", 1, 1, -1); /* select this server */ - servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store); + servlist_select_and_show (GTK_TREE_VIEW (edit_trees[SERVER_TREE]), &iter, store); /*servlist_start_editing (GTK_TREE_VIEW (treeview));*/ servlist_server_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL); } +static void +servlist_addcommand (void) +{ + GtkTreeIter iter; + GtkListStore *store; + + if (!selected_net) + return; + + store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CMD_TREE]))); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, "", 1, 1, -1); + + servlist_select_and_show (GTK_TREE_VIEW (edit_trees[CMD_TREE]), &iter, store); + + servlist_server_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL); +} + +static void +servlist_deletecommand (void) +{ + GtkTreeSelection *sel; + GtkTreeModel *model; + GtkTreeIter iter; + + /* find the selected item in the GUI */ + model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CMD_TREE])); + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[CMD_TREE])); + + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); +} + static void servlist_addnet_cb (GtkWidget *item, GtkTreeView *treeview) { @@ -378,7 +489,7 @@ servlist_move_server (ircserver *serv, int delta) { selected_net->servlist = g_slist_remove (selected_net->servlist, serv); selected_net->servlist = g_slist_insert (selected_net->servlist, serv, pos); - servlist_servers_populate (selected_net, edit_tree); + servlist_servers_populate (selected_net, edit_trees[SERVER_TREE]); } } } @@ -526,9 +637,6 @@ servlist_edit_update (ircnet *net) servlist_update_from_entry (&net->nick2, edit_entry_nick2); servlist_update_from_entry (&net->user, edit_entry_user); servlist_update_from_entry (&net->real, edit_entry_real); - - servlist_update_from_entry (&net->autojoin, edit_entry_join); - servlist_update_from_entry (&net->command, edit_entry_cmd); servlist_update_from_entry (&net->pass, edit_entry_pass); } @@ -565,12 +673,12 @@ servlist_edit_cb (GtkWidget *but, gpointer none) edit_win = servlist_open_edit (serverlist_win, selected_net); gtkutil_set_icon (edit_win); - servlist_servers_populate (selected_net, edit_tree); - g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_tree))), + servlist_servers_populate (selected_net, edit_trees[SERVER_TREE]); + g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[SERVER_TREE]))), "changed", G_CALLBACK (servlist_server_row_cb), NULL); g_signal_connect (G_OBJECT (edit_win), "delete_event", G_CALLBACK (servlist_editwin_delete_cb), 0); - g_signal_connect (G_OBJECT (edit_tree), "key_press_event", + g_signal_connect (G_OBJECT (edit_trees[SERVER_TREE]), "key_press_event", G_CALLBACK (servlist_serv_keypress_cb), 0); gtk_widget_show (edit_win); } @@ -610,7 +718,7 @@ servlist_deleteserver (ircserver *serv, GtkTreeModel *model) return; /* remove from GUI */ - sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_tree)); + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[SERVER_TREE])); if (gtk_tree_selection_get_selected (sel, &model, &iter)) gtk_list_store_remove (GTK_LIST_STORE (model), &iter); @@ -620,13 +728,13 @@ servlist_deleteserver (ircserver *serv, GtkTreeModel *model) } static void -servlist_editserverbutton_cb (GtkWidget *item, gpointer none) +servlist_editbutton_cb (GtkWidget *item, GtkNotebook *notebook) { - servlist_start_editing (GTK_TREE_VIEW (edit_tree)); + servlist_start_editing (GTK_TREE_VIEW (edit_trees[gtk_notebook_get_current_page(notebook)])); } static void -servlist_deleteserver_cb (GtkWidget *item, gpointer none) +servlist_deleteserver_cb (void) { GtkTreeSelection *sel; GtkTreeModel *model; @@ -636,8 +744,8 @@ servlist_deleteserver_cb (GtkWidget *item, gpointer none) int pos; /* find the selected item in the GUI */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_tree)); - sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_tree)); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[SERVER_TREE])); + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[SERVER_TREE])); if (gtk_tree_selection_get_selected (sel, &model, &iter)) { @@ -649,6 +757,21 @@ servlist_deleteserver_cb (GtkWidget *item, gpointer none) } } +static void +servlist_editcommand_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 ircnet * servlist_find_selected_net (GtkTreeSelection *sel) { @@ -702,6 +825,7 @@ servlist_savegui (void) if (sp) sp[0] = 0; /* spaces will break the login */ /* strcpy (prefs.hex_irc_real_name, GTK_ENTRY (entry_greal)->text); */ + //FIXME: Save commands(and load them) and favorites servlist_save (); save_config (); /* For nicks stored in hexchat.conf */ @@ -756,105 +880,78 @@ servlist_editkey_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, GtkT } static void -servlist_addchannel (GtkWidget *tree, char *channel) +servlist_addchannel (char *channel) { GtkTreeIter iter; GtkListStore *store; - store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (tree)); + store = GTK_LIST_STORE(gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CHANNEL_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")); + servlist_select_and_show (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE]), &iter, store); + servlist_start_editing (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE])); } static void -servlist_deletechannel_cb (GtkWidget *item, GtkWidget *tree) +servlist_deletechannel (void) { 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)); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE])); + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[CHANNEL_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_addbutton_cb (GtkWidget *item, GtkNotebook *notebook) { - servlist_start_editing (GTK_TREE_VIEW (tree)); + switch (gtk_notebook_get_current_page (notebook)) + { + case SERVER_TREE: + servlist_addserver (); + break; + case CHANNEL_TREE: + servlist_addchannel ("#channel"); + break; + case CMD_TREE: + servlist_addcommand (); + break; + default: + break; + } } -/* save everything from the GUI to the GtkEntry */ - static void -servlist_autojoineditok_cb (GtkWidget *button, GtkWidget *tree) +servlist_deletebutton_cb (GtkWidget *item, GtkNotebook *notebook) { - 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 (edit_win && selected_net) - gtk_entry_set_text (GTK_ENTRY (edit_entry_join), autojoin); - else + switch (gtk_notebook_get_current_page (notebook)) { - if (fav_add_net->autojoin) - free (fav_add_net->autojoin); - fav_add_net->autojoin = strdup (autojoin); + case SERVER_TREE: + servlist_deleteserver_cb (); + break; + case CHANNEL_TREE: + servlist_deletechannel (); + break; + case CMD_TREE: + servlist_deletecommand (); + break; + default: + break; } - g_free (autojoin); - } - - /* this does g_free too */ - joinlist_free (channels, keys); - - if (fav_add_net) - servlist_save (); } void servlist_autojoinedit (ircnet *net, char *channel, gboolean add) { +#if 0 // FIXME: adding favorites from menu GtkWidget *win; GtkWidget *scrolledwindow; GtkTreeModel *model; @@ -995,7 +1092,6 @@ servlist_autojoinedit (ircnet *net, char *channel, gboolean add) gtk_widget_show (wid); gtk_widget_grab_focus (wid); /* =========== */ - if (net->autojoin) { joinlist_split (net->autojoin, &channels, &keys); @@ -1026,15 +1122,14 @@ servlist_autojoinedit (ircnet *net, char *channel, gboolean add) if (channel && add) { - servlist_addchannel (tree, channel); + servlist_addchannel (channel); snprintf (buf, sizeof (buf), _("%s has been added."), channel); snprintf (lab, sizeof (lab), "%s", buf); gtk_label_set_markup (GTK_LABEL (label2), lab); } fav_add_net = net; - - gtk_widget_show (win); +#endif } static void @@ -1339,17 +1434,14 @@ servlist_combo_cb (GtkEntry *entry, gpointer userdata) if (!selected_net) return; - if (!ignore_changed) - { - if (selected_net->encoding) - free (selected_net->encoding); - selected_net->encoding = strdup (entry->text); - } + if (selected_net->encoding) + free (selected_net->encoding); + selected_net->encoding = strdup (entry->text); } /* Fills up the network's authentication type so that it's guaranteed to be either NULL or a valid value. */ static void -servlist_logintypecombo_cb (GtkEntry *entry, gpointer userdata) +servlist_logintypecombo_cb (GtkComboBox *cb, gpointer userdata) { int index; @@ -1358,17 +1450,14 @@ servlist_logintypecombo_cb (GtkEntry *entry, gpointer userdata) return; } - if (!ignore_changed) - { - index = gtk_combo_box_get_active (GTK_COMBO_BOX (entry)); /* starts at 0, returns -1 for invalid selections */ + index = gtk_combo_box_get_active (cb); /* starts at 0, returns -1 for invalid selections */ - if (index != -1) - { - /* The selection is valid. It can be 0, which is the default type, but we need to allow - * that so that you can revert from other types. servlist_save() will dump 0 anyway. - */ - selected_net->logintype = login_types_conf[index]; - } + if (index != -1) + { + /* The selection is valid. It can be 0, which is the default type, but we need to allow + * that so that you can revert from other types. servlist_save() will dump 0 anyway. + */ + selected_net->logintype = login_types_conf[index]; } } @@ -1379,14 +1468,17 @@ servlist_create_charsetcombo (void) GtkWidget *cb; int i; - cb = gtk_combo_box_entry_new_text (); - gtk_combo_box_append_text (GTK_COMBO_BOX (cb), "System default"); + cb = gtk_combo_box_text_new_with_entry (); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (cb), "System default"); i = 0; while (pages[i]) { - gtk_combo_box_append_text (GTK_COMBO_BOX (cb), (char *)pages[i]); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (cb), (char *)pages[i]); i++; } + + gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN(cb))), selected_net->encoding ? selected_net->encoding : "System default"); + g_signal_connect (G_OBJECT (GTK_BIN (cb)->child), "changed", G_CALLBACK (servlist_combo_cb), NULL); @@ -1399,16 +1491,18 @@ servlist_create_logintypecombo (void) GtkWidget *cb; int i; - cb = gtk_combo_box_entry_new_text (); + cb = gtk_combo_box_text_new (); i = 0; while (login_types[i]) { - gtk_combo_box_append_text (GTK_COMBO_BOX (cb), (char *)login_types[i]); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (cb), (char *)login_types[i]); i++; } + gtk_combo_box_set_active (GTK_COMBO_BOX (cb), servlist_get_login_desc_index(selected_net->logintype)); + g_signal_connect (G_OBJECT (GTK_BIN (cb)), "changed", G_CALLBACK (servlist_logintypecombo_cb), NULL); return cb; @@ -1458,12 +1552,14 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) GtkWidget *label34; GtkWidget *label_logintype; GtkWidget *comboboxentry_charset; - GtkWidget *comboboxentry_logintypes; + GtkWidget *combobox_logintypes; GtkWidget *hbox1; GtkWidget *scrolledwindow2; GtkWidget *scrolledwindow4; GtkWidget *scrolledwindow5; GtkWidget *treeview_servers; + GtkWidget *treeview_channels; + GtkWidget *treeview_commands; GtkWidget *vbuttonbox1; GtkWidget *buttonadd; GtkWidget *buttonremove; @@ -1488,13 +1584,12 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_window_set_modal (GTK_WINDOW (editwindow), TRUE); gtk_window_set_type_hint (GTK_WINDOW (editwindow), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_role (GTK_WINDOW (editwindow), "editserv"); + gtk_window_set_resizable(GTK_WINDOW (editwindow), FALSE); vbox5 = gtk_vbox_new (FALSE, 0); - gtk_widget_show (vbox5); gtk_container_add (GTK_CONTAINER (editwindow), vbox5); table3 = gtk_table_new (17, 3, FALSE); - gtk_widget_show (table3); gtk_box_pack_start (GTK_BOX (vbox5), table3, TRUE, TRUE, 0); gtk_table_set_row_spacings (GTK_TABLE (table3), 2); gtk_table_set_col_spacings (GTK_TABLE (table3), 8); @@ -1537,29 +1632,14 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) servlist_create_entry (table3, _("Rea_l name:"), 11, net->real, &edit_label_real, 0); - edit_entry_join = - servlist_create_entry (table3, _("_Favorite channels:"), 12, - net->autojoin, 0, - _("Channels to join, separated by commas, but not spaces!")); - - edit_entry_cmd = - servlist_create_entry (table3, _("Connect command:"), 13, - net->command, 0, - _("Extra command to execute after connecting. If you need more than one, set this to LOAD -e , where is a text-file full of commands to execute.")); - label_logintype = gtk_label_new (_("Login method:")); - gtk_widget_show (label_logintype); gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 15, 16, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5); - comboboxentry_logintypes = servlist_create_logintypecombo (); - ignore_changed = TRUE; - gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_logintypes)->child), net->logintype ? login_types[servlist_get_login_desc_index (net->logintype)] : login_types[0]); - ignore_changed = FALSE; - gtk_widget_show (comboboxentry_logintypes); - gtk_table_attach (GTK_TABLE (table3), comboboxentry_logintypes, 2, 3, 15, 16, + combobox_logintypes = servlist_create_logintypecombo (); + gtk_table_attach (GTK_TABLE (table3), combobox_logintypes, 2, 3, 15, 16, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); @@ -1570,44 +1650,30 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE); label34 = gtk_label_new (_("Character set:")); - gtk_widget_show (label34); gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 18, 19, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5); comboboxentry_charset = servlist_create_charsetcombo (); - ignore_changed = TRUE; - gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_charset)->child), net->encoding ? net->encoding : "System default"); - ignore_changed = FALSE; - gtk_widget_show (comboboxentry_charset); gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 18, 19, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); hbox1 = gtk_hbox_new (FALSE, 0); - gtk_widget_show (hbox1); gtk_table_attach (GTK_TABLE (table3), hbox1, 1, 3, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolledwindow2); scrolledwindow4 = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolledwindow4); scrolledwindow5 = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolledwindow5); -#if 0 /* FIXME! */ notebook = gtk_notebook_new (); - gtk_widget_show (notebook); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow2, gtk_label_new ("Servers")); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow4, gtk_label_new ("Favorite channels")); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow5, gtk_label_new ("Connect commands")); gtk_box_pack_start (GTK_BOX (hbox1), notebook, TRUE, TRUE, 0); -#else - gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow2, TRUE, TRUE, 0); -#endif gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); @@ -1622,13 +1688,15 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow5), GTK_SHADOW_IN); + + /* Server Tree */ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); model = GTK_TREE_MODEL (store); - edit_tree = treeview_servers = gtk_tree_view_new_with_model (model); + edit_trees[SERVER_TREE] = treeview_servers = gtk_tree_view_new_with_model (model); g_object_unref (model); - gtk_widget_show (treeview_servers); gtk_container_add (GTK_CONTAINER (scrolledwindow2), treeview_servers); + gtk_widget_set_size_request (treeview_servers, -1, 80); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_servers), FALSE); @@ -1642,39 +1710,90 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) "editable", 1, NULL); + + /* Channel Tree */ + store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); + model = GTK_TREE_MODEL (store); + + edit_trees[CHANNEL_TREE] = treeview_channels = gtk_tree_view_new_with_model (model); + g_object_unref (model); + gtk_container_add (GTK_CONTAINER (scrolledwindow4), treeview_channels); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_channels), TRUE); + + renderer = gtk_cell_renderer_text_new (); + g_signal_connect (G_OBJECT (renderer), "edited", + G_CALLBACK (servlist_editchannel_cb), model); + gtk_tree_view_insert_column_with_attributes ( + GTK_TREE_VIEW (treeview_channels), -1, + _("Channel"), renderer, + "text", 0, + "editable", 2, + NULL); + + renderer = gtk_cell_renderer_text_new (); + g_signal_connect (G_OBJECT (renderer), "edited", + G_CALLBACK (servlist_editkey_cb), model); + gtk_tree_view_insert_column_with_attributes ( + GTK_TREE_VIEW (treeview_channels), -1, + _("Key (Password)"), renderer, + "text", 1, + "editable", 2, + NULL); + + gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (treeview_channels), 0), TRUE); + gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (treeview_channels), 1), TRUE); + gtk_tree_sortable_set_sort_column_id ((GtkTreeSortable *)model, 0, GTK_SORT_ASCENDING); + servlist_channels_populate (selected_net, treeview_channels); + + /* Command Tree */ + store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); + model = GTK_TREE_MODEL (store); + + edit_trees[CMD_TREE] = treeview_commands = gtk_tree_view_new_with_model (model); + g_object_unref (model); + gtk_container_add (GTK_CONTAINER (scrolledwindow5), treeview_commands); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_commands), + FALSE); + + renderer = gtk_cell_renderer_text_new (); + g_signal_connect (G_OBJECT (renderer), "edited", + G_CALLBACK (servlist_editcommand_cb), model); + gtk_tree_view_insert_column_with_attributes ( + GTK_TREE_VIEW (treeview_commands), -1, + 0, renderer, + "text", 0, + "editable", 1, + NULL); + + /* Button Box */ 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_box_pack_start (GTK_BOX (hbox1), vbuttonbox1, FALSE, FALSE, 3); buttonadd = gtk_button_new_from_stock ("gtk-add"); g_signal_connect (G_OBJECT (buttonadd), "clicked", - G_CALLBACK (servlist_addserver_cb), edit_tree); - gtk_widget_show (buttonadd); + G_CALLBACK (servlist_addbutton_cb), notebook); 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_deleteserver_cb), NULL); - gtk_widget_show (buttonremove); + G_CALLBACK (servlist_deletebutton_cb), notebook); 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_editserverbutton_cb), NULL); - gtk_widget_show (buttonedit); + G_CALLBACK (servlist_editbutton_cb), notebook); gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonedit); GTK_WIDGET_SET_FLAGS (buttonedit, GTK_CAN_DEFAULT); + gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_END); hseparator2 = gtk_hseparator_new (); - gtk_widget_show (hseparator2); gtk_box_pack_start (GTK_BOX (vbox5), hseparator2, FALSE, FALSE, 8); hbuttonbox4 = gtk_hbutton_box_new (); - gtk_widget_show (hbuttonbox4); gtk_box_pack_start (GTK_BOX (vbox5), hbuttonbox4, FALSE, FALSE, 0); gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox4), GTK_BUTTONBOX_END); @@ -1682,7 +1801,6 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) button10 = gtk_button_new_from_stock ("gtk-close"); g_signal_connect (G_OBJECT (button10), "clicked", G_CALLBACK (servlist_edit_close_cb), 0); - gtk_widget_show (button10); gtk_container_add (GTK_CONTAINER (hbuttonbox4), button10); GTK_WIDGET_SET_FLAGS (button10, GTK_CAN_DEFAULT); @@ -1694,6 +1812,8 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_widget_grab_focus (button10); gtk_widget_grab_default (button10); + gtk_widget_show_all (editwindow); + return editwindow; } -- cgit 1.4.1 From b33f70571ea6c7ceec3c11ed36155ab59ab49646 Mon Sep 17 00:00:00 2001 From: TingPing Date: Sat, 11 May 2013 09:31:56 -0400 Subject: fix error --- src/fe-gtk/servlistgui.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 4a3f28fb..70976957 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -757,21 +757,6 @@ servlist_deleteserver_cb (void) } } -static void -servlist_editcommand_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 ircnet * servlist_find_selected_net (GtkTreeSelection *sel) { @@ -879,6 +864,21 @@ servlist_editkey_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, GtkT gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, newval, -1); } +static void +servlist_editcommand_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_addchannel (char *channel) { -- cgit 1.4.1 From 68fa03348336036ded68e18f20efc62368f41c9e Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 11:54:42 +0200 Subject: Re-enable resize --- src/fe-gtk/servlistgui.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 70976957..2f1ba674 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -1501,7 +1501,7 @@ servlist_create_logintypecombo (void) i++; } - gtk_combo_box_set_active (GTK_COMBO_BOX (cb), servlist_get_login_desc_index(selected_net->logintype)); + gtk_combo_box_set_active (GTK_COMBO_BOX (cb), servlist_get_login_desc_index (selected_net->logintype)); g_signal_connect (G_OBJECT (GTK_BIN (cb)), "changed", G_CALLBACK (servlist_logintypecombo_cb), NULL); @@ -1584,7 +1584,6 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_window_set_modal (GTK_WINDOW (editwindow), TRUE); gtk_window_set_type_hint (GTK_WINDOW (editwindow), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_role (GTK_WINDOW (editwindow), "editserv"); - gtk_window_set_resizable(GTK_WINDOW (editwindow), FALSE); vbox5 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (editwindow), vbox5); -- cgit 1.4.1 From 5c663adf3518701db794e11c3d332423f51b9f0e Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 12:56:26 +0200 Subject: Reorganize a bit and fix spacing --- src/fe-gtk/servlistgui.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 2f1ba674..fa8c4827 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -1315,6 +1315,7 @@ servlist_create_entry (GtkWidget *table, char *labeltext, int row, gtk_entry_set_text (GTK_ENTRY (entry), def ? def : ""); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); +#if 0 /* FIXME */ if (row == 12) /* for "Favorite channels:" */ { GtkWidget *button, *box; @@ -1333,9 +1334,12 @@ servlist_create_entry (GtkWidget *table, char *labeltext, int row, } else { +#endif gtk_table_attach (GTK_TABLE (table), entry, 2, 3, row, row+1, GTK_FILL|GTK_EXPAND, 0, 0, 0); +#if 0 } +#endif return entry; } @@ -1623,39 +1627,39 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) servlist_create_entry (table3, _("Second choice:"), 9, net->nick2, &edit_label_nick2, 0); - edit_entry_user = - servlist_create_entry (table3, _("_User name:"), 10, net->user, - &edit_label_user, 0); - edit_entry_real = - servlist_create_entry (table3, _("Rea_l name:"), 11, net->real, + servlist_create_entry (table3, _("Rea_l name:"), 10, net->real, &edit_label_real, 0); - label_logintype = gtk_label_new (_("Login method:")); - gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 15, 16, + edit_entry_user = + servlist_create_entry (table3, _("_User name:"), 11, net->user, + &edit_label_user, 0); + + label_logintype = gtk_label_new (_("Login method:")); + gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 12, 13, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5); combobox_logintypes = servlist_create_logintypecombo (); - gtk_table_attach (GTK_TABLE (table3), combobox_logintypes, 2, 3, 15, 16, + gtk_table_attach (GTK_TABLE (table3), combobox_logintypes, 2, 3, 12, 13, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); edit_entry_pass = - servlist_create_entry (table3, _("Password:"), 17, + servlist_create_entry (table3, _("Password:"), 14, net->pass, 0, _("Password used for login. If in doubt, leave blank.")); gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE); label34 = gtk_label_new (_("Character set:")); - gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 18, 19, + gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 15, 16, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5); comboboxentry_charset = servlist_create_charsetcombo (); - gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 18, 19, + gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 15, 16, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0); -- cgit 1.4.1 From 712eb5428e1b2aa2a9edfb3eb95375f0fca29ff5 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 13:06:25 +0200 Subject: GtkComboBoxText requires GTK+ 2.24, dump code for older versions --- configure.ac | 2 +- share/doc/readme.md | 2 +- src/fe-gtk/dccgui.c | 8 ++++---- src/fe-gtk/fe-gtk.c | 12 ++++-------- src/fe-gtk/menu.c | 4 ---- src/fe-gtk/plugin-tray.c | 4 ---- src/fe-gtk/xtext.c | 4 ---- 7 files changed, 10 insertions(+), 26 deletions(-) diff --git a/configure.ac b/configure.ac index 88f8464d..910565e9 100644 --- a/configure.ac +++ b/configure.ac @@ -199,7 +199,7 @@ dnl ********************************************************************* # we might get undefined macro without this test if test "$gtkfe" = yes ; then - AM_PATH_GTK_2_0(2.14.0, havegtk=yes, havegtk=no) + AM_PATH_GTK_2_0(2.24.0, havegtk=yes, havegtk=no) if test "$havegtk" = no; then gtkfe=no diff --git a/share/doc/readme.md b/share/doc/readme.md index ec2a6d9f..9d9cc91c 100644 --- a/share/doc/readme.md +++ b/share/doc/readme.md @@ -21,7 +21,7 @@ in general. HexChat runs on most BSD and POSIX compliant operating systems. ## Requirements: - * GTK+ 2.14 + * GTK+ 2.24 * GLib 2.14 HexChat is known to work on, at least: diff --git a/src/fe-gtk/dccgui.c b/src/fe-gtk/dccgui.c index 0fb2e7e5..24d3bcbf 100644 --- a/src/fe-gtk/dccgui.c +++ b/src/fe-gtk/dccgui.c @@ -685,14 +685,14 @@ dcc_detail_label (char *text, GtkWidget *box, int num) static void dcc_exp_cb (GtkWidget *exp, GtkWidget *box) { -#if GTK_CHECK_VERSION(2,20,0) if (gtk_widget_get_visible (box)) -#else - if (GTK_WIDGET_VISIBLE (box)) -#endif + { gtk_widget_hide (box); + } else + { gtk_widget_show (box); + } } static void diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index 0c3583d3..d737b744 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -897,15 +897,15 @@ fe_gui_info (session *sess, int info_type) switch (info_type) { case 0: /* window status */ -#if GTK_CHECK_VERSION(2,20,0) if (!gtk_widget_get_visible (GTK_WIDGET (sess->gui->window))) -#else - if (!GTK_WIDGET_VISIBLE (GTK_WIDGET (sess->gui->window))) -#endif + { return 2; /* hidden (iconified or systray) */ + } if (gtk_window_is_active (GTK_WINDOW (sess->gui->window))) + { return 1; /* active/focused */ + } return 0; /* normal (no keyboard focus or behind a window) */ } @@ -920,11 +920,7 @@ fe_gui_info_ptr (session *sess, int info_type) { case 0: /* native window pointer (for plugins) */ #ifdef WIN32 -#if GTK_CHECK_VERSION(2,24,8) return gdk_win32_window_get_impl_hwnd (sess->gui->window->window); -#else - return GDK_WINDOW_HWND (sess->gui->window->window); -#endif #else return sess->gui->window; #endif diff --git a/src/fe-gtk/menu.c b/src/fe-gtk/menu.c index f0f49730..79e1bad8 100644 --- a/src/fe-gtk/menu.c +++ b/src/fe-gtk/menu.c @@ -1729,11 +1729,7 @@ static gboolean menu_canacaccel (GtkWidget *widget, guint signal_id, gpointer user_data) { /* GTK2.2 behaviour */ -#if GTK_CHECK_VERSION(2,20,0) return gtk_widget_is_sensitive (widget); -#else - return GTK_WIDGET_IS_SENSITIVE (widget); -#endif } /* === STUFF FOR /MENU === */ diff --git a/src/fe-gtk/plugin-tray.c b/src/fe-gtk/plugin-tray.c index 501dc0cd..d0196bcb 100644 --- a/src/fe-gtk/plugin-tray.c +++ b/src/fe-gtk/plugin-tray.c @@ -414,11 +414,7 @@ tray_toggle_visibility (gboolean force_hide) if (!win) return FALSE; -#if GTK_CHECK_VERSION(2,20,0) if (force_hide || gtk_widget_get_visible (GTK_WIDGET (win))) -#else - if (force_hide || GTK_WIDGET_VISIBLE (win)) -#endif { if (prefs.hex_gui_tray_away) hexchat_command (ph, "ALLSERV AWAY"); diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c index e151524d..94db4687 100644 --- a/src/fe-gtk/xtext.c +++ b/src/fe-gtk/xtext.c @@ -1034,11 +1034,7 @@ gtk_xtext_realize (GtkWidget * widget) gdk_window_set_user_data (widget->window, widget); -#if GTK_CHECK_VERSION(2,24,0) xtext->depth = gdk_window_get_visual (widget->window)->depth; -#else - xtext->depth = gdk_drawable_get_visual (widget->window)->depth; -#endif val.subwindow_mode = GDK_INCLUDE_INFERIORS; val.graphics_exposures = 0; -- cgit 1.4.1 From fde85c79dfa81f704da7f41d0284feea245ea7be Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 15:22:28 +0200 Subject: Reorganize the network editor --- src/fe-gtk/servlistgui.c | 137 ++++++++++++++++++----------------------------- 1 file changed, 51 insertions(+), 86 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index fa8c4827..f0c04f6e 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -36,6 +36,8 @@ #include "pixmaps.h" #include "fkeys.h" +#define SERVLIST_X_PADDING 4 /* horizontal paddig in the network editor */ +#define SERVLIST_Y_PADDING 0 /* vertical padding in the network editor */ /* servlistgui.c globals */ static GtkWidget *serverlist_win = NULL; @@ -222,7 +224,6 @@ servlist_channel_save (void) static void servlist_channels_populate (ircnet *net, GtkWidget *treeview) { - GtkTreeModel *model; GtkListStore *store; GSList *channels, *keys; GSList *clist, *klist; @@ -1288,8 +1289,7 @@ servlist_create_check (int num, int state, GtkWidget *table, int row, int col, c gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (but), state); g_signal_connect (G_OBJECT (but), "toggled", G_CALLBACK (servlist_check_cb), GINT_TO_POINTER (num)); - gtk_table_attach (GTK_TABLE (table), but, col, col+2, row, row+1, - GTK_FILL|GTK_EXPAND, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), but, col, col+2, row, row+1, GTK_FILL|GTK_EXPAND, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); gtk_widget_show (but); return but; @@ -1305,8 +1305,7 @@ servlist_create_entry (GtkWidget *table, char *labeltext, int row, if (label_ret) *label_ret = label; gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, 1, 2, row, row+1, - GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, GTK_FILL, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); entry = gtk_entry_new (); @@ -1329,14 +1328,12 @@ servlist_create_entry (GtkWidget *table, char *labeltext, int row, gtk_box_pack_end (GTK_BOX (box), button, 0, 0, 0); gtk_widget_show_all (box); - gtk_table_attach (GTK_TABLE (table), box, 2, 3, row, row+1, - GTK_FILL|GTK_EXPAND, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), box, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); } else { #endif - gtk_table_attach (GTK_TABLE (table), entry, 2, 3, row, row+1, - GTK_FILL|GTK_EXPAND, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), entry, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); #if 0 } #endif @@ -1592,81 +1589,9 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) vbox5 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (editwindow), vbox5); - table3 = gtk_table_new (17, 3, FALSE); - gtk_box_pack_start (GTK_BOX (vbox5), table3, TRUE, TRUE, 0); - gtk_table_set_row_spacings (GTK_TABLE (table3), 2); - gtk_table_set_col_spacings (GTK_TABLE (table3), 8); - - check = servlist_create_check (0, !(net->flags & FLAG_CYCLE), table3, - 2, 1, _("Connect to selected server only")); - add_tip (check, _("Don't cycle through all the servers when the connection fails.")); - - servlist_create_check (3, net->flags & FLAG_AUTO_CONNECT, table3, - 3, 1, _("Connect to this network automatically")); - servlist_create_check (4, !(net->flags & FLAG_USE_PROXY), table3, - 4, 1, _("Bypass proxy server")); - check = servlist_create_check (2, net->flags & FLAG_USE_SSL, table3, - 5, 1, _("Use SSL for all the servers on this network")); -#ifndef USE_OPENSSL - gtk_widget_set_sensitive (check, FALSE); -#endif - check = servlist_create_check (5, net->flags & FLAG_ALLOW_INVALID, table3, - 6, 1, _("Accept invalid SSL certificates")); -#ifndef USE_OPENSSL - gtk_widget_set_sensitive (check, FALSE); -#endif - - servlist_create_check (1, net->flags & FLAG_USE_GLOBAL, table3, - 7, 1, _("Use global user information")); - - edit_entry_nick = - servlist_create_entry (table3, _("_Nick name:"), 8, net->nick, - &edit_label_nick, 0); - - edit_entry_nick2 = - servlist_create_entry (table3, _("Second choice:"), 9, net->nick2, - &edit_label_nick2, 0); - - edit_entry_real = - servlist_create_entry (table3, _("Rea_l name:"), 10, net->real, - &edit_label_real, 0); - - edit_entry_user = - servlist_create_entry (table3, _("_User name:"), 11, net->user, - &edit_label_user, 0); - - label_logintype = gtk_label_new (_("Login method:")); - gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 12, 13, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5); - - combobox_logintypes = servlist_create_logintypecombo (); - gtk_table_attach (GTK_TABLE (table3), combobox_logintypes, 2, 3, 12, 13, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - - edit_entry_pass = - servlist_create_entry (table3, _("Password:"), 14, - net->pass, 0, - _("Password used for login. If in doubt, leave blank.")); - gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE); - - label34 = gtk_label_new (_("Character set:")); - gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 15, 16, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5); - - comboboxentry_charset = servlist_create_charsetcombo (); - gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 15, 16, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - + /* tabs and buttons */ hbox1 = gtk_hbox_new (FALSE, 0); - gtk_table_attach (GTK_TABLE (table3), hbox1, 1, 3, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + gtk_box_pack_start (GTK_BOX (vbox5), hbox1, TRUE, TRUE, 4); scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); scrolledwindow4 = gtk_scrolled_window_new (NULL, NULL); @@ -1676,7 +1601,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow2, gtk_label_new ("Servers")); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow4, gtk_label_new ("Favorite channels")); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow5, gtk_label_new ("Connect commands")); - gtk_box_pack_start (GTK_BOX (hbox1), notebook, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox1), notebook, TRUE, TRUE, SERVLIST_X_PADDING); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); @@ -1793,13 +1718,53 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) GTK_WIDGET_SET_FLAGS (buttonedit, GTK_CAN_DEFAULT); gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_END); + /* checkboxes and entries */ + table3 = gtk_table_new (13, 2, FALSE); + gtk_box_pack_start (GTK_BOX (vbox5), table3, TRUE, TRUE, 0); + gtk_table_set_row_spacings (GTK_TABLE (table3), 2); + gtk_table_set_col_spacings (GTK_TABLE (table3), 8); + + check = servlist_create_check (0, !(net->flags & FLAG_CYCLE), table3, 0, 0, _("Connect to selected server only")); + add_tip (check, _("Don't cycle through all the servers when the connection fails.")); + servlist_create_check (3, net->flags & FLAG_AUTO_CONNECT, table3, 1, 0, _("Connect to this network automatically")); + servlist_create_check (4, !(net->flags & FLAG_USE_PROXY), table3, 2, 0, _("Bypass proxy server")); + check = servlist_create_check (2, net->flags & FLAG_USE_SSL, table3, 3, 0, _("Use SSL for all the servers on this network")); +#ifndef USE_OPENSSL + gtk_widget_set_sensitive (check, FALSE); +#endif + check = servlist_create_check (5, net->flags & FLAG_ALLOW_INVALID, table3, 4, 0, _("Accept invalid SSL certificates")); +#ifndef USE_OPENSSL + gtk_widget_set_sensitive (check, FALSE); +#endif + servlist_create_check (1, net->flags & FLAG_USE_GLOBAL, table3, 5, 0, _("Use global user information")); + + edit_entry_nick = servlist_create_entry (table3, _("_Nick name:"), 6, net->nick, &edit_label_nick, 0); + edit_entry_nick2 = servlist_create_entry (table3, _("Second choice:"), 7, net->nick2, &edit_label_nick2, 0); + edit_entry_real = servlist_create_entry (table3, _("Rea_l name:"), 8, net->real, &edit_label_real, 0); + edit_entry_user = servlist_create_entry (table3, _("_User name:"), 9, net->user, &edit_label_user, 0); + + label_logintype = gtk_label_new (_("Login method:")); + gtk_table_attach (GTK_TABLE (table3), label_logintype, 0, 1, 10, 11, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), SERVLIST_X_PADDING, SERVLIST_Y_PADDING); + gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5); + combobox_logintypes = servlist_create_logintypecombo (); + gtk_table_attach (GTK_TABLE (table3), combobox_logintypes, 1, 2, 10, 11, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 4, 2); + + edit_entry_pass = servlist_create_entry (table3, _("Password:"), 11, net->pass, 0, _("Password used for login. If in doubt, leave blank.")); + gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE); + + label34 = gtk_label_new (_("Character set:")); + gtk_table_attach (GTK_TABLE (table3), label34, 0, 1, 12, 13, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), SERVLIST_X_PADDING, SERVLIST_Y_PADDING); + gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5); + comboboxentry_charset = servlist_create_charsetcombo (); + gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 1, 2, 12, 13, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 4, 2); + + /* rule and close button */ hseparator2 = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox5), hseparator2, FALSE, FALSE, 8); hbuttonbox4 = gtk_hbutton_box_new (); gtk_box_pack_start (GTK_BOX (vbox5), hbuttonbox4, FALSE, FALSE, 0); - gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox4), - GTK_BUTTONBOX_END); + gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox4), GTK_BUTTONBOX_END); button10 = gtk_button_new_from_stock ("gtk-close"); g_signal_connect (G_OBJECT (button10), "clicked", -- cgit 1.4.1 From 85c7e07351b9538e480dc2899fdeb8a70ecf8e74 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 15:58:52 +0200 Subject: Set up window sizes correctly --- src/fe-gtk/servlistgui.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index f0c04f6e..bccd9dc7 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -41,14 +41,12 @@ /* servlistgui.c globals */ static GtkWidget *serverlist_win = NULL; -static GtkWidget *networks_tree; /* network TreeView */ -#ifdef WIN32 -static int win_width = 324; -static int win_height = 426; -#else -static int win_width = 364; -static int win_height = 478; -#endif +static GtkWidget *networks_tree; /* network TreeView */ + +static int netlist_win_width = 0; /* don't hardcode pixels, just use as much as needed by default, save if resized */ +static int netlist_win_height = 0; +static int netedit_win_width = 0; +static int netedit_win_height = 0; /* global user info */ static GtkWidget *entry_nick1; @@ -662,7 +660,15 @@ static gboolean servlist_configure_cb (GtkWindow *win, GdkEventConfigure *event, gpointer none) { /* remember the window size */ - gtk_window_get_size (win, &win_width, &win_height); + gtk_window_get_size (win, &netlist_win_width, &netlist_win_height); + return FALSE; +} + +static gboolean +servlist_edit_configure_cb (GtkWindow *win, GdkEventConfigure *event, gpointer none) +{ + /* remember the window size */ + gtk_window_get_size (win, &netedit_win_width, &netedit_win_height); return FALSE; } @@ -679,6 +685,8 @@ servlist_edit_cb (GtkWidget *but, gpointer none) "changed", G_CALLBACK (servlist_server_row_cb), NULL); g_signal_connect (G_OBJECT (edit_win), "delete_event", G_CALLBACK (servlist_editwin_delete_cb), 0); + g_signal_connect (G_OBJECT (edit_win), "configure_event", + G_CALLBACK (servlist_edit_configure_cb), 0); g_signal_connect (G_OBJECT (edit_trees[SERVER_TREE]), "key_press_event", G_CALLBACK (servlist_serv_keypress_cb), 0); gtk_widget_show (edit_win); @@ -983,7 +991,6 @@ servlist_autojoinedit (ircnet *net, char *channel, gboolean add) win = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width (GTK_CONTAINER (win), 4); gtk_window_set_title (GTK_WINDOW (win), _(DISPLAY_NAME": 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); if (edit_win) gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (edit_win)); @@ -1579,7 +1586,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_container_set_border_width (GTK_CONTAINER (editwindow), 4); snprintf (buf, sizeof (buf), _(DISPLAY_NAME": Edit %s"), net->name); gtk_window_set_title (GTK_WINDOW (editwindow), buf); - gtk_window_set_default_size (GTK_WINDOW (editwindow), 354, 0); + gtk_window_set_default_size (GTK_WINDOW (editwindow), netedit_win_width, netedit_win_height); gtk_window_set_position (GTK_WINDOW (editwindow), GTK_WIN_POS_MOUSE); gtk_window_set_transient_for (GTK_WINDOW (editwindow), GTK_WINDOW (parent)); gtk_window_set_modal (GTK_WINDOW (editwindow), TRUE); @@ -1826,7 +1833,7 @@ servlist_open_networks (void) servlist = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width (GTK_CONTAINER (servlist), 4); gtk_window_set_title (GTK_WINDOW (servlist), _(DISPLAY_NAME": Network List")); - gtk_window_set_default_size (GTK_WINDOW (servlist), win_width, win_height); + gtk_window_set_default_size (GTK_WINDOW (servlist), netlist_win_width, netlist_win_height); gtk_window_set_position (GTK_WINDOW (servlist), GTK_WIN_POS_MOUSE); gtk_window_set_role (GTK_WINDOW (servlist), "servlist"); gtk_window_set_type_hint (GTK_WINDOW (servlist), GDK_WINDOW_TYPE_HINT_DIALOG); -- cgit 1.4.1 From d5e8fa47f0e3211cf415a0ce5f5c75224fa5c776 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 16:21:38 +0200 Subject: Allocate all extra vertical space to the treeviews --- src/fe-gtk/servlistgui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index bccd9dc7..4e014c5a 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -1727,7 +1727,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) /* checkboxes and entries */ table3 = gtk_table_new (13, 2, FALSE); - gtk_box_pack_start (GTK_BOX (vbox5), table3, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox5), table3, FALSE, FALSE, 0); gtk_table_set_row_spacings (GTK_TABLE (table3), 2); gtk_table_set_col_spacings (GTK_TABLE (table3), 8); -- cgit 1.4.1 From 4d30512e057f8f078e64542941fa1f9b4a24d470 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 16:30:45 +0200 Subject: Fix layout when resized --- src/fe-gtk/servlistgui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 4e014c5a..2cd74da2 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -1608,6 +1608,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow2, gtk_label_new ("Servers")); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow4, gtk_label_new ("Favorite channels")); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow5, gtk_label_new ("Connect commands")); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_BOTTOM); gtk_box_pack_start (GTK_BOX (hbox1), notebook, TRUE, TRUE, SERVLIST_X_PADDING); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), @@ -1723,7 +1724,6 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) G_CALLBACK (servlist_editbutton_cb), notebook); gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonedit); GTK_WIDGET_SET_FLAGS (buttonedit, GTK_CAN_DEFAULT); - gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_END); /* checkboxes and entries */ table3 = gtk_table_new (13, 2, FALSE); -- cgit 1.4.1 From af03fa3c7c78ce51017c9e71369e637d91f95208 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 20:06:22 +0200 Subject: Fix connect commands --- configure.ac | 2 +- share/doc/readme.md | 2 +- src/common/inbound.c | 10 ++- src/common/servlist.c | 88 +++++++++++++++----- src/common/servlist.h | 14 +++- src/fe-gtk/servlistgui.c | 209 +++++++++++++++++++++++++++++++++++------------ 6 files changed, 248 insertions(+), 77 deletions(-) diff --git a/configure.ac b/configure.ac index 910565e9..56a7abe1 100644 --- a/configure.ac +++ b/configure.ac @@ -184,7 +184,7 @@ dnl ********************************************************************* dnl ** GLIB ************************************************************* dnl ********************************************************************* -AM_PATH_GLIB_2_0(2.14.0, glib=yes, glib=no) +AM_PATH_GLIB_2_0(2.28.0, glib=yes, glib=no) if test "$glib" = no; then AC_MSG_ERROR(Cannot find GLib!) fi diff --git a/share/doc/readme.md b/share/doc/readme.md index 9d9cc91c..dc66e0ac 100644 --- a/share/doc/readme.md +++ b/share/doc/readme.md @@ -22,7 +22,7 @@ in general. HexChat runs on most BSD and POSIX compliant operating systems. ## Requirements: * GTK+ 2.24 - * GLib 2.14 + * GLib 2.28 HexChat is known to work on, at least: diff --git a/src/common/inbound.c b/src/common/inbound.c index 2383955e..4f23403f 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1384,6 +1384,8 @@ inbound_nickserv_login (server *serv) void inbound_login_end (session *sess, char *text) { + GSList *cmdlist; + commandentry *cmd; server *serv = sess->server; if (!serv->end_of_motd) @@ -1398,9 +1400,13 @@ inbound_login_end (session *sess, char *text) if (serv->network) { /* there may be more than 1, separated by \n */ - if (((ircnet *)serv->network)->command) + + cmdlist = ((ircnet *)serv->network)->commandlist; + while (cmdlist) { - token_foreach (((ircnet *)serv->network)->command, '\n', inbound_exec_eom_cmd, sess); + cmd = cmdlist->data; + inbound_exec_eom_cmd (cmd->command, sess); + cmdlist = cmdlist->next; } /* send nickserv password */ diff --git a/src/common/servlist.c b/src/common/servlist.c index f30dcf48..ed822925 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -814,6 +814,29 @@ servlist_server_find (ircnet *net, char *name, int *pos) return NULL; } +commandentry * +servlist_command_find (ircnet *net, char *cmd, int *pos) +{ + GSList *list = net->commandlist; + commandentry *entry; + int i = 0; + + while (list) + { + entry = list->data; + if (strcmp (entry->command, cmd) == 0) + { + if (pos) + *pos = i; + return entry; + } + i++; + list = list->next; + } + + return NULL; +} + /* find a network (e.g. (ircnet *) to "FreeNode") from a hostname (e.g. "irc.eu.freenode.net") */ @@ -881,6 +904,20 @@ servlist_server_add (ircnet *net, char *name) return serv; } +commandentry * +servlist_command_add (ircnet *net, char *cmd) +{ + commandentry *entry; + + entry = malloc (sizeof (commandentry)); + memset (entry, 0, sizeof (commandentry)); + entry->command = strdup (cmd); + + net->commandlist = g_slist_append (net->commandlist, entry); + + return entry; +} + void servlist_server_remove (ircnet *net, ircserver *serv) { @@ -901,6 +938,14 @@ servlist_server_remove_all (ircnet *net) } } +void +servlist_command_remove (ircnet *net, commandentry *entry) +{ + free (entry->command); + free (entry); + net->commandlist = g_slist_remove (net->commandlist, entry); +} + static void free_and_clear (char *str) { @@ -948,8 +993,8 @@ servlist_net_remove (ircnet *net) free_and_clear (net->pass); if (net->autojoin) free (net->autojoin); - if (net->command) - free (net->command); + if (net->commandlist) + g_slist_free_full (net->commandlist, (GDestroyNotify) g_free); if (net->comment) free (net->comment); if (net->encoding) @@ -963,7 +1008,9 @@ servlist_net_remove (ircnet *net) { serv = list->data; if (serv->network == net) + { serv->network = NULL; + } list = list->next; } } @@ -1037,7 +1084,6 @@ servlist_load (void) FILE *fp; char buf[2048]; int len; - char *tmp; ircnet *net = NULL; /* simple migration we will keep for a short while */ @@ -1084,9 +1130,9 @@ servlist_load (void) net->autojoin = strdup (buf + 2); break; case 'C': - if (net->command) + /*if (net->command) { - /* concat extra commands with a \n separator */ + // concat extra commands with a \n separator tmp = net->command; net->command = malloc (strlen (tmp) + strlen (buf + 2) + 2); strcpy (net->command, tmp); @@ -1095,6 +1141,8 @@ servlist_load (void) free (tmp); } else net->command = strdup (buf + 2); + */ + servlist_command_add (net, buf + 2); break; case 'F': net->flags = atoi (buf + 2); @@ -1161,13 +1209,6 @@ servlist_check_encoding (char *charset) return FALSE; } -static int -servlist_write_ccmd (char *str, void *fp) -{ - return fprintf (fp, "C=%s\n", (str[0] == '/') ? str + 1 : str); -} - - int servlist_save (void) { @@ -1175,8 +1216,10 @@ servlist_save (void) char *buf; ircnet *net; ircserver *serv; + commandentry *cmd; GSList *list; - GSList *hlist; + GSList *netlist; + GSList *cmdlist; #ifndef WIN32 int first = FALSE; @@ -1235,17 +1278,22 @@ servlist_save (void) } } - if (net->command) - token_foreach (net->command, '\n', servlist_write_ccmd, fp); - fprintf (fp, "F=%d\nD=%d\n", net->flags, net->selected); - hlist = net->servlist; - while (hlist) + netlist = net->servlist; + while (netlist) { - serv = hlist->data; + serv = netlist->data; fprintf (fp, "S=%s\n", serv->hostname); - hlist = hlist->next; + netlist = netlist->next; + } + + cmdlist = net->commandlist; + while (cmdlist) + { + cmd = cmdlist->data; + fprintf (fp, "C=%s\n", cmd->command); + cmdlist = cmdlist->next; } if (fprintf (fp, "\n") < 1) diff --git a/src/common/servlist.h b/src/common/servlist.h index c38c5129..141df127 100644 --- a/src/common/servlist.h +++ b/src/common/servlist.h @@ -25,6 +25,11 @@ typedef struct ircserver char *hostname; } ircserver; +typedef struct commandentry +{ + char *command; +} commandentry; + typedef struct ircnet { char *name; @@ -34,11 +39,11 @@ typedef struct ircnet char *real; char *pass; char *autojoin; - char *command; int logintype; char *comment; char *encoding; GSList *servlist; + GSList *commandlist; int selected; guint32 flags; } ircnet; @@ -72,9 +77,12 @@ void servlist_net_remove (ircnet *net); ircnet *servlist_net_find (char *name, int *pos, int (*cmpfunc) (const char *, const char *)); ircnet *servlist_net_find_from_server (char *server_name); -void servlist_server_remove (ircnet *net, ircserver *serv); -ircserver *servlist_server_add (ircnet *net, char *name); ircserver *servlist_server_find (ircnet *net, char *name, int *pos); +commandentry *servlist_command_find (ircnet *net, char *cmd, int *pos); +ircserver *servlist_server_add (ircnet *net, char *name); +commandentry *servlist_command_add (ircnet *net, char *command); +void servlist_server_remove (ircnet *net, ircserver *serv); +void servlist_command_remove (ircnet *net, commandentry *entry); void joinlist_split (char *autojoin, GSList **channels, GSList **keys); gboolean joinlist_is_in_list (server *serv, char *channel); diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 2cd74da2..3c9ecd22 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -277,6 +277,36 @@ servlist_servers_populate (ircnet *net, GtkWidget *treeview) } } +static void +servlist_commands_populate (ircnet *net, GtkWidget *treeview) +{ + GtkListStore *store; + GtkTreeIter iter; + int i; + commandentry *entry; + GSList *list = net->commandlist; + + store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); + gtk_list_store_clear (store); + + i = 0; + while (list) + { + entry = list->data; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, entry->command, 1, 1, -1); + + if (net->selected == i) + { + /* select this server */ + servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store); + } + + i++; + list = list->next; + } +} + static void servlist_networks_populate_ (GtkWidget *treeview, GSList *netlist, gboolean favorites) { @@ -384,7 +414,7 @@ servlist_addserver (void) /* select this server */ servlist_select_and_show (GTK_TREE_VIEW (edit_trees[SERVER_TREE]), &iter, store); - /*servlist_start_editing (GTK_TREE_VIEW (treeview));*/ + servlist_start_editing (GTK_TREE_VIEW (edit_trees[SERVER_TREE])); servlist_server_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL); } @@ -399,30 +429,17 @@ servlist_addcommand (void) return; store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CMD_TREE]))); + servlist_command_add (selected_net, "ECHO hello"); gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, "", 1, 1, -1); + gtk_list_store_set (store, &iter, 0, "ECHO hello", 1, 1, -1); servlist_select_and_show (GTK_TREE_VIEW (edit_trees[CMD_TREE]), &iter, store); + servlist_start_editing (GTK_TREE_VIEW (edit_trees[CMD_TREE])); servlist_server_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL); } -static void -servlist_deletecommand (void) -{ - GtkTreeSelection *sel; - GtkTreeModel *model; - GtkTreeIter iter; - - /* find the selected item in the GUI */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CMD_TREE])); - sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[CMD_TREE])); - - if (gtk_tree_selection_get_selected (sel, &model, &iter)) - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); -} - static void servlist_addnet_cb (GtkWidget *item, GtkTreeView *treeview) { @@ -681,6 +698,7 @@ servlist_edit_cb (GtkWidget *but, gpointer none) edit_win = servlist_open_edit (serverlist_win, selected_net); gtkutil_set_icon (edit_win); servlist_servers_populate (selected_net, edit_trees[SERVER_TREE]); + servlist_commands_populate (selected_net, edit_trees[CMD_TREE]); g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[SERVER_TREE]))), "changed", G_CALLBACK (servlist_server_row_cb), NULL); g_signal_connect (G_OBJECT (edit_win), "delete_event", @@ -762,7 +780,55 @@ servlist_deleteserver_cb (void) serv = servlist_server_find (selected_net, servname, &pos); g_free (servname); if (serv) + { servlist_deleteserver (serv, model); + } + } +} + +static void +servlist_deletecommand (commandentry *entry, GtkTreeModel *model) +{ + GtkTreeSelection *sel; + GtkTreeIter iter; + + /* remove from GUI */ + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[CMD_TREE])); + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + { + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + } + + /* remove from list */ + if (selected_net) + { + servlist_command_remove (selected_net, entry); + } +} + +static void +servlist_deletecommand_cb (void) +{ + GtkTreeSelection *sel; + GtkTreeModel *model; + GtkTreeIter iter; + char *command; + commandentry *entry; + int pos; + + /* find the selected item in the GUI */ + model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CMD_TREE])); + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[CMD_TREE])); + + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + { + gtk_tree_model_get (model, &iter, 0, &command, -1); /* query the content of the selection */ + entry = servlist_command_find (selected_net, command, &pos); + g_free (command); + if (entry) + { + servlist_deletecommand (entry, model); + } } } @@ -873,21 +939,6 @@ servlist_editkey_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, GtkT gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, newval, -1); } -static void -servlist_editcommand_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_addchannel (char *channel) { @@ -905,7 +956,7 @@ servlist_addchannel (char *channel) } static void -servlist_deletechannel (void) +servlist_deletechannel_cb (void) { GtkTreeSelection *sel; GtkTreeModel *model; @@ -947,10 +998,10 @@ servlist_deletebutton_cb (GtkWidget *item, GtkNotebook *notebook) servlist_deleteserver_cb (); break; case CHANNEL_TREE: - servlist_deletechannel (); + servlist_deletechannel_cb (); break; case CMD_TREE: - servlist_deletecommand (); + servlist_deletecommand_cb (); break; default: break; @@ -1392,6 +1443,20 @@ servlist_sanitize_hostname (char *host) return ret; } +/* remove leading slash */ +static char * +servlist_sanitize_command (char *cmd) +{ + if (cmd[0] == '/') + { + return (g_strdup (cmd + 1)); + } + else + { + return (g_strdup (cmd)); + } +} + static void servlist_editserver_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2, gpointer user_data) @@ -1436,6 +1501,49 @@ servlist_editserver_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2, gtk_tree_path_free (path); } +static void +servlist_editcommand_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2, gpointer user_data) +{ + GtkTreeModel *model = (GtkTreeModel *)user_data; + GtkTreeIter iter; + GtkTreePath *path; + char *cmd; + commandentry *entry; + + if (!selected_net) + return; + + path = gtk_tree_path_new_from_string (arg1); + + if (!gtk_tree_model_get_iter (model, &iter, path)) + { + gtk_tree_path_free (path); + return; + } + + gtk_tree_model_get (model, &iter, 0, &cmd, -1); + entry = servlist_command_find (selected_net, cmd, NULL); + g_free (cmd); + + if (entry) + { + /* delete empty item */ + if (arg2[0] == 0) + { + servlist_deletecommand (entry, model); + gtk_tree_path_free (path); + return; + } + + cmd = entry->command; + entry->command = servlist_sanitize_command (arg2); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, entry->command, -1); + free (cmd); + } + + gtk_tree_path_free (path); +} + static void servlist_combo_cb (GtkEntry *entry, gpointer userdata) { @@ -1596,7 +1704,8 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) vbox5 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (editwindow), vbox5); - /* tabs and buttons */ + + /* Tabs and buttons */ hbox1 = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox5), hbox1, TRUE, TRUE, 4); @@ -1611,18 +1720,14 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_BOTTOM); gtk_box_pack_start (GTK_BOX (hbox1), notebook, TRUE, TRUE, SERVLIST_X_PADDING); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow2), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow4), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow4), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow5), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow5), - GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_SHADOW_IN); + + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow4), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow4), GTK_SHADOW_IN); + + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow5), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow5), GTK_SHADOW_IN); /* Server Tree */ @@ -1681,6 +1786,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_tree_sortable_set_sort_column_id ((GtkTreeSortable *)model, 0, GTK_SORT_ASCENDING); servlist_channels_populate (selected_net, treeview_channels); + /* Command Tree */ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); model = GTK_TREE_MODEL (store); @@ -1701,6 +1807,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) "editable", 1, NULL); + /* Button Box */ vbuttonbox1 = gtk_vbutton_box_new (); gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 3); @@ -1725,7 +1832,8 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonedit); GTK_WIDGET_SET_FLAGS (buttonedit, GTK_CAN_DEFAULT); - /* checkboxes and entries */ + + /* Checkboxes and entries */ table3 = gtk_table_new (13, 2, FALSE); gtk_box_pack_start (GTK_BOX (vbox5), table3, FALSE, FALSE, 0); gtk_table_set_row_spacings (GTK_TABLE (table3), 2); @@ -1765,7 +1873,8 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) comboboxentry_charset = servlist_create_charsetcombo (); gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 1, 2, 12, 13, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 4, 2); - /* rule and close button */ + + /* Rule and Close button */ hseparator2 = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox5), hseparator2, FALSE, FALSE, 8); -- cgit 1.4.1 From 0badd9b874b2bd7ebbeb4209cbbc3fc0c9ce8899 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 20:09:07 +0200 Subject: Remove dead code --- src/common/servlist.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/common/servlist.c b/src/common/servlist.c index ed822925..79591331 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -1130,18 +1130,6 @@ servlist_load (void) net->autojoin = strdup (buf + 2); break; case 'C': - /*if (net->command) - { - // concat extra commands with a \n separator - tmp = net->command; - net->command = malloc (strlen (tmp) + strlen (buf + 2) + 2); - strcpy (net->command, tmp); - strcat (net->command, "\n"); - strcat (net->command, buf + 2); - free (tmp); - } else - net->command = strdup (buf + 2); - */ servlist_command_add (net, buf + 2); break; case 'F': -- cgit 1.4.1 From 791e0fc11f1132c25ce700ae975d6cee93ab9acc Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 20:42:29 +0200 Subject: Make login type more intuitive and disable unused /NS --- src/fe-gtk/servlistgui.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 3c9ecd22..7f2985b3 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -120,7 +120,9 @@ static int login_types_conf[] = 7, /* /pass */ 1, /* /msg NickServ */ 2, /* /NickServ */ +#if 0 3, /* /NS */ +#endif 4, /* /msg NS */ 5, /* /auth */ }; @@ -128,13 +130,15 @@ static int login_types_conf[] = static const char *login_types[]= { "Default", - "SASL", - "Server Password", - "Message NickServ", - "NickServ", - "NS", - "Message NS", - "AUTH", + "SASL (username + password)", + "Server Password (/PASS password)", + "NickServ (/MSG NickServ + password)", + "NickServ (/NickServ + password)", +#if 0 + "NickServ (/NS + password)", +#endif + "NickServ (/MSG NS + password)", + "AUTH (/AUTH nickname password)", NULL }; -- cgit 1.4.1 From bb86771425cfdd3d09c91ce3583bb61d55005bc2 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sat, 11 May 2013 20:47:39 +0200 Subject: Add explanation as well --- src/fe-gtk/servlistgui.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 7f2985b3..439613a0 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -1623,6 +1623,7 @@ servlist_create_logintypecombo (void) gtk_combo_box_set_active (GTK_COMBO_BOX (cb), servlist_get_login_desc_index (selected_net->logintype)); + add_tip (cb, _("The way you identify yourself to the server. For custom login methods use connect commands.")); g_signal_connect (G_OBJECT (GTK_BIN (cb)), "changed", G_CALLBACK (servlist_logintypecombo_cb), NULL); return cb; -- cgit 1.4.1 From 198dc9eb43e6d0e5c1bb44849ce671ebf18cafcd Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 05:44:32 +0200 Subject: Fix favorite channels except in inbound.c --- src/common/hexchat.h | 2 +- src/common/inbound.c | 2 + src/common/server.c | 4 +- src/common/servlist.c | 266 ++++++++++------------- src/common/servlist.h | 20 +- src/fe-gtk/menu.c | 4 + src/fe-gtk/servlistgui.c | 536 +++++++++++++++++------------------------------ 7 files changed, 322 insertions(+), 512 deletions(-) diff --git a/src/common/hexchat.h b/src/common/hexchat.h index 0a449bfa..060fd082 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -566,7 +566,7 @@ typedef struct server time_t away_time; /* when we were marked away */ char *encoding; /* NULL for system */ - char *autojoin; /* list of channels & keys to join */ + GSList *favlist; /* list of channels & keys to join */ unsigned int motd_skipped:1; unsigned int connected:1; diff --git a/src/common/inbound.c b/src/common/inbound.c index 4f23403f..926a34ba 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1069,6 +1069,7 @@ inbound_nameslist_end (server *serv, char *chan) static gboolean check_autojoin_channels (server *serv) { +#if 0//FIXME char *po; session *sess; GSList *list = sess_list; @@ -1137,6 +1138,7 @@ check_autojoin_channels (server *serv) serv->joindelay_tag = 0; fe_server_event (serv, FE_SE_LOGGEDIN, i); +#endif return FALSE; } diff --git a/src/common/server.c b/src/common/server.c index 26d9a7cb..7d48163f 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -2030,8 +2030,8 @@ server_free (server *serv) free (serv->last_away_reason); if (serv->encoding) free (serv->encoding); - if (serv->autojoin) - free (serv->autojoin); + if (serv->favlist) + g_slist_free_full (serv->favlist, g_free); fe_server_callback (serv); diff --git a/src/common/servlist.c b/src/common/servlist.c index 79591331..7c1789a9 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -610,11 +610,13 @@ servlist_connect (session *sess, ircnet *net, gboolean join) { sess->willjoinchannel[0] = 0; - if (net->autojoin) + if (net->favchanlist) { - if (serv->autojoin) - free (serv->autojoin); - serv->autojoin = strdup (net->autojoin); + if (serv->favlist) + { + g_slist_free_full (serv->favlist, g_free); + } + serv->favlist = g_slist_copy_deep (net->favchanlist, (GCopyFunc) g_strdup, NULL); } } @@ -804,7 +806,9 @@ servlist_server_find (ircnet *net, char *name, int *pos) if (strcmp (serv->hostname, name) == 0) { if (pos) + { *pos = i; + } return serv; } i++; @@ -814,6 +818,31 @@ servlist_server_find (ircnet *net, char *name, int *pos) return NULL; } +favchannel * +servlist_favchan_find (ircnet *net, char *channel, int *pos) +{ + GSList *list = net->favchanlist; + favchannel *favchan; + int i = 0; + + while (list) + { + favchan = list->data; + if (strcmp (favchan->name, channel) == 0) + { + if (pos) + { + *pos = i; + } + return favchan; + } + i++; + list = list->next; + } + + return NULL; +} + commandentry * servlist_command_find (ircnet *net, char *cmd, int *pos) { @@ -827,7 +856,9 @@ servlist_command_find (ircnet *net, char *cmd, int *pos) if (strcmp (entry->command, cmd) == 0) { if (pos) + { *pos = i; + } return entry; } i++; @@ -918,6 +949,32 @@ servlist_command_add (ircnet *net, char *cmd) return entry; } +favchannel * +servlist_favchan_add (ircnet *net, char *channel) +{ + int pos; + favchannel *chan; + + chan = malloc (sizeof (favchannel)); + memset (chan, 0, sizeof (favchannel)); + + if (strchr (channel, ',') != NULL) + { + pos = strchr (channel, ',') - channel; + chan->name = g_strndup (channel, pos); + chan->key = g_strdup (channel + pos + 1); + } + else + { + chan->name = g_strdup (channel); + chan->key = NULL; + } + + net->favchanlist = g_slist_append (net->favchanlist, chan); + + return chan; +} + void servlist_server_remove (ircnet *net, ircserver *serv) { @@ -946,6 +1003,15 @@ servlist_command_remove (ircnet *net, commandentry *entry) net->commandlist = g_slist_remove (net->commandlist, entry); } +void +servlist_favchan_remove (ircnet *net, favchannel *channel) +{ + g_free (channel->name); + g_free (channel->key); + g_free (channel); + net->favchanlist = g_slist_remove (net->favchanlist, channel); +} + static void free_and_clear (char *str) { @@ -991,10 +1057,10 @@ servlist_net_remove (ircnet *net) if (net->real) free (net->real); free_and_clear (net->pass); - if (net->autojoin) - free (net->autojoin); + if (net->favchanlist) + g_slist_free_full (net->favchanlist, g_free); if (net->commandlist) - g_slist_free_full (net->commandlist, (GDestroyNotify) g_free); + g_slist_free_full (net->commandlist, g_free); if (net->comment) free (net->comment); if (net->encoding) @@ -1049,7 +1115,7 @@ servlist_load_defaults (void) net->encoding = strdup (IRC_DEFAULT_CHARSET); if (def[i].channel) { - net->autojoin = strdup (def[i].channel); + servlist_favchan_add (net, def[i].channel); } if (def[i].charset) { @@ -1127,7 +1193,7 @@ servlist_load (void) net->pass = strdup (buf + 2); break; case 'J': - net->autojoin = strdup (buf + 2); + servlist_favchan_add (net, buf + 2); break; case 'C': servlist_command_add (net, buf + 2); @@ -1205,9 +1271,11 @@ servlist_save (void) ircnet *net; ircserver *serv; commandentry *cmd; + favchannel *favchan; GSList *list; GSList *netlist; GSList *cmdlist; + GSList *favlist; #ifndef WIN32 int first = FALSE; @@ -1249,8 +1317,6 @@ servlist_save (void) fprintf (fp, "R=%s\n", net->real); if (net->pass) fprintf (fp, "P=%s\n", net->pass); - if (net->autojoin) - fprintf (fp, "J=%s\n", net->autojoin); if (net->logintype) fprintf (fp, "L=%d\n", net->logintype); if (net->encoding && g_ascii_strcasecmp (net->encoding, "System") && @@ -1284,6 +1350,23 @@ servlist_save (void) cmdlist = cmdlist->next; } + favlist = net->favchanlist; + while (favlist) + { + favchan = favlist->data; + + if (favchan->key) + { + fprintf (fp, "J=%s,%s\n", favchan->name, favchan->key); + } + else + { + fprintf (fp, "J=%s\n", favchan->name); + } + + favlist = favlist->next; + } + if (fprintf (fp, "\n") < 1) { fclose (fp); @@ -1297,162 +1380,33 @@ servlist_save (void) return TRUE; } -static void -joinlist_free1 (GSList *list) -{ - GSList *head = list; - - for (; list; list = list->next) - g_free (list->data); - g_slist_free (head); -} - -void -joinlist_free (GSList *channels, GSList *keys) -{ - joinlist_free1 (channels); - joinlist_free1 (keys); -} - -gboolean -joinlist_is_in_list (server *serv, char *channel) -{ - GSList *channels, *keys; - GSList *list; - - if (!serv->network || !((ircnet *)serv->network)->autojoin) - return FALSE; - - joinlist_split (((ircnet *)serv->network)->autojoin, &channels, &keys); - - for (list = channels; list; list = list->next) - { - if (serv->p_cmp (list->data, channel) == 0) - return TRUE; - } - - joinlist_free (channels, keys); - - return FALSE; -} - -gchar * -joinlist_merge (GSList *channels, GSList *keys) +static int +joinlist_find_chan (favchannel *curr_item, const char *channel) { - GString *out = g_string_new (NULL); - GSList *list; - int i, j; - - for (; channels; channels = channels->next) + if (!g_ascii_strcasecmp (curr_item->name, channel)) { - g_string_append (out, channels->data); - - if (channels->next) - g_string_append_c (out, ','); + return 0; } - - /* count number of REAL keys */ - for (i = 0, list = keys; list; list = list->next) - if (list->data) - i++; - - if (i > 0) + else { - g_string_append_c (out, ' '); - - for (j = 0; keys; keys = keys->next) - { - if (keys->data) - { - g_string_append (out, keys->data); - j++; - if (j == i) - break; - } - - if (keys->next) - g_string_append_c (out, ','); - } + return 1; } - - return g_string_free (out, FALSE); } -void -joinlist_split (char *autojoin, GSList **channels, GSList **keys) +gboolean +joinlist_is_in_list (server *serv, char *channel) { - char *parta, *partb; - char *chan, *key; - int len; - - *channels = NULL; - *keys = NULL; - - /* after the first space, the keys begin */ - parta = autojoin; - partb = strchr (autojoin, ' '); - if (partb) - partb++; - - while (1) + if (!serv->network || !((ircnet *)serv->network)->favchanlist) { - chan = parta; - key = partb; - - if (1) - { - while (parta[0] != 0 && parta[0] != ',' && parta[0] != ' ') - { - parta++; - } - } - - if (partb) - { - while (partb[0] != 0 && partb[0] != ',' && partb[0] != ' ') - { - partb++; - } - } - - len = parta - chan; - if (len < 1) - break; - *channels = g_slist_append (*channels, g_strndup (chan, len)); - - len = partb - key; - *keys = g_slist_append (*keys, len ? g_strndup (key, len) : NULL); - - if (parta[0] == ' ' || parta[0] == 0) - break; - parta++; - - if (partb) - { - if (partb[0] == 0 || partb[0] == ' ') - partb = NULL; /* no more keys, but maybe more channels? */ - else - partb++; - } + return FALSE; } -#if 0 - GSList *lista, *listb; - int i; - - printf("-----\n"); - i = 0; - lista = *channels; - listb = *keys; - while (lista) + if (g_slist_find_custom (((ircnet *)serv->network)->favchanlist, channel, (GCompareFunc) joinlist_find_chan)) { - printf("%d. |%s| |%s|\n", i, lista->data, listb->data); - i++; - lista = lista->next; - listb = listb->next; + return TRUE; + } + else + { + return FALSE; } - printf("-----\n\n"); -#endif } - - diff --git a/src/common/servlist.h b/src/common/servlist.h index 141df127..350a1558 100644 --- a/src/common/servlist.h +++ b/src/common/servlist.h @@ -30,6 +30,12 @@ typedef struct commandentry char *command; } commandentry; +typedef struct favchannel +{ + char *name; + char *key; +} favchannel; + typedef struct ircnet { char *name; @@ -38,12 +44,12 @@ typedef struct ircnet char *user; char *real; char *pass; - char *autojoin; int logintype; char *comment; char *encoding; GSList *servlist; GSList *commandlist; + GSList *favchanlist; int selected; guint32 flags; } ircnet; @@ -79,14 +85,20 @@ ircnet *servlist_net_find_from_server (char *server_name); ircserver *servlist_server_find (ircnet *net, char *name, int *pos); commandentry *servlist_command_find (ircnet *net, char *cmd, int *pos); +favchannel *servlist_favchan_find (ircnet *net, char *channel, int *pos); + ircserver *servlist_server_add (ircnet *net, char *name); commandentry *servlist_command_add (ircnet *net, char *command); +favchannel *servlist_favchan_add (ircnet *net, char *channel); + void servlist_server_remove (ircnet *net, ircserver *serv); void servlist_command_remove (ircnet *net, commandentry *entry); +void servlist_favchan_remove (ircnet *net, favchannel *channel); -void joinlist_split (char *autojoin, GSList **channels, GSList **keys); gboolean joinlist_is_in_list (server *serv, char *channel); -void joinlist_free (GSList *channels, GSList *keys); -gchar *joinlist_merge (GSList *channels, GSList *keys); +/* FIXME +void joinlist_split (char *autojoin, GSList **channels, GSList **keys); +void joinlist_free (GSList *channels, GSList *keys); +*/ #endif diff --git a/src/fe-gtk/menu.c b/src/fe-gtk/menu.c index 79e1bad8..014ef3e7 100644 --- a/src/fe-gtk/menu.c +++ b/src/fe-gtk/menu.c @@ -1048,9 +1048,13 @@ menu_addfavoritemenu (server *serv, GtkWidget *menu, char *channel) } if (joinlist_is_in_list (serv, channel)) + { mg_create_icon_item (_("_Remove from Favorites"), GTK_STOCK_REMOVE, menu, menu_delfav_cb, serv); + } else + { mg_create_icon_item (_("_Add to Favorites"), GTK_STOCK_ADD, menu, menu_addfav_cb, serv); + } } static void diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 439613a0..59012e42 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -181,75 +181,33 @@ servlist_select_and_show (GtkTreeView *treeview, GtkTreeIter *iter, } } -static void -servlist_channel_save (void) -{ - GtkTreeModel *model; - GtkTreeIter iter; - char *channel, *key; - char *autojoin; - GSList *channels = NULL, *keys = NULL; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CHANNEL_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)); - } - - autojoin = joinlist_merge (channels, keys); - if (autojoin) - { - if (selected_net->autojoin) - g_free(selected_net->autojoin); - strcpy (selected_net->autojoin, autojoin); - g_free (autojoin); - } - - /* this does g_free too */ - joinlist_free (channels, keys); -} - static void servlist_channels_populate (ircnet *net, GtkWidget *treeview) { GtkListStore *store; - GSList *channels, *keys; - GSList *clist, *klist; GtkTreeIter iter; + int i; + favchannel *favchan; + GSList *list = net->favchanlist; - if (net->autojoin) - { - joinlist_split (net->autojoin, &channels, &keys); - - clist = channels; - klist = keys; + store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); + gtk_list_store_clear (store); - store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview))); + i = 0; + while (list) + { + favchan = list->data; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, favchan->name, 1, favchan->key, 2, TRUE, -1); - while (clist) + if (net->selected == i) { - 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; + /* select this server */ + servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store); } - joinlist_free (channels, keys); + i++; + list = list->next; } } @@ -273,8 +231,10 @@ servlist_servers_populate (ircnet *net, GtkWidget *treeview) gtk_list_store_set (store, &iter, 0, serv->hostname, 1, 1, -1); if (net->selected == i) + { /* select this server */ servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store); + } i++; list = list->next; @@ -414,7 +374,7 @@ servlist_addserver (void) servlist_server_add (selected_net, "newserver/6667"); gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, "newserver/6667", 1, 1, -1); + gtk_list_store_set (store, &iter, 0, "newserver/6667", 1, TRUE, -1); /* select this server */ servlist_select_and_show (GTK_TREE_VIEW (edit_trees[SERVER_TREE]), &iter, store); @@ -436,7 +396,7 @@ servlist_addcommand (void) servlist_command_add (selected_net, "ECHO hello"); gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, "ECHO hello", 1, 1, -1); + gtk_list_store_set (store, &iter, 0, "ECHO hello", 1, TRUE, -1); servlist_select_and_show (GTK_TREE_VIEW (edit_trees[CMD_TREE]), &iter, store); servlist_start_editing (GTK_TREE_VIEW (edit_trees[CMD_TREE])); @@ -444,6 +404,28 @@ servlist_addcommand (void) servlist_server_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL); } +static void +servlist_addchannel (void) +{ + GtkTreeIter iter; + GtkListStore *store; + + if (!selected_net) + return; + + store = GTK_LIST_STORE(gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE]))); + servlist_favchan_add (selected_net, "#channel"); + + 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 (edit_trees[CHANNEL_TREE]), &iter, store); + servlist_start_editing (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE])); + + servlist_server_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL); +} + static void servlist_addnet_cb (GtkWidget *item, GtkTreeView *treeview) { @@ -702,6 +684,7 @@ servlist_edit_cb (GtkWidget *but, gpointer none) edit_win = servlist_open_edit (serverlist_win, selected_net); gtkutil_set_icon (edit_win); servlist_servers_populate (selected_net, edit_trees[SERVER_TREE]); + servlist_channels_populate (selected_net, edit_trees[CHANNEL_TREE]); servlist_commands_populate (selected_net, edit_trees[CMD_TREE]); g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[SERVER_TREE]))), "changed", G_CALLBACK (servlist_server_row_cb), NULL); @@ -836,6 +819,53 @@ servlist_deletecommand_cb (void) } } +static void +servlist_deletechannel (favchannel *favchan, GtkTreeModel *model) +{ + GtkTreeSelection *sel; + GtkTreeIter iter; + + /* remove from GUI */ + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE])); + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + { + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + } + + /* remove from list */ + if (selected_net) + { + servlist_favchan_remove (selected_net, favchan); + } +} + +static void +servlist_deletechannel_cb (void) +{ + GtkTreeSelection *sel; + GtkTreeModel *model; + GtkTreeIter iter; + char *name; + char *key; + favchannel *favchan; + int pos; + + /* find the selected item in the GUI */ + model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE])); + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE])); + + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + { + gtk_tree_model_get (model, &iter, 0, &name, 1, &key, -1); /* query the content of the selection */ + favchan = servlist_favchan_find (selected_net, name, &pos); + g_free (name); + if (favchan) + { + servlist_deletechannel (favchan, model); + } + } +} + static ircnet * servlist_find_selected_net (GtkTreeSelection *sel) { @@ -889,7 +919,6 @@ servlist_savegui (void) if (sp) sp[0] = 0; /* spaces will break the login */ /* strcpy (prefs.hex_irc_real_name, GTK_ENTRY (entry_greal)->text); */ - //FIXME: Save commands(and load them) and favorites servlist_save (); save_config (); /* For nicks stored in hexchat.conf */ @@ -911,69 +940,6 @@ servlist_get_iter_from_name (GtkTreeModel *model, gchar *name, GtkTreeIter *iter return TRUE; } -static void -servlist_editchannel_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, GtkTreeModel *model) -{ - GtkTreeIter iter; - static int loop_guard = FALSE; - - if (loop_guard) - return; - - if (!servlist_get_iter_from_name (model, name, &iter)) - return; - - loop_guard = TRUE; - /* 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); - loop_guard = FALSE; -} - -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 (char *channel) -{ - GtkTreeIter iter; - GtkListStore *store; - - store = GTK_LIST_STORE(gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CHANNEL_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 (edit_trees[CHANNEL_TREE]), &iter, store); - servlist_start_editing (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE])); -} - -static void -servlist_deletechannel_cb (void) -{ - GtkTreeSelection *sel; - GtkTreeModel *model; - GtkTreeIter iter; - - /* find the selected item in the GUI */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE])); - sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[CHANNEL_TREE])); - - if (gtk_tree_selection_get_selected (sel, &model, &iter)) - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); -} - static void servlist_addbutton_cb (GtkWidget *item, GtkNotebook *notebook) { @@ -983,7 +949,7 @@ servlist_addbutton_cb (GtkWidget *item, GtkNotebook *notebook) servlist_addserver (); break; case CHANNEL_TREE: - servlist_addchannel ("#channel"); + servlist_addchannel (); break; case CMD_TREE: servlist_addcommand (); @@ -1015,184 +981,25 @@ servlist_deletebutton_cb (GtkWidget *item, GtkNotebook *notebook) void servlist_autojoinedit (ircnet *net, char *channel, gboolean add) { -#if 0 // FIXME: adding favorites from menu - GtkWidget *win; - GtkWidget *scrolledwindow; - GtkTreeModel *model; - GtkListStore *store; - GtkCellRenderer *renderer; - GtkWidget *tree; - GtkWidget *table; - GtkWidget *label; - GtkWidget *label2; - GtkWidget *bbox; - GtkWidget *wid; - - GtkWidget *vbuttonbox1; - GtkWidget *buttonadd; - GtkWidget *buttonremove; - GtkWidget *buttonedit; - - char buf[128]; - char lab[128]; - GSList *channels, *keys; - GSList *clist, *klist; - GtkTreeIter iter; - - if (edit_win && 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); - gtk_window_set_title (GTK_WINDOW (win), _(DISPLAY_NAME": Favorite Channels (Auto-Join List)")); - gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_MOUSE); - if (edit_win) - gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (edit_win)); - gtk_window_set_modal (GTK_WINDOW (win), TRUE); - gtk_window_set_type_hint (GTK_WINDOW (win), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_role (GTK_WINDOW (win), "editserv"); - - table = gtk_table_new (1, 1, FALSE); - gtk_container_add (GTK_CONTAINER (win), table); - gtk_widget_show (table); - - 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); + favchannel *fav; + char *buf; - 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, 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), - GTK_SHADOW_IN); - gtk_widget_show (scrolledwindow); - - store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); - model = GTK_TREE_MODEL (store); - - tree = gtk_tree_view_new_with_model (model); - g_object_unref (model); - gtk_container_add (GTK_CONTAINER (scrolledwindow), tree); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree), TRUE); - gtk_widget_show (tree); - - renderer = gtk_cell_renderer_text_new (); - 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, - "text", 0, - "editable", 2, - NULL); - - renderer = gtk_cell_renderer_text_new (); - 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, - "text", 1, - "editable", 2, - NULL); - - 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) + if (add) { - joinlist_split (net->autojoin, &channels, &keys); - - clist = channels; - klist = keys; - - while (clist) - { - if (channel && !add && !rfc_casecmp (channel, clist->data)) - { - snprintf (buf, sizeof (buf), _("%s has been removed."), channel); - snprintf (lab, sizeof (lab), "%s", 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; - } - - joinlist_free (channels, keys); + servlist_favchan_add (net, channel); + servlist_save (); + buf = g_strdup_printf (_("Channel %s added to favorites."), channel); } - - if (channel && add) + else { - servlist_addchannel (channel); - snprintf (buf, sizeof (buf), _("%s has been added."), channel); - snprintf (lab, sizeof (lab), "%s", buf); - gtk_label_set_markup (GTK_LABEL (label2), lab); + fav = servlist_favchan_find (net, channel, NULL); + servlist_favchan_remove (net, fav); + servlist_save (); + buf = g_strdup_printf (_("Channel %s removed from favorites."), channel); } - fav_add_net = net; -#endif + fe_message (buf, FE_MSG_INFO); + g_free (buf); } static void @@ -1211,12 +1018,6 @@ servlist_toggle_global_user (gboolean sensitive) gtk_widget_set_sensitive (edit_label_real, sensitive); } -static void -servlist_autojoinedit_cb (GtkWidget *button, ircnet *net) -{ - servlist_autojoinedit (net, NULL, FALSE); -} - static void servlist_connect_cb (GtkWidget *button, gpointer userdata) { @@ -1376,29 +1177,7 @@ servlist_create_entry (GtkWidget *table, char *labeltext, int row, gtk_entry_set_text (GTK_ENTRY (entry), def ? def : ""); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); -#if 0 /* FIXME */ - if (row == 12) /* for "Favorite channels:" */ - { - GtkWidget *button, *box; - - box = gtk_hbox_new (0, 0); - button = gtk_button_new_with_label ("..."); - g_signal_connect (G_OBJECT (button), "clicked", - G_CALLBACK (servlist_autojoinedit_cb), selected_net); - - gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0); - gtk_box_pack_end (GTK_BOX (box), button, 0, 0, 0); - gtk_widget_show_all (box); - - gtk_table_attach (GTK_TABLE (table), box, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); - } - else - { -#endif - gtk_table_attach (GTK_TABLE (table), entry, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); -#if 0 - } -#endif + gtk_table_attach (GTK_TABLE (table), entry, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); return entry; } @@ -1462,23 +1241,20 @@ servlist_sanitize_command (char *cmd) } static void -servlist_editserver_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2, - gpointer user_data) +servlist_editserver_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, gpointer user_data) { GtkTreeModel *model = (GtkTreeModel *)user_data; GtkTreeIter iter; - GtkTreePath *path; char *servname; ircserver *serv; if (!selected_net) + { return; + } - path = gtk_tree_path_new_from_string (arg1); - - if (!gtk_tree_model_get_iter (model, &iter, path)) + if (!servlist_get_iter_from_name (model, name, &iter)) { - gtk_tree_path_free (path); return; } @@ -1489,39 +1265,34 @@ servlist_editserver_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2, if (serv) { /* delete empty item */ - if (arg2[0] == 0) + if (newval[0] == 0) { servlist_deleteserver (serv, model); - gtk_tree_path_free (path); return; } servname = serv->hostname; - serv->hostname = servlist_sanitize_hostname (arg2); + serv->hostname = servlist_sanitize_hostname (newval); gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, serv->hostname, -1); free (servname); } - - gtk_tree_path_free (path); } static void -servlist_editcommand_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2, gpointer user_data) +servlist_editcommand_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, gpointer user_data) { GtkTreeModel *model = (GtkTreeModel *)user_data; GtkTreeIter iter; - GtkTreePath *path; char *cmd; commandentry *entry; if (!selected_net) + { return; + } - path = gtk_tree_path_new_from_string (arg1); - - if (!gtk_tree_model_get_iter (model, &iter, path)) + if (!servlist_get_iter_from_name (model, name, &iter)) { - gtk_tree_path_free (path); return; } @@ -1532,20 +1303,88 @@ servlist_editcommand_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2, gp if (entry) { /* delete empty item */ - if (arg2[0] == 0) + if (newval[0] == 0) { servlist_deletecommand (entry, model); - gtk_tree_path_free (path); return; } cmd = entry->command; - entry->command = servlist_sanitize_command (arg2); + entry->command = servlist_sanitize_command (newval); gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, entry->command, -1); free (cmd); } +} - gtk_tree_path_free (path); +static void +servlist_editchannel_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, gpointer user_data) +{ + GtkTreeModel *model = (GtkTreeModel *)user_data; + GtkTreeIter iter; + char *chan; + char *key; + favchannel *favchan; + + if (!selected_net) + { + return; + } + + if (!servlist_get_iter_from_name (model, name, &iter)) + { + return; + } + + gtk_tree_model_get (model, &iter, 0, &chan, 1, &key, -1); + favchan = servlist_favchan_find (selected_net, chan, NULL); + g_free (chan); + + if (favchan) + { + /* delete empty item */ + if (newval[0] == 0) + { + servlist_deletechannel (favchan, model); + return; + } + + chan = favchan->name; + favchan->name = g_strdup (newval); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, favchan->name, -1); + g_free (chan); + } +} + +static void +servlist_editkey_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, gpointer user_data) +{ + GtkTreeModel *model = (GtkTreeModel *)user_data; + GtkTreeIter iter; + char *chan; + char *key; + favchannel *favchan; + + if (!selected_net) + { + return; + } + + if (!servlist_get_iter_from_name (model, name, &iter)) + { + return; + } + + gtk_tree_model_get (model, &iter, 0, &chan, 1, &key, -1); + favchan = servlist_favchan_find (selected_net, chan, NULL); + g_free (chan); + + if (favchan) + { + key = favchan->key; + favchan->key = g_strdup (newval); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, favchan->key, -1); + g_free (key); + } } static void @@ -1789,7 +1628,6 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (treeview_channels), 0), TRUE); gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (treeview_channels), 1), TRUE); gtk_tree_sortable_set_sort_column_id ((GtkTreeSortable *)model, 0, GTK_SORT_ASCENDING); - servlist_channels_populate (selected_net, treeview_channels); /* Command Tree */ -- cgit 1.4.1 From de819e12bf65fea45d0173e499026f3f5baba620 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 05:55:14 +0200 Subject: g_slist_copy_deep() requires GLib 2.34 --- configure.ac | 2 +- share/doc/readme.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 56a7abe1..2fc226b8 100644 --- a/configure.ac +++ b/configure.ac @@ -184,7 +184,7 @@ dnl ********************************************************************* dnl ** GLIB ************************************************************* dnl ********************************************************************* -AM_PATH_GLIB_2_0(2.28.0, glib=yes, glib=no) +AM_PATH_GLIB_2_0(2.34.0, glib=yes, glib=no) if test "$glib" = no; then AC_MSG_ERROR(Cannot find GLib!) fi diff --git a/share/doc/readme.md b/share/doc/readme.md index dc66e0ac..7f490ce0 100644 --- a/share/doc/readme.md +++ b/share/doc/readme.md @@ -22,7 +22,7 @@ in general. HexChat runs on most BSD and POSIX compliant operating systems. ## Requirements: * GTK+ 2.24 - * GLib 2.28 + * GLib 2.34 HexChat is known to work on, at least: -- cgit 1.4.1 From 171dbcdedf0712c3822bf619ea2fc4f329c0aef3 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 05:58:16 +0200 Subject: Remove dead GLib code --- src/common/dcc.c | 9 --------- src/fe-gtk/fkeys.c | 4 ---- src/fe-gtk/sexy-spell-entry.c | 21 --------------------- 3 files changed, 34 deletions(-) diff --git a/src/common/dcc.c b/src/common/dcc.c index 9014296e..4980cabc 100644 --- a/src/common/dcc.c +++ b/src/common/dcc.c @@ -66,15 +66,6 @@ #define BIG_STR_TO_INT(x) strtoul(x,NULL,10) #endif -/* This is practically copy-paste from gstdio.h. - * GStatBuf was added in 2.26. On Win32 we already use that, - * so we only gotta check this on Unix */ -#ifndef WIN32 -#if !GLIB_CHECK_VERSION(2,26,0) -typedef struct stat GStatBuf; -#endif -#endif - static char *dcctypes[] = { "SEND", "RECV", "CHAT", "CHAT" }; struct dccstat_info dccstat[] = { diff --git a/src/fe-gtk/fkeys.c b/src/fe-gtk/fkeys.c index d1532e60..8a9a13c2 100644 --- a/src/fe-gtk/fkeys.c +++ b/src/fe-gtk/fkeys.c @@ -1637,10 +1637,6 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, strncat (buf, result, COMP_BUF - prefix_len); cursor_pos = strlen (buf); g_free(result); -#if !GLIB_CHECK_VERSION(2,4,0) - g_utf8_validate (buf, -1, (const gchar **)&result); - (*result) = 0; -#endif if (postfix) { strcat (buf, " "); diff --git a/src/fe-gtk/sexy-spell-entry.c b/src/fe-gtk/sexy-spell-entry.c index 0b9aa0e4..2d83fb86 100644 --- a/src/fe-gtk/sexy-spell-entry.c +++ b/src/fe-gtk/sexy-spell-entry.c @@ -954,7 +954,6 @@ enchant_has_lang(const gchar *lang, GSList *langs) { void sexy_spell_entry_activate_default_languages(SexySpellEntry *entry) { -#if GLIB_CHECK_VERSION (2, 6, 0) /*const gchar* const *langs; int i; gchar *lastprefix = NULL;*/ @@ -1003,26 +1002,6 @@ sexy_spell_entry_activate_default_languages(SexySpellEntry *entry) /* If we don't have any languages activated, use "en" */ if (entry->priv->dict_list == NULL) sexy_spell_entry_activate_language_internal(entry, "en", NULL); -#else - gchar *lang; - - if (!have_enchant) - return; - - lang = (gchar *) g_getenv("LANG"); - - if (lang != NULL) { - if (g_ascii_strncasecmp(lang, "C", 1) == 0) - lang = NULL; - else if (lang[0] == '\0') - lang = NULL; - } - - if (lang == NULL) - lang = "en"; - - sexy_spell_entry_activate_language_internal(entry, lang, NULL); -#endif } static void -- cgit 1.4.1 From 9327a5c71f8aeb12f61060d3d2543f4cee001c40 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 06:16:26 +0200 Subject: Reduce GLib requirement --- configure.ac | 2 +- share/doc/readme.md | 2 +- src/common/servlist.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 2fc226b8..56a7abe1 100644 --- a/configure.ac +++ b/configure.ac @@ -184,7 +184,7 @@ dnl ********************************************************************* dnl ** GLIB ************************************************************* dnl ********************************************************************* -AM_PATH_GLIB_2_0(2.34.0, glib=yes, glib=no) +AM_PATH_GLIB_2_0(2.28.0, glib=yes, glib=no) if test "$glib" = no; then AC_MSG_ERROR(Cannot find GLib!) fi diff --git a/share/doc/readme.md b/share/doc/readme.md index 7f490ce0..dc66e0ac 100644 --- a/share/doc/readme.md +++ b/share/doc/readme.md @@ -22,7 +22,7 @@ in general. HexChat runs on most BSD and POSIX compliant operating systems. ## Requirements: * GTK+ 2.24 - * GLib 2.34 + * GLib 2.28 HexChat is known to work on, at least: diff --git a/src/common/servlist.c b/src/common/servlist.c index 7c1789a9..83815c9f 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -581,6 +581,41 @@ static const struct defaultserver def[] = GSList *network_list = 0; +#if !GLIB_CHECK_VERSION(2,34,0) +#define g_slist_copy_deep servlist_slist_copy_deep +/* FIXME copy-paste from gslist.c, should be dumped sometime */ +static GSList* +servlist_slist_copy_deep (GSList *list, GCopyFunc func, gpointer user_data) +{ + GSList *new_list = NULL; + + if (list) + { + GSList *last; + + new_list = g_slice_new (GSList); + if (func) + new_list->data = func (list->data, user_data); + else + new_list->data = list->data; + last = new_list; + list = list->next; + while (list) + { + last->next = g_slice_new (GSList); + last = last->next; + if (func) + last->data = func (list->data, user_data); + else + last->data = list->data; + list = list->next; + } + last->next = NULL; + } + + return new_list; +} +#endif void servlist_connect (session *sess, ircnet *net, gboolean join) -- cgit 1.4.1 From 9c96528a98e786c6d755d32cf981a90138a4e5ee Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 06:19:42 +0200 Subject: Remove unused variable --- src/fe-gtk/servlistgui.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 59012e42..289965fe 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -77,7 +77,6 @@ static GtkWidget *edit_trees[N_TREES]; 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); -- cgit 1.4.1 From 5df669a329813292bdc0f8f69901e58a5fc2bc32 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 16:02:26 +0200 Subject: Make the order consistent for load and save --- src/common/servlist.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/common/servlist.c b/src/common/servlist.c index 83815c9f..d9654d77 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -1227,26 +1227,26 @@ servlist_load (void) case 'P': net->pass = strdup (buf + 2); break; - case 'J': - servlist_favchan_add (net, buf + 2); + case 'L': + net->logintype = atoi (buf + 2); break; - case 'C': - servlist_command_add (net, buf + 2); + case 'E': + net->encoding = strdup (buf + 2); break; case 'F': net->flags = atoi (buf + 2); break; - case 'D': - net->selected = atoi (buf + 2); - break; - case 'E': - net->encoding = strdup (buf + 2); - break; case 'S': /* new server/hostname for this network */ servlist_server_add (net, buf + 2); break; - case 'L': - net->logintype = atoi (buf + 2); + case 'C': + servlist_command_add (net, buf + 2); + break; + case 'J': + servlist_favchan_add (net, buf + 2); + break; + case 'D': + net->selected = atoi (buf + 2); break; } } -- cgit 1.4.1 From cadcfc553c762f4658b3b34dd08038d6af029451 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 16:37:32 +0200 Subject: Cosmetics --- src/fe-gtk/servlistgui.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 289965fe..2bb65dbc 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -132,7 +132,7 @@ static const char *login_types[]= "SASL (username + password)", "Server Password (/PASS password)", "NickServ (/MSG NickServ + password)", - "NickServ (/NickServ + password)", + "NickServ (/NICKSERV + password)", #if 0 "NickServ (/NS + password)", #endif -- cgit 1.4.1 From aac707956287e89639348edab4c7bd6782efd912 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 16:38:21 +0200 Subject: Add code for migrating existing configs --- src/common/servlist.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/common/servlist.c b/src/common/servlist.c index d9654d77..3fd16f7f 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -661,7 +661,7 @@ servlist_connect (session *sess, ircnet *net, gboolean join) } else { - serv->loginmethod = 2; /* use /NickServ by default */ + serv->loginmethod = 7; /* Use server password by default. If we had a NickServ password, it'd be set to 2 already. */ } serv->password[0] = 0; @@ -1248,6 +1248,34 @@ servlist_load (void) case 'D': net->selected = atoi (buf + 2); break; + /* FIXME Migration code. In 2.9.5 the order was: + * + * P=serverpass, A=saslpass, B=nickservpass + * + * So if server password was unset, we can safely use SASL + * password for our new universal password, or if that's also + * unset, use NickServ password. + * + * Should be removed at some point. + */ + case 'A': + if (!net->pass) + { + net->pass = strdup (buf + 2); + if (!net->logintype) + { + net->logintype = 6; + } + } + case 'B': + if (!net->pass) + { + net->pass = strdup (buf + 2); + if (!net->logintype) + { + net->logintype = 2; + } + } } } if (buf[0] == 'N') -- cgit 1.4.1 From c044bdfe326db8330cfd856432a06270d8010184 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 16:38:31 +0200 Subject: Fix warning --- src/common/servlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/servlist.c b/src/common/servlist.c index 3fd16f7f..02bc5906 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -995,7 +995,7 @@ servlist_favchan_add (ircnet *net, char *channel) if (strchr (channel, ',') != NULL) { - pos = strchr (channel, ',') - channel; + pos = (int) (strchr (channel, ',') - channel); chan->name = g_strndup (channel, pos); chan->key = g_strdup (channel + pos + 1); } -- cgit 1.4.1 From 2c15270be1cdb3c5034373a4d47eae3b11e19688 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Sun, 12 May 2013 16:59:21 +0200 Subject: Remember selected tab --- src/fe-gtk/servlistgui.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 2bb65dbc..2e799f8b 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -48,6 +48,8 @@ static int netlist_win_height = 0; static int netedit_win_width = 0; static int netedit_win_height = 0; +static int netedit_active_tab = 0; + /* global user info */ static GtkWidget *entry_nick1; static GtkWidget *entry_nick2; @@ -1386,6 +1388,15 @@ servlist_editkey_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, gpoi } } +static gboolean +servlist_edit_tabswitch_cb (GtkNotebook *nb, gpointer *newtab, guint newindex, gpointer user_data) +{ + /* remember the active tab */ + netedit_active_tab = newindex; + + return FALSE; +} + static void servlist_combo_cb (GtkEntry *entry, gpointer userdata) { @@ -1740,6 +1751,12 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) gtk_widget_show_all (editwindow); + /* We can't set the active tab without child elements being shown, so this must be *after* gtk_widget_show()s! */ + gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), netedit_active_tab); + + /* We need to connect this *after* setting the active tab so that the value doesn't get overriden. */ + g_signal_connect (G_OBJECT (notebook), "switch-page", G_CALLBACK (servlist_edit_tabswitch_cb), notebook); + return editwindow; } -- cgit 1.4.1 From 83107ee222a9b660bb73595dd321ffd724864876 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Mon, 13 May 2013 13:22:25 +0200 Subject: Use macros instead of raw numbers for login type --- src/common/inbound.c | 17 ++++++++++------- src/common/proto-irc.c | 20 +++++++++++--------- src/common/servlist.c | 20 ++++++++++---------- src/common/servlist.h | 13 ++++++++++++- src/fe-gtk/servlistgui.c | 16 ++++++++-------- 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index 926a34ba..f16c7b53 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1373,13 +1373,16 @@ static int inbound_nickserv_login (server *serv) { /* this could grow ugly, but let's hope there won't be new NickServ types */ - if (serv->loginmethod >= 1 && serv->loginmethod <= 5) - { - return 1; - } - else - { - return 0; + switch (serv->loginmethod) + { + case LOGIN_MSG_NICKSERV: + case LOGIN_NICKSERV: + case LOGIN_NS: + case LOGIN_MSG_NS: + case LOGIN_AUTH: + return 1; + default: + return 0; } } diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 7c73b5ab..c763fb71 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -50,7 +50,7 @@ irc_login (server *serv, char *user, char *realname) { tcp_sendf (serv, "CAP LS\r\n"); /* start with CAP LS as Charybdis sasl.txt suggests */ - if (serv->password[0] && serv->loginmethod == 7) + if (serv->password[0] && serv->loginmethod == LOGIN_PASS) { tcp_sendf (serv, "PASS %s\r\n", serv->password); } @@ -67,19 +67,21 @@ irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3) /* are all ircd authors idiots? */ switch (serv->loginmethod) { - case 1: + case LOGIN_MSG_NICKSERV: tcp_sendf (serv, "PRIVMSG NICKSERV :%s %s%s%s\r\n", cmd, arg1, arg2, arg3); break; - case 2: + case LOGIN_NICKSERV: tcp_sendf (serv, "NICKSERV %s %s%s%s\r\n", cmd, arg1, arg2, arg3); break; - case 3: +#if 0 + case LOGIN_NS: tcp_sendf (serv, "NS %s %s%s%s\r\n", cmd, arg1, arg2, arg3); break; - case 4: +#endif + case LOGIN_MSG_NS: tcp_sendf (serv, "PRIVMSG NS :%s %s%s%s\r\n", cmd, arg1, arg2, arg3); break; - case 5: + case LOGIN_AUTH: /* why couldn't QuakeNet implement one of the existing ones? */ tcp_sendf (serv, "AUTH %s %s\r\n", arg1, arg2); } @@ -88,7 +90,7 @@ irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3) static void irc_ns_identify (server *serv, char *pass) { - if (serv->loginmethod == 5) /* QuakeNet needs to do everything in its own ways... */ + if (serv->loginmethod == LOGIN_AUTH) /* QuakeNet needs to do everything in its own ways... */ { irc_nickserv (serv, "", serv->nick, pass, ""); } @@ -101,7 +103,7 @@ irc_ns_identify (server *serv, char *pass) static void irc_ns_ghost (server *serv, char *usname, char *pass) { - if (serv->loginmethod != 5) + if (serv->loginmethod != LOGIN_AUTH) { irc_nickserv (serv, "GHOST", usname, " ", pass); } @@ -1276,7 +1278,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[]) want_cap = 1; } /* if the SASL password is set AND auth mode is set to SASL, request SASL auth */ - if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->password) != 0 && serv->loginmethod == 6) + if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->password) != 0 && serv->loginmethod == LOGIN_SASL) { strcat (buffer, "sasl "); want_cap = 1; diff --git a/src/common/servlist.c b/src/common/servlist.c index 02bc5906..d5b7dc06 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -167,7 +167,7 @@ static const struct defaultserver def[] = {0, "irc.criten.net"}, {0, "irc.eu.criten.net"}, - {"DALnet", 0, 0, 0, 2}, + {"DALnet", 0}, {0, "irc.dal.net"}, {0, "irc.eu.dal.net"}, @@ -245,7 +245,7 @@ static const struct defaultserver def[] = {0, "irc.ggn.net"}, {0, "irc.vendetta.com"}, - {"freenode", 0, "#hexchat", 0, 6}, + {"freenode", 0, "#hexchat", 0, LOGIN_SASL}, #ifdef USE_OPENSSL {0, "irc.freenode.net/+6697"}, #endif @@ -263,7 +263,7 @@ static const struct defaultserver def[] = /* {0, "sprynet.us.galaxynet.org"}, {0, "atlanta.ga.us.galaxynet.org"},*/ - {"GameSurge", 0, 0, 0, 2}, + {"GameSurge", 0}, {0, "irc.gamesurge.net"}, /* {"GamesNET", 0}, @@ -426,7 +426,7 @@ static const struct defaultserver def[] = {0, "nfsi.ptnet.org"}, {0, "fctunl.ptnet.org"}, - {"QuakeNet", 0, 0, 0, 5}, + {"QuakeNet", 0, 0, 0, LOGIN_AUTH}, {0, "irc.quakenet.org"}, {0, "irc.se.quakenet.org"}, {0, "irc.dk.quakenet.org"}, @@ -460,7 +460,7 @@ static const struct defaultserver def[] = {"Rizon", 0}, {0, "irc.rizon.net"}, - {"RusNet", 0, 0, "KOI8-R (Cyrillic)", 2}, + {"RusNet", 0, 0, "KOI8-R (Cyrillic)"}, {0, "irc.tomsk.net"}, {0, "irc.rinet.ru"}, {0, "irc.run.net"}, @@ -545,7 +545,7 @@ static const struct defaultserver def[] = {0, "us.undernet.org"}, {0, "eu.undernet.org"}, - {"UniBG", 0, 0, 0, 4}, + {"UniBG", 0, 0, 0, LOGIN_MSG_NS}, {0, "irc.lirex.com"}, {0, "irc.naturella.com"}, {0, "irc.spnet.net"}, @@ -638,7 +638,7 @@ servlist_connect (session *sess, ircnet *net, gboolean join) return; ircserv = list->data; - /* incase a protocol switch is added to the servlist gui */ + /* in case a protocol switch is added to the servlist gui */ server_fill_her_up (sess->server); if (join) @@ -661,7 +661,7 @@ servlist_connect (session *sess, ircnet *net, gboolean join) } else { - serv->loginmethod = 7; /* Use server password by default. If we had a NickServ password, it'd be set to 2 already. */ + serv->loginmethod = LOGIN_DEFAULT_REAL; } serv->password[0] = 0; @@ -1264,7 +1264,7 @@ servlist_load (void) net->pass = strdup (buf + 2); if (!net->logintype) { - net->logintype = 6; + net->logintype = LOGIN_SASL; } } case 'B': @@ -1273,7 +1273,7 @@ servlist_load (void) net->pass = strdup (buf + 2); if (!net->logintype) { - net->logintype = 2; + net->logintype = LOGIN_NICKSERV; } } } diff --git a/src/common/servlist.h b/src/common/servlist.h index 350a1558..8558154b 100644 --- a/src/common/servlist.h +++ b/src/common/servlist.h @@ -58,13 +58,24 @@ extern GSList *network_list; #define FLAG_CYCLE 1 #define FLAG_USE_GLOBAL 2 -#define FLAG_USE_SSL 4 +#define FLAG_USE_SSL 4 #define FLAG_AUTO_CONNECT 8 #define FLAG_USE_PROXY 16 #define FLAG_ALLOW_INVALID 32 #define FLAG_FAVORITE 64 #define FLAG_COUNT 7 +/* Login methods. Use server password by default - if we had a NickServ password, it'd be set to 2 already by servlist_load() */ +#define LOGIN_DEFAULT_REAL LOGIN_PASS /* this is to set the default login method for unknown servers */ +#define LOGIN_DEFAULT 0 /* this is for the login type dropdown, doesn't serve any other purpose */ +#define LOGIN_MSG_NICKSERV 1 +#define LOGIN_NICKSERV 2 +#define LOGIN_NS 3 +#define LOGIN_MSG_NS 4 +#define LOGIN_AUTH 5 +#define LOGIN_SASL 6 +#define LOGIN_PASS 7 + /* DEFAULT_CHARSET is already defined in wingdi.h */ #define IRC_DEFAULT_CHARSET "UTF-8 (Unicode)" diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index 2e799f8b..53aba691 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -116,16 +116,16 @@ static const char *pages[]= */ static int login_types_conf[] = { - 0, /* default - we don't use this but it makes indexing consistent with login_types[] so it's nice */ - 6, /* SASL */ - 7, /* /pass */ - 1, /* /msg NickServ */ - 2, /* /NickServ */ + LOGIN_DEFAULT, /* default entry - we don't use this but it makes indexing consistent with login_types[] so it's nice */ + LOGIN_SASL, + LOGIN_PASS, + LOGIN_MSG_NICKSERV, + LOGIN_NICKSERV, #if 0 - 3, /* /NS */ + LOGIN_NS, #endif - 4, /* /msg NS */ - 5, /* /auth */ + LOGIN_MSG_NS, + LOGIN_AUTH, }; static const char *login_types[]= -- cgit 1.4.1 From 7cdfeff20490971c40deed9f59697f0e524348c8 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Mon, 13 May 2013 13:38:01 +0200 Subject: Add note about preferred tab size --- share/doc/hacking.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/share/doc/hacking.md b/share/doc/hacking.md index 68badd71..a63dc044 100644 --- a/share/doc/hacking.md +++ b/share/doc/hacking.md @@ -2,10 +2,10 @@ Just some tips if you're going to help with HexChat code (patches etc): -* Use tabs, not spaces, to indent code. +* Use tabs, not spaces, to indent and align code. -* Use a tab size of 3 (most editors will let you choose this). - Type :set ts=3 in vim/gvim. +* Use a tab size of 4 (most editors will let you choose this). + Type :set ts=4 in vim/gvim. * Try to stick to the same consistant coding style (vertically aligned braces, a space after if, while, functions etc.): -- cgit 1.4.1 From a435e8648fa16c8f661626b055e0e6626bf26460 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Tue, 14 May 2013 16:40:32 +0200 Subject: Fix initial autojoins and some erroneous copies/frees --- src/common/hexchat.h | 2 +- src/common/inbound.c | 35 +++++++++++++++++++++++++++++++- src/common/proto-irc.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/common/server.c | 2 +- src/common/servlist.c | 40 +++++++++++++++++++++++++++++------- src/common/servlist.h | 5 +++++ 6 files changed, 129 insertions(+), 10 deletions(-) diff --git a/src/common/hexchat.h b/src/common/hexchat.h index 060fd082..5fdbfc45 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -479,7 +479,7 @@ typedef struct server void (*p_ns_identify)(struct server *, char *pass); void (*p_ns_ghost)(struct server *, char *usname, char *pass); void (*p_join)(struct server *, char *channel, char *key); - void (*p_join_list)(struct server *, GSList *channels, GSList *keys); + void (*p_join_list)(struct server *, GSList *favorites); void (*p_login)(struct server *, char *user, char *realname); void (*p_join_info)(struct server *, char *channel); void (*p_mode)(struct server *, char *target, char *mode); diff --git a/src/common/inbound.c b/src/common/inbound.c index f16c7b53..dd35ad1c 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1066,10 +1066,10 @@ inbound_nameslist_end (server *serv, char *chan) return FALSE; } +#if 0//FIXME remove when finished porting static gboolean check_autojoin_channels (server *serv) { -#if 0//FIXME char *po; session *sess; GSList *list = sess_list; @@ -1138,7 +1138,40 @@ check_autojoin_channels (server *serv) serv->joindelay_tag = 0; fe_server_event (serv, FE_SE_LOGGEDIN, i); + return FALSE; +} #endif + +static gboolean +check_autojoin_channels (server *serv) +{ + int i = 0; + + /* shouldn't really happen, the io tag is destroyed in server.c */ + if (!is_server (serv)) + { + return FALSE; + } + + /* send auto join list */ + if (serv->favlist) + { + serv->p_join_list (serv, serv->favlist); + i++; + + /* FIXME this is not going to work and is not needed either. server_free() does the job already. */ + /* g_slist_free_full (serv->favlist, servlist_favchan_free); */ + } + + /* This is really only for re-connects when you + * join channels not in the auto-join list. + */ + + /* FIXME handle reconnects */ + + serv->joindelay_tag = 0; + fe_server_event (serv, FE_SE_LOGGEDIN, i); + return FALSE; } diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index c763fb71..f6d8af5e 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -118,6 +118,7 @@ irc_join (server *serv, char *channel, char *key) tcp_sendf (serv, "JOIN %s\r\n", channel); } +#if 0//FIXME remove when finished porting static void irc_join_list_flush (server *serv, GString *c, GString *k) { @@ -231,6 +232,60 @@ irc_join_list (server *serv, GSList *channels, GSList *keys) } irc_join_list_flush (serv, c, k); +#endif + +static void +irc_join_list_flush (server *serv) +{ + /* FIXME implement flushing for too long favorites lists */ +} + +static void +irc_join_list (server *serv, GSList *favorites) +{ + int first_item = 1; + favchannel *fav; + char *chanstr; + char *keystr; + GString *chanlist = g_string_new (NULL); + GString *keylist = g_string_new (NULL); + GSList *favlist; + + favlist = favorites; + + while (favlist) + { + fav = favlist->data; + + if (!first_item) + { + g_string_append_c (chanlist, ','); /* add separators but only if it's not the 1st element */ + g_string_append_c (keylist, ','); + } + + g_string_append (chanlist, fav->name); + + if (fav->key) + { + g_string_append (keylist, fav->key); + } + else + { + g_string_append_c (keylist, 'x'); /* 'x' filler for keyless channels */ + } + + first_item = 0; + favlist = favlist->next; + } + + chanstr = g_string_free (chanlist, FALSE); /* convert our strings to char arrays */ + keystr = g_string_free (keylist, FALSE); + + tcp_sendf (serv, "JOIN %s %s\r\n", chanstr, keystr); /* send the actual command */ + + g_free (chanstr); /* cleanup */ + g_free (keystr); + g_slist_free (favlist); } static void diff --git a/src/common/server.c b/src/common/server.c index 7d48163f..c867e86a 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -2031,7 +2031,7 @@ server_free (server *serv) if (serv->encoding) free (serv->encoding); if (serv->favlist) - g_slist_free_full (serv->favlist, g_free); + g_slist_free_full (serv->favlist, servlist_favchan_free); fe_server_callback (serv); diff --git a/src/common/servlist.c b/src/common/servlist.c index d5b7dc06..b6e28ac7 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -617,6 +617,20 @@ servlist_slist_copy_deep (GSList *list, GCopyFunc func, gpointer user_data) } #endif +favchannel * +servlist_favchan_copy (favchannel *fav) +{ + favchannel *newfav; + + newfav = malloc (sizeof (favchannel)); + memset (newfav, 0, sizeof (favchannel)); + + newfav->name = g_strdup (fav->name); + newfav->key = g_strdup (fav->key); /* g_strdup() can handle NULLs so no need to check it */ + + return newfav; +} + void servlist_connect (session *sess, ircnet *net, gboolean join) { @@ -649,9 +663,9 @@ servlist_connect (session *sess, ircnet *net, gboolean join) { if (serv->favlist) { - g_slist_free_full (serv->favlist, g_free); + g_slist_free_full (serv->favlist, servlist_favchan_free); } - serv->favlist = g_slist_copy_deep (net->favchanlist, (GCopyFunc) g_strdup, NULL); + serv->favlist = g_slist_copy_deep (net->favchanlist, (GCopyFunc) servlist_favchan_copy, NULL); } } @@ -1030,20 +1044,32 @@ servlist_server_remove_all (ircnet *net) } } +void +servlist_command_free (commandentry *entry) +{ + g_free (entry->command); + g_free (entry); +} + void servlist_command_remove (ircnet *net, commandentry *entry) { - free (entry->command); - free (entry); + servlist_command_free (entry); net->commandlist = g_slist_remove (net->commandlist, entry); } void -servlist_favchan_remove (ircnet *net, favchannel *channel) +servlist_favchan_free (favchannel *channel) { g_free (channel->name); g_free (channel->key); g_free (channel); +} + +void +servlist_favchan_remove (ircnet *net, favchannel *channel) +{ + servlist_favchan_free (channel); net->favchanlist = g_slist_remove (net->favchanlist, channel); } @@ -1093,9 +1119,9 @@ servlist_net_remove (ircnet *net) free (net->real); free_and_clear (net->pass); if (net->favchanlist) - g_slist_free_full (net->favchanlist, g_free); + g_slist_free_full (net->favchanlist, servlist_favchan_free); if (net->commandlist) - g_slist_free_full (net->commandlist, g_free); + g_slist_free_full (net->commandlist, servlist_command_free); if (net->comment) free (net->comment); if (net->encoding) diff --git a/src/common/servlist.h b/src/common/servlist.h index 8558154b..dd88de1d 100644 --- a/src/common/servlist.h +++ b/src/common/servlist.h @@ -102,10 +102,15 @@ ircserver *servlist_server_add (ircnet *net, char *name); commandentry *servlist_command_add (ircnet *net, char *command); favchannel *servlist_favchan_add (ircnet *net, char *channel); +void servlist_command_free (commandentry *entry); +void servlist_favchan_free (favchannel *channel); + void servlist_server_remove (ircnet *net, ircserver *serv); void servlist_command_remove (ircnet *net, commandentry *entry); void servlist_favchan_remove (ircnet *net, favchannel *channel); +favchannel *servlist_favchan_copy (favchannel *fav); + gboolean joinlist_is_in_list (server *serv, char *channel); /* FIXME -- cgit 1.4.1 From 947dd452942288aee8e109e3cb3e8b121146725b Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Tue, 14 May 2013 16:52:16 +0200 Subject: Fix warnings --- src/common/inbound.c | 2 +- src/common/server.c | 2 +- src/common/servlist.c | 6 +++--- src/common/util.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index dd35ad1c..fabd020e 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1160,7 +1160,7 @@ check_autojoin_channels (server *serv) i++; /* FIXME this is not going to work and is not needed either. server_free() does the job already. */ - /* g_slist_free_full (serv->favlist, servlist_favchan_free); */ + /* g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); */ } /* This is really only for re-connects when you diff --git a/src/common/server.c b/src/common/server.c index c867e86a..9b71d53d 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -2031,7 +2031,7 @@ server_free (server *serv) if (serv->encoding) free (serv->encoding); if (serv->favlist) - g_slist_free_full (serv->favlist, servlist_favchan_free); + g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); fe_server_callback (serv); diff --git a/src/common/servlist.c b/src/common/servlist.c index b6e28ac7..b55498cc 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -663,7 +663,7 @@ servlist_connect (session *sess, ircnet *net, gboolean join) { if (serv->favlist) { - g_slist_free_full (serv->favlist, servlist_favchan_free); + g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); } serv->favlist = g_slist_copy_deep (net->favchanlist, (GCopyFunc) servlist_favchan_copy, NULL); } @@ -1119,9 +1119,9 @@ servlist_net_remove (ircnet *net) free (net->real); free_and_clear (net->pass); if (net->favchanlist) - g_slist_free_full (net->favchanlist, servlist_favchan_free); + g_slist_free_full (net->favchanlist, (GDestroyNotify) servlist_favchan_free); if (net->commandlist) - g_slist_free_full (net->commandlist, servlist_command_free); + g_slist_free_full (net->commandlist, (GDestroyNotify) servlist_command_free); if (net->comment) free (net->comment); if (net->encoding) diff --git a/src/common/util.c b/src/common/util.c index 29a0f3ed..a6c9fe21 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1886,7 +1886,7 @@ int main (int argc, char *argv[]) list = get_subdirs ("foo"); display_list (list); #if GLIB_CHECK_VERSION(2,28,0) - g_slist_free_full (list, (GFunc) g_free); + g_slist_free_full (list, (GDestroyNotify) g_free); #else g_slist_foreach (list, (GFunc) g_free, NULL); g_slist_free (list); -- cgit 1.4.1 From 12cdb7704c58af2d2e2d7f54a9fa288e59825d3f Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Tue, 14 May 2013 18:20:05 +0200 Subject: Fix command splitting when the channel list is too long --- src/common/proto-irc.c | 164 ++++++++++++------------------------------------- 1 file changed, 39 insertions(+), 125 deletions(-) diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index f6d8af5e..8beb83f2 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -118,135 +118,31 @@ irc_join (server *serv, char *channel, char *key) tcp_sendf (serv, "JOIN %s\r\n", channel); } -#if 0//FIXME remove when finished porting static void -irc_join_list_flush (server *serv, GString *c, GString *k) +irc_join_list_flush (server *serv, GString *channels, GString *keys) { - char *chanstr, *keystr; + char *chanstr; + char *keystr; + + chanstr = g_string_free (channels, FALSE); /* convert our strings to char arrays */ + keystr = g_string_free (keys, FALSE); + + tcp_sendf (serv, "JOIN %s %s\r\n", chanstr, keystr); /* send the actual command */ - chanstr = g_string_free (c, FALSE); - keystr = g_string_free (k, FALSE); - if (chanstr[0]) - { - if (keystr[0]) - tcp_sendf (serv, "JOIN %s %s\r\n", chanstr, keystr); - else - tcp_sendf (serv, "JOIN %s\r\n", chanstr); - } g_free (chanstr); g_free (keystr); } -/* join a whole list of channels & keys, split to multiple lines - * to get around 512 limit */ - -static void -irc_join_list (server *serv, GSList *channels, GSList *keys) -{ - GSList *clist; - GSList *klist; - GString *c = g_string_new (NULL); - GString *k = g_string_new (NULL); - int len; - int add; - int i, j; - - i = j = 0; - len = 9; /* "JOIN\r\n" */ - clist = channels; - klist = keys; - - while (clist) - { - /* measure how many bytes this channel would add... */ - if (1) - { - add = strlen (clist->data); - if (i != 0) - add++; /* comma */ - } - - if (klist->data) - { - add += strlen (klist->data); - } - else - { - add++; /* 'x' filler */ - } - - if (j != 0) - add++; /* comma */ - - /* too big? dump buffer and start a fresh one */ - if (len + add > 512) - { - irc_join_list_flush (serv, c, k); - - c = g_string_new (NULL); - k = g_string_new (NULL); - i = j = 0; - len = 9; - } - - /* now actually add it to our GStrings */ - if (1) - { - add = strlen (clist->data); - if (i != 0) - { - add++; - g_string_append_c (c, ','); - } - g_string_append (c, clist->data); - i++; - } - - if (klist->data) - { - add += strlen (klist->data); - if (j != 0) - { - add++; - g_string_append_c (k, ','); - } - g_string_append (k, klist->data); - j++; - } - else - { - add++; - if (j != 0) - { - add++; - g_string_append_c (k, ','); - } - g_string_append_c (k, 'x'); - j++; - } - - len += add; - - klist = klist->next; - clist = clist->next; - } - - irc_join_list_flush (serv, c, k); -#endif - -static void -irc_join_list_flush (server *serv) -{ - /* FIXME implement flushing for too long favorites lists */ -} +/* Join a whole list of channels & keys, split to multiple lines + * to get around the 512 limit. + */ static void irc_join_list (server *serv, GSList *favorites) { - int first_item = 1; + int first_item = 1; /* determine whether we add commas or not */ + int len = 9; /* JOINchannelskeys\r\n\0 */ favchannel *fav; - char *chanstr; - char *keystr; GString *chanlist = g_string_new (NULL); GString *keylist = g_string_new (NULL); GSList *favlist; @@ -257,9 +153,33 @@ irc_join_list (server *serv, GSList *favorites) { fav = favlist->data; + len += strlen (fav->name); + if (fav->key) + { + len += strlen (fav->key); + } + + if (len >= 512) /* command length exceeds the IRC hard limit, flush it and start from scratch */ + { + irc_join_list_flush (serv, chanlist, keylist); + + chanlist = g_string_new (NULL); + keylist = g_string_new (NULL); + + len = 9; + first_item = 1; /* list dumped, omit commas once again */ + } + if (!first_item) { - g_string_append_c (chanlist, ','); /* add separators but only if it's not the 1st element */ + /* This should be done before the length check, but channel names + * are already at least 2 characters long so it would trigger the + * flush anyway. + */ + len += 2; + + /* add separators but only if it's not the 1st element */ + g_string_append_c (chanlist, ','); g_string_append_c (keylist, ','); } @@ -278,13 +198,7 @@ irc_join_list (server *serv, GSList *favorites) favlist = favlist->next; } - chanstr = g_string_free (chanlist, FALSE); /* convert our strings to char arrays */ - keystr = g_string_free (keylist, FALSE); - - tcp_sendf (serv, "JOIN %s %s\r\n", chanstr, keystr); /* send the actual command */ - - g_free (chanstr); /* cleanup */ - g_free (keystr); + irc_join_list_flush (serv, chanlist, keylist); g_slist_free (favlist); } -- cgit 1.4.1 From 81990ce53b90aa3351ef5981ce2a74c54a1f85f5 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Wed, 15 May 2013 08:49:28 +0200 Subject: Change prototype --- src/common/inbound.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index fabd020e..ec625c03 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1142,7 +1142,7 @@ check_autojoin_channels (server *serv) } #endif -static gboolean +static void check_autojoin_channels (server *serv) { int i = 0; @@ -1150,7 +1150,7 @@ check_autojoin_channels (server *serv) /* shouldn't really happen, the io tag is destroyed in server.c */ if (!is_server (serv)) { - return FALSE; + return; } /* send auto join list */ @@ -1171,8 +1171,6 @@ check_autojoin_channels (server *serv) serv->joindelay_tag = 0; fe_server_event (serv, FE_SE_LOGGEDIN, i); - - return FALSE; } void -- cgit 1.4.1 From 8cf025f18d85c079a8e95140cdc5abc8b6fc9c04 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Wed, 15 May 2013 11:43:38 +0200 Subject: Fix autojoins for sessions --- src/common/inbound.c | 95 +++++++++++++------------------------------------- src/common/proto-irc.c | 4 +-- src/common/servlist.c | 32 ++++++++++++----- src/common/servlist.h | 3 +- 4 files changed, 51 insertions(+), 83 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index ec625c03..953a78ee 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1066,39 +1066,38 @@ inbound_nameslist_end (server *serv, char *chan) return FALSE; } -#if 0//FIXME remove when finished porting -static gboolean +static void check_autojoin_channels (server *serv) { - char *po; + int i = 0; session *sess; GSList *list = sess_list; - int i = 0; - GSList *channels, *keys; + GSList *sess_channels = NULL; /* joined channels that are not in the favorites list */ - /* shouldnt really happen, the io tag is destroyed in server.c */ + /* shouldn't really happen, the io tag is destroyed in server.c */ if (!is_server (serv)) - return FALSE; + { + return; + } /* send auto join list */ - if (serv->autojoin) + if (serv->favlist) { - joinlist_split (serv->autojoin, &channels, &keys); - serv->p_join_list (serv, channels, keys); - joinlist_free (channels, keys); - - free (serv->autojoin); - serv->autojoin = NULL; + serv->p_join_list (serv, serv->favlist); i++; + + /* FIXME this is not going to work and is not needed either. server_free() does the job already. */ + /* g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); */ } - /* this is really only for re-connects when you - * join channels not in the auto-join list. */ - channels = NULL; - keys = NULL; + /* This is really only for re-connects when you + * join channels not in the auto-join list. + */ + while (list) { sess = list->data; + if (sess->server == serv) { if (sess->willjoinchannel[0] != 0) @@ -1106,69 +1105,23 @@ check_autojoin_channels (server *serv) strcpy (sess->waitchannel, sess->willjoinchannel); sess->willjoinchannel[0] = 0; - po = strchr (sess->waitchannel, ','); - if (po) - *po = 0; - po = strchr (sess->waitchannel, ' '); - if (po) - *po = 0; - - /* There can be no gap between keys, list keyed chans first. */ - if (sess->channelkey[0] != 0) - { - channels = g_slist_prepend (channels, g_strdup (sess->waitchannel)); - keys = g_slist_prepend (keys, g_strdup (sess->channelkey)); - } - else + if (!servlist_favchan_find (serv->network, sess->waitchannel, NULL)) /* don't reconnect if it's already in the favlist */ { - channels = g_slist_append (channels, g_strdup (sess->waitchannel)); - keys = g_slist_append (keys, g_strdup (sess->channelkey)); + sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, sess->channelkey); + i++; } - i++; } } - list = list->next; - } - - if (channels) - { - serv->p_join_list (serv, channels, keys); - joinlist_free (channels, keys); - } - serv->joindelay_tag = 0; - fe_server_event (serv, FE_SE_LOGGEDIN, i); - return FALSE; -} -#endif - -static void -check_autojoin_channels (server *serv) -{ - int i = 0; - - /* shouldn't really happen, the io tag is destroyed in server.c */ - if (!is_server (serv)) - { - return; + list = list->next; } - /* send auto join list */ - if (serv->favlist) + if (sess_channels) { - serv->p_join_list (serv, serv->favlist); - i++; - - /* FIXME this is not going to work and is not needed either. server_free() does the job already. */ - /* g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); */ + serv->p_join_list (serv, sess_channels); + g_slist_free_full (sess_channels, (GDestroyNotify) servlist_favchan_free); } - /* This is really only for re-connects when you - * join channels not in the auto-join list. - */ - - /* FIXME handle reconnects */ - serv->joindelay_tag = 0; fe_server_event (serv, FE_SE_LOGGEDIN, i); } diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 8beb83f2..792927db 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -185,13 +185,13 @@ irc_join_list (server *serv, GSList *favorites) g_string_append (chanlist, fav->name); - if (fav->key) + if (fav->key && strlen (fav->key)) /* strlen() is required since key can be '' for session->channelkey */ { g_string_append (keylist, fav->key); } else { - g_string_append_c (keylist, 'x'); /* 'x' filler for keyless channels */ + g_string_append_c (keylist, 'x'); /* 'x' filler for keyless channels so that our JOIN command is always well-formatted */ } first_item = 0; diff --git a/src/common/servlist.c b/src/common/servlist.c index b55498cc..da0b746d 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -998,30 +998,44 @@ servlist_command_add (ircnet *net, char *cmd) return entry; } -favchannel * -servlist_favchan_add (ircnet *net, char *channel) +GSList * +servlist_favchan_listadd (GSList *chanlist, char *channel, char *key) { - int pos; favchannel *chan; chan = malloc (sizeof (favchannel)); memset (chan, 0, sizeof (favchannel)); + chan->name = g_strdup (channel); + chan->key = g_strdup (key); + chanlist = g_slist_append (chanlist, chan); + + return chanlist; +} + +void +servlist_favchan_add (ircnet *net, char *channel) +{ + int pos; + char *name; + char *key; + if (strchr (channel, ',') != NULL) { pos = (int) (strchr (channel, ',') - channel); - chan->name = g_strndup (channel, pos); - chan->key = g_strdup (channel + pos + 1); + name = g_strndup (channel, pos); + key = g_strdup (channel + pos + 1); } else { - chan->name = g_strdup (channel); - chan->key = NULL; + name = g_strdup (channel); + key = NULL; } - net->favchanlist = g_slist_append (net->favchanlist, chan); + net->favchanlist = servlist_favchan_listadd (net->favchanlist, name, key); - return chan; + g_free (name); + g_free (key); } void diff --git a/src/common/servlist.h b/src/common/servlist.h index dd88de1d..92100b9b 100644 --- a/src/common/servlist.h +++ b/src/common/servlist.h @@ -100,7 +100,7 @@ favchannel *servlist_favchan_find (ircnet *net, char *channel, int *pos); ircserver *servlist_server_add (ircnet *net, char *name); commandentry *servlist_command_add (ircnet *net, char *command); -favchannel *servlist_favchan_add (ircnet *net, char *channel); +void servlist_favchan_add (ircnet *net, char *channel); void servlist_command_free (commandentry *entry); void servlist_favchan_free (favchannel *channel); @@ -110,6 +110,7 @@ void servlist_command_remove (ircnet *net, commandentry *entry); void servlist_favchan_remove (ircnet *net, favchannel *channel); favchannel *servlist_favchan_copy (favchannel *fav); +GSList *servlist_favchan_listadd (GSList *chanlist, char *channel, char *key); gboolean joinlist_is_in_list (server *serv, char *channel); -- cgit 1.4.1 From 6f09752db4561cb1995990d80ca658c654360834 Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Wed, 15 May 2013 11:48:37 +0200 Subject: Cosmetics --- src/common/inbound.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index 953a78ee..ee57854f 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1080,7 +1080,7 @@ check_autojoin_channels (server *serv) return; } - /* send auto join list */ + /* autojoin to favorite channels */ if (serv->favlist) { serv->p_join_list (serv, serv->favlist); @@ -1090,10 +1090,7 @@ check_autojoin_channels (server *serv) /* g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); */ } - /* This is really only for re-connects when you - * join channels not in the auto-join list. - */ - + /* upon a reconnect, also autojoin to channels not in the favorites but joined during the session */ while (list) { sess = list->data; -- cgit 1.4.1 From 0020f81e7934725c8ba4c8bdc5a72facbc317dce Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Wed, 15 May 2013 18:26:54 +0200 Subject: Fix reconnect keys --- src/common/inbound.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index ee57854f..2f33199a 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1073,6 +1073,7 @@ check_autojoin_channels (server *serv) session *sess; GSList *list = sess_list; GSList *sess_channels = NULL; /* joined channels that are not in the favorites list */ + favchannel *fav; /* shouldn't really happen, the io tag is destroyed in server.c */ if (!is_server (serv)) @@ -1080,17 +1081,7 @@ check_autojoin_channels (server *serv) return; } - /* autojoin to favorite channels */ - if (serv->favlist) - { - serv->p_join_list (serv, serv->favlist); - i++; - - /* FIXME this is not going to work and is not needed either. server_free() does the job already. */ - /* g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); */ - } - - /* upon a reconnect, also autojoin to channels not in the favorites but joined during the session */ + /* If there's a session (i.e. this is a reconnect), autojoin to everything that was open previously. */ while (list) { sess = list->data; @@ -1102,11 +1093,20 @@ check_autojoin_channels (server *serv) strcpy (sess->waitchannel, sess->willjoinchannel); sess->willjoinchannel[0] = 0; - if (!servlist_favchan_find (serv->network, sess->waitchannel, NULL)) /* don't reconnect if it's already in the favlist */ + fav = servlist_favchan_find (serv->network, sess->waitchannel, NULL); /* Is this channel in our favorites? */ + + /* session->channelkey is initially unset for channels joined from the favorites. You have to fill them up manually from favorites settings. */ + if (fav) { - sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, sess->channelkey); - i++; + /* session->channelkey is set if there was a key change during the session. In that case, use the session key, not the one from favorites. */ + if (fav->key && !strlen (sess->channelkey)) + { + safe_strcpy (sess->channelkey, fav->key, sizeof (sess->channelkey)); + } } + + sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, sess->channelkey); + i++; } } @@ -1118,6 +1118,18 @@ check_autojoin_channels (server *serv) serv->p_join_list (serv, sess_channels); g_slist_free_full (sess_channels, (GDestroyNotify) servlist_favchan_free); } + else + { + /* If there's no session, just autojoin to favorites. */ + if (serv->favlist) + { + serv->p_join_list (serv, serv->favlist); + i++; + + /* FIXME this is not going to work and is not needed either. server_free() does the job already. */ + /* g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); */ + } + } serv->joindelay_tag = 0; fe_server_event (serv, FE_SE_LOGGEDIN, i); -- cgit 1.4.1 From 2ff8e74061875617d45fdc9a40a733aac1214abd Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Wed, 15 May 2013 23:52:14 +0200 Subject: Omit filler keys if no channel's using them --- src/common/proto-irc.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 792927db..c689b814 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -119,7 +119,7 @@ irc_join (server *serv, char *channel, char *key) } static void -irc_join_list_flush (server *serv, GString *channels, GString *keys) +irc_join_list_flush (server *serv, GString *channels, GString *keys, int send_keys) { char *chanstr; char *keystr; @@ -127,7 +127,14 @@ irc_join_list_flush (server *serv, GString *channels, GString *keys) chanstr = g_string_free (channels, FALSE); /* convert our strings to char arrays */ keystr = g_string_free (keys, FALSE); - tcp_sendf (serv, "JOIN %s %s\r\n", chanstr, keystr); /* send the actual command */ + if (send_keys) + { + tcp_sendf (serv, "JOIN %s %s\r\n", chanstr, keystr); /* send the actual command */ + } + else + { + tcp_sendf (serv, "JOIN %s\r\n", chanstr); /* send the actual command */ + } g_free (chanstr); g_free (keystr); @@ -141,6 +148,7 @@ static void irc_join_list (server *serv, GSList *favorites) { int first_item = 1; /* determine whether we add commas or not */ + int send_keys = 0; /* if none of our channels have keys, we can omit the 'x' fillers altogether */ int len = 9; /* JOINchannelskeys\r\n\0 */ favchannel *fav; GString *chanlist = g_string_new (NULL); @@ -161,13 +169,14 @@ irc_join_list (server *serv, GSList *favorites) if (len >= 512) /* command length exceeds the IRC hard limit, flush it and start from scratch */ { - irc_join_list_flush (serv, chanlist, keylist); + irc_join_list_flush (serv, chanlist, keylist, send_keys); chanlist = g_string_new (NULL); keylist = g_string_new (NULL); len = 9; first_item = 1; /* list dumped, omit commas once again */ + send_keys = 0; /* also omit keys until we actually find one */ } if (!first_item) @@ -188,6 +197,7 @@ irc_join_list (server *serv, GSList *favorites) if (fav->key && strlen (fav->key)) /* strlen() is required since key can be '' for session->channelkey */ { g_string_append (keylist, fav->key); + send_keys = 1; } else { @@ -198,7 +208,7 @@ irc_join_list (server *serv, GSList *favorites) favlist = favlist->next; } - irc_join_list_flush (serv, chanlist, keylist); + irc_join_list_flush (serv, chanlist, keylist, send_keys); g_slist_free (favlist); } -- cgit 1.4.1 From fd1b276aabcf7a7e4269ca6ae72e04411212f35c Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Thu, 16 May 2013 00:04:58 +0200 Subject: Make sure the created favchannel instances have a NULL key when the session's key is empty --- src/common/inbound.c | 10 +++++++++- src/common/proto-irc.c | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/common/inbound.c b/src/common/inbound.c index 2f33199a..07539a63 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -1105,7 +1105,15 @@ check_autojoin_channels (server *serv) } } - sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, sess->channelkey); + /* for easier checks, ensure that favchannel->key is just NULL when session->channelkey is empty i.e. '' */ + if (strlen (sess->channelkey)) + { + sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, sess->channelkey); + } + else + { + sess_channels = servlist_favchan_listadd (sess_channels, sess->waitchannel, NULL); + } i++; } } diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index c689b814..9b375d92 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -194,7 +194,7 @@ irc_join_list (server *serv, GSList *favorites) g_string_append (chanlist, fav->name); - if (fav->key && strlen (fav->key)) /* strlen() is required since key can be '' for session->channelkey */ + if (fav->key) /* strlen() is required since key can be '' for session->channelkey */ { g_string_append (keylist, fav->key); send_keys = 1; -- cgit 1.4.1 From 8ccd11ee4bbf3d4a7a7fc06a872eca6d20544cba Mon Sep 17 00:00:00 2001 From: Berke Viktor Date: Thu, 16 May 2013 00:08:43 +0200 Subject: Remove comment --- src/common/proto-irc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 9b375d92..00767b89 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -194,7 +194,7 @@ irc_join_list (server *serv, GSList *favorites) g_string_append (chanlist, fav->name); - if (fav->key) /* strlen() is required since key can be '' for session->channelkey */ + if (fav->key) { g_string_append (keylist, fav->key); send_keys = 1; -- cgit 1.4.1