hexchat/src/fe-gtk/servlistgui.c

2237 lines
62 KiB
C
Raw Permalink Normal View History

2011-02-23 22:14:30 -05:00
/* X-Chat
* Copyright (C) 2004-2008 Peter Zelezny.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
2011-02-23 22:14:30 -05:00
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <gdk/gdkkeysyms.h>
2012-10-24 15:33:02 -04:00
#include "../common/hexchat.h"
#include "../common/hexchatc.h"
2011-02-23 22:14:30 -05:00
#include "../common/servlist.h"
#include "../common/cfgfiles.h"
#include "../common/fe.h"
2012-07-21 08:26:19 -04:00
#include "../common/util.h"
2011-02-23 22:14:30 -05:00
#include "fe-gtk.h"
#include "gtkutil.h"
#include "menu.h"
#include "pixmaps.h"
2012-10-20 21:03:38 -04:00
#include "fkeys.h"
2011-02-23 22:14:30 -05:00
2013-05-11 09:22:28 -04:00
#define SERVLIST_X_PADDING 4 /* horizontal paddig in the network editor */
#define SERVLIST_Y_PADDING 0 /* vertical padding in the network editor */
2011-02-23 22:14:30 -05:00
/* servlistgui.c globals */
static GtkWidget *serverlist_win = NULL;
2013-05-11 09:58:52 -04:00
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;
2011-02-23 22:14:30 -05:00
2013-05-12 10:59:21 -04:00
static int netedit_active_tab = 0;
2011-02-23 22:14:30 -05:00
/* global user info */
static GtkWidget *entry_nick1;
static GtkWidget *entry_nick2;
static GtkWidget *entry_nick3;
static GtkWidget *entry_guser;
/* static GtkWidget *entry_greal; */
2011-02-23 22:14:30 -05:00
2013-05-11 09:20:03 -04:00
enum {
SERVER_TREE,
CHANNEL_TREE,
CMD_TREE,
N_TREES,
};
2011-02-23 22:14:30 -05:00
/* 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_pass;
static GtkWidget *edit_label_nick;
static GtkWidget *edit_label_nick2;
static GtkWidget *edit_label_real;
static GtkWidget *edit_label_user;
2013-05-11 09:20:03 -04:00
static GtkWidget *edit_trees[N_TREES];
2011-02-23 22:14:30 -05:00
static ircnet *selected_net = NULL;
static ircserver *selected_serv = NULL;
static commandentry *selected_cmd = NULL;
static favchannel *selected_chan = NULL;
2011-02-23 22:14:30 -05:00
static session *servlist_sess;
static void servlist_network_row_cb (GtkTreeSelection *sel, gpointer user_data);
static GtkWidget *servlist_open_edit (GtkWidget *parent, ircnet *net);
static const char *pages[]=
{
2012-10-13 00:17:27 -04:00
IRC_DEFAULT_CHARSET,
"CP1252 (Windows-1252)",
2011-02-23 22:14:30 -05:00
"ISO-8859-15 (Western Europe)",
"ISO-8859-2 (Central Europe)",
"ISO-8859-7 (Greek)",
"ISO-8859-8 (Hebrew)",
"ISO-8859-9 (Turkish)",
"ISO-2022-JP (Japanese)",
"SJIS (Japanese)",
"CP949 (Korean)",
"KOI8-R (Cyrillic)",
"CP1251 (Cyrillic)",
"CP1256 (Arabic)",
"CP1257 (Baltic)",
"GB18030 (Chinese)",
"TIS-620 (Thai)",
NULL
};
/* 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[] =
{
LOGIN_DEFAULT, /* default entry - we don't use this but it makes indexing consistent with login_types[] so it's nice */
LOGIN_SASL,
2013-09-04 17:34:57 -04:00
#ifdef USE_OPENSSL
LOGIN_SASLEXTERNAL,
2013-09-04 17:34:57 -04:00
#endif
LOGIN_PASS,
LOGIN_MSG_NICKSERV,
LOGIN_NICKSERV,
2013-09-04 17:34:57 -04:00
#ifdef USE_OPENSSL
LOGIN_CHALLENGEAUTH,
2013-09-04 17:34:57 -04:00
#endif
LOGIN_CUSTOM
#if 0
LOGIN_NS,
2013-05-18 23:17:13 -04:00
LOGIN_MSG_NS,
LOGIN_AUTH,
#endif
};
static const char *login_types[]=
{
"Default",
"SASL (username + password)",
2013-09-04 17:34:57 -04:00
#ifdef USE_OPENSSL
"SASL EXTERNAL (cert)",
2013-09-04 17:34:57 -04:00
#endif
"Server Password (/PASS password)",
"NickServ (/MSG NickServ + password)",
2013-05-12 10:37:32 -04:00
"NickServ (/NICKSERV + password)",
2013-09-04 17:34:57 -04:00
#ifdef USE_OPENSSL
"Challenge Auth (username + password)",
2013-09-04 17:34:57 -04:00
#endif
"Custom... (connect commands)",
#if 0
"NickServ (/NS + password)",
2013-05-18 23:17:13 -04:00
"NickServ (/MSG NS + password)",
"AUTH (/AUTH nickname password)",
#endif
NULL
};
/* 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 */
}
2011-02-23 22:14:30 -05:00
static void
servlist_select_and_show (GtkTreeView *treeview, GtkTreeIter *iter,
GtkListStore *store)
{
GtkTreePath *path;
GtkTreeSelection *sel;
sel = gtk_tree_view_get_selection (treeview);
/* select this network */
gtk_tree_selection_select_iter (sel, iter);
/* and make sure it's visible */
path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
if (path)
{
gtk_tree_view_scroll_to_cell (treeview, path, NULL, TRUE, 0.5, 0.5);
gtk_tree_view_set_cursor (treeview, path, NULL, FALSE);
gtk_tree_path_free (path);
}
}
2013-05-11 09:20:03 -04:00
static void
servlist_channels_populate (ircnet *net, GtkWidget *treeview)
{
GtkListStore *store;
GtkTreeIter iter;
int i;
favchannel *favchan;
GSList *list = net->favchanlist;
2013-05-11 09:20:03 -04:00
store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
gtk_list_store_clear (store);
2013-05-11 09:20:03 -04:00
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);
2013-05-11 09:20:03 -04:00
if (net->selected == i)
2013-05-11 09:20:03 -04:00
{
/* select this server */
servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store);
2013-05-11 09:20:03 -04:00
}
i++;
list = list->next;
2013-05-11 09:20:03 -04:00
}
}
2011-02-23 22:14:30 -05:00
static void
servlist_servers_populate (ircnet *net, GtkWidget *treeview)
{
GtkListStore *store;
GtkTreeIter iter;
int i;
ircserver *serv;
GSList *list = net->servlist;
store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
gtk_list_store_clear (store);
i = 0;
while (list)
{
serv = list->data;
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, serv->hostname, 1, 1, -1);
if (net->selected == i)
{
2011-02-23 22:14:30 -05:00
/* select this server */
servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store);
}
2011-02-23 22:14:30 -05:00
i++;
list = list->next;
}
}
2013-05-11 14:06:22 -04:00
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;
}
}
2011-02-23 22:14:30 -05:00
static void
servlist_networks_populate_ (GtkWidget *treeview, GSList *netlist, gboolean favorites)
{
GtkListStore *store;
GtkTreeIter iter;
int i;
ircnet *net;
if (!netlist)
{
net = servlist_net_add (_("New Network"), "", FALSE);
servlist_server_add (net, "newserver/6667");
netlist = network_list;
}
store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
gtk_list_store_clear (store);
i = 0;
while (netlist)
{
net = netlist->data;
if (!favorites || (net->flags & FLAG_FAVORITE))
{
if (favorites)
gtk_list_store_insert_with_values (store, &iter, 0x7fffffff, 0, net->name, 1, 1, 2, 400, -1);
else
gtk_list_store_insert_with_values (store, &iter, 0x7fffffff, 0, net->name, 1, 1, 2, (net->flags & FLAG_FAVORITE) ? 800 : 400, -1);
2012-10-22 07:49:28 -04:00
if (i == prefs.hex_gui_slist_select)
2011-02-23 22:14:30 -05:00
{
/* select this network */
servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store);
selected_net = net;
}
}
i++;
netlist = netlist->next;
}
}
static void
servlist_networks_populate (GtkWidget *treeview, GSList *netlist)
{
2012-10-22 07:49:28 -04:00
servlist_networks_populate_ (treeview, netlist, prefs.hex_gui_slist_fav);
2011-02-23 22:14:30 -05:00
}
static void
servlist_server_row_cb (GtkTreeSelection *sel, gpointer user_data)
{
GtkTreeModel *model;
GtkTreeIter iter;
ircserver *serv;
char *servname;
int pos;
if (!selected_net)
return;
if (gtk_tree_selection_get_selected (sel, &model, &iter))
{
gtk_tree_model_get (model, &iter, 0, &servname, -1);
serv = servlist_server_find (selected_net, servname, &pos);
g_free (servname);
if (serv)
selected_net->selected = pos;
selected_serv = serv;
}
}
static void
servlist_command_row_cb (GtkTreeSelection *sel, gpointer user_data)
{
GtkTreeModel *model;
GtkTreeIter iter;
commandentry *cmd;
char *cmdname;
int pos;
if (!selected_net)
return;
if (gtk_tree_selection_get_selected (sel, &model, &iter))
{
gtk_tree_model_get (model, &iter, 0, &cmdname, -1);
cmd = servlist_command_find (selected_net, cmdname, &pos);
g_free (cmdname);
if (cmd)
selected_net->selected = pos;
selected_cmd = cmd;
}
}
static void
servlist_channel_row_cb (GtkTreeSelection *sel, gpointer user_data)
{
GtkTreeModel *model;
GtkTreeIter iter;
favchannel *channel;
char *channame;
int pos;
if (!selected_net)
return;
if (gtk_tree_selection_get_selected (sel, &model, &iter))
{
gtk_tree_model_get (model, &iter, 0, &channame, -1);
channel = servlist_favchan_find (selected_net, channame, &pos);
g_free (channame);
if (channel)
selected_net->selected = pos;
selected_chan = channel;
}
}
2011-02-23 22:14:30 -05:00
static void
servlist_start_editing (GtkTreeView *tree)
{
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreePath *path;
sel = gtk_tree_view_get_selection (tree);
if (gtk_tree_selection_get_selected (sel, &model, &iter))
{
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
if (path)
{
gtk_tree_view_set_cursor (tree, path,
gtk_tree_view_get_column (tree, 0), TRUE);
gtk_tree_path_free (path);
}
}
}
static void
2013-05-11 09:20:03 -04:00
servlist_addserver (void)
2011-02-23 22:14:30 -05:00
{
GtkTreeIter iter;
GtkListStore *store;
if (!selected_net)
return;
2013-05-11 09:20:03 -04:00
store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (edit_trees[SERVER_TREE])));
2011-02-23 22:14:30 -05:00
servlist_server_add (selected_net, "newserver/6667");
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "newserver/6667", 1, TRUE, -1);
2011-02-23 22:14:30 -05:00
/* select this server */
2013-05-11 09:20:03 -04:00
servlist_select_and_show (GTK_TREE_VIEW (edit_trees[SERVER_TREE]), &iter, store);
2013-05-11 14:06:22 -04:00
servlist_start_editing (GTK_TREE_VIEW (edit_trees[SERVER_TREE]));
2011-02-23 22:14:30 -05:00
servlist_server_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL);
}
2013-05-11 09:20:03 -04:00
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])));
2013-05-11 14:06:22 -04:00
servlist_command_add (selected_net, "ECHO hello");
2013-05-11 09:20:03 -04:00
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "ECHO hello", 1, TRUE, -1);
2013-05-11 09:20:03 -04:00
servlist_select_and_show (GTK_TREE_VIEW (edit_trees[CMD_TREE]), &iter, store);
2013-05-11 14:06:22 -04:00
servlist_start_editing (GTK_TREE_VIEW (edit_trees[CMD_TREE]));
2013-05-11 09:20:03 -04:00
servlist_command_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL);
2013-05-11 09:20:03 -04:00
}
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_channel_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL);
}
2011-02-23 22:14:30 -05:00
static void
servlist_addnet_cb (GtkWidget *item, GtkTreeView *treeview)
{
GtkTreeIter iter;
GtkListStore *store;
ircnet *net;
net = servlist_net_add (_("New Network"), "", TRUE);
net->encoding = g_strdup (IRC_DEFAULT_CHARSET);
2011-02-23 22:14:30 -05:00
servlist_server_add (net, "newserver/6667");
store = (GtkListStore *)gtk_tree_view_get_model (treeview);
gtk_list_store_prepend (store, &iter);
gtk_list_store_set (store, &iter, 0, net->name, 1, 1, -1);
/* select this network */
servlist_select_and_show (GTK_TREE_VIEW (networks_tree), &iter, store);
servlist_start_editing (GTK_TREE_VIEW (networks_tree));
servlist_network_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL);
}
static void
servlist_deletenetwork (ircnet *net)
{
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
/* remove from GUI */
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree));
if (gtk_tree_selection_get_selected (sel, &model, &iter))
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
/* remove from list */
servlist_net_remove (net);
/* force something to be selected */
gtk_tree_model_get_iter_first (model, &iter);
servlist_select_and_show (GTK_TREE_VIEW (networks_tree), &iter,
GTK_LIST_STORE (model));
servlist_network_row_cb (sel, NULL);
}
static void
servlist_deletenetdialog_cb (GtkDialog *dialog, gint arg1, ircnet *net)
{
gtk_widget_destroy (GTK_WIDGET (dialog));
if (arg1 == GTK_RESPONSE_OK)
servlist_deletenetwork (net);
}
static GSList *
servlist_move_item (GtkTreeView *view, GSList *list, gpointer item, int delta)
2011-02-23 22:14:30 -05:00
{
GtkTreeModel *store;
GtkTreeIter iter1, iter2;
GtkTreeSelection *sel;
GtkTreePath *path;
2011-02-23 22:14:30 -05:00
int pos;
/* Keep tree in sync w/ list, there has to be an easier way to get iters */
sel = gtk_tree_view_get_selection (view);
gtk_tree_selection_get_selected (sel, &store, &iter1);
path = gtk_tree_model_get_path (store, &iter1);
if (delta == 1)
gtk_tree_path_next (path);
else
gtk_tree_path_prev (path);
gtk_tree_model_get_iter (store, &iter2, path);
2013-06-04 11:32:51 -04:00
gtk_tree_path_free (path);
pos = g_slist_index (list, item);
2011-02-23 22:14:30 -05:00
if (pos >= 0)
{
pos += delta;
if (pos >= 0)
{
list = g_slist_remove (list, item);
list = g_slist_insert (list, item, pos);
2011-02-23 22:14:30 -05:00
gtk_list_store_swap (GTK_LIST_STORE (store), &iter1, &iter2);
2011-02-23 22:14:30 -05:00
}
}
return list;
2011-02-23 22:14:30 -05:00
}
static gboolean
servlist_net_keypress_cb (GtkWidget *wid, GdkEventKey *evt, gpointer tree)
{
gboolean handled = FALSE;
if (!selected_net || prefs.hex_gui_slist_fav)
2011-02-23 22:14:30 -05:00
return FALSE;
2012-10-20 21:03:38 -04:00
if (evt->state & STATE_SHIFT)
2011-02-23 22:14:30 -05:00
{
2013-09-15 03:21:56 -04:00
if (evt->keyval == GDK_KEY_Up)
2011-02-23 22:14:30 -05:00
{
handled = TRUE;
network_list = servlist_move_item (GTK_TREE_VIEW (tree), network_list, selected_net, -1);
2011-02-23 22:14:30 -05:00
}
2013-09-15 03:21:56 -04:00
else if (evt->keyval == GDK_KEY_Down)
2011-02-23 22:14:30 -05:00
{
handled = TRUE;
network_list = servlist_move_item (GTK_TREE_VIEW (tree), network_list, selected_net, +1);
2011-02-23 22:14:30 -05:00
}
}
return handled;
2011-02-23 22:14:30 -05:00
}
static gint
servlist_compare (ircnet *net1, ircnet *net2)
{
gchar *net1_casefolded, *net2_casefolded;
int result=0;
net1_casefolded=g_utf8_casefold(net1->name,-1),
net2_casefolded=g_utf8_casefold(net2->name,-1),
result=g_utf8_collate(net1_casefolded,net2_casefolded);
g_free(net1_casefolded);
g_free(net2_casefolded);
return result;
}
static void
servlist_sort (GtkWidget *button, gpointer none)
{
network_list=g_slist_sort(network_list,(GCompareFunc)servlist_compare);
servlist_networks_populate (networks_tree, network_list);
}
static gboolean
servlist_has_selection (GtkTreeView *tree)
{
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
/* make sure something is selected */
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
return gtk_tree_selection_get_selected (sel, &model, &iter);
}
static void
servlist_favor (GtkWidget *button, gpointer none)
{
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
if (!selected_net)
return;
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree));
if (gtk_tree_selection_get_selected (sel, &model, &iter))
{
if (selected_net->flags & FLAG_FAVORITE)
{
gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2, 400, -1);
selected_net->flags &= ~FLAG_FAVORITE;
}
else
{
gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2, 800, -1);
selected_net->flags |= FLAG_FAVORITE;
}
}
}
static void
servlist_update_from_entry (char **str, GtkWidget *entry)
{
g_free (*str);
2011-02-23 22:14:30 -05:00
if (gtk_entry_get_text (GTK_ENTRY (entry))[0] == 0)
2011-02-23 22:14:30 -05:00
*str = NULL;
else
*str = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
2011-02-23 22:14:30 -05:00
}
static void
servlist_edit_update (ircnet *net)
{
servlist_update_from_entry (&net->nick, edit_entry_nick);
servlist_update_from_entry (&net->nick2, edit_entry_nick2);
servlist_update_from_entry (&net->user, edit_entry_user);
servlist_update_from_entry (&net->real, edit_entry_real);
servlist_update_from_entry (&net->pass, edit_entry_pass);
}
static void
servlist_edit_close_cb (GtkWidget *button, gpointer userdata)
{
if (selected_net)
servlist_edit_update (selected_net);
gtk_widget_destroy (edit_win);
edit_win = NULL;
}
static gint
servlist_editwin_delete_cb (GtkWidget *win, GdkEventAny *event, gpointer none)
{
servlist_edit_close_cb (NULL, NULL);
return FALSE;
}
static gboolean
servlist_configure_cb (GtkWindow *win, GdkEventConfigure *event, gpointer none)
{
/* remember the window size */
2013-05-11 09:58:52 -04:00
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);
2011-02-23 22:14:30 -05:00
return FALSE;
}
static void
servlist_edit_cb (GtkWidget *but, gpointer none)
{
if (!servlist_has_selection (GTK_TREE_VIEW (networks_tree)))
return;
edit_win = servlist_open_edit (serverlist_win, selected_net);
gtkutil_set_icon (edit_win);
2013-05-11 09:20:03 -04:00
servlist_servers_populate (selected_net, edit_trees[SERVER_TREE]);
servlist_channels_populate (selected_net, edit_trees[CHANNEL_TREE]);
2013-05-11 14:06:22 -04:00
servlist_commands_populate (selected_net, edit_trees[CMD_TREE]);
2011-02-23 22:14:30 -05:00
g_signal_connect (G_OBJECT (edit_win), "delete_event",
G_CALLBACK (servlist_editwin_delete_cb), 0);
2013-05-11 09:58:52 -04:00
g_signal_connect (G_OBJECT (edit_win), "configure_event",
G_CALLBACK (servlist_edit_configure_cb), 0);
2011-02-23 22:14:30 -05:00
gtk_widget_show (edit_win);
}
static void
servlist_deletenet_cb (GtkWidget *item, ircnet *net)
{
GtkWidget *dialog;
if (!servlist_has_selection (GTK_TREE_VIEW (networks_tree)))
return;
net = selected_net;
if (!net)
return;
dialog = gtk_message_dialog_new (GTK_WINDOW (serverlist_win),
GTK_DIALOG_DESTROY_WITH_PARENT |
GTK_DIALOG_MODAL,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_OK_CANCEL,
_("Really remove network \"%s\" and all its servers?"),
net->name);
g_signal_connect (dialog, "response",
G_CALLBACK (servlist_deletenetdialog_cb), net);
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_widget_show (dialog);
}
static void
servlist_deleteserver (ircserver *serv, GtkTreeModel *model)
{
GtkTreeSelection *sel;
GtkTreeIter iter;
/* don't remove the last server */
if (selected_net && g_slist_length (selected_net->servlist) < 2)
return;
/* remove from GUI */
2013-05-11 09:20:03 -04:00
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_trees[SERVER_TREE]));
2011-02-23 22:14:30 -05:00
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_server_remove (selected_net, serv);
}
static void
2013-05-11 09:20:03 -04:00
servlist_editbutton_cb (GtkWidget *item, GtkNotebook *notebook)
2011-02-23 22:14:30 -05:00
{
2013-05-11 09:20:03 -04:00
servlist_start_editing (GTK_TREE_VIEW (edit_trees[gtk_notebook_get_current_page(notebook)]));
2011-02-23 22:14:30 -05:00
}
static void
2013-05-11 09:20:03 -04:00
servlist_deleteserver_cb (void)
2011-02-23 22:14:30 -05:00
{
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
char *servname;
ircserver *serv;
int pos;
/* find the selected item in the GUI */
2013-05-11 09:20:03 -04:00
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]));
2011-02-23 22:14:30 -05:00
if (gtk_tree_selection_get_selected (sel, &model, &iter))
{
gtk_tree_model_get (model, &iter, 0, &servname, -1);
serv = servlist_server_find (selected_net, servname, &pos);
g_free (servname);
if (serv)
2013-05-11 14:06:22 -04:00
{
2011-02-23 22:14:30 -05:00
servlist_deleteserver (serv, model);
2013-05-11 14:06:22 -04:00
}
}
}
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);
}
2011-02-23 22:14:30 -05:00
}
}
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);
}
}
}
2011-02-23 22:14:30 -05:00
static ircnet *
servlist_find_selected_net (GtkTreeSelection *sel)
{
GtkTreeModel *model;
GtkTreeIter iter;
char *netname;
int pos;
ircnet *net = NULL;
if (gtk_tree_selection_get_selected (sel, &model, &iter))
{
gtk_tree_model_get (model, &iter, 0, &netname, -1);
net = servlist_net_find (netname, &pos, strcmp);
g_free (netname);
if (net)
2012-10-22 07:49:28 -04:00
prefs.hex_gui_slist_select = pos;
2011-02-23 22:14:30 -05:00
}
return net;
}
static void
servlist_network_row_cb (GtkTreeSelection *sel, gpointer user_data)
{
ircnet *net;
selected_net = NULL;
net = servlist_find_selected_net (sel);
if (net)
selected_net = net;
}
static int
servlist_savegui (void)
{
char *sp;
2014-02-02 19:07:52 -05:00
const char *nick1, *nick2;
2011-02-23 22:14:30 -05:00
/* check for blank username, ircd will not allow this */
if (gtk_entry_get_text (GTK_ENTRY (entry_guser))[0] == 0)
2011-02-23 22:14:30 -05:00
return 1;
/* if (gtk_entry_get_text (GTK_ENTRY (entry_greal))[0] == 0)
return 1; */
2011-02-23 22:14:30 -05:00
nick1 = gtk_entry_get_text (GTK_ENTRY (entry_nick1));
nick2 = gtk_entry_get_text (GTK_ENTRY (entry_nick2));
/* ensure unique nicknames */
if (!rfc_casecmp (nick1, nick2))
return 2;
safe_strcpy (prefs.hex_irc_nick1, nick1, sizeof(prefs.hex_irc_nick1));
safe_strcpy (prefs.hex_irc_nick2, nick2, sizeof(prefs.hex_irc_nick2));
safe_strcpy (prefs.hex_irc_nick3, gtk_entry_get_text (GTK_ENTRY (entry_nick3)), sizeof(prefs.hex_irc_nick3));
safe_strcpy (prefs.hex_irc_user_name, gtk_entry_get_text (GTK_ENTRY (entry_guser)), sizeof(prefs.hex_irc_user_name));