home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Linux
/
Divers
/
yagirc-0.51.tar.gz
/
yagirc-0.51.tar
/
yagirc-0.51
/
gui_setup_server.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-05-11
|
17KB
|
542 lines
/*
gui_setup_server.c : Servers notebook entry for setup
Copyright (C) 1998 Timo Sirainen
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include <glib.h>
#include "os.h"
#include "gui.h"
#include "gui_setup_server.h"
GList *servers; /* list of local servers */
GList *globalservers; /* list of global servers */
/* temp entry widgets */
static GtkWidget *nick_text, *name_text;
static GtkWidget *server_text, *port_text, *ircnet_text, *location_text;
int compare_servers(SETUP_SERVER_REC *p1, SETUP_SERVER_REC *p2)
{
int n;
if (p1 == NULL) return -1;
if (p2 == NULL) return 1;
n = strcasecmp(p1->ircnet, p2->ircnet);
if (n == 0)
{
n = strcasecmp(p1->location, p2->location);
if (n == 0)
n = strcasecmp(p1->name, p2->name);
}
return n;
}
/* add new server to server list */
SETUP_SERVER_REC *add_server_list(GList **servers, char *net, char *name, int port, char *location)
{
SETUP_SERVER_REC *server;
GList *tmp;
g_return_val_if_fail(net != NULL, NULL);
g_return_val_if_fail(location != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
/* check if there's any existing servers with that name.. */
for (tmp = g_list_first(*servers); tmp != NULL; tmp = tmp->next)
{
server = (SETUP_SERVER_REC *) tmp->data;
if (strcasecmp(server->name, name) == 0)
{
/* found, remove it. */
*servers = g_list_remove_link(*servers, tmp);
break;
}
}
server = (SETUP_SERVER_REC *) g_malloc(sizeof(SETUP_SERVER_REC));
server->ircnet = g_strdup(net);
server->name = g_strdup(name);
server->location = g_strdup(location);
server->port = port;
if (*servers == globalservers)
*servers = g_list_insert_sorted(*servers, server, (GCompareFunc) compare_servers);
else
*servers = g_list_append(*servers, server);
return server;
}
/* remove server from server list */
void remove_server_list(GList **servers, SETUP_SERVER_REC *rec)
{
g_return_if_fail(rec != NULL);
*servers = g_list_remove(*servers, rec);
g_free(rec->ircnet);
g_free(rec->name);
g_free(rec->location);
g_free(rec);
}
/* Add server to GtkList */
static GList *server_list_add(SETUP_SERVER_REC *server)
{
GtkWidget *li;
GList *list;
char *str;
/* create list item widget */
str = (char *) g_malloc(strlen(server->ircnet)+
strlen(server->name)+
strlen(server->location)+10);
sprintf(str, "%s: [%s] %s", server->ircnet, server->location, server->name);
li = gtk_list_item_new_with_label(str);
g_free(str);
gtk_object_set_data(GTK_OBJECT(li), "server", server);
gtk_widget_show(li);
/* add to local server list */
list = g_list_append(NULL, li);
return list;
}
/* Add new server to both GList and GtkList */
static SETUP_SERVER_REC *local_server_add(GtkList *gtklist, char *ircnet, char *name, int port, char *location)
{
SETUP_SERVER_REC *server;
/* add to list */
server = add_server_list(&servers, ircnet, name, port, location);
gtk_list_append_items(gtklist, server_list_add(server));
return server;
}
/* Remove server from both GList and GtkList */
static void local_server_remove(GtkList *gtklist, GtkWidget *widget)
{
SETUP_SERVER_REC *rec;
int pos, len;
rec = gtk_object_get_data(GTK_OBJECT(widget), "server");
remove_server_list(&servers, rec);
pos = gtk_list_child_position(gtklist, widget);
gtk_list_clear_items(gtklist, pos, pos+1);
len = g_list_length(gtklist->children)-1;
gtk_list_select_item(gtklist, pos > len ? len : pos);
}
/* make a tree list of servers */
static void create_server_tree(GList *servers, GtkTree *tree)
{
GList *tmp;
GtkWidget *li, *subtree, *subitem;
char *ircnet;
g_return_if_fail(tree != NULL);
/* clear previous tree */
gtk_tree_clear_items(tree, 0, -1);
ircnet = ""; subtree = GTK_WIDGET(tree); subitem = NULL;
for (tmp = g_list_first(servers); tmp != NULL; tmp = tmp->next)
{
SETUP_SERVER_REC *serv;
char *str;
serv = (SETUP_SERVER_REC *) tmp->data;
str = (char *) g_malloc(strlen(serv->ircnet)+strlen(serv->location)+strlen(serv->name)+10);
sprintf(str, "[%s] %s", serv->location, serv->name);
if (strcasecmp(ircnet, serv->ircnet) != 0)
{
if (subitem != NULL)
{
gtk_tree_item_set_subtree(GTK_TREE_ITEM(subitem), subtree);
}
li = gtk_tree_item_new_with_label(serv->ircnet);
gtk_widget_show (li);
subtree = gtk_tree_new();
subitem = li;
gtk_tree_append(tree, li);
ircnet = serv->ircnet;
}
li = gtk_tree_item_new_with_label(str);
gtk_widget_show (li);
gtk_tree_append(GTK_TREE(subtree), li);
gtk_object_set_data(GTK_OBJECT(li), "server", serv);
g_free(str);
}
if (subitem != NULL)
{
gtk_tree_item_set_subtree(GTK_TREE_ITEM(subitem), subtree);
}
}
/* make a list of servers */
static void create_server_list(GList *servers, GtkList *list)
{
g_return_if_fail(list != NULL);
/* clear previous list */
gtk_list_clear_items(list, 0, -1);
for (servers = g_list_first(servers); servers != NULL; servers = servers->next)
gtk_list_append_items(list, server_list_add((SETUP_SERVER_REC *) servers->data));
}
/* draw server setup dialog */
static void server_dialog(GtkList *gtklist, char *net, char *location, char *server, int port, GtkSignalFunc func)
{
GtkWidget *win;
GtkWidget *button;
char tmp[20];
g_return_if_fail(net != NULL);
g_return_if_fail(server != NULL);
g_return_if_fail(location != NULL);
g_return_if_fail(func != NULL);
win = gtk_dialog_new();
gtk_object_set_data(GTK_OBJECT(win), "gtklist", gtklist);
gtk_grab_add (GTK_WIDGET (win));
ircnet_text = gui_add_label(GTK_WIDGET(GTK_DIALOG(win)->vbox), "IRC net:", net);
location_text = gui_add_label(GTK_WIDGET(GTK_DIALOG(win)->vbox), "Location:", location);
server_text = gui_add_label(GTK_WIDGET(GTK_DIALOG(win)->vbox), "Server:", server);
sprintf(tmp, "%d", port);
port_text = gui_add_label(GTK_WIDGET(GTK_DIALOG(win)->vbox), "Port:", tmp);
button = gtk_button_new_with_label ("Ok");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG(win)->action_area), button, TRUE, TRUE, 0);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
func, GTK_OBJECT(win));
/*GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);*/
gtk_widget_show (button);
button = gtk_button_new_with_label ("Cancel");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG(win)->action_area), button, TRUE, TRUE, 0);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (gtk_widget_destroy),
GTK_OBJECT(win));
gtk_widget_show (button);
gtk_widget_show(win);
}
/* signal: OK button pressed in add server dialog */
static SETUP_SERVER_REC *add_server_ok(GtkWidget *widget, GtkWidget *dialog)
{
SETUP_SERVER_REC *serv;
GtkList *gtklist;
char *net, *servtext, *location, *tmp;
int port;
g_return_val_if_fail(dialog != NULL, NULL);
gui_get_label(net, ircnet_text);
gui_get_label(location, location_text);
gui_get_label(servtext, server_text);
gui_get_label(tmp, port_text);
sscanf(tmp, "%d", &port);
g_free(tmp);
gtklist = gtk_object_get_data(GTK_OBJECT(dialog), "gtklist");
serv = local_server_add(gtklist, net, servtext, port, location);
g_free(net);
g_free(location);
g_free(servtext);
gtk_widget_destroy(dialog);
return serv;
}
/* signal: add server button pressed */
static void sig_add_server(GtkWidget *widget, GtkList *list)
{
server_dialog(list, "", "", "", 6667, GTK_SIGNAL_FUNC(add_server_ok));
}
/* signal: OK button pressed in edit server dialog */
static void edit_server_ok(GtkWidget *widget, GtkWidget *dialog)
{
GtkList *gtklist;
g_return_if_fail(dialog != NULL);
/* remove old entry */
gtklist = gtk_object_get_data(GTK_OBJECT(dialog), "gtklist");
local_server_remove(gtklist, GTK_WIDGET(gtklist->selection->data));
/* add new entry */
add_server_ok(widget, dialog);
gtk_widget_destroy(dialog);
}
/* signal: edit server button pressed */
static void sig_edit_server(GtkWidget *widget, GtkList *list)
{
SETUP_SERVER_REC *server;
g_return_if_fail(list != NULL);
if (list->selection == NULL) return;
server = gtk_object_get_data(GTK_OBJECT(list->selection->data), "server");
server_dialog(list, server->ircnet, server->location, server->name,
server->port, GTK_SIGNAL_FUNC(edit_server_ok));
}
/* signal: delete server button pressed */
static void sig_delete_server(GtkWidget *widget, GtkList *list)
{
g_return_if_fail(list != NULL);
if (list->selection == NULL) return;
local_server_remove(list, GTK_WIDGET(list->selection->data));
}
/* signal: "move up" button pressed */
static void sig_move_server_up(GtkWidget *widget, GtkList *gtklist)
{
SETUP_SERVER_REC *server;
GList *list;
gpointer data;
int pos;
g_return_if_fail(gtklist != NULL);
if (gtklist->selection == NULL) return;
pos = gtk_list_child_position(gtklist, gtklist->selection->data);
g_return_if_fail(pos != -1);
if (pos == 0) return;
server = gtk_object_get_data(GTK_OBJECT(gtklist->selection->data), "server");
list = server_list_add(server);
gtk_list_clear_items(gtklist, pos, pos+1);
gtk_list_insert_items(gtklist, list, pos-1);
gtk_list_select_item(gtklist, pos-1);
/* modify also glist.. */
list = g_list_nth(servers, pos);
g_return_if_fail(list != NULL);
data = list->data;
servers = g_list_remove_link(servers, list);
servers = g_list_insert(servers, data, pos-1);
}
/* signal: "move down" button pressed */
static void sig_move_server_down(GtkWidget *widget, GtkList *gtklist)
{
SETUP_SERVER_REC *server;
GList *list;
gpointer data;
int pos;
g_return_if_fail(gtklist != NULL);
if (gtklist->selection == NULL) return;
pos = gtk_list_child_position(gtklist, gtklist->selection->data);
g_return_if_fail(pos != -1);
if (pos >= g_list_length(gtklist->children)-1) return;
server = gtk_object_get_data(GTK_OBJECT(gtklist->selection->data), "server");
list = server_list_add(server);
gtk_list_clear_items(gtklist, pos, pos+1);
gtk_list_insert_items(gtklist, list, pos+1);
gtk_list_select_item(gtklist, pos+1);
/* modify also glist.. */
list = g_list_nth(servers, pos);
g_return_if_fail(list != NULL);
data = list->data;
servers = g_list_remove_link(servers, list);
servers = g_list_insert(servers, data, pos+1);
}
/* signal: move server button pressed */
static void sig_move_server(GtkWidget *widget, GtkTree *tree)
{
GtkList *list;
GList *tmp, *next;
g_return_if_fail(tree != NULL);
list = gtk_object_get_data(GTK_OBJECT(widget), "list");
for (tmp = g_list_first(tree->selection); tmp != NULL; tmp = next)
{
SETUP_SERVER_REC *server;
next = tmp->next;
server = gtk_object_get_data(GTK_OBJECT(tmp->data), "server");
if (server != NULL)
{
local_server_add(list, server->ircnet, server->name, server->port,
server->location);
}
gtk_tree_unselect_child(tree, tmp->data);
}
}
static GtkWidget *create_global_servers(GtkWidget *vbox)
{
GtkWidget *tree;
GtkWidget *scrollbox;
scrollbox = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbox),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(vbox), scrollbox, TRUE, TRUE, 0);
gtk_widget_show(scrollbox);
/* server list */
tree = gtk_tree_new();
gtk_tree_set_selection_mode(GTK_TREE(tree), GTK_SELECTION_MULTIPLE);
gtk_container_add(GTK_CONTAINER(scrollbox), tree);
gtk_widget_show(tree);
create_server_tree(globalservers, GTK_TREE(tree));
return tree;
}
GtkWidget *create_local_servers(GtkWidget *vbox, int max)
{
GtkWidget *hbox, *vbox2;
GtkWidget *scrollbox;
GtkWidget *list;
GtkWidget *button;
GtkWidget *arrow;
hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, max, max, 5);
gtk_widget_show(hbox);
/* Create server list widget */
scrollbox = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbox),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(hbox), scrollbox, TRUE, TRUE, 0);
gtk_widget_show(scrollbox);
list = gtk_list_new();
gtk_list_set_selection_mode(GTK_LIST(list), GTK_SELECTION_BROWSE);
gtk_container_add(GTK_CONTAINER(scrollbox), list);
gtk_widget_show(list);
create_server_list(servers, GTK_LIST(list));
/* create buttons to move server up/down in list */
vbox2 = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 0);
gtk_widget_show(vbox2);
button = gtk_button_new();
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(sig_move_server_up), list);
arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_OUT);
gtk_container_add(GTK_CONTAINER(button), arrow);
gtk_widget_show(arrow);
gtk_box_pack_start(GTK_BOX(vbox2), button, TRUE, TRUE, 0);
gtk_widget_show(button);
button = gtk_button_new();
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(sig_move_server_down), list);
arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
gtk_container_add(GTK_CONTAINER(button), arrow);
gtk_widget_show(arrow);
gtk_box_pack_start(GTK_BOX(vbox2), button, TRUE, TRUE, 0);
gtk_widget_show(button);
hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
gtk_widget_show(hbox);
/* add/edit/delete buttons */
button = gtk_button_new_with_label(_("Add"));
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(sig_add_server), list);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 10);
gtk_widget_show(button);
button = gtk_button_new_with_label(_("Edit"));
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(sig_edit_server), list);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 10);
gtk_widget_show(button);
button = gtk_button_new_with_label(_("Delete"));
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(sig_delete_server), list);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 10);
gtk_widget_show(button);
return list;
}
/* draw server notebook section */
void gui_setup_servers(GtkWidget *vbox)
{
GtkWidget *button;
GtkWidget *tree, *list;
tree = create_global_servers(vbox);
button = gtk_button_new_with_label("copy server(s) to local list");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(sig_move_server), tree);
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 5);
gtk_widget_show(button);
list = create_local_servers(vbox, FALSE);
gtk_object_set_data(GTK_OBJECT(button), "list", list);
nick_text = gui_add_label(vbox, "Nick:", default_nick);
name_text = gui_add_label(vbox, "Name:", real_name);
}
/* OK button pressed in dialog - accept changes */
void gui_setup_servers_accept(void)
{
if (default_nick != NULL) g_free(default_nick);
if (real_name != NULL) g_free(real_name);
gui_get_label(default_nick, nick_text);
gui_get_label(real_name, name_text);
}